Refactor to avoid using fork to create initial file (#122)

* Refactor to avoid using fork to create initial file

* Use correct exit value on failure
This commit is contained in:
Quincey Koziol 2020-11-25 15:42:53 -06:00 committed by GitHub
parent 4e23defcdc
commit 3ebcfb8bf3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -53,9 +53,6 @@ static void verify_data_sets(hid_t file_id, int min_dset, int max_dset);
/* local test function declarations */
static hbool_t parse_flags(int argc, char *argv[], hbool_t *setup_ptr, hbool_t *ici_ptr, int *file_idx_ptr,
int *mpi_size_ptr, hbool_t display);
static void usage(void);
static unsigned construct_test_file(int test_file_index);
static void par_create_dataset(int dset_num, hid_t file_id, int mpi_rank, int mpi_size);
static void par_delete_dataset(int dset_num, hid_t file_id, int mpi_rank);
@ -1743,13 +1740,6 @@ par_delete_dataset(int dset_num, hid_t file_id, int mpi_rank)
} /* par_delete_dataset() */
/* This test uses many POSIX things that are not available on
* Windows. We're using a check for fork(2) here as a proxy for
* all POSIX/Unix/Linux things until this test can be made
* more platform-independent.
*/
#ifdef H5_HAVE_FORK
/*-------------------------------------------------------------------------
* Function: par_insert_cache_image()
*
@ -1781,63 +1771,14 @@ par_delete_dataset(int dset_num, hid_t file_id, int mpi_rank)
static void
par_insert_cache_image(int file_name_idx, int mpi_rank, int mpi_size)
{
hbool_t show_progress = FALSE;
if (pass) {
if (mpi_rank == 0) { /* insert cache image in supplied test file */
char file_name_idx_str[32];
char mpi_size_str[32];
int child_status;
pid_t child_pid;
HDsprintf(file_name_idx_str, "%d", file_name_idx);
HDsprintf(mpi_size_str, "%d", mpi_size);
child_pid = fork();
if (child_pid == 0) { /* this is the child process */
/* fun and games to shutup the compiler */
char param0[32] = "t_cache_image";
char param1[32] = "ici";
char *child_argv[] = {param0, param1, file_name_idx_str, mpi_size_str, NULL};
/* we may need to play with the path here */
if (execv("t_cache_image", child_argv) == -1) {
HDfprintf(stdout, "execl() of ici process failed. errno = %d(%s)\n", errno,
strerror(errno));
HDexit(1);
}
}
else if (child_pid != -1) {
/* this is the parent process -- wait until child is done */
if (-1 == waitpid(child_pid, &child_status, WUNTRACED)) {
HDfprintf(stdout, "can't wait on ici process.\n");
pass = FALSE;
}
else if (!WIFEXITED(child_status)) {
HDfprintf(stdout, "ici process hasn't exitied.\n");
pass = FALSE;
}
else if (WEXITSTATUS(child_status) != 0) {
HDfprintf(stdout, "ici process reports failure.\n");
pass = FALSE;
}
else if (show_progress) {
HDfprintf(stdout, "cache image insertion complete.\n");
}
}
else { /* fork failed */
HDfprintf(stdout, "can't create process to insert cache image.\n");
pass = FALSE;
if (!serial_insert_cache_image(file_name_idx, mpi_size)) {
HDfprintf(stderr, "\n\nCache image insertion failed.\n");
HDfprintf(stderr, " failure mssg = \"%s\"\n", failure_mssg);
HDexit(EXIT_FAILURE);
}
}
}
@ -1853,15 +1794,6 @@ par_insert_cache_image(int file_name_idx, int mpi_rank, int mpi_size)
return;
} /* par_insert_cache_image() */
#else /* H5_HAVE_FORK */
static void
par_insert_cache_image(int file_name_idx, int mpi_rank, int mpi_size)
{
return;
} /* par_insert_cache_image() */
#endif /* H5_HAVE_FORK */
/*-------------------------------------------------------------------------
* Function: par_verify_dataset()
@ -2461,158 +2393,6 @@ serial_verify_dataset(int dset_num, hid_t file_id, int mpi_size)
} /* serial_verify_dataset() */
/*-------------------------------------------------------------------------
* Function: parse_flags
*
* Purpose: Parse the flags passed to this program, and load the
* values into the supplied field.
*
* Return: Success: 1
* Failure: 0
*
* Programmer: J Mainzer
* 4/28/11
*
*-------------------------------------------------------------------------
*/
static hbool_t
parse_flags(int argc, char *argv[], hbool_t *setup_ptr, hbool_t *ici_ptr, int *file_idx_ptr,
int *mpi_size_ptr, hbool_t display)
{
const char *fcn_name = "parse_flags()";
const char *(ops[]) = {"setup", "ici"};
int success = TRUE;
HDassert(setup_ptr);
HDassert(*setup_ptr == FALSE);
HDassert(ici_ptr);
HDassert(*ici_ptr == FALSE);
HDassert(file_idx_ptr);
HDassert(mpi_size_ptr);
if (setup_ptr == NULL) {
success = FALSE;
HDfprintf(stdout, "%s: bad arg(s) on entry.\n", fcn_name);
}
if ((success) && ((argc != 1) && (argc != 2) && (argc != 4))) {
success = FALSE;
usage();
}
if ((success) && (argc >= 2)) {
if (strcmp(argv[1], ops[0]) == 0) {
if (argc != 2) {
success = FALSE;
usage();
}
else {
*setup_ptr = TRUE;
}
}
else if (strcmp(argv[1], ops[1]) == 0) {
if (argc != 4) {
success = FALSE;
usage();
}
else {
*ici_ptr = TRUE;
*file_idx_ptr = atoi(argv[2]);
*mpi_size_ptr = atoi(argv[3]);
}
}
}
if ((success) && (display)) {
if (*setup_ptr)
HDfprintf(stdout, "t_cache_image setup\n");
else if (*ici_ptr)
HDfprintf(stdout, "t_cache_image ici %d %d\n", *file_idx_ptr, *mpi_size_ptr);
else
HDfprintf(stdout, "t_cache_image\n");
}
return (success);
} /* parse_flags() */
/*-------------------------------------------------------------------------
* Function: usage
*
* Purpose: Display a brief message describing the purpose and use
* of the program.
*
* Return: void
*
* Programmer: John Mainzer
* 4/28/11
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
void
usage(void)
{
const char *s[] = {
"\n",
"t_cache_image:\n",
"\n",
"Run the parallel cache image tests. \n"
"\n"
"In general, this program is run via MPI. However, at present, files\n"
"with cache images can only be constructed by serial processes.\n",
"\n",
"To square this circle, one process in the parallel computation \n"
"forks a serial version of the test program to handle this detail.\n",
"The \"setup\" parameter indicates that t_cache_image is being \n",
"invokde for this purpose.\n",
"\n",
"Similarly, only a serial process can add a cache image to an\n",
"existing file.\n",
"\n",
"Here again, one process forks a serial version of the test program\n",
"with the \"ici\" parameter.\n"
"\n",
"usage: t_cache_image [setup|ici m n]\n",
"\n",
"where:\n",
"\n",
" setup parameter forces creation of test file\n",
"\n",
" ici parameter forces insertion of a cache image into the \n",
" m th test file, created by a parallel computation with .\n",
" n processes\n",
"\n",
"Returns 0 on success, 1 on failure.\n",
"\n",
NULL,
};
int i = 0;
while (s[i] != NULL) {
HDfprintf(stdout, "%s", s[i]);
i++;
}
return;
} /* usage() */
/*-------------------------------------------------------------------------
* Function: verify_data_sets()
*
@ -3814,13 +3594,6 @@ smoke_check_1(MPI_Comm mpi_comm, MPI_Info mpi_info, int mpi_rank, int mpi_size)
} /* smoke_check_1() */
/* This test uses many POSIX things that are not available on
* Windows. We're using a check for fork(2) here as a proxy for
* all POSIX/Unix/Linux things until this test can be made
* more platform-independent.
*/
#ifdef H5_HAVE_FORK
/*-------------------------------------------------------------------------
* Function: main
*
@ -3850,65 +3623,12 @@ smoke_check_1(MPI_Comm mpi_comm, MPI_Info mpi_info, int mpi_rank, int mpi_size)
int
main(int argc, char **argv)
{
hbool_t setup = FALSE;
hbool_t ici = FALSE;
unsigned nerrs = 0;
MPI_Comm comm = MPI_COMM_WORLD;
MPI_Info info = MPI_INFO_NULL;
int file_idx;
int i;
int mpi_size;
int mpi_rank;
if (!parse_flags(argc, argv, &setup, &ici, &file_idx, &mpi_size, FALSE))
exit(1); /* exit now if unable to parse flags */
if (setup) { /* construct test files and exit */
H5open();
HDfprintf(stdout, "Constructing test files: \n");
HDfflush(stdout);
i = 0;
while ((FILENAMES[i] != NULL) && (i < TEST_FILES_TO_CONSTRUCT)) {
HDfprintf(stdout, " writing %s ... ", FILENAMES[i]);
HDfflush(stdout);
construct_test_file(i);
if (pass) {
HDprintf("done.\n");
HDfflush(stdout);
}
else {
HDprintf("failed.\n");
HDexit(1);
}
i++;
}
HDfprintf(stdout, "Test file construction complete.\n");
HDexit(0);
}
else if (ici) {
if (serial_insert_cache_image(file_idx, mpi_size)) {
HDexit(0);
}
else {
HDfprintf(stderr, "\n\nCache image insertion failed.\n");
HDfprintf(stderr, " failure mssg = \"%s\"\n", failure_mssg);
HDexit(1);
}
}
HDassert(!setup);
HDassert(!ici);
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
@ -3937,50 +3657,28 @@ main(int argc, char **argv)
}
if (mpi_rank == 0) { /* create test files */
int i;
int child_status;
pid_t child_pid;
HDfprintf(stdout, "Constructing test files: \n");
HDfflush(stdout);
child_pid = fork();
i = 0;
while ((FILENAMES[i] != NULL) && (i < TEST_FILES_TO_CONSTRUCT)) {
HDfprintf(stdout, " writing %s ... ", FILENAMES[i]);
HDfflush(stdout);
construct_test_file(i);
if (child_pid == 0) { /* this is the child process */
/* fun and games to shutup the compiler */
char param0[32] = "t_cache_image";
char param1[32] = "setup";
char *child_argv[] = {param0, param1, NULL};
/* we may need to play with the path here */
if (execv("t_cache_image", child_argv) == -1) {
HDfprintf(stdout, "execl() of setup process failed. errno = %d(%s)\n", errno,
strerror(errno));
HDexit(1);
}
}
else if (child_pid != -1) {
/* this is the parent process -- wait until child is done */
if (-1 == waitpid(child_pid, &child_status, WUNTRACED)) {
HDfprintf(stdout, "can't wait on setup process.\n");
}
else if (!WIFEXITED(child_status)) {
HDfprintf(stdout, "setup process hasn't exitied.\n");
}
else if (WEXITSTATUS(child_status) != 0) {
HDfprintf(stdout, "setup process reports failure.\n");
if (pass) {
HDprintf("done.\n");
HDfflush(stdout);
}
else {
HDfprintf(stdout, "testfile construction complete -- proceeding with tests.\n");
HDprintf("failed.\n");
HDexit(EXIT_FAILURE);
}
i++;
}
else { /* fork failed */
HDfprintf(stdout, "can't create process to construct test file.\n");
}
HDfprintf(stdout, "Test file construction complete.\n");
}
/* can't start test until test files exist */
@ -4018,13 +3716,3 @@ finish:
return (nerrs > 0);
} /* main() */
#else /* H5_HAVE_FORK */
int
main(void)
{
HDfprintf(stderr, "Non-POSIX platform. Skipping.\n");
return EXIT_SUCCESS;
} /* end main() */
#endif /* H5_HAVE_FORK */