/*------------------------------------------------------------------------- * Function: main * * Purpose: h5watch * * Return: Success: 0 * Failure: 1 * * Programmer: Vailin Choi; August 2010 * *------------------------------------------------------------------------- */ int main(int argc, const char *argv[]) { char drivername[50]; char *fname = NULL; char *dname = NULL; void *edata; H5E_auto2_t func; char *x; hid_t fid = -1; hid_t fapl = -1; /* Set up tool name and exit status */ h5tools_setprogname(PROGRAMNAME); h5tools_setstatus(EXIT_SUCCESS); /* Disable error reporting */ H5Eget_auto2(H5E_DEFAULT, &func, &edata); H5Eset_auto2(H5E_DEFAULT, NULL, NULL); /* Initialize h5tools lib */ h5tools_init(); /* parse command line options */ parse_command_line(argc, argv); if(argc <= opt_ind) { error_msg("missing dataset name\n"); usage(h5tools_getprogname()); leave(EXIT_FAILURE); } /* Mostly copied from tools/h5ls coding & modified accordingly */ /* * [OBJECT] is specified as * [<filename>/<path_to_dataset>/<dsetname>] * * Example: ../dir1/foo/bar/dset * \_________/\______/ * file obj * * The dichotomy is determined by calling H5Fopen() repeatedly until it * succeeds. The first call uses the entire name and each subsequent call * chops off the last component. If we reach the beginning of the name * then there must have been something wrong with the file (perhaps it * doesn't exist). */ if((fname = HDstrdup(argv[opt_ind])) == NULL) { error_msg("memory allocation failed (file %s:line %d)\n", __FILE__, __LINE__); h5tools_setstatus(EXIT_FAILURE); } /* Create a copy of file access property list */ if((fapl = H5Pcreate(H5P_FILE_ACCESS)) < 0) return -1; /* Set to use the latest library format */ if(H5Pset_libver_bounds(fapl, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST) < 0) return -1; do { while(fname && *fname) { fid = h5tools_fopen(fname, H5F_ACC_RDONLY|H5F_ACC_SWMR_READ, fapl, NULL, drivername, sizeof drivername); if(fid >= 0) { HDfprintf(stdout, "Opened \"%s\" with %s driver.\n", fname, drivername); break; /*success*/ } /* end if */ /* Shorten the file name; lengthen the object name */ x = dname; dname = HDstrrchr(fname, '/'); if(x) *x = '/'; if(!dname) break; *dname = '\0'; } /* end while */ /* Try opening the file again if somehow unstable */ } while(g_retry-- > 0 && fid == FAIL); if(fid < 0) { error_msg("unable to open file \"%s\"\n", fname); if(fname) HDfree(fname); if(fapl >= 0) H5Pclose(fapl); leave(EXIT_FAILURE); } if(!dname) { error_msg("no dataset specified\n"); h5tools_setstatus(EXIT_FAILURE); } else { *dname = '/'; x = dname; if((dname = HDstrdup(dname)) == NULL) { error_msg("memory allocation failed (file %s:line %d)\n", __FILE__, __LINE__); h5tools_setstatus(EXIT_FAILURE); } else { *x = '\0'; /* Validate dataset */ if(check_dataset(fid, dname) < 0) h5tools_setstatus(EXIT_FAILURE); /* Validate input "fields" */ else if(g_list_of_fields && *g_list_of_fields) if(process_cmpd_fields(fid, dname) < 0) h5tools_setstatus(EXIT_FAILURE); } } /* If everything is fine, start monitoring the datset */ if(h5tools_getstatus() != EXIT_FAILURE) if(monitor_dataset(fid, dname) < 0) h5tools_setstatus(EXIT_FAILURE); /* Free spaces */ if(fname) HDfree(fname); if(dname) HDfree(dname); if(g_list_of_fields) HDfree(g_list_of_fields); if(g_listv) { H5LD_clean_vector(g_listv); HDfree(g_listv); } if(g_dup_fields) HDfree(g_dup_fields); /* Close the file access property list */ if(fapl >= 0 && H5Pclose(fapl) < 0) { error_msg("unable to close file access property list\n"); h5tools_setstatus(EXIT_FAILURE); } /* Close the file */ if(H5Fclose(fid) < 0) { error_msg("unable to close file\n"); h5tools_setstatus(EXIT_FAILURE); } H5Eset_auto2(H5E_DEFAULT, func, edata); /* exit */ leave(h5tools_getstatus()); } /* main() */
/*------------------------------------------------------------------------- * Function: read_records * * Purpose: For a given dataset, checks to make sure that the stated * and actual sizes are the same. If they are not, then * we have an inconsistent dataset due to a SWMR error. * * Parameters: const char *filename * The SWMR test file's name. * * unsigned verbose * Whether verbose console output is desired. * * unsigned long nrecords * The total number of records to read. * * unsigned poll_time * The amount of time to sleep (s). * * unsigned reopen_count * * * Return: Success: 0 * Failure: -1 * *------------------------------------------------------------------------- */ static int read_records(const char *filename, unsigned verbose, unsigned long nrecords, unsigned poll_time, unsigned reopen_count) { hid_t fid; /* File ID */ hid_t aid; /* Attribute ID */ time_t start_time; /* Starting time */ hid_t mem_sid; /* Memory dataspace ID */ symbol_t record; /* The record to add to the dataset */ unsigned seed; /* Seed for random number generator */ unsigned iter_to_reopen = reopen_count; /* # of iterations until reopen */ unsigned long u; /* Local index variable */ hid_t fapl; HDassert(filename); HDassert(poll_time != 0); /* Create file access property list */ if((fapl = h5_fileaccess()) < 0) return -1; H5Pset_fclose_degree(fapl, H5F_CLOSE_SEMI); /* Emit informational message */ if(verbose) HDfprintf(stderr, "Opening file: %s\n", filename); /* Open the file */ if((fid = H5Fopen(filename, H5F_ACC_RDONLY | H5F_ACC_SWMR_READ, fapl)) < 0) return -1; /* Seed the random number generator with the attribute in the file */ if((aid = H5Aopen(fid, "seed", H5P_DEFAULT)) < 0) return -1; if(H5Aread(aid, H5T_NATIVE_UINT, &seed) < 0) return -1; if(H5Aclose(aid) < 0) return -1; HDsrandom(seed); /* Reset the record */ /* (record's 'info' field might need to change for each record written, also) */ HDmemset(&record, 0, sizeof(record)); /* Create a dataspace for the record to read */ if((mem_sid = H5Screate(H5S_SCALAR)) < 0) return -1; /* Emit informational message */ if(verbose) HDfprintf(stderr, "Reading records\n"); /* Get the starting time */ start_time = HDtime(NULL); /* Read records */ for(u = 0; u < nrecords; u++) { symbol_info_t *symbol = NULL; /* Symbol (dataset) */ htri_t attr_exists; /* Whether the sequence number attribute exists */ unsigned long file_u; /* Attribute sequence number (writer's "u") */ /* Get a random dataset, according to the symbol distribution */ symbol = choose_dataset(); /* Fill in "nrecords" field. Note that this depends on the writer * using the same algorithm and "nrecords" */ symbol->nrecords = nrecords / 5; /* Wait until we can read the dataset */ do { /* Check if sequence attribute exists */ if((attr_exists = H5Aexists_by_name(fid, symbol->name, "seq", H5P_DEFAULT)) < 0) return -1; if(attr_exists) { /* Read sequence number attribute */ if((aid = H5Aopen_by_name(fid, symbol->name, "seq", H5P_DEFAULT, H5P_DEFAULT)) < 0) return -1; if(H5Aread(aid, H5T_NATIVE_ULONG, &file_u) < 0) return -1; if(H5Aclose(aid) < 0) return -1; /* Check if sequence number is at least u - if so, this should * guarantee that this record has been written */ if(file_u >= u) break; } /* end if */ /* Check for timeout */ if(HDtime(NULL) >= (time_t)(start_time + (time_t)TIMEOUT)) { HDfprintf(stderr, "Reader timed out\n"); return -1; } /* end if */ /* Pause */ HDsleep(poll_time); /* Retrieve and print the collection of metadata read retries */ if(print_metadata_retries_info(fid) < 0) HDfprintf(stderr, "Warning: could not obtain metadata retries info\n"); /* Reopen the file */ if(H5Fclose(fid) < 0) return -1; if((fid = H5Fopen(filename, H5F_ACC_RDONLY | H5F_ACC_SWMR_READ, fapl)) < 0) return -1; iter_to_reopen = reopen_count; } while(1); /* Emit informational message */ if(verbose) HDfprintf(stderr, "Checking dataset %lu\n", u); /* Check dataset */ if(check_dataset(fid, verbose, symbol, &record, mem_sid) < 0) return -1; HDmemset(&record, 0, sizeof(record)); /* Check for reopen */ iter_to_reopen--; if(iter_to_reopen == 0) { /* Emit informational message */ if(verbose) HDfprintf(stderr, "Reopening file: %s\n", filename); /* Retrieve and print the collection of metadata read retries */ if(print_metadata_retries_info(fid) < 0) HDfprintf(stderr, "Warning: could not obtain metadata retries info\n"); /* Reopen the file */ if(H5Fclose(fid) < 0) return -1; if((fid = H5Fopen(filename, H5F_ACC_RDONLY | H5F_ACC_SWMR_READ, fapl)) < 0) return -1; iter_to_reopen = reopen_count; } /* end if */ } /* end while */ /* Retrieve and print the collection of metadata read retries */ if(print_metadata_retries_info(fid) < 0) HDfprintf(stderr, "Warning: could not obtain metadata retries info\n"); /* Close file */ if(H5Fclose(fid) < 0) return -1; /* Close the memory dataspace */ if(H5Sclose(mem_sid) < 0) return -1; return 0; } /* end read_records() */