mirror of
https://github.com/HDFGroup/hdf5.git
synced 2024-11-21 01:04:10 +08:00
[svn-r4091]
Purpose: Use port hunting to test the Stream VFD Description: The stream driver is tested by streaming data between two different processes on the local machine on a given default port. If this port is already is use, port hunting should find the next available port to use. The hostname/port information which is actually used by the sender is written to a temporary file which is then read by the receiver process to connect to the sender's port. For the purpose of testing I switched back the default port to use from 10007 to 5678 which is at least already used by another service on modi4. Platforms tested: x86 Linux, Irix 32/64 bit (modi4), Dec Alpha, Unicos on T3E, Hitachi SR8000, AIX on SP2
This commit is contained in:
parent
9f06972b48
commit
69b26f8ecb
@ -17,15 +17,20 @@
|
|||||||
/*
|
/*
|
||||||
* This program tests the functionality of the Stream Virtual File Driver.
|
* This program tests the functionality of the Stream Virtual File Driver.
|
||||||
* 1. It spawns two new processes, a sender and a receiver.
|
* 1. It spawns two new processes, a sender and a receiver.
|
||||||
* 2. The sender opens an HDF5 file for writing and writes
|
* 2. The sender opens an HDF5 file for writing using the Stream driver.
|
||||||
* a sample dataset to it.
|
* It will use a reserved port which should fail to be bound.
|
||||||
|
* Then it will try a couple of successive ports until bind succeeds.
|
||||||
|
* This final "hostname:port" information is written into a temporary
|
||||||
|
* file as a single line of text.
|
||||||
|
* The sender then writes a sample dataset to the HDF5 file.
|
||||||
* On closing the file the Stream VFD would send the file
|
* On closing the file the Stream VFD would send the file
|
||||||
* contents to any connected client.
|
* contents to any connected client.
|
||||||
* 3. The receiver serves as a client attempting to open an
|
* 3. The receiver serves as a client attempting to open an
|
||||||
* HDF5 file for reading. On opening the file the Stream VFD
|
* HDF5 file for reading. On opening the file the Stream VFD
|
||||||
* would establish a socket connection to the sender process,
|
* would establish a socket connection to the sender process,
|
||||||
* identified by its hostname (which is localhost in this example)
|
* identified by its hostname and a port number (which is obtained
|
||||||
* and a port number, and read the file contents via this socket.
|
* from the temporary text file the sender should have created),
|
||||||
|
* and read the file contents via this socket.
|
||||||
* Aftwerwards the dataset is read from the file into memory
|
* Aftwerwards the dataset is read from the file into memory
|
||||||
* and verified.
|
* and verified.
|
||||||
* 4. The main program waits for termination of its two child
|
* 4. The main program waits for termination of its two child
|
||||||
@ -60,11 +65,15 @@ int main (void)
|
|||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
|
|
||||||
|
|
||||||
#define DELAY 10 /* sleeping time in seconds */
|
#define SLEEPTIME 10 /* sleeping time in seconds */
|
||||||
#define RANK 2 /* sample dataset rank */
|
#define RANK 2 /* sample dataset rank */
|
||||||
#define DIMS 50 /* sample dataset dimensions */
|
#define DIMS 50 /* sample dataset dimensions */
|
||||||
#define DATASETNAME "IntArray" /* sample dataset name */
|
#define DATASETNAME "IntArray" /* sample dataset name */
|
||||||
#define FILENAME "localhost:10007" /* filename argument */
|
#define HOSTNAME "localhost" /* hostname of this machine */
|
||||||
|
#define PORT "5678" /* default port to use */
|
||||||
|
#define MAXHUNT 500 /* max number of ports to hunt */
|
||||||
|
#define HDF5_FILENAME HOSTNAME ":" PORT /* name of the streamed file */
|
||||||
|
#define TEMPFILENAME "stream_test.tmp" /* temporary filename */
|
||||||
|
|
||||||
|
|
||||||
static int sender (void)
|
static int sender (void)
|
||||||
@ -75,6 +84,8 @@ static int sender (void)
|
|||||||
herr_t status;
|
herr_t status;
|
||||||
hid_t fapl, file;
|
hid_t fapl, file;
|
||||||
hid_t dataspace, dataset;
|
hid_t dataspace, dataset;
|
||||||
|
H5FD_stream_fapl_t stream_fapl;
|
||||||
|
FILE *tempfile;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -87,7 +98,26 @@ static int sender (void)
|
|||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
status = H5Pset_fapl_stream (fapl, NULL);
|
/*
|
||||||
|
* Setup file access property list and select Stream VFD.
|
||||||
|
*
|
||||||
|
* - block increment for realloc() should be chosen by the driver
|
||||||
|
* - no external socket is provided (should be created internally)
|
||||||
|
* - do I/O on this processor on this socket
|
||||||
|
* - only one client is allowed to connect at a time
|
||||||
|
* - no READ broadcast function is provided (since we only send data)
|
||||||
|
* - if bind to default port (given in the filename argument) fails
|
||||||
|
* do port hunting on the following MAXHUNT ports
|
||||||
|
*/
|
||||||
|
stream_fapl.increment = 0;
|
||||||
|
stream_fapl.socket = H5FD_STREAM_INVALID_SOCKET;
|
||||||
|
stream_fapl.do_socket_io = 1;
|
||||||
|
stream_fapl.backlog = 1;
|
||||||
|
stream_fapl.broadcast_fn = NULL;
|
||||||
|
stream_fapl.broadcast_arg = NULL;
|
||||||
|
stream_fapl.maxhunt = MAXHUNT;
|
||||||
|
|
||||||
|
status = H5Pset_fapl_stream (fapl, &stream_fapl);
|
||||||
if (status < 0)
|
if (status < 0)
|
||||||
{
|
{
|
||||||
fprintf (stderr, "sender: couldn't set file access property list "
|
fprintf (stderr, "sender: couldn't set file access property list "
|
||||||
@ -134,17 +164,51 @@ static int sender (void)
|
|||||||
* default file creation properties, and STREAM file
|
* default file creation properties, and STREAM file
|
||||||
* access properties.
|
* access properties.
|
||||||
*/
|
*/
|
||||||
printf (" sender: opening file '%s' for writing...\n", FILENAME);
|
printf (" sender: opening file on host '%s' port %s for writing...\n",
|
||||||
file = H5Fcreate (FILENAME, H5F_ACC_TRUNC, H5P_DEFAULT, fapl);
|
HOSTNAME, PORT);
|
||||||
|
file = H5Fcreate (HDF5_FILENAME, H5F_ACC_TRUNC, H5P_DEFAULT, fapl);
|
||||||
if (file < 0)
|
if (file < 0)
|
||||||
{
|
{
|
||||||
fprintf (stderr, "sender: couldn't create file for '%s'\n", FILENAME);
|
fprintf (stderr, "sender: couldn't create file on '%s' using port %s and "
|
||||||
|
"following %d\n", HOSTNAME, PORT, MAXHUNT);
|
||||||
free (data);
|
free (data);
|
||||||
H5Sclose (dataspace);
|
H5Sclose (dataspace);
|
||||||
H5Pclose (fapl);
|
H5Pclose (fapl);
|
||||||
return (-5);
|
return (-5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get the file access property list to find out what port is actually used.
|
||||||
|
*/
|
||||||
|
status = H5Pget_fapl_stream (fapl, &stream_fapl);
|
||||||
|
if (status < 0)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "sender: couldn't get file access property list "
|
||||||
|
"for Stream VFD\n");
|
||||||
|
free (data);
|
||||||
|
H5Sclose (dataspace);
|
||||||
|
H5Pclose (fapl);
|
||||||
|
return (-6);
|
||||||
|
}
|
||||||
|
printf (" sender: using port %d...\n", (int) stream_fapl.port);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Write the "hostname:port" information to a temporary file
|
||||||
|
* which can be read by the receiver process.
|
||||||
|
*/
|
||||||
|
tempfile = fopen (TEMPFILENAME, "w");
|
||||||
|
if (tempfile == NULL)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "sender: couldn't open temporary file to write "
|
||||||
|
"\"hostname:port\" information\n");
|
||||||
|
free (data);
|
||||||
|
H5Sclose (dataspace);
|
||||||
|
H5Pclose (fapl);
|
||||||
|
return (-7);
|
||||||
|
}
|
||||||
|
fprintf (tempfile, "%s:%d", HOSTNAME, (int) stream_fapl.port);
|
||||||
|
fclose (tempfile);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create a new dataset within the file using defined dataspace and
|
* Create a new dataset within the file using defined dataspace and
|
||||||
* default dataset creation properties.
|
* default dataset creation properties.
|
||||||
@ -158,14 +222,14 @@ static int sender (void)
|
|||||||
H5Fclose (file);
|
H5Fclose (file);
|
||||||
H5Sclose (dataspace);
|
H5Sclose (dataspace);
|
||||||
H5Pclose (fapl);
|
H5Pclose (fapl);
|
||||||
return (-6);
|
return (-8);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Write the data to the dataset using default transfer properties.
|
* Write the data to the dataset using default transfer properties.
|
||||||
*/
|
*/
|
||||||
printf (" sender: writing dataset '%s' of type INTEGER to file '%s'...\n",
|
printf (" sender: writing dataset '%s' of type INTEGER to file '%s:%d'...\n",
|
||||||
DATASETNAME, FILENAME);
|
DATASETNAME, HOSTNAME, (int) stream_fapl.port);
|
||||||
status = H5Dwrite (dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT,
|
status = H5Dwrite (dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT,
|
||||||
data);
|
data);
|
||||||
if (status < 0)
|
if (status < 0)
|
||||||
@ -176,16 +240,16 @@ static int sender (void)
|
|||||||
H5Sclose (dataspace);
|
H5Sclose (dataspace);
|
||||||
H5Pclose (fapl);
|
H5Pclose (fapl);
|
||||||
fprintf (stderr, "sender: couldn't write dataset\n");
|
fprintf (stderr, "sender: couldn't write dataset\n");
|
||||||
return (-7);
|
return (-9);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Now give the receiver some time to connect before closing the file
|
* Now give the receiver some time to connect before closing the file
|
||||||
* and releasing resources.
|
* and releasing resources.
|
||||||
*/
|
*/
|
||||||
printf (" sender: sleeping for %d seconds...\n", DELAY);
|
printf (" sender: sleeping for %d seconds...\n", SLEEPTIME);
|
||||||
sleep (DELAY);
|
sleep (SLEEPTIME);
|
||||||
printf (" sender: closing file '%s'\n", FILENAME);
|
printf (" sender: closing file '%s:%d'\n", HOSTNAME, (int) stream_fapl.port);
|
||||||
H5Sclose (dataspace);
|
H5Sclose (dataspace);
|
||||||
H5Dclose (dataset);
|
H5Dclose (dataset);
|
||||||
H5Fclose (file);
|
H5Fclose (file);
|
||||||
@ -210,6 +274,8 @@ static int receiver (void)
|
|||||||
int *data; /* read buffer */
|
int *data; /* read buffer */
|
||||||
int nerrors; /* total number of errors during verify */
|
int nerrors; /* total number of errors during verify */
|
||||||
int status; /* return code of HDF5 routines */
|
int status; /* return code of HDF5 routines */
|
||||||
|
char filename[50]; /* filename of the streamed HDF5 file */
|
||||||
|
FILE *tempfile; /* descriptor for temporary file */
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -227,21 +293,42 @@ static int receiver (void)
|
|||||||
{
|
{
|
||||||
fprintf (stderr, "receiver: couldn't set file access property list "
|
fprintf (stderr, "receiver: couldn't set file access property list "
|
||||||
"for Stream VFD\n");
|
"for Stream VFD\n");
|
||||||
|
H5Pclose (fapl);
|
||||||
return (-2);
|
return (-2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Now give the sender some time to open the file and accepting connections.
|
* Now give the sender some time to open the file and accepting connections.
|
||||||
*/
|
*/
|
||||||
printf (" receiver: sleeping for %d seconds...\n", DELAY / 2);
|
printf (" receiver: sleeping for %d seconds...\n", SLEEPTIME / 2);
|
||||||
sleep (DELAY / 2);
|
sleep (SLEEPTIME / 2);
|
||||||
printf (" receiver: opening file '%s' for reading...\n", FILENAME);
|
|
||||||
file = H5Fopen (FILENAME, H5F_ACC_RDONLY, fapl);
|
/*
|
||||||
|
* Read the "hostname:port" information from the temporary file
|
||||||
|
* the sender should have created.
|
||||||
|
*/
|
||||||
|
tempfile = fopen (TEMPFILENAME, "r");
|
||||||
|
if (tempfile == NULL)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "receiver: couldn't open temporary file to read "
|
||||||
|
"\"hostname:port\" information\n");
|
||||||
|
H5Pclose (fapl);
|
||||||
|
return (-3);
|
||||||
|
}
|
||||||
|
fgets (filename, sizeof (filename) - 1, tempfile);
|
||||||
|
fclose (tempfile);
|
||||||
|
unlink (TEMPFILENAME);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Open the streamed HDF5 file for reading.
|
||||||
|
*/
|
||||||
|
printf (" receiver: opening file '%s' for reading...\n", filename);
|
||||||
|
file = H5Fopen (filename, H5F_ACC_RDONLY, fapl);
|
||||||
H5Pclose (fapl);
|
H5Pclose (fapl);
|
||||||
if (file < 0)
|
if (file < 0)
|
||||||
{
|
{
|
||||||
fprintf (stderr, "receiver: couldn't open file from '%s'\n", FILENAME);
|
fprintf (stderr, "receiver: couldn't open file from '%s'\n", filename);
|
||||||
return (-3);
|
return (-4);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -252,7 +339,7 @@ static int receiver (void)
|
|||||||
if (dataset < 0)
|
if (dataset < 0)
|
||||||
{
|
{
|
||||||
fprintf (stderr, "receiver: couldn't open dataset '%s'\n", DATASETNAME);
|
fprintf (stderr, "receiver: couldn't open dataset '%s'\n", DATASETNAME);
|
||||||
return (-4);
|
return (-5);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -291,7 +378,7 @@ static int receiver (void)
|
|||||||
/*
|
/*
|
||||||
* Read dataset from file into memory.
|
* Read dataset from file into memory.
|
||||||
*/
|
*/
|
||||||
data = (int *) malloc ((size_t)(nelems * sizeof (int)));
|
data = (int *) malloc ((size_t) nelems * sizeof (int));
|
||||||
status = H5Dread (dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT,
|
status = H5Dread (dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT,
|
||||||
data);
|
data);
|
||||||
H5Dclose (dataset);
|
H5Dclose (dataset);
|
||||||
@ -299,7 +386,7 @@ static int receiver (void)
|
|||||||
/*
|
/*
|
||||||
* Close the file.
|
* Close the file.
|
||||||
*/
|
*/
|
||||||
printf (" receiver: closing file '%s'...\n", FILENAME);
|
printf (" receiver: closing file '%s'...\n", filename);
|
||||||
H5Fclose (file);
|
H5Fclose (file);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
Reference in New Issue
Block a user