From fa087c39199fccc1686b122e67b56e06c8fbe313 Mon Sep 17 00:00:00 2001 From: Jordan Henderson Date: Tue, 11 Feb 2020 17:57:19 -0600 Subject: Update Tools library to be better compatible with VOL connectors Modify h5repack to integrate with VOL connectors Update tools library to accomodate VOL connectors Update logic in h5tools_fopen for VOL connectors Add command-line options to h5repack for specifying in/out VOL connectors Implement h5tools_set_vol_fapl Fix library shutdown issue Integrate ROS3 and HDFS VFDs into new h5tools_get_fapl() scheme Avoid H5Ocopy in h5repack when using different VOL connectors Update h5tools_test_utils.c for ROS3 and HDFS integration --- hl/tools/h5watch/h5watch.c | 10 +- src/H5.c | 4 +- src/H5VLint.c | 2 +- src/H5VLpassthru.c | 12 + tools/lib/h5diff.c | 4 +- tools/lib/h5tools.c | 611 ++++++++++++++++++------ tools/lib/h5tools.h | 49 +- tools/lib/h5tools_error.h | 52 +- tools/lib/h5tools_utils.c | 159 +++--- tools/lib/h5tools_utils.h | 7 +- tools/libtest/h5tools_test_utils.c | 18 +- tools/src/h5copy/h5copy.c | 4 +- tools/src/h5dump/h5dump.c | 198 +++----- tools/src/h5format_convert/h5format_convert.c | 2 +- tools/src/h5ls/h5ls.c | 249 +++------- tools/src/h5repack/h5repack.c | 5 +- tools/src/h5repack/h5repack.h | 4 +- tools/src/h5repack/h5repack_copy.c | 82 +++- tools/src/h5repack/h5repack_main.c | 208 ++++++-- tools/src/h5repack/h5repack_verify.c | 22 +- tools/src/h5stat/h5stat.c | 194 +++----- tools/src/misc/h5clear.c | 4 +- tools/src/misc/h5mkgrp.c | 2 +- tools/test/h5format_convert/h5fc_chk_idx.c | 2 +- tools/test/h5repack/h5repacktst.c | 10 +- tools/test/h5repack/testfiles/h5repack-help.txt | 12 + tools/test/misc/clear_open_chk.c | 2 +- 27 files changed, 1166 insertions(+), 762 deletions(-) diff --git a/hl/tools/h5watch/h5watch.c b/hl/tools/h5watch/h5watch.c index b7f583c..ff9a078 100644 --- a/hl/tools/h5watch/h5watch.c +++ b/hl/tools/h5watch/h5watch.c @@ -822,7 +822,9 @@ main(int argc, const char *argv[]) char *fname = NULL; /* File name */ char *dname = NULL; /* Dataset name */ void *edata; /* Error reporting */ + void *tools_edata; /* Error reporting */ H5E_auto2_t func; /* Error reporting */ + H5E_auto2_t tools_func; /* Error reporting */ char *x; /* Temporary string pointer */ hid_t fid = -1; /* File ID */ hid_t fapl = -1; /* File access property list */ @@ -838,6 +840,10 @@ main(int argc, const char *argv[]) /* Initialize h5tools lib */ h5tools_init(); + /* Disable tools error reporting */ + H5Eget_auto2(H5tools_ERR_STACK_g, &tools_func, &tools_edata); + H5Eset_auto2(H5tools_ERR_STACK_g, NULL, NULL); + /* To exit from h5watch for SIGTERM signal */ if(HDsignal(SIGTERM, catch_signal) == SIG_ERR) { error_msg("An error occurred while setting a signal handler.\n"); @@ -890,7 +896,7 @@ main(int argc, const char *argv[]) do { while(fname && *fname) { - fid = h5tools_fopen(fname, H5F_ACC_RDONLY|H5F_ACC_SWMR_READ, fapl, NULL, drivername, sizeof drivername); + fid = h5tools_fopen(fname, H5F_ACC_RDONLY|H5F_ACC_SWMR_READ, fapl, FALSE, drivername, sizeof drivername); if(fid >= 0) { HDfprintf(stdout, "Opened \"%s\" with %s driver.\n", fname, drivername); @@ -966,6 +972,8 @@ main(int argc, const char *argv[]) } H5Eset_auto2(H5E_DEFAULT, func, edata); + H5Eset_auto2(H5tools_ERR_STACK_g, tools_func, tools_edata); + /* exit */ leave(h5tools_getstatus()); } /* main() */ diff --git a/src/H5.c b/src/H5.c index 16c12cb..62a1c09 100644 --- a/src/H5.c +++ b/src/H5.c @@ -355,7 +355,9 @@ H5_term_library(void) pending += DOWN(Z); pending += DOWN(FD); pending += DOWN(VL); - pending += DOWN(PL); + /* Don't shut down the plugin code until all "pluggable" interfaces (Z, FD, PL) are shut down */ + if(pending == 0) + pending += DOWN(PL); /* Don't shut down the error code until other APIs which use it are shut down */ if(pending == 0) pending += DOWN(E); diff --git a/src/H5VLint.c b/src/H5VLint.c index 6572faa..861629f 100644 --- a/src/H5VLint.c +++ b/src/H5VLint.c @@ -273,7 +273,7 @@ H5VL_term_package(void) else { if(H5I_nmembers(H5I_VOL) > 0) { /* Unregister all VOL connectors */ - (void)H5I_clear_type(H5I_VOL, FALSE, FALSE); + (void)H5I_clear_type(H5I_VOL, TRUE, FALSE); n++; } /* end if */ else { diff --git a/src/H5VLpassthru.c b/src/H5VLpassthru.c index 8b3dc62..2cf470e 100644 --- a/src/H5VLpassthru.c +++ b/src/H5VLpassthru.c @@ -1591,6 +1591,10 @@ H5VL_pass_through_file_create(const char *name, unsigned flags, hid_t fcpl_id, /* Get copy of our VOL info from FAPL */ H5Pget_vol_info(fapl_id, (void **)&info); + /* Make sure we have info about the underlying VOL to be used */ + if (!info) + return NULL; + /* Copy the FAPL */ under_fapl_id = H5Pcopy(fapl_id); @@ -1645,6 +1649,10 @@ H5VL_pass_through_file_open(const char *name, unsigned flags, hid_t fapl_id, /* Get copy of our VOL info from FAPL */ H5Pget_vol_info(fapl_id, (void **)&info); + /* Make sure we have info about the underlying VOL to be used */ + if (!info) + return NULL; + /* Copy the FAPL */ under_fapl_id = H5Pcopy(fapl_id); @@ -1785,6 +1793,10 @@ H5VL_pass_through_file_specific(void *file, H5VL_file_specific_t specific_type, /* Get copy of our VOL info from FAPL */ H5Pget_vol_info(fapl_id, (void **)&info); + /* Make sure we have info about the underlying VOL to be used */ + if (!info) + return (-1); + /* Copy the FAPL */ under_fapl_id = H5Pcopy(fapl_id); diff --git a/tools/lib/h5diff.c b/tools/lib/h5diff.c index 86726b4..fff0b9a 100644 --- a/tools/lib/h5diff.c +++ b/tools/lib/h5diff.c @@ -570,14 +570,14 @@ h5diff(const char *fname1, const char *fname2, const char *objname1, const char *------------------------------------------------------------------------- */ /* open file 1 */ - if((file1_id = h5tools_fopen(fname1, H5F_ACC_RDONLY, H5P_DEFAULT, NULL, NULL, (size_t)0)) < 0) { + if((file1_id = h5tools_fopen(fname1, H5F_ACC_RDONLY, H5P_DEFAULT, FALSE, NULL, (size_t)0)) < 0) { parallel_print("h5diff: <%s>: unable to open file\n", fname1); H5TOOLS_GOTO_ERROR(H5DIFF_ERR, "<%s>: unable to open file\n", fname1); } /* end if */ H5TOOLS_DEBUG("file1_id = %s", fname1); /* open file 2 */ - if((file2_id = h5tools_fopen(fname2, H5F_ACC_RDONLY, H5P_DEFAULT, NULL, NULL, (size_t)0)) < 0) { + if((file2_id = h5tools_fopen(fname2, H5F_ACC_RDONLY, H5P_DEFAULT, FALSE, NULL, (size_t)0)) < 0) { parallel_print("h5diff: <%s>: unable to open file\n", fname2); H5TOOLS_GOTO_ERROR(H5DIFF_ERR, "<%s>: unable to open file\n", fname2); } /* end if */ diff --git a/tools/lib/h5tools.c b/tools/lib/h5tools.c index 33f1e11..57e537d 100644 --- a/tools/lib/h5tools.c +++ b/tools/lib/h5tools.c @@ -29,7 +29,7 @@ int H5tools_INDENT_g = 0; /* global variables */ -hid_t H5tools_ERR_STACK_g = 0; +hid_t H5tools_ERR_STACK_g = H5I_INVALID_HID; hid_t H5tools_ERR_CLS_g = H5I_INVALID_HID; hid_t H5E_tools_g = H5I_INVALID_HID; hid_t H5E_tools_min_id_g = H5I_INVALID_HID; @@ -54,35 +54,41 @@ unsigned long long packed_data_mask; /* mask in which packed bits to display */ int enable_error_stack = 0; /* re-enable error stack; disable=0 enable=1 */ /* sort parameters */ -H5_index_t sort_by = H5_INDEX_NAME; /*sort_by [creation_order | name] */ -H5_iter_order_t sort_order = H5_ITER_INC; /*sort_order [ascending | descending] */ +H5_index_t sort_by = H5_INDEX_NAME; /* sort_by [creation_order | name] */ +H5_iter_order_t sort_order = H5_ITER_INC; /* sort_order [ascending | descending] */ /* module-scoped variables */ static int h5tools_init_g; /* if h5tools lib has been initialized */ -/* Names of VFDs */ -static const char *drivernames[]={ +/* Names of VOL connectors */ +const char *volnames[] = { + H5VL_NATIVE_NAME, + H5VL_PASSTHRU_NAME, +}; + +/* Names of VFDs. These names are always available so that + * the tools can emit special messages when a VFD is asked + * for by name but is not compiled into the library or is + * somehow otherwise not enabled. + * + */ +const char *drivernames[] = { "sec2", + "direct", + "log", + "windows", + "stdio", + "core", "family", "split", "multi", -#ifdef H5_HAVE_PARALLEL "mpio", -#endif /* H5_HAVE_PARALLEL */ + "ros3", + "hdfs", }; -/* This enum should match the entries in the above drivers_list since they - * are indexes into the drivers_list array. */ -typedef enum { - SEC2_IDX = 0 - ,FAMILY_IDX - ,SPLIT_IDX - ,MULTI_IDX -#ifdef H5_HAVE_PARALLEL - ,MPIO_IDX -#endif /* H5_HAVE_PARALLEL */ -} driver_idx; -#define NUM_DRIVERS (sizeof(drivernames) / sizeof(drivernames[0])) +#define NUM_VOLS (sizeof(volnames) / sizeof(volnames[0])) +#define NUM_DRIVERS (sizeof(drivernames) / sizeof(drivernames[0])) /*------------------------------------------------------------------------- * Function: h5tools_init @@ -131,16 +137,19 @@ h5tools_init(void) void h5tools_close(void) { - H5E_auto2_t tools_func; - void *tools_edata; + H5E_auto2_t tools_func; + void *tools_edata; + if (h5tools_init_g) { /* special case where only data is output to stdout */ - if((rawoutstream == NULL) && rawdatastream && (rawdatastream == stdout)) + if ((rawoutstream == NULL) && rawdatastream && (rawdatastream == stdout)) HDfprintf(rawdatastream, "\n"); H5Eget_auto2(H5tools_ERR_STACK_g, &tools_func, &tools_edata); - if(tools_func!=NULL) + + if (tools_func) H5Eprint2(H5tools_ERR_STACK_g, rawerrorstream); + if (rawattrstream && rawattrstream != stdout) { if (fclose(rawattrstream)) perror("closing rawattrstream"); @@ -425,189 +434,521 @@ h5tools_set_error_file(const char *fname, int is_bin) } /*------------------------------------------------------------------------- - * Function: h5tools_get_fapl + * Function: h5tools_set_vfd_fapl + * + * Purpose: Given a VFL driver name, sets the appropriate driver on the + * specified FAPL. * - * Purpose: Get a FAPL for a given VFL driver name. + * TODO: Add handling for Windows VFD. * * Return: positive - succeeded * negative - failed *------------------------------------------------------------------------- */ -static hid_t -h5tools_get_fapl(hid_t fapl, const char *driver, unsigned *drivernum) +static herr_t +h5tools_set_vfd_fapl(hid_t fapl, h5tools_get_fapl_info_t *get_info) { - hid_t new_fapl = H5I_INVALID_HID; /* Copy of file access property list passed in, or new property list */ herr_t ret_value = SUCCEED; - /* Make a copy of the FAPL, for the file open call to use, eventually */ - if (fapl == H5P_DEFAULT) { - if ((new_fapl = H5Pcreate(H5P_FILE_ACCESS)) < 0) - H5TOOLS_GOTO_ERROR(FAIL, "H5Pcreate failed"); - } /* end if */ - else { - if ((new_fapl = H5Pcopy(fapl)) < 0) - H5TOOLS_GOTO_ERROR(FAIL, "H5Pcopy failed"); - } /* end else */ - - /* Determine which driver the user wants to open the file with. Try - * that driver. If it can't open it, then fail. */ - if (!HDstrcmp(driver, drivernames[SEC2_IDX])) { - /* SEC2 driver */ - if (H5Pset_fapl_sec2(new_fapl) < 0) + /* Currently, only retrieving a VFD by name is supported */ + if (GET_VFD_BY_NAME != get_info->get_type) + H5TOOLS_GOTO_ERROR(FAIL, "unsupported VFD retrieval type; only retrieval by name is supported"); + + /* + * Determine which driver the user wants to open the file with. + * Try that driver; if it can't open the file, then fail. + */ + if (!HDstrcmp(get_info->u.name, drivernames[SEC2_VFD_IDX])) { + /* SEC2 Driver */ + if (H5Pset_fapl_sec2(fapl) < 0) H5TOOLS_GOTO_ERROR(FAIL, "H5Pset_fapl_sec2 failed"); + } + else if (!HDstrcmp(get_info->u.name, drivernames[DIRECT_VFD_IDX])) { +#ifdef H5_HAVE_DIRECT + /* Direct Driver */ + if (H5Pset_fapl_direct(fapl, 1024, 4096, 8 * 4096) < 0) + H5TOOLS_GOTO_ERROR(FAIL, "H5Pset_fapl_direct failed"); +#else + H5TOOLS_GOTO_ERROR(FAIL, "Direct VFD is not enabled"); +#endif + } + else if (!HDstrcmp(get_info->u.name, drivernames[LOG_VFD_IDX])) { + unsigned long long log_flags = H5FD_LOG_LOC_IO | H5FD_LOG_ALLOC; + + /* Log Driver */ + if (H5Pset_fapl_log(fapl, NULL, log_flags, (size_t) 0) < 0) + H5TOOLS_GOTO_ERROR(FAIL, "H5Pset_fapl_sec2 failed"); + } + else if (!HDstrcmp(get_info->u.name, drivernames[WINDOWS_VFD_IDX])) { +#ifdef H5_HAVE_WINDOWS - if (drivernum) - *drivernum = SEC2_IDX; +#else + H5TOOLS_GOTO_ERROR(FAIL, "Windows VFD is not enabled"); +#endif + } + else if (!HDstrcmp(get_info->u.name, drivernames[STDIO_VFD_IDX])) { + /* Stdio Driver */ + if (H5Pset_fapl_stdio(fapl) < 0) + H5TOOLS_GOTO_ERROR(FAIL, "H5Pset_fapl_stdio failed"); } - else if (!HDstrcmp(driver, drivernames[FAMILY_IDX])) { + else if (!HDstrcmp(get_info->u.name, drivernames[CORE_VFD_IDX])) { + /* Core Driver */ + if (H5Pset_fapl_core(fapl, (size_t) H5_MB, TRUE) < 0) + H5TOOLS_GOTO_ERROR(FAIL, "H5Pset_fapl_stdio failed"); + } + else if (!HDstrcmp(get_info->u.name, drivernames[FAMILY_VFD_IDX])) { /* FAMILY Driver */ /* Set member size to be 0 to indicate the current first member size * is the member size. */ - if (H5Pset_fapl_family(new_fapl, (hsize_t) 0, H5P_DEFAULT) < 0) + if (H5Pset_fapl_family(fapl, (hsize_t) 0, H5P_DEFAULT) < 0) H5TOOLS_GOTO_ERROR(FAIL, "H5Pset_fapl_family failed"); - - if (drivernum) - *drivernum = FAMILY_IDX; } - else if (!HDstrcmp(driver, drivernames[SPLIT_IDX])) { + else if (!HDstrcmp(get_info->u.name, drivernames[SPLIT_VFD_IDX])) { /* SPLIT Driver */ - if (H5Pset_fapl_split(new_fapl, "-m.h5", H5P_DEFAULT, "-r.h5", H5P_DEFAULT) < 0) + if (H5Pset_fapl_split(fapl, "-m.h5", H5P_DEFAULT, "-r.h5", H5P_DEFAULT) < 0) H5TOOLS_GOTO_ERROR(FAIL, "H5Pset_fapl_split failed"); - - if (drivernum) - *drivernum = SPLIT_IDX; } - else if (!HDstrcmp(driver, drivernames[MULTI_IDX])) { + else if (!HDstrcmp(get_info->u.name, drivernames[MULTI_VFD_IDX])) { /* MULTI Driver */ - if (H5Pset_fapl_multi(new_fapl, NULL, NULL, NULL, NULL, TRUE) < 0) + if (H5Pset_fapl_multi(fapl, NULL, NULL, NULL, NULL, TRUE) < 0) H5TOOLS_GOTO_ERROR(FAIL, "H5Pset_fapl_multi failed"); - - if(drivernum) - *drivernum = MULTI_IDX; } + else if (!HDstrcmp(get_info->u.name, drivernames[MPIO_VFD_IDX])) { #ifdef H5_HAVE_PARALLEL - else if(!HDstrcmp(driver, drivernames[MPIO_IDX])) { int mpi_initialized, mpi_finalized; /* MPI-I/O Driver */ + /* check if MPI is available. */ MPI_Initialized(&mpi_initialized); MPI_Finalized(&mpi_finalized); - if(mpi_initialized && !mpi_finalized) { - if(H5Pset_fapl_mpio(new_fapl, MPI_COMM_WORLD, MPI_INFO_NULL) < 0) + if (mpi_initialized && !mpi_finalized) { + if (H5Pset_fapl_mpio(fapl, MPI_COMM_WORLD, MPI_INFO_NULL) < 0) H5TOOLS_GOTO_ERROR(FAIL, "H5Pset_fapl_mpio failed"); - if(drivernum) - *drivernum = MPIO_IDX; } /* end if */ - } +#else + H5TOOLS_GOTO_ERROR(FAIL, "MPI-I/O VFD is not enabled"); #endif /* H5_HAVE_PARALLEL */ + } + else if (!HDstrcmp(get_info->u.name, drivernames[ROS3_VFD_IDX])) { +#ifdef H5_HAVE_ROS3_VFD + if (!get_info->info) + H5TOOLS_GOTO_ERROR(FAIL, "Read-only S3 VFD info is invalid"); + if (H5Pset_fapl_ros3(fapl, (H5FD_ros3_fapl_t *)get_info->info) < 0) + H5TOOLS_GOTO_ERROR(FAIL, "H5Pset_fapl_ros3() failed"); +#else + H5TOOLS_GOTO_ERROR(FAIL, "Read-only S3 VFD is not enabled"); +#endif + } + else if (!HDstrcmp(get_info->u.name, drivernames[HDFS_VFD_IDX])) { +#ifdef H5_HAVE_LIBHDFS + if (!get_info->info) + H5TOOLS_GOTO_ERROR(FAIL, "HDFS VFD info is invalid"); + if (H5Pset_fapl_hdfs(fapl, (H5FD_hdfs_fapl_t *)get_info->info) < 0) + H5TOOLS_GOTO_ERROR(FAIL, "H5Pset_fapl_hdfs() failed"); +#else + H5TOOLS_GOTO_ERROR(FAIL, "The HDFS VFD is not enabled"); +#endif + } + else + H5TOOLS_GOTO_ERROR(FAIL, "invalid VFD name"); + +done: + return ret_value; +} + +/*------------------------------------------------------------------------- + * Function: h5tools_set_vol_fapl + * + * Purpose: Given a VOL connector name or ID, sets the appropriate + * connector on the specified FAPL. + * + * Return: positive - succeeded + * negative - failed + *------------------------------------------------------------------------- + */ +static herr_t +h5tools_set_vol_fapl(hid_t fapl, h5tools_get_fapl_info_t *get_info) +{ + htri_t connector_is_registered; + hid_t connector_id = H5I_INVALID_HID; + herr_t ret_value = SUCCEED; + + if (GET_VOL_BY_NAME != get_info->get_type && GET_VOL_BY_ID != get_info->get_type) + H5TOOLS_GOTO_ERROR(FAIL, "invalid VOL retrieval type"); + + if (GET_VOL_BY_NAME == get_info->get_type) { + /* Retrieve VOL connector by name */ + + if ((connector_is_registered = H5VLis_connector_registered_by_name(get_info->u.name)) < 0) + H5TOOLS_GOTO_ERROR(FAIL, "can't check if VOL connector is registered"); + if (connector_is_registered) { + if ((connector_id = H5VLget_connector_id_by_name(get_info->u.name)) < 0) + H5TOOLS_GOTO_ERROR(FAIL, "can't get VOL connector ID"); + } + else { + /* Check for VOL connectors that ship with the library */ + if (!strcmp(get_info->u.name, H5VL_NATIVE_NAME)) { + connector_id = H5VL_NATIVE; + } + else if (!strcmp(get_info->u.name, H5VL_PASSTHRU_NAME)) { + connector_id = H5VL_PASSTHRU; + } + else { + if ((connector_id = H5VLregister_connector_by_name(get_info->u.name, H5P_DEFAULT)) < 0) + H5TOOLS_GOTO_ERROR(FAIL, "can't register VOL connector"); + } + } + } + else { + /* Retrieve VOL connector by ID */ + + if ((connector_is_registered = H5VLis_connector_registered_by_value((H5VL_class_value_t) get_info->u.id)) < 0) + H5TOOLS_GOTO_ERROR(FAIL, "can't check if VOL connector is registered"); + if (connector_is_registered) { + if ((connector_id = H5VLget_connector_id_by_value((H5VL_class_value_t) get_info->u.id)) < 0) + H5TOOLS_GOTO_ERROR(FAIL, "can't get VOL connector ID"); + } + else { + /* Check for VOL connectors that ship with the library */ + if (get_info->u.id == H5VL_NATIVE_VALUE) { + connector_id = H5VL_NATIVE; + } + else if (get_info->u.id == H5VL_PASSTHRU_VALUE) { + connector_id = H5VL_PASSTHRU; + } + else { + if ((connector_id = H5VLregister_connector_by_value((H5VL_class_value_t) get_info->u.id, H5P_DEFAULT)) < 0) + H5TOOLS_GOTO_ERROR(FAIL, "can't register VOL connector"); + } + } + } + + if (H5Pset_vol(fapl, connector_id, get_info->info) < 0) + H5TOOLS_GOTO_ERROR(FAIL, "can't set VOL connector on FAPL"); + +done: + if (ret_value < 0) { + if (connector_id >= 0 && H5Idec_ref(connector_id) < 0) + H5TOOLS_ERROR(FAIL, "failed to decrement refcount on VOL connector ID"); + } + + return ret_value; +} + +/*------------------------------------------------------------------------- + * Function: h5tools_get_fapl + * + * Purpose: Get a FAPL for a given VFL driver name, VOL connector name + * or VOL connector ID. + * + * Return: positive - succeeded + * negative - failed + *------------------------------------------------------------------------- + */ +hid_t +h5tools_get_fapl(hid_t fapl, h5tools_get_fapl_info_t *get_info) +{ + hid_t new_fapl = H5I_INVALID_HID; + hid_t ret_value = H5I_INVALID_HID; + + if (fapl < 0) + H5TOOLS_GOTO_ERROR(FAIL, "invalid FAPL"); + if (!get_info) + H5TOOLS_GOTO_ERROR(FAIL, "invalid FAPL retrieval info"); + + /* Make a copy of the FAPL if necessary, or create a FAPL if + * H5P_DEFAULT is specified. */ + if (H5P_DEFAULT == fapl) { + if ((new_fapl = H5Pcreate(H5P_FILE_ACCESS)) < 0) + H5TOOLS_GOTO_ERROR(H5I_INVALID_HID, "H5Pcreate failed"); + } /* end if */ + else { + if ((new_fapl = H5Pcopy(fapl)) < 0) + H5TOOLS_GOTO_ERROR(H5I_INVALID_HID, "H5Pcopy failed"); + } + + if (GET_VFD_BY_NAME == get_info->get_type) { + if (h5tools_set_vfd_fapl(new_fapl, get_info) < 0) + H5TOOLS_GOTO_ERROR(H5I_INVALID_HID, "failed to set VFD on FAPL"); + } + else if (GET_VOL_BY_NAME == get_info->get_type || GET_VOL_BY_ID == get_info->get_type) { + if (h5tools_set_vol_fapl(new_fapl, get_info) < 0) + H5TOOLS_GOTO_ERROR(H5I_INVALID_HID, "failed to set VOL on FAPL"); + } else - ret_value = -1; + H5TOOLS_GOTO_ERROR(H5I_INVALID_HID, "invalid FAPL retrieval type"); + + ret_value = new_fapl; done: - if((new_fapl != H5P_DEFAULT) && (ret_value < 0)) { + if ((new_fapl >= 0) && (ret_value < 0)) { H5Pclose(new_fapl); new_fapl = H5I_INVALID_HID; } - return(new_fapl); + return ret_value; +} + +/*------------------------------------------------------------------------- + * Function: h5tools_get_vfd_name + * + * Purpose: Given a FAPL, retrieves the name of the VFL driver set on it + * if using a native-terminal VOL connector. If a + * non-native-terminal VOL connector is set on the FAPL, the + * first byte of the returned driver name will be set to the null + * terminator. + * + * Return: SUCCEED/FAIL + *------------------------------------------------------------------------- + */ +herr_t +h5tools_get_vfd_name(hid_t fapl_id, char *drivername, size_t drivername_size) +{ + hid_t fapl_vol_id = H5I_INVALID_HID; + herr_t ret_value = SUCCEED; + + if (fapl_id < 0) + H5TOOLS_GOTO_ERROR(FAIL, "invalid FAPL"); + if (!drivername) + H5TOOLS_GOTO_ERROR(FAIL, "drivername is NULL"); + if (drivername && !drivername_size) + H5TOOLS_GOTO_ERROR(FAIL, "drivername_size must be non-zero"); + + /* Initialize the driver name */ + drivername[0] = '\0'; + + if (fapl_id == H5P_DEFAULT) + fapl_id = H5P_FILE_ACCESS_DEFAULT; + + /* Retrieve ID of the VOL connector set on the FAPL */ + if (H5Pget_vol_id(fapl_id, &fapl_vol_id) < 0) + H5TOOLS_ERROR(FAIL, "failed to retrieve VOL ID from FAPL"); + + /* TODO: For now, we have no way of determining if an arbitrary + * VOL connector is native-terminal. */ + if (fapl_vol_id == H5VL_NATIVE) { + const char *driver_name; + hid_t driver_id; + + if ((driver_id = H5Pget_driver(fapl_id)) < 0) + H5TOOLS_GOTO_ERROR(FAIL, "failed to retrieve VFL driver ID from FAPL"); + + if (driver_id == H5FD_SEC2) + driver_name = drivernames[SEC2_VFD_IDX]; +#ifdef H5_HAVE_DIRECT + else if (driver_id == H5FD_DIRECT) + driver_name = drivernames[DIRECT_VFD_IDX]; +#endif + else if (driver_id == H5FD_LOG) + driver_name = drivernames[LOG_VFD_IDX]; +#ifdef H5_HAVE_WINDOWS + else if (driver_id == H5FD_WINDOWS) + driver_name = drivernames[WINDOWS_VFD_IDX]; +#endif + else if (driver_id == H5FD_STDIO) + driver_name = drivernames[STDIO_VFD_IDX]; + else if (driver_id == H5FD_CORE) + driver_name = drivernames[CORE_VFD_IDX]; + else if (driver_id == H5FD_FAMILY) + driver_name = drivernames[FAMILY_VFD_IDX]; + else if (driver_id == H5FD_MULTI) + driver_name = drivernames[MULTI_VFD_IDX]; +#ifdef H5_HAVE_PARALLEL + else if (driver_id == H5FD_MPIO) + driver_name = drivernames[MPIO_VFD_IDX]; +#endif +#ifdef H5_HAVE_ROS3_VFD + else if (driver_id == H5FD_ROS3) + driver_name = drivernames[ROS3_VFD_IDX]; +#endif +#ifdef H5_HAVE_LIBHDFS + else if (driver_id == H5FD_HDFS) + driver_name = drivernames[HDFS_VFD_IDX]; +#endif + else + driver_name = "unknown"; + + HDstrncpy(drivername, driver_name, drivername_size); + drivername[drivername_size - 1] = '\0'; + } + +done: + /* Close retrieved VOL ID */ + if (fapl_vol_id >= 0) + if (H5VLclose(fapl_vol_id) < 0) + H5TOOLS_ERROR(FAIL, "failed to close VOL ID"); + + return ret_value; } /*------------------------------------------------------------------------- * Function: h5tools_fopen * - * Purpose: Loop through the various types of VFL drivers trying to open FNAME. - * If the HDF5 library is version 1.2 or less, then we have only the SEC2 - * driver to try out. If the HDF5 library is greater than version 1.2, - * then we have the FAMILY, SPLIT, and MULTI drivers to play with. + * Purpose: Opens file FNAME using the specified flags and FAPL. + * + * The 'use_specific_driver' parameter is used to control the + * VFD/VOL connector that this routine uses to open the file + * with. If 'use_specific_driver' is set to TRUE, this routine + * assumes that the caller has already set a specific VFD or VOL + * connector on the given FAPL and will attempt to directly use + * the FAPL for opening the file. We assume that the caller knows + * what they are doing; if the file is unable to be opened using + * that FAPL, this routine will return H5I_INVALID_HID. * - * If DRIVER is non-NULL, then it will try to open the file with that - * driver first. We assume that the user knows what they are doing so, if - * we fail, then we won't try other file drivers. + * However, if 'use_specific_driver' is set to FALSE, this + * routine assumes that the caller HAS NOT set a specific VFD or + * VOL connector on the given FAPL and will instead loop through + * the various available VFL drivers and VOL connectors trying to + * open FNAME. + * + * The list of available VFL drivers is as follows: + * - If the HDF5 library is version 1.2 or less, then we have + * only the SEC2 driver to try out. + * - If the HDF5 library is greater than version 1.2, then we + * have the FAMILY, SPLIT, and MULTI drivers to play with. + * + * The list of available VOL connectors is as follows: + * - "Native" VOL connector + * - Pass-through VOL connector * * Return: - * On success, returns a file id for the opened file. If DRIVERNAME is - * non-null then the first DRIVERNAME_SIZE-1 characters of the driver - * name are copied into the DRIVERNAME array and null terminated. + * On success, returns a file ID for the opened file. If DRIVERNAME is + * non-null and the native VOL connector is the terminal connector, + * then the first DRIVERNAME_SIZE-1 characters of the driver name are + * copied into the DRIVERNAME array and null terminated. If the + * native VOL connector is NOT the terminal connector, then the first + * byte of DRIVERNAME will be set to the null terminator. * - * Otherwise, the function returns FAIL. If DRIVERNAME is non-null then - * the first byte is set to the null terminator. + * On failure, the function returns H5I_INVALID_HID and DRIVERNAME + * will not be set. *------------------------------------------------------------------------- */ hid_t -h5tools_fopen(const char *fname, unsigned flags, hid_t fapl, const char *driver, +h5tools_fopen(const char *fname, unsigned flags, hid_t fapl, hbool_t use_specific_driver, char *drivername, size_t drivername_size) { - unsigned drivernum; - hid_t fid = FAIL; - hid_t my_fapl = H5P_DEFAULT; - - if (driver && *driver) { - /* Get the correct FAPL for the given driver */ - if ((my_fapl = h5tools_get_fapl(fapl, driver, &drivernum)) < 0) - goto done; + hid_t fid = H5I_INVALID_HID; + hid_t tmp_vol_fapl = H5I_INVALID_HID; + hid_t tmp_vfd_fapl = H5I_INVALID_HID; + hid_t used_fapl = H5I_INVALID_HID; + unsigned volnum, drivernum; + hid_t ret_value = H5I_INVALID_HID; - /* allow error stack display if enable-error-stack has optional arg number */ - if (enable_error_stack > 1) { - fid = H5Fopen(fname, flags, my_fapl); - } - else { - H5E_BEGIN_TRY { - fid = H5Fopen(fname, flags, my_fapl); - } H5E_END_TRY; - } - - if (fid == FAIL) - goto done; + /* + * First try to open the file using just the given FAPL. If the + * HDF5_VOL_CONNECTOR environment variable has been set, this will + * allow us to attempt to open the file using the specified VOL + * connector before we go looping through all available ones, + * which will override any VOL connector set by use of the + * environment variable. + */ + /* Allow error stack display if --enable-error-stack has optional arg number */ + if (enable_error_stack > 1) { + fid = H5Fopen(fname, flags, fapl); } else { - /* Try to open the file using each of the drivers */ - for (drivernum = 0; drivernum < NUM_DRIVERS; drivernum++) { - /* Get the correct FAPL for the given driver */ - if((my_fapl = h5tools_get_fapl(fapl, drivernames[drivernum], NULL)) < 0) - goto done; - - /* allow error stack display if enable-error-stack has optional arg number */ - if (enable_error_stack > 1) { - fid = H5Fopen(fname, flags, my_fapl); - } - else { - H5E_BEGIN_TRY { - fid = H5Fopen(fname, flags, my_fapl); - } H5E_END_TRY; - } + H5E_BEGIN_TRY { + fid = H5Fopen(fname, flags, fapl); + } H5E_END_TRY; + } - if (fid != FAIL) - break; - else { - /* Close the FAPL */ - H5Pclose(my_fapl); - my_fapl = H5P_DEFAULT; - } /* end else */ - } + /* If we succeeded in opening the file, we're done. */ + if (fid >= 0) { + used_fapl = fapl; + H5TOOLS_GOTO_DONE(fid); } - /* Save the driver name */ - if (drivername && drivername_size) { - if (fid != FAIL) { - HDstrncpy(drivername, drivernames[drivernum], drivername_size); - drivername[drivername_size - 1] = '\0'; + /* + * If we failed to open the file and the caller specified 'use_specific_driver' + * as TRUE, we should return failure now since the file couldn't be opened with + * the VFL driver/VOL connector that was set on the FAPL by the caller. + */ + if (fid < 0 && use_specific_driver) + H5TOOLS_GOTO_ERROR(H5I_INVALID_HID, "failed to open file using specified FAPL"); + + /* + * As a final resort, try to open the file using each of the available + * VOL connectors. When the native VOL connector is the current "terminal" + * connector being looked at, also try using each of the available VFL drivers. + */ + for (volnum = 0; volnum < NUM_VOLS; volnum++) { + h5tools_get_fapl_info_t get_vol_info; + + get_vol_info.get_type = GET_VOL_BY_NAME; + get_vol_info.info = NULL; + get_vol_info.u.name = volnames[volnum]; + + /* Get a FAPL for the current VOL connector */ + if ((tmp_vol_fapl = h5tools_get_fapl(fapl, &get_vol_info)) < 0) + continue; + + /* TODO: For now, we have no way of determining if an arbitrary + * VOL connector is native-terminal. */ + if (NATIVE_VOL_IDX == volnum) { + /* + * If using the native VOL connector, or a VOL connector which has the + * native connector as its terminal connector, loop through all of the + * VFL drivers as well. + */ + for (drivernum = 0; drivernum < NUM_DRIVERS; drivernum++) { + h5tools_get_fapl_info_t get_vfd_info; + + /* Skip the log VFD as it prints out to standard out */ + if (drivernum == LOG_VFD_IDX) + continue; + + get_vfd_info.get_type = GET_VFD_BY_NAME; + get_vfd_info.info = NULL; + get_vfd_info.u.name = drivernames[drivernum]; + + /* Using the current VOL FAPL as a base, get the correct FAPL for the given VFL driver */ + if ((tmp_vfd_fapl = h5tools_get_fapl(tmp_vol_fapl, &get_vfd_info)) < 0) + continue; + + if ((fid = h5tools_fopen(fname, flags, tmp_vfd_fapl, TRUE, drivername, drivername_size)) >= 0) { + used_fapl = tmp_vfd_fapl; + H5TOOLS_GOTO_DONE(fid); + } + else { + /* Close the temporary VFD FAPL */ + H5Pclose(tmp_vfd_fapl); + tmp_vfd_fapl = H5I_INVALID_HID; + } + } } else { - /*no file opened*/ - drivername[0] = '\0'; + if ((fid = h5tools_fopen(fname, flags, tmp_vol_fapl, TRUE, drivername, drivername_size)) >= 0) { + used_fapl = tmp_vol_fapl; + H5TOOLS_GOTO_DONE(fid); + } + else { + /* Close the temporary VOL FAPL */ + H5Pclose(tmp_vol_fapl); + tmp_vol_fapl = H5I_INVALID_HID; + } } } + /* File was unable to be opened at all */ + ret_value = H5I_INVALID_HID; + done: - if(my_fapl != H5P_DEFAULT) - H5Pclose(my_fapl); + /* Save the driver name if using a native-terminal VOL connector */ + if (drivername && drivername_size && ret_value >= 0) + if (used_fapl >= 0 && h5tools_get_vfd_name(used_fapl, drivername, drivername_size) < 0) + H5TOOLS_ERROR(H5I_INVALID_HID, "failed to retrieve name of VFD used to open file"); - return fid; + if (tmp_vfd_fapl >= 0) + H5Pclose(tmp_vfd_fapl); + if (tmp_vol_fapl >= 0) + H5Pclose(tmp_vol_fapl); + + return ret_value; } /*------------------------------------------------------------------------- diff --git a/tools/lib/h5tools.h b/tools/lib/h5tools.h index 9440e7a..11b0a1d 100644 --- a/tools/lib/h5tools.h +++ b/tools/lib/h5tools.h @@ -539,6 +539,52 @@ typedef struct h5tools_context_t { int display_char; /* */ } h5tools_context_t; +typedef enum { + GET_VFD_BY_NAME, + GET_VOL_BY_NAME, + GET_VOL_BY_ID +} h5tools_get_fapl_type_t; + +typedef struct h5tools_get_fapl_info_t { + h5tools_get_fapl_type_t get_type; + + /* Pointer to information to be passed to the driver/connector for its setup */ + const void *info; + + /* Field specifying either the driver's/connector's name, or the driver's/connector's ID */ + union { + const char *name; + long id; + } u; +} h5tools_get_fapl_info_t; + +extern const char *volnames[]; +extern const char *drivernames[]; + +/* This enum should match the entries in the above 'volnames' + * since they are indices into the 'volnames' array. */ +typedef enum { + NATIVE_VOL_IDX = 0, + PASS_THROUGH_VOL_IDX, +} vol_idx; + +/* This enum should match the entries in the above 'drivernames' + * since they are indices into the 'drivernames' array. */ +typedef enum { + SEC2_VFD_IDX = 0, + DIRECT_VFD_IDX, + LOG_VFD_IDX, + WINDOWS_VFD_IDX, + STDIO_VFD_IDX, + CORE_VFD_IDX, + FAMILY_VFD_IDX, + SPLIT_VFD_IDX, + MULTI_VFD_IDX, + MPIO_VFD_IDX, + ROS3_VFD_IDX, + HDFS_VFD_IDX, +} driver_idx; + /* The following include, h5tools_str.h, must be after the * above stucts are defined. There is a dependency in the following * include that hasn't been identified yet. */ @@ -591,8 +637,9 @@ H5TOOLS_DLL int h5tools_set_attr_output_file(const char *fname, int is_bin); H5TOOLS_DLL int h5tools_set_input_file(const char *fname, int is_bin); H5TOOLS_DLL int h5tools_set_output_file(const char *fname, int is_bin); H5TOOLS_DLL int h5tools_set_error_file(const char *fname, int is_bin); +H5TOOLS_DLL hid_t h5tools_get_fapl(hid_t fapl, h5tools_get_fapl_info_t *get_info); H5TOOLS_DLL hid_t h5tools_fopen(const char *fname, unsigned flags, hid_t fapl, - const char *driver, char *drivername, size_t drivername_len); + hbool_t use_specific_driver, char *drivername, size_t drivername_size); H5TOOLS_DLL hid_t h5tools_get_little_endian_type(hid_t type); H5TOOLS_DLL hid_t h5tools_get_big_endian_type(hid_t type); H5TOOLS_DLL htri_t h5tools_detect_vlen(hid_t tid); diff --git a/tools/lib/h5tools_error.h b/tools/lib/h5tools_error.h index 4e2e935..764fb91 100644 --- a/tools/lib/h5tools_error.h +++ b/tools/lib/h5tools_error.h @@ -101,14 +101,16 @@ do { * H5TOOLS_PUSH_ERROR macro, used to push an error to an error stack. Not meant to * be called directly. */ -#define H5TOOLS_PUSH_ERROR(estack_id, err_cls, maj_err_id, min_err_id, ...) \ -do { \ - if (estack_id >= 0 && err_cls >= 0) \ - H5Epush2(estack_id, __FILE__, FUNC, __LINE__, err_cls, maj_err_id, min_err_id, __VA_ARGS__); \ - else { \ - HDfprintf(stderr, __VA_ARGS__); \ - HDfprintf(stderr, "\n"); \ - } \ +#define H5TOOLS_PUSH_ERROR(estack_id, err_cls, maj_err_id, min_err_id, ...) \ +do { \ + if (enable_error_stack > 0) { \ + if (estack_id >= 0 && err_cls >= 0) \ + H5Epush2(estack_id, __FILE__, FUNC, __LINE__, err_cls, maj_err_id, min_err_id, __VA_ARGS__); \ + else { \ + HDfprintf(stderr, __VA_ARGS__); \ + HDfprintf(stderr, "\n"); \ + } \ + } \ } while(0) /* @@ -167,30 +169,30 @@ do { #ifdef H5_TOOLS_DEBUG -#define H5TOOLS_START_DEBUG(...) \ -do { \ - H5tools_INDENT_g += 2; \ +#define H5TOOLS_START_DEBUG(...) \ +do { \ + H5tools_INDENT_g += 2; \ HDfprintf(stderr, "%*sENTER %s:%d in %s()...", H5tools_INDENT_g, "", __FILE__, __LINE__, FUNC); \ - HDfprintf(stderr, __VA_ARGS__); \ - HDfprintf(stderr, "\n"); \ - HDfflush(stderr); \ + HDfprintf(stderr, __VA_ARGS__); \ + HDfprintf(stderr, "\n"); \ + HDfflush(stderr); \ } while(0) -#define H5TOOLS_DEBUG(...) \ -do { \ +#define H5TOOLS_DEBUG(...) \ +do { \ HDfprintf(stderr, "%*s %s:%d in %s()...", H5tools_INDENT_g, "", __FILE__, __LINE__, FUNC); \ - HDfprintf(stderr, __VA_ARGS__); \ - HDfprintf(stderr, "\n"); \ - HDfflush(stderr); \ + HDfprintf(stderr, __VA_ARGS__); \ + HDfprintf(stderr, "\n"); \ + HDfflush(stderr); \ } while(0) -#define H5TOOLS_ENDDEBUG(...) \ -do { \ +#define H5TOOLS_ENDDEBUG(...) \ +do { \ HDfprintf(stderr, "%*sEXIT %s:%d in %s()...", H5tools_INDENT_g, "", __FILE__, __LINE__, FUNC); \ - HDfprintf(stderr, __VA_ARGS__); \ - HDfprintf(stderr, "\n"); \ - H5tools_INDENT_g -= 2; \ - HDfflush(stderr); \ + HDfprintf(stderr, __VA_ARGS__); \ + HDfprintf(stderr, "\n"); \ + H5tools_INDENT_g -= 2; \ + HDfflush(stderr); \ } while(0) #else diff --git a/tools/lib/h5tools_utils.c b/tools/lib/h5tools_utils.c index 45e436c..8a7a4dd 100644 --- a/tools/lib/h5tools_utils.c +++ b/tools/lib/h5tools_utils.c @@ -1079,6 +1079,55 @@ done: return ret_value; } +#ifdef H5_HAVE_ROS3_VFD +/*---------------------------------------------------------------------------- + * + * Function: h5tools_parse_ros3_fapl_tuple + * + * Purpose: A convenience function that parses a string containing a tuple + * of S3 VFD credential information and then passes the result to + * `h5tools_populate_ros3_fapl()` in order to setup a valid + * configuration for the S3 VFD. + * + * Return: SUCCEED/FAIL + * + *---------------------------------------------------------------------------- + */ +herr_t +h5tools_parse_ros3_fapl_tuple(const char *tuple_str, int delim, + H5FD_ros3_fapl_t *fapl_config_out) +{ + const char *ccred[3]; + unsigned nelems = 0; + char *start = NULL; + char *s3cred_src = NULL; + char **s3cred = NULL; + herr_t ret_value = SUCCEED; + + /* Attempt to parse S3 credentials tuple */ + if (parse_tuple(tuple_str, delim, &s3cred_src, &nelems, &s3cred) < 0) + H5TOOLS_GOTO_ERROR(FAIL, "failed to parse S3 VFD info tuple"); + + /* Sanity-check tuple count */ + if (nelems != 3) + H5TOOLS_GOTO_ERROR(FAIL, "invalid S3 VFD credentials"); + + ccred[0] = (const char *)s3cred[0]; + ccred[1] = (const char *)s3cred[1]; + ccred[2] = (const char *)s3cred[2]; + + if (0 == h5tools_populate_ros3_fapl(fapl_config_out, ccred)) + H5TOOLS_GOTO_ERROR(FAIL, "failed to populate S3 VFD FAPL config"); + +done: + if (s3cred) + HDfree(s3cred); + if (s3cred_src) + HDfree(s3cred_src); + + return ret_value; +} + /*---------------------------------------------------------------------------- * @@ -1142,7 +1191,6 @@ done: * *---------------------------------------------------------------------------- */ -#ifdef H5_HAVE_ROS3_VFD int h5tools_populate_ros3_fapl(H5FD_ros3_fapl_t *fa, const char **values) @@ -1266,73 +1314,72 @@ h5tools_populate_ros3_fapl(H5FD_ros3_fapl_t *fa, done: return ret_value; - } /* h5tools_populate_ros3_fapl */ #endif /* H5_HAVE_ROS3_VFD */ - -/*----------------------------------------------------------------------------- - * - * Function: h5tools_set_configured_fapl - * - * Purpose: prepare fapl_id with the given property list, according to - * VFD prototype. +#ifdef H5_HAVE_LIBHDFS +/*---------------------------------------------------------------------------- * - * Return: 0 on failure, 1 on success + * Function: h5tools_parse_hdfs_fapl_tuple * - * Programmer: Jacob Smith - * 2018-05-21 + * Purpose: A convenience function that parses a string containing a tuple + * of HDFS VFD configuration information. * - * Changes: None. + * Return: SUCCEED/FAIL * - *----------------------------------------------------------------------------- + *---------------------------------------------------------------------------- */ -int -h5tools_set_configured_fapl(hid_t fapl_id, - const char vfd_name[], - void *fapl_t_ptr) +herr_t +h5tools_parse_hdfs_fapl_tuple(const char *tuple_str, int delim, + H5FD_hdfs_fapl_t *fapl_config_out) { - int ret_value = 1; - - if (fapl_id < 0) { - return 0; + unsigned long k = 0; + unsigned nelems = 0; + char *props_src = NULL; + char **props = NULL; + herr_t ret_value = SUCCEED; + + /* Attempt to parse HDFS configuration tuple */ + if (parse_tuple(tuple_str, delim, &props_src, &nelems, &props) < 0) + H5TOOLS_GOTO_ERROR(FAIL, "failed to parse HDFS VFD configuration tuple"); + + /* Sanity-check tuple count */ + if (nelems != 5) + H5TOOLS_GOTO_ERROR(FAIL, "invalid HDFS VFD configuration"); + + /* Populate fapl configuration structure with given properties. + * WARNING: No error-checking is done on length of input strings... + * Silent overflow is possible, albeit unlikely. + */ + if (HDstrncmp(props[0], "", 1)) { + HDstrncpy(fapl_config_out->namenode_name, (const char *)props[0], HDstrlen(props[0])); } - - if (!strcmp("", vfd_name)) { - goto done; - -#ifdef H5_HAVE_ROS3_VFD - } else if (!strcmp("ros3", vfd_name)) { - if ((fapl_id == H5P_DEFAULT) || - (fapl_t_ptr == NULL) || - (FAIL == H5Pset_fapl_ros3( - fapl_id, - (H5FD_ros3_fapl_t *)fapl_t_ptr))) - { - ret_value = 0; - goto done; - } -#endif /* H5_HAVE_ROS3_VFD */ - -#ifdef H5_HAVE_LIBHDFS - } else if (!strcmp("hdfs", vfd_name)) { - if ((fapl_id == H5P_DEFAULT) || - (fapl_t_ptr == NULL) || - (FAIL == H5Pset_fapl_hdfs( - fapl_id, - (H5FD_hdfs_fapl_t *)fapl_t_ptr))) - { - ret_value = 0; - goto done; - } -#endif /* H5_HAVE_LIBHDFS */ - - } else { - ret_value = 0; /* unrecognized fapl type "name" */ + if (HDstrncmp(props[1], "", 1)) { + k = strtoul((const char *)props[1], NULL, 0); + if (errno == ERANGE) + H5TOOLS_GOTO_ERROR(FAIL, "supposed port number wasn't"); + fapl_config_out->namenode_port = (int32_t)k; + } + if (HDstrncmp(props[2], "", 1)) { + HDstrncpy(fapl_config_out->kerberos_ticket_cache, (const char *)props[2], HDstrlen(props[2])); + } + if (HDstrncmp(props[3], "", 1)) { + HDstrncpy(fapl_config_out->user_name, (const char *)props[3], HDstrlen(props[3])); + } + if (HDstrncmp(props[4], "", 1)) { + k = HDstrtoul((const char *)props[4], NULL, 0); + if (errno == ERANGE) + H5TOOLS_GOTO_ERROR(FAIL, "supposed buffersize number wasn't"); + fapl_config_out->stream_buffer_size = (int32_t)k; } done: - return ret_value; + if (props) + HDfree(props); + if (props_src) + HDfree(props_src); -} /* h5tools_set_configured_fapl() */ + return ret_value; +} +#endif /* H5_HAVE_LIBHDFS */ diff --git a/tools/lib/h5tools_utils.h b/tools/lib/h5tools_utils.h index 598930c..42144cc 100644 --- a/tools/lib/h5tools_utils.h +++ b/tools/lib/h5tools_utils.h @@ -173,10 +173,15 @@ H5TOOLS_DLL void h5tools_setprogname(const char*progname); H5TOOLS_DLL int h5tools_getstatus(void); H5TOOLS_DLL void h5tools_setstatus(int d_status); H5TOOLS_DLL int h5tools_getenv_update_hyperslab_bufsize(void); -H5TOOLS_DLL int h5tools_set_configured_fapl(hid_t fapl_id, const char vfd_name[], void *fapl_t_ptr); #ifdef H5_HAVE_ROS3_VFD +H5TOOLS_DLL herr_t h5tools_parse_ros3_fapl_tuple(const char *tuple_str, int delim, + H5FD_ros3_fapl_t *fapl_config_out); H5TOOLS_DLL int h5tools_populate_ros3_fapl(H5FD_ros3_fapl_t *fa, const char **values); #endif /* H5_HAVE_ROS3_VFD */ +#ifdef H5_HAVE_LIBHDFS +H5TOOLS_DLL herr_t h5tools_parse_hdfs_fapl_tuple(const char *tuple_str, int delim, + H5FD_hdfs_fapl_t *fapl_config_out); +#endif #ifdef __cplusplus } diff --git a/tools/libtest/h5tools_test_utils.c b/tools/libtest/h5tools_test_utils.c index 726f4c4..160e06f 100644 --- a/tools/libtest/h5tools_test_utils.c +++ b/tools/libtest/h5tools_test_utils.c @@ -960,7 +960,7 @@ error : * * Function: test_set_configured_fapl() * - * Purpose: Verify `h5tools_set_configured_fapl()` with ROS3 VFD + * Purpose: Verify `h5tools_get_fapl()` with ROS3 and HDFS VFDs * * Return: 0 if test passes * 1 if failure @@ -1147,7 +1147,8 @@ test_set_configured_fapl(void) TESTING("programmatic fapl set"); for (i = 0; i < n_cases; i++) { - int result; + h5tools_get_fapl_info_t get_fapl_info; + hid_t result; testcase C = cases[i]; fapl_id = H5I_INVALID_HID; @@ -1169,11 +1170,14 @@ test_set_configured_fapl(void) #endif /* UTIL_TEST_DEBUG */ /* test */ - result = h5tools_set_configured_fapl( - fapl_id, - C.vfdname, - C.conf_fa); - JSVERIFY( result, C.expected, C.message ) + get_fapl_info.get_type = GET_VFD_BY_NAME; + get_fapl_info.info = C.conf_fa; + get_fapl_info.u.name = C.vfdname; + result = h5tools_get_fapl(H5P_DEFAULT, &get_fapl_info); + if (C.expected == 0) + JSVERIFY( result, H5I_INVALID_HID, C.message) + else + JSVERIFY_NOT( result, H5I_INVALID_HID, C.message) #if UTIL_TEST_DEBUG HDfprintf(stderr, "after test\n"); fflush(stderr); diff --git a/tools/src/h5copy/h5copy.c b/tools/src/h5copy/h5copy.c index e1370e2..8805d08 100644 --- a/tools/src/h5copy/h5copy.c +++ b/tools/src/h5copy/h5copy.c @@ -342,13 +342,13 @@ main (int argc, const char *argv[]) /* Attempt to open an existing HDF5 file first. Need to open the dst file before the src file just in case that the dst and src are the same file */ - fid_dst = h5tools_fopen(fname_dst, H5F_ACC_RDWR, H5P_DEFAULT, NULL, NULL, 0); + fid_dst = h5tools_fopen(fname_dst, H5F_ACC_RDWR, H5P_DEFAULT, FALSE, NULL, 0); /*------------------------------------------------------------------------- * open input file *-------------------------------------------------------------------------*/ - fid_src = h5tools_fopen(fname_src, H5F_ACC_RDONLY, H5P_DEFAULT, NULL, NULL, 0); + fid_src = h5tools_fopen(fname_src, H5F_ACC_RDONLY, H5P_DEFAULT, FALSE, NULL, 0); /*------------------------------------------------------------------------- * test for error in opening input file diff --git a/tools/src/h5dump/h5dump.c b/tools/src/h5dump/h5dump.c index d97fdc0..6255f7c 100644 --- a/tools/src/h5dump/h5dump.c +++ b/tools/src/h5dump/h5dump.c @@ -25,23 +25,25 @@ static int useschema = 1; static const char *xml_dtd_uri = NULL; #ifdef H5_HAVE_ROS3_VFD +/* Default "anonymous" S3 configuration */ static H5FD_ros3_fapl_t ros3_fa = { - 1, /* version */ - false, /* authenticate */ - "", /* aws region */ - "", /* access key id */ - "", /* secret access key */ + 1, /* FAPL Version */ + false, /* Authenticate? */ + "", /* AWS Region */ + "", /* Access Key ID */ + "", /* Secret Access Key */ }; #endif /* H5_HAVE_ROS3_VFD */ #ifdef H5_HAVE_LIBHDFS +/* "Default" HDFS configuration */ static H5FD_hdfs_fapl_t hdfs_fa = { - 1, /* fapl version */ - "localhost", /* namenode name */ - 0, /* namenode port */ - "", /* kerberos ticket cache */ - "", /* user name */ - 2048, /* stream buffer size */ + 1, /* FAPL Version */ + "localhost", /* Namenode Name */ + 0, /* Namenode Port */ + "", /* Kerberos ticket cache */ + "", /* User name */ + 2048, /* Stream buffer size */ }; #endif /* H5_HAVE_LIBHDFS */ @@ -1251,106 +1253,37 @@ end_collect: goto done; case '$': -#ifndef H5_HAVE_ROS3_VFD +#ifdef H5_HAVE_ROS3_VFD + if (h5tools_parse_ros3_fapl_tuple(opt_arg, ',', &ros3_fa) < 0) { + error_msg("failed to parse S3 VFD credential info\n"); + usage(h5tools_getprogname()); + free_handler(hand, argc); + hand = NULL; + h5tools_setstatus(EXIT_FAILURE); + goto done; + } +#else error_msg("Read-Only S3 VFD not enabled.\n"); h5tools_setstatus(EXIT_FAILURE); goto done; -#else - /* s3 credential */ - { - char **s3_cred = NULL; - char *s3_cred_string = NULL; - const char *ccred[3]; - unsigned nelems = 0; - if (FAIL == parse_tuple(opt_arg, ',', &s3_cred_string, &nelems, &s3_cred)) { - error_msg("unable to parse malformed s3 credentials\n"); - usage(h5tools_getprogname()); - free_handler(hand, argc); - hand = NULL; - h5tools_setstatus(EXIT_FAILURE); - goto done; - } - if (nelems != 3) { - error_msg("s3 credentials expects 3 elements\n"); - usage(h5tools_getprogname()); - free_handler(hand, argc); - hand = NULL; - h5tools_setstatus(EXIT_FAILURE); - goto done; - } - ccred[0] = (const char *)s3_cred[0]; - ccred[1] = (const char *)s3_cred[1]; - ccred[2] = (const char *)s3_cred[2]; - if (0 == h5tools_populate_ros3_fapl(&ros3_fa, ccred)) { - error_msg("Invalid S3 credentials\n"); - usage(h5tools_getprogname()); - free_handler(hand, argc); - hand = NULL; - h5tools_setstatus(EXIT_FAILURE); - goto done; - } - HDfree(s3_cred); - HDfree(s3_cred_string); - } /* s3 credential block */ +#endif break; -#endif /* H5_HAVE_ROS3_VFD */ case '#': -#ifndef H5_HAVE_LIBHDFS - error_msg("HDFS VFD is not enabled.\n"); - goto error; -#else - { - /* read hdfs properties tuple and store values in `hdfs_fa` */ - unsigned nelems = 0; - char *props_src = NULL; - char **props = NULL; - unsigned long k = 0; - if (FAIL == parse_tuple((const char *)opt_arg, ',', &props_src, &nelems, &props)) { - error_msg("unable to parse hdfs properties tuple\n"); - goto error; - } - /* sanity-check tuple count - */ - if (nelems != 5) { - h5tools_setstatus(EXIT_FAILURE); - goto error; - } - /* Populate fapl configuration structure with given - * properties. - * WARNING: No error-checking is done on length of input - * strings... Silent overflow is possible, albeit - * unlikely. - */ - if (strncmp(props[0], "", 1)) - HDstrncpy(hdfs_fa.namenode_name, (const char *)props[0], HDstrlen(props[0])); - - if (strncmp(props[1], "", 1)) { - k = strtoul((const char *)props[1], NULL, 0); - if (errno == ERANGE) { - h5tools_setstatus(EXIT_FAILURE); - goto error; - } - hdfs_fa.namenode_port = (int32_t)k; - } - if (strncmp(props[2], "", 1)) - HDstrncpy(hdfs_fa.kerberos_ticket_cache, (const char *)props[2], HDstrlen(props[2])); - - if (strncmp(props[3], "", 1)) - HDstrncpy(hdfs_fa.user_name, (const char *)props[3], HDstrlen(props[3])); - - if (strncmp(props[4], "", 1)) { - k = strtoul((const char *)props[4], NULL, 0); - if (errno == ERANGE) { - h5tools_setstatus(EXIT_FAILURE); - goto error; - } - hdfs_fa.stream_buffer_size = (int32_t)k; - } - HDfree(props); - HDfree(props_src); +#ifdef H5_HAVE_LIBHDFS + if (h5tools_parse_hdfs_fapl_tuple(opt_arg, ',', &hdfs_fa) < 0) { + error_msg("failed to parse HDFS VFD configuration info\n"); + usage(h5tools_getprogname()); + free_handler(hand, argc); + hand = NULL; + h5tools_setstatus(EXIT_FAILURE); + goto done; } -#endif /* H5_HAVE_LIBHDFS */ +#else + error_msg("HDFS VFD not enabled.\n"); + h5tools_setstatus(EXIT_FAILURE); + goto done; +#endif break; case '?': @@ -1482,53 +1415,44 @@ main(int argc, const char *argv[]) h5trav_set_index(sort_by, sort_order); if (driver != NULL) { - void *conf_fa = NULL; + h5tools_get_fapl_info_t get_fapl_info; + + /* Currently, only retrieval of VFDs is supported. */ + get_fapl_info.get_type = GET_VFD_BY_NAME; + get_fapl_info.info = NULL; + get_fapl_info.u.name = driver; - if (!strcmp(driver, "ros3")) { -#ifndef H5_HAVE_ROS3_VFD + if (!HDstrcmp(driver, drivernames[ROS3_VFD_IDX])) { +#ifdef H5_HAVE_ROS3_VFD + get_fapl_info.info = (void *)&ros3_fa; +#else error_msg("Read-Only S3 VFD not enabled.\n"); h5tools_setstatus(EXIT_FAILURE); goto done; -#else - conf_fa = (void *)&ros3_fa; -#endif /* H5_HAVE_ROS3_VFD */ +#endif } - else if (!HDstrcmp(driver, "hdfs")) { -#ifndef H5_HAVE_LIBHDFS - error_msg("HDFS VFD is not enabled.\n"); + else if (!HDstrcmp(driver, drivernames[HDFS_VFD_IDX])) { +#ifdef H5_HAVE_LIBHDFS + get_fapl_info.info = (void *)&hdfs_fa; +#else + error_msg("The HDFS VFD is not enabled.\n"); h5tools_setstatus(EXIT_FAILURE); goto done; -#else - conf_fa = (void *)&hdfs_fa; -#endif /* H5_HAVE_LIBHDFS */ +#endif } - if (conf_fa != NULL) { - fapl_id = H5Pcreate(H5P_FILE_ACCESS); - if (fapl_id < 0) { - error_msg("unable to create fapl entry\n"); - h5tools_setstatus(EXIT_FAILURE); - goto done; - } - /* driver guaranteed "ros3" or "hdfs" */ - /* conf_fa appropriate to driver */ - if (0 == h5tools_set_configured_fapl(fapl_id, driver, conf_fa)) { - error_msg("unable to set fapl\n"); - h5tools_setstatus(EXIT_FAILURE); - goto done; - } + if ((fapl_id = h5tools_get_fapl(H5P_DEFAULT, &get_fapl_info)) < 0) { + error_msg("unable to create FAPL for file access\n"); + h5tools_setstatus(EXIT_FAILURE); + goto done; } } /* driver defined */ while(opt_ind < argc) { fname = HDstrdup(argv[opt_ind++]); - if (fapl_id != H5P_DEFAULT) { - fid = H5Fopen(fname, H5F_ACC_RDONLY, fapl_id); - } - else { - fid = h5tools_fopen(fname, H5F_ACC_RDONLY, H5P_DEFAULT, driver, NULL, 0); - } + fid = h5tools_fopen(fname, H5F_ACC_RDONLY, fapl_id, + (fapl_id == H5P_DEFAULT) ? FALSE : TRUE, NULL, 0); if (fid < 0) { error_msg("unable to open file \"%s\"\n", fname); @@ -1704,6 +1628,7 @@ main(int argc, const char *argv[]) /* To Do: clean up XML table */ H5Eset_auto2(H5E_DEFAULT, func, edata); + H5Eset_auto2(H5tools_ERR_STACK_g, tools_func, tools_edata); leave(h5tools_getstatus()); @@ -1735,6 +1660,7 @@ done: /* To Do: clean up XML table */ H5Eset_auto2(H5E_DEFAULT, func, edata); + H5Eset_auto2(H5tools_ERR_STACK_g, tools_func, tools_edata); leave(h5tools_getstatus()); } /* main */ diff --git a/tools/src/h5format_convert/h5format_convert.c b/tools/src/h5format_convert/h5format_convert.c index bb606ac..01e7fe0 100644 --- a/tools/src/h5format_convert/h5format_convert.c +++ b/tools/src/h5format_convert/h5format_convert.c @@ -421,7 +421,7 @@ main(int argc, const char *argv[]) HDfprintf(stdout, "It is noop...\n"); /* Open the HDF5 file */ - if((fid = h5tools_fopen(fname_g, H5F_ACC_RDWR, H5P_DEFAULT, NULL, NULL, 0)) < 0) { + if((fid = h5tools_fopen(fname_g, H5F_ACC_RDWR, H5P_DEFAULT, FALSE, NULL, 0)) < 0) { error_msg("unable to open file \"%s\"\n", fname_g); h5tools_setstatus(EXIT_FAILURE); goto done; diff --git a/tools/src/h5ls/h5ls.c b/tools/src/h5ls/h5ls.c index f3f9ede..11f3f0b 100644 --- a/tools/src/h5ls/h5ls.c +++ b/tools/src/h5ls/h5ls.c @@ -2833,41 +2833,41 @@ leave(int ret) int main(int argc, const char *argv[]) { - hid_t file_id = H5I_INVALID_HID; - char *fname = NULL, *oname = NULL, *x; - const char *s = NULL; - char *rest; - int argno; - static char root_name[] = "/"; - char drivername[50]; - const char *preferred_driver = NULL; - int err_exit = 0; - hid_t fapl_id = H5P_DEFAULT; - H5E_auto2_t func; - H5E_auto2_t tools_func; - void *edata; - void *tools_edata; + hid_t file_id = H5I_INVALID_HID; + char *fname = NULL, *oname = NULL, *x; + const char *s = NULL; + char *rest; + int argno; + static char root_name[] = "/"; + char drivername[50]; + const char *preferred_driver = NULL; + int err_exit = 0; + hid_t fapl_id = H5P_DEFAULT; + H5E_auto2_t func; + H5E_auto2_t tools_func; + void *edata; + void *tools_edata; #ifdef H5_HAVE_ROS3_VFD - /* default "anonymous" s3 configuration */ + /* Default "anonymous" S3 configuration */ H5FD_ros3_fapl_t ros3_fa = { - 1, /* fapl version */ - false, /* authenticate */ - "", /* aws region */ - "", /* access key id */ - "", /* secret access key */ + 1, /* FAPL Version */ + false, /* Authenticate? */ + "", /* AWS Region */ + "", /* Access Key ID */ + "", /* Secret Access Key */ }; -#endif /* H5_HVAE_ROS3_VFD */ +#endif /* H5_HAVE_ROS3_VFD */ #ifdef H5_HAVE_LIBHDFS - /* "default" HDFS configuration */ + /* "Default" HDFS configuration */ H5FD_hdfs_fapl_t hdfs_fa = { - 1, /* fapl version */ - "localhost", /* namenode name */ - 0, /* namenode port */ - "", /* kerberos ticket cache */ - "", /* user name */ - 2048, /* stream buffer size */ + 1, /* FAPL Version */ + "localhost", /* Namenode Name */ + 0, /* Namenode Port */ + "", /* Kerberos ticket cache */ + "", /* User name */ + 2048, /* Stream buffer size */ }; #endif /* H5_HAVE_LIBHDFS */ @@ -3005,18 +3005,7 @@ main(int argc, const char *argv[]) } else if (!HDstrncmp(argv[argno], "--s3-cred=", (size_t)10)) { -#ifndef H5_HAVE_ROS3_VFD - HDfprintf(rawerrorstream, "Error: Read-Only S3 VFD is not enabled\n\n"); - usage(); - leave(EXIT_FAILURE); -#else - unsigned nelems = 0; - char *start = NULL; - char *s3cred_src = NULL; - char **s3cred = NULL; - char const *ccred[3]; - /* try to parse s3 credentials tuple - */ +#ifdef H5_HAVE_ROS3_VFD start = strchr(argv[argno], '='); if (start == NULL) { HDfprintf(rawerrorstream, "Error: Unable to parse null credentials tuple\n" @@ -3025,124 +3014,38 @@ main(int argc, const char *argv[]) leave(EXIT_FAILURE); } start++; - if (FAIL == parse_tuple((const char *)start, ',', &s3cred_src, &nelems, &s3cred)) { - HDfprintf(rawerrorstream, "Error: Unable to parse S3 credentials\n\n"); - usage(); - leave(EXIT_FAILURE); - } - /* sanity-check tuple count - */ - if (nelems != 3) { - HDfprintf(rawerrorstream, "Error: Invalid S3 credentials\n\n"); - usage(); - leave(EXIT_FAILURE); - } - ccred[0] = (const char *)s3cred[0]; - ccred[1] = (const char *)s3cred[1]; - ccred[2] = (const char *)s3cred[2]; - if (0 == h5tools_populate_ros3_fapl(&ros3_fa, ccred)) { - HDfprintf(rawerrorstream, "Error: Invalid S3 credentials\n\n"); + + if (h5tools_parse_ros3_fapl_tuple(start, ',', &ros3_fa) < 0) { + HDfprintf(rawerrorstream, "Error: failed to parse S3 VFD credential info\n\n"); usage(); leave(EXIT_FAILURE); } - HDfree(s3cred); - HDfree(s3cred_src); -#endif /* H5_HAVE_ROS3_VFD */ - +#else + HDfprintf(rawerrorstream, "Error: Read-Only S3 VFD is not enabled\n\n"); + usage(); + leave(EXIT_FAILURE); +#endif } else if (!HDstrncmp(argv[argno], "--hdfs-attrs=", (size_t)13)) { -#ifndef H5_HAVE_LIBHDFS - PRINTVALSTREAM(rawoutstream, "The HDFS VFD is not enabled.\n"); - leave(EXIT_FAILURE); -#else - /* Parse received configuration data and set fapl config struct */ - - hbool_t _debug = FALSE; - unsigned nelems = 0; - char const *start = NULL; - char *props_src = NULL; - char **props = NULL; - unsigned long k = 0; - - /* try to parse tuple - */ - if (_debug) { - HDfprintf(stderr, "configuring hdfs...\n"); - } +#ifdef H5_HAVE_LIBHDFS + char const *start = NULL; + start = argv[argno]+13; /* should never segfault: worst case of */ if (*start != '(') { /* null-termintor after '='. */ - - if (_debug) { - HDfprintf(stderr, " no tuple.\n"); - } - usage(); - leave(EXIT_FAILURE); - } - if (FAIL == parse_tuple((const char *)start, ',', &props_src, &nelems, &props)) { - HDfprintf(stderr, " unable to parse tuple.\n"); usage(); leave(EXIT_FAILURE); } - /* sanity-check tuple count - */ - if (nelems != 5) { - HDfprintf(stderr, " expected 5-ple, got `%d`\n", nelems); + if (h5tools_parse_hdfs_fapl_tuple(start, ',', &hdfs_fa) < 0) { + HDfprintf(rawerrorstream, "Error: failed to parse HDFS VFD configuration info\n\n"); usage(); leave(EXIT_FAILURE); } - if (_debug) { - HDfprintf(stderr, " got hdfs-attrs tuple: `(%s,%s,%s,%s,%s)`\n", props[0], props[1], props[2], props[3], props[4]); - } - - /* Populate fapl configuration structure with given properties. - * WARNING: No error-checking is done on length of input strings... - * Silent overflow is possible, albeit unlikely. - */ - if (HDstrncmp(props[0], "", 1)) { - if (_debug) { - HDfprintf(stderr, " setting namenode name: %s\n", props[0]); - } - HDstrncpy(hdfs_fa.namenode_name, (const char *)props[0], HDstrlen(props[0])); - } - if (HDstrncmp(props[1], "", 1)) { - k = strtoul((const char *)props[1], NULL, 0); - if (errno == ERANGE) { - HDfprintf(stderr, " supposed port number wasn't.\n"); - leave(EXIT_FAILURE); - } - if (_debug) { - HDfprintf(stderr, " setting namenode port: %lu\n", k); - } - hdfs_fa.namenode_port = (int32_t)k; - } - if (HDstrncmp(props[2], "", 1)) { - if (_debug) { - HDfprintf(stderr, " setting kerb cache path: %s\n", props[2]); - } - HDstrncpy(hdfs_fa.kerberos_ticket_cache, (const char *)props[2], HDstrlen(props[2])); - } - if (HDstrncmp(props[3], "", 1)) { - if (_debug) { - HDfprintf(stderr, " setting username: %s\n", props[3]); - } - HDstrncpy(hdfs_fa.user_name, (const char *)props[3], HDstrlen(props[3])); - } - if (HDstrncmp(props[4], "", 1)) { - k = HDstrtoul((const char *)props[4], NULL, 0); - if (errno == ERANGE) { - HDfprintf(stderr, " supposed buffersize number wasn't.\n"); - leave(EXIT_FAILURE); - } - if (_debug) { - HDfprintf(stderr, " setting stream buffer size: %lu\n", k); - } - hdfs_fa.stream_buffer_size = (int32_t)k; - } - HDfree(props); - HDfree(props_src); -#endif /* H5_HAVE_LIBHDFS */ - +#else + HDfprintf(rawerrorstream, "Error: The HDFS VFD is not enabled\n\n"); + usage(); + leave(EXIT_FAILURE); +#endif } else if('-'!=argv[argno][1]) { /* Single-letter switches */ @@ -3236,41 +3139,35 @@ main(int argc, const char *argv[]) } if (preferred_driver) { - void *conf_fa = NULL; + h5tools_get_fapl_info_t get_fapl_info; - if (!HDstrcmp(preferred_driver, "ros3")) { -#ifndef H5_HAVE_ROS3_VFD - HDfprintf(rawerrorstream, "Error: Read-Only S3 VFD not enabled.\n\n"); - usage(); - leave(EXIT_FAILURE); -#else - conf_fa = (void *)&ros3_fa; -#endif /* H5_HAVE_ROS3_VFD */ + /* Currently, only retrieval of VFDs is supported. */ + get_fapl_info.get_type = GET_VFD_BY_NAME; + get_fapl_info.info = NULL; + get_fapl_info.u.name = preferred_driver; - } - else if (!HDstrcmp(preferred_driver, "hdfs")) { -#ifndef H5_HAVE_LIBHDFS - PRINTVALSTREAM(rawoutstream, "The HDFS VFD is not enabled.\n"); + if (!HDstrcmp(preferred_driver, drivernames[ROS3_VFD_IDX])) { +#ifdef H5_HAVE_ROS3_VFD + get_fapl_info.info = (void *)&ros3_fa; +#else + HDfprintf(rawerrorstream, "Error: Read-Only S3 VFD is not enabled\n\n"); leave(EXIT_FAILURE); +#endif + } + else if (!HDstrcmp(preferred_driver, drivernames[HDFS_VFD_IDX])) { +#ifdef H5_HAVE_LIBHDFS + get_fapl_info.info = (void *)&hdfs_fa; #else - conf_fa = (void *)&hdfs_fa; -#endif /* H5_HAVE_LIBHDFS */ + HDfprintf(rawerrorstream, "Error: The HDFS VFD is not enabled\n\n"); + leave(EXIT_FAILURE); +#endif } - if (conf_fa != NULL) { - HDassert(fapl_id == H5P_DEFAULT); - fapl_id = H5Pcreate(H5P_FILE_ACCESS); - if (fapl_id < 0) { - HDfprintf(rawerrorstream, "Error: Unable to create fapl entry\n\n"); - leave(EXIT_FAILURE); - } - if (0 == h5tools_set_configured_fapl(fapl_id, preferred_driver, conf_fa)) { - HDfprintf(rawerrorstream, "Error: Unable to set fapl\n\n"); - usage(); - leave(EXIT_FAILURE); - } + if ((fapl_id = h5tools_get_fapl(H5P_DEFAULT, &get_fapl_info)) < 0) { + HDfprintf(rawerrorstream, "Error: Unable to create FAPL for file access\n\n"); + leave(EXIT_FAILURE); } - } /* preferred_driver defined */ + } if (enable_error_stack > 0) { H5Eset_auto2(H5E_DEFAULT, func, edata); @@ -3301,12 +3198,8 @@ main(int argc, const char *argv[]) file_id = H5I_INVALID_HID; while (fname && *fname) { - if (fapl_id != H5P_DEFAULT) { - file_id = H5Fopen(fname, H5F_ACC_RDONLY, fapl_id); - } - else { - file_id = h5tools_fopen(fname, H5F_ACC_RDONLY, H5P_DEFAULT, preferred_driver, drivername, sizeof drivername); - } + file_id = h5tools_fopen(fname, H5F_ACC_RDONLY, fapl_id, + (fapl_id == H5P_DEFAULT) ? FALSE : TRUE, drivername, sizeof drivername); if (file_id >= 0) { if (verbose_g) diff --git a/tools/src/h5repack/h5repack.c b/tools/src/h5repack/h5repack.c index 8eeaa0e..081bdcd 100644 --- a/tools/src/h5repack/h5repack.c +++ b/tools/src/h5repack/h5repack.c @@ -79,6 +79,8 @@ h5repack_init(pack_opt_t *options, int verbose, hbool_t latest) options->layout_g = H5D_LAYOUT_ERROR; options->low_bound = H5F_LIBVER_EARLIEST; options->high_bound = H5F_LIBVER_LATEST; + options->fin_fapl = H5P_DEFAULT; + options->fout_fapl = H5P_DEFAULT; for (n = 0; n < H5_REPACK_MAX_NFILTERS; n++) { options->filter_g[n].filtn = -1; @@ -751,7 +753,8 @@ check_objects(const char* fname, pack_opt_t *options) * open the file *------------------------------------------------------------------------- */ - if ((fid = h5tools_fopen(fname, H5F_ACC_RDONLY, H5P_DEFAULT, NULL, NULL, 0)) < 0) + if ((fid = h5tools_fopen(fname, H5F_ACC_RDONLY, options->fin_fapl, + (options->fin_fapl == H5P_DEFAULT) ? FALSE : TRUE, NULL, 0)) < 0) H5TOOLS_GOTO_ERROR((-1), "h5tools_fopen failed <%s>: %s", fname, H5FOPENERROR); /*------------------------------------------------------------------------- diff --git a/tools/src/h5repack/h5repack.h b/tools/src/h5repack/h5repack.h index 52ecb0e..caa1166 100644 --- a/tools/src/h5repack/h5repack.h +++ b/tools/src/h5repack/h5repack.h @@ -114,6 +114,8 @@ typedef struct { hbool_t latest; /*pack file with the latest file format */ H5F_libver_t low_bound; /* The file's low bound as in H5Fset_libver_bounds() */ H5F_libver_t high_bound; /* The file's high bound as in H5Fset_libver_bounds() */ + hid_t fin_fapl; /* FAPL to use for opening the input file */ + hid_t fout_fapl; /* FAPL to use for opening/creating the output file */ int grp_compact; /* Set the maximum number of links to store as header messages in the group */ int grp_indexed; /* Set the minimum number of links to store in the indexed format */ int msg_size[8]; /* Minimum size of shared messages: dataspace, @@ -151,7 +153,7 @@ int h5repack_addlayout(const char* str, pack_opt_t *options); int h5repack_init(pack_opt_t *options, int verbose, hbool_t latest); int h5repack_end(pack_opt_t *options); int h5repack_verify(const char *in_fname, const char *out_fname, pack_opt_t *options); -int h5repack_cmp_pl(const char *fname1, const char *fname2); +int h5repack_cmp_pl(const char *fname1, hid_t fname1_fapl, const char *fname2, hid_t fname2_fapl); /* Note: The below copy_named_datatype(), named_datatype_free(), copy_attr() * and struct named_dt_t were located in h5repack_copy.c as static prior to diff --git a/tools/src/h5repack/h5repack_copy.c b/tools/src/h5repack/h5repack_copy.c index 1044244..ae93b30 100644 --- a/tools/src/h5repack/h5repack_copy.c +++ b/tools/src/h5repack/h5repack_copy.c @@ -67,7 +67,6 @@ copy_objects(const char* fnamein, const char* fnameout, pack_opt_t *options) hid_t grp_in = H5I_INVALID_HID; /* group ID */ hid_t gcpl_in = H5I_INVALID_HID; /* group creation property list */ hid_t fcpl = H5P_DEFAULT; /* file creation property list ID */ - hid_t fapl = H5P_DEFAULT; /* file access property list ID */ trav_table_t *travt = NULL; hsize_t ub_size = 0; /* size of user block */ H5F_fspace_strategy_t set_strategy; /* Strategy to be set in outupt file */ @@ -85,7 +84,8 @@ copy_objects(const char* fnamein, const char* fnameout, pack_opt_t *options) * open input file *------------------------------------------------------------------------- */ - if ((fidin = h5tools_fopen(fnamein, H5F_ACC_RDONLY, H5P_DEFAULT, NULL, NULL, (size_t) 0)) < 0) + if ((fidin = h5tools_fopen(fnamein, H5F_ACC_RDONLY, options->fin_fapl, + (options->fin_fapl == H5P_DEFAULT) ? FALSE : TRUE, NULL, (size_t) 0)) < 0) H5TOOLS_GOTO_ERROR((-1), "h5tools_fopen failed <%s>: %s", fnamein, H5FOPENERROR); /* get user block size and file space strategy/persist/threshold */ @@ -122,12 +122,14 @@ copy_objects(const char* fnamein, const char* fnameout, pack_opt_t *options) if(options->latest) options->low_bound = options->high_bound = H5F_LIBVER_LATEST; + /* Create file access property list */ - if((fapl = H5Pcreate(H5P_FILE_ACCESS)) < 0) - H5TOOLS_GOTO_ERROR((-1), "H5Pcreate failed to create file access property list"); + if (options->fout_fapl == H5P_DEFAULT) + if ((options->fout_fapl = H5Pcreate(H5P_FILE_ACCESS)) < 0) + H5TOOLS_GOTO_ERROR((-1), "H5Pcreate failed to create file access property list"); /* It can be default, latest or other settings by users */ - if(H5Pset_libver_bounds(fapl, options->low_bound, options->high_bound) < 0) + if(H5Pset_libver_bounds(options->fout_fapl, options->low_bound, options->high_bound) < 0) H5TOOLS_GOTO_ERROR((-1), "H5Pset_libver_bounds failed to set format version bounds"); /* Check if we need to create a non-default file creation property list */ @@ -218,12 +220,12 @@ print_user_block(fnamein, fidin); */ if (options->alignment > 0) { /* either use the FAPL already created or create a new one */ - if (fapl == H5P_DEFAULT) + if (options->fout_fapl == H5P_DEFAULT) /* create a file access property list */ - if ((fapl = H5Pcreate(H5P_FILE_ACCESS)) < 0) + if ((options->fout_fapl = H5Pcreate(H5P_FILE_ACCESS)) < 0) H5TOOLS_GOTO_ERROR((-1), "H5Pcreate failed to create file access property list"); - if (H5Pset_alignment(fapl, options->threshold, options->alignment) < 0) + if (H5Pset_alignment(options->fout_fapl, options->threshold, options->alignment) < 0) H5TOOLS_GOTO_ERROR((-1), "H5Pset_alignment failed to set alignment"); } @@ -233,12 +235,12 @@ print_user_block(fnamein, fidin); */ if (options->meta_block_size > 0) { /* either use the FAPL already created or create a new one */ - if (fapl == H5P_DEFAULT) + if (options->fout_fapl == H5P_DEFAULT) /* create a file access property list */ - if ((fapl = H5Pcreate(H5P_FILE_ACCESS)) < 0) + if ((options->fout_fapl = H5Pcreate(H5P_FILE_ACCESS)) < 0) H5TOOLS_GOTO_ERROR((-1), "H5Pcreate failed to create file access property list"); - if (H5Pset_meta_block_size(fapl, options->meta_block_size) < 0) + if (H5Pset_meta_block_size(options->fout_fapl, options->meta_block_size) < 0) H5TOOLS_GOTO_ERROR((-1), "H5Pset_meta_block_size failed to set metadata block size"); } @@ -297,7 +299,7 @@ print_user_block(fnamein, fidin); if (options->verbose) HDprintf("Making new file ...\n"); - if ((fidout = H5Fcreate(fnameout, H5F_ACC_TRUNC, fcpl, fapl)) < 0) + if ((fidout = H5Fcreate(fnameout, H5F_ACC_TRUNC, fcpl, options->fout_fapl)) < 0) H5TOOLS_GOTO_ERROR((-1), "H5Fcreate could not create file <%s>:", fnameout); /*------------------------------------------------------------------------- @@ -352,7 +354,6 @@ done: H5E_BEGIN_TRY { H5Pclose(fcpl_in); H5Pclose(gcpl_in); - H5Pclose(fapl); H5Pclose(fcpl); H5Gclose(grp_in); H5Fclose(fidin); @@ -702,11 +703,14 @@ do_copy_objects(hid_t fidin, hid_t fidout, trav_table_t *travt, break; - /*------------------------------------------------------------------------- - * H5TRAV_TYPE_DATASET - *------------------------------------------------------------------------- - */ + /*------------------------------------------------------------------------- + * H5TRAV_TYPE_DATASET + *------------------------------------------------------------------------- + */ case H5TRAV_TYPE_DATASET: + { + hbool_t use_h5ocopy; + has_filter = 0; req_filter = 0; @@ -764,9 +768,47 @@ do_copy_objects(hid_t fidin, hid_t fidout, trav_table_t *travt, * otherwise we do a copy using H5Ocopy *------------------------------------------------------------------------- */ - if (options->op_tbl->nelems || options->all_filter == 1 - || options->all_layout == 1 || is_ref || is_named) { + use_h5ocopy = !(options->op_tbl->nelems || options->all_filter == 1 + || options->all_layout == 1 || is_ref || is_named); + + /* + * Check if we are using different source and destination VOL connectors. + * In this case, we currently have to avoid usage of H5Ocopy since it + * doesn't support this. + */ + if (use_h5ocopy && (options->fin_fapl != H5P_DEFAULT || options->fout_fapl != H5P_DEFAULT)) { + hid_t in_vol_id; + hid_t out_vol_id; + hid_t default_vol_id; + + if (H5Pget_vol_id(H5P_FILE_ACCESS_DEFAULT, &default_vol_id) < 0) + H5TOOLS_GOTO_ERROR((-1), "H5Pget_vol_id failed"); + + if (options->fin_fapl == H5P_DEFAULT) + in_vol_id = default_vol_id; + else + if (H5Pget_vol_id(options->fin_fapl, &in_vol_id) < 0) + H5TOOLS_GOTO_ERROR((-1), "H5Pget_vol_id failed"); + if (options->fout_fapl == H5P_DEFAULT) + out_vol_id = default_vol_id; + else + if (H5Pget_vol_id(options->fout_fapl, &out_vol_id) < 0) + H5TOOLS_GOTO_ERROR((-1), "H5Pget_vol_id failed"); + + if (in_vol_id != out_vol_id) + use_h5ocopy = FALSE; + + if (in_vol_id != default_vol_id) + if (H5VLclose(in_vol_id) < 0) + H5TOOLS_GOTO_ERROR((-1), "H5VLclose failed"); + if (out_vol_id != default_vol_id) + if (H5VLclose(out_vol_id) < 0) + H5TOOLS_GOTO_ERROR((-1), "H5VLclose failed"); + if (H5VLclose(default_vol_id) < 0) + H5TOOLS_GOTO_ERROR((-1), "H5VLclose failed"); + } + if (!use_h5ocopy) { int j; if ((dset_in = H5Dopen2(fidin, travt->objs[i].name, H5P_DEFAULT)) < 0) @@ -1135,7 +1177,9 @@ do_copy_objects(hid_t fidin, hid_t fidout, trav_table_t *travt, HDprintf(FORMAT_OBJ, "dset", travt->objs[i].name); } /* end whether we have request for filter/chunking */ + break; + } /* H5TRAV_TYPE_DATASET */ /*------------------------------------------------------------------------- * H5TRAV_TYPE_NAMED_DATATYPE diff --git a/tools/src/h5repack/h5repack_main.c b/tools/src/h5repack/h5repack_main.c index 16899a3..50b6a92 100644 --- a/tools/src/h5repack/h5repack_main.c +++ b/tools/src/h5repack/h5repack_main.c @@ -62,6 +62,12 @@ static struct long_options l_opts[] = { { "sort_by", require_arg, 'q' }, { "sort_order", require_arg, 'z' }, { "enable-error-stack", no_arg, 'E' }, + { "src-vol-id", require_arg, '1' }, + { "src-vol-name", require_arg, '2' }, + { "src-vol-info", require_arg, '3' }, + { "dst-vol-id", require_arg, '4' }, + { "dst-vol-name", require_arg, '5' }, + { "dst-vol-info", require_arg, '6' }, { NULL, 0, '\0' } }; @@ -86,6 +92,18 @@ static void usage(const char *prog) { PRINTVALSTREAM(rawoutstream, " -n, --native Use a native HDF5 type when repacking\n"); PRINTVALSTREAM(rawoutstream, " --enable-error-stack Prints messages from the HDF5 error stack as they\n"); PRINTVALSTREAM(rawoutstream, " occur\n"); + PRINTVALSTREAM(rawoutstream, " --src-vol-id ID of the VOL connector to use for opening the input\n"); + PRINTVALSTREAM(rawoutstream, " HDF5 file specified\n"); + PRINTVALSTREAM(rawoutstream, " --src-vol-name Name of the VOL connector to use for opening the input\n"); + PRINTVALSTREAM(rawoutstream, " HDF5 file specified\n"); + PRINTVALSTREAM(rawoutstream, " --src-vol-info VOL-specific info to pass to the VOL connector used for\n"); + PRINTVALSTREAM(rawoutstream, " opening the input HDF5 file specified\n"); + PRINTVALSTREAM(rawoutstream, " --dst-vol-id ID of the VOL connector to use for opening the output\n"); + PRINTVALSTREAM(rawoutstream, " HDF5 file specified\n"); + PRINTVALSTREAM(rawoutstream, " --dst-vol-name Name of the VOL connector to use for opening the output\n"); + PRINTVALSTREAM(rawoutstream, " HDF5 file specified\n"); + PRINTVALSTREAM(rawoutstream, " --dst-vol-info VOL-specific info to pass to the VOL connector used for\n"); + PRINTVALSTREAM(rawoutstream, " opening the output HDF5 file specified\n"); PRINTVALSTREAM(rawoutstream, " -L, --latest Use latest version of file format\n"); PRINTVALSTREAM(rawoutstream, " This option will take precedence over the options\n"); PRINTVALSTREAM(rawoutstream, " --low and --high\n"); @@ -334,7 +352,7 @@ int read_info(const char *filename, pack_opt_t *options) if (!HDstrcmp(stype, "-l")) { if (h5repack_addlayout(comp_info, options) == -1) { - error_msg("could not add chunck option\n"); + error_msg("could not add chunk option\n"); h5tools_setstatus(EXIT_FAILURE); ret_value = EXIT_FAILURE; goto done; @@ -412,9 +430,17 @@ set_sort_order(const char *form) static int parse_command_line(int argc, const char **argv, pack_opt_t* options) { + h5tools_get_fapl_info_t get_in_vol_info; + h5tools_get_fapl_info_t get_out_vol_info; + hbool_t custom_in_fapl = FALSE; + hbool_t custom_out_fapl = FALSE; + hid_t tmp_fapl = H5I_INVALID_HID; int bound, opt; int ret_value = 0; + memset(&get_in_vol_info, 0, sizeof(h5tools_get_fapl_info_t)); + memset(&get_out_vol_info, 0, sizeof(h5tools_get_fapl_info_t)); + /* parse command line options */ while (EOF != (opt = get_option(argc, argv, s_opts, l_opts))) { switch ((char) opt) { @@ -434,13 +460,13 @@ int parse_command_line(int argc, const char **argv, pack_opt_t* options) case 'h': usage(h5tools_getprogname()); h5tools_setstatus(EXIT_SUCCESS); - ret_value = -1; + ret_value = 1; goto done; case 'V': print_version(h5tools_getprogname()); h5tools_setstatus(EXIT_SUCCESS); - ret_value = -1; + ret_value = 1; goto done; case 'v': @@ -478,9 +504,12 @@ int parse_command_line(int argc, const char **argv, pack_opt_t* options) break; case 'e': - ret_value = read_info(opt_arg, options); - if (ret_value < 0) + if ((ret_value = read_info(opt_arg, options)) < 0) { + error_msg("failed to read from repack options file <%s>\n", opt_arg); + h5tools_setstatus(EXIT_FAILURE); + ret_value = -1; goto done; + } break; case 'n': @@ -495,6 +524,8 @@ int parse_command_line(int argc, const char **argv, pack_opt_t* options) bound = HDatoi(opt_arg); if (bound < H5F_LIBVER_EARLIEST || bound > H5F_LIBVER_LATEST) { error_msg("in parsing low bound\n"); + h5tools_setstatus(EXIT_FAILURE); + ret_value = -1; goto done; } options->low_bound = bound; @@ -504,6 +535,8 @@ int parse_command_line(int argc, const char **argv, pack_opt_t* options) bound = HDatoi(opt_arg); if (bound < H5F_LIBVER_EARLIEST || bound > H5F_LIBVER_LATEST) { error_msg("in parsing high bound\n"); + h5tools_setstatus(EXIT_FAILURE); + ret_value = -1; goto done; } options->high_bound = bound; @@ -625,8 +658,8 @@ int parse_command_line(int argc, const char **argv, pack_opt_t* options) break; case 'q': - if (H5_INDEX_UNKNOWN == set_sort_by(opt_arg)) { - error_msg(" failed to set sort by form <%s>\n", opt_arg); + if (H5_INDEX_UNKNOWN == (sort_by = set_sort_by(opt_arg))) { + error_msg("failed to set sort by form <%s>\n", opt_arg); h5tools_setstatus(EXIT_FAILURE); ret_value = -1; goto done; @@ -634,8 +667,8 @@ int parse_command_line(int argc, const char **argv, pack_opt_t* options) break; case 'z': - if (set_sort_order(opt_arg) == H5_ITER_UNKNOWN) { - error_msg(" failed to set sort order form <%s>\n", opt_arg); + if (H5_ITER_UNKNOWN == (sort_order = set_sort_order(opt_arg))) { + error_msg("failed to set sort order form <%s>\n", opt_arg); h5tools_setstatus(EXIT_FAILURE); ret_value = -1; goto done; @@ -646,6 +679,38 @@ int parse_command_line(int argc, const char **argv, pack_opt_t* options) enable_error_stack = 1; break; + case '1': + get_in_vol_info.get_type = GET_VOL_BY_ID; + get_in_vol_info.u.id = HDatol(opt_arg); + custom_in_fapl = TRUE; + break; + + case '2': + get_in_vol_info.get_type = GET_VOL_BY_NAME; + get_in_vol_info.u.name = opt_arg; + custom_in_fapl = TRUE; + break; + + case '3': + get_in_vol_info.info = opt_arg; + break; + + case '4': + get_out_vol_info.get_type = GET_VOL_BY_ID; + get_out_vol_info.u.id = HDatol(opt_arg); + custom_out_fapl = TRUE; + break; + + case '5': + get_out_vol_info.get_type = GET_VOL_BY_NAME; + get_out_vol_info.u.name = opt_arg; + custom_out_fapl = TRUE; + break; + + case '6': + get_out_vol_info.info = opt_arg; + break; + default: break; } /* end switch */ @@ -653,30 +718,71 @@ int parse_command_line(int argc, const char **argv, pack_opt_t* options) /* If neither -i nor -o given, get in and out files positionally */ if (0 == (has_i + has_o)) { - if (argv[opt_ind] != NULL && argv[opt_ind + 1] != NULL) { - infile = argv[opt_ind]; - outfile = argv[opt_ind + 1]; - - if (!HDstrcmp(infile, outfile)) { - error_msg("file names cannot be the same\n"); - usage(h5tools_getprogname()); - h5tools_setstatus(EXIT_FAILURE); - ret_value = -1; - } - } - else { - error_msg("file names missing\n"); - usage(h5tools_getprogname()); - h5tools_setstatus(EXIT_FAILURE); - ret_value = -1; - } - } - else if (has_i != 1 || has_o != 1) { - error_msg("filenames must be either both -i -o or both positional\n"); - usage(h5tools_getprogname()); - h5tools_setstatus(EXIT_FAILURE); - ret_value = -1; - } + if (argv[opt_ind] != NULL && argv[opt_ind + 1] != NULL) { + infile = argv[opt_ind]; + outfile = argv[opt_ind + 1]; + + if (!HDstrcmp(infile, outfile)) { + error_msg("file names cannot be the same\n"); + usage(h5tools_getprogname()); + h5tools_setstatus(EXIT_FAILURE); + ret_value = -1; + } + } + else { + error_msg("file names missing\n"); + usage(h5tools_getprogname()); + h5tools_setstatus(EXIT_FAILURE); + ret_value = -1; + } + } + else if (has_i != 1 || has_o != 1) { + error_msg("filenames must be either both -i -o or both positional\n"); + usage(h5tools_getprogname()); + h5tools_setstatus(EXIT_FAILURE); + ret_value = -1; + } + + /* Setup FAPL for input and output file accesses */ + if (custom_in_fapl) { + if ((tmp_fapl = h5tools_get_fapl(options->fin_fapl, &get_in_vol_info)) < 0) { + error_msg("failed to setup FAPL for input file\n"); + h5tools_setstatus(EXIT_FAILURE); + ret_value = -1; + goto done; + } + + /* Close old FAPL */ + if (options->fin_fapl != H5P_DEFAULT) + if (H5Pclose(options->fin_fapl) < 0) { + error_msg("failed to close FAPL\n"); + h5tools_setstatus(EXIT_FAILURE); + ret_value = -1; + goto done; + } + + options->fin_fapl = tmp_fapl; + } + + if (custom_out_fapl) { + if ((tmp_fapl = h5tools_get_fapl(options->fout_fapl, &get_out_vol_info)) < 0) { + error_msg("failed to setup FAPL for output file\n"); + h5tools_setstatus(EXIT_FAILURE); + ret_value = -1; + goto done; + } + + /* Close old FAPL */ + if (options->fout_fapl != H5P_DEFAULT) + if (H5Pclose(options->fout_fapl) < 0) { + error_msg("failed to close FAPL\n"); + h5tools_setstatus(EXIT_FAILURE); + ret_value = -1; + goto done; + } + + options->fout_fapl = tmp_fapl; + } done: return ret_value; @@ -694,14 +800,18 @@ done: */ int main(int argc, const char **argv) { - pack_opt_t options; /*the global options */ + pack_opt_t options; /*the global options */ H5E_auto2_t func; H5E_auto2_t tools_func; void *edata; void *tools_edata; + int parse_ret; HDmemset(&options, 0, sizeof(pack_opt_t)); + /* Initialize h5tools lib */ + h5tools_init(); + h5tools_setprogname(PROGRAMNAME); h5tools_setstatus(EXIT_SUCCESS); @@ -709,29 +819,38 @@ int main(int argc, const char **argv) H5Eget_auto2(H5E_DEFAULT, &func, &edata); H5Eset_auto2(H5E_DEFAULT, NULL, NULL); - /* Initialize h5tools lib */ - h5tools_init(); - /* Disable tools error reporting */ H5Eget_auto2(H5tools_ERR_STACK_g, &tools_func, &tools_edata); H5Eset_auto2(H5tools_ERR_STACK_g, NULL, NULL); /* update hyperslab buffer size from H5TOOLS_BUFSIZE env if exist */ if (h5tools_getenv_update_hyperslab_bufsize() < 0) { + HDprintf("Error occurred while retrieving H5TOOLS_BUFSIZE value\n"); h5tools_setstatus(EXIT_FAILURE); goto done; } /* initialize options */ if (h5repack_init(&options, 0, FALSE) < 0) { + HDprintf("Error occurred while initializing repack options\n"); h5tools_setstatus(EXIT_FAILURE); goto done; } + /* Initialize default indexing options */ sort_by = H5_INDEX_CRT_ORDER; - if (parse_command_line(argc, argv, &options) < 0) + parse_ret = parse_command_line(argc, argv, &options); + if (parse_ret < 0) { + HDprintf("Error occurred while parsing command-line options\n"); + h5tools_setstatus(EXIT_FAILURE); goto done; + } + else if (parse_ret > 0) { + /* Short-circuit success */ + h5tools_setstatus(EXIT_SUCCESS); + goto done; + } if (enable_error_stack > 0) { H5Eset_auto2(H5E_DEFAULT, func, edata); @@ -739,9 +858,20 @@ int main(int argc, const char **argv) } /* pack it */ - h5tools_setstatus(h5repack(infile, outfile, &options)); + if (h5repack(infile, outfile, &options) < 0) { + HDprintf("Error occurred while repacking\n"); + h5tools_setstatus(EXIT_FAILURE); + goto done; + } + + h5tools_setstatus(EXIT_SUCCESS); done: + if (options.fin_fapl >= 0 && options.fin_fapl != H5P_DEFAULT) + H5Pclose(options.fin_fapl); + if (options.fout_fapl >= 0 && options.fout_fapl != H5P_DEFAULT) + H5Pclose(options.fout_fapl); + /* free tables */ h5repack_end(&options); diff --git a/tools/src/h5repack/h5repack_verify.c b/tools/src/h5repack/h5repack_verify.c index 683988c..7bb5dfd 100644 --- a/tools/src/h5repack/h5repack_verify.c +++ b/tools/src/h5repack/h5repack_verify.c @@ -353,16 +353,16 @@ int verify_layout(hid_t pid, pack_info_t *obj) *------------------------------------------------------------------------- */ -int h5repack_cmp_pl(const char *fname1, const char *fname2) +int h5repack_cmp_pl(const char *fname1, hid_t fname1_fapl, const char *fname2, hid_t fname2_fapl) { - hid_t fid1 =H5I_INVALID_HID; /* file ID */ - hid_t fid2 =H5I_INVALID_HID; /* file ID */ - hid_t dset1 =H5I_INVALID_HID; /* dataset ID */ - hid_t dset2 =H5I_INVALID_HID; /* dataset ID */ - hid_t gid =H5I_INVALID_HID; /* group ID */ - hid_t dcpl1 =H5I_INVALID_HID; /* dataset creation property list ID */ - hid_t dcpl2 =H5I_INVALID_HID; /* dataset creation property list ID */ - hid_t gcplid =H5I_INVALID_HID; /* group creation property list */ + hid_t fid1 = H5I_INVALID_HID; /* file ID */ + hid_t fid2 = H5I_INVALID_HID; /* file ID */ + hid_t dset1 = H5I_INVALID_HID; /* dataset ID */ + hid_t dset2 = H5I_INVALID_HID; /* dataset ID */ + hid_t gid = H5I_INVALID_HID; /* group ID */ + hid_t dcpl1 = H5I_INVALID_HID; /* dataset creation property list ID */ + hid_t dcpl2 = H5I_INVALID_HID; /* dataset creation property list ID */ + hid_t gcplid = H5I_INVALID_HID; /* group creation property list */ unsigned crt_order_flag1; /* group creation order flag */ unsigned crt_order_flag2; /* group creation order flag */ trav_table_t *trav = NULL; @@ -374,9 +374,9 @@ int h5repack_cmp_pl(const char *fname1, const char *fname2) *------------------------------------------------------------------------- */ /* Open the files */ - if ((fid1 = H5Fopen(fname1, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0) + if ((fid1 = h5tools_fopen(fname1, H5F_ACC_RDONLY, fname1_fapl, TRUE, NULL, 0)) < 0) H5TOOLS_GOTO_ERROR((-1), "h5tools_fopen failed <%s>: %s", fname1, H5FOPENERROR); - if ((fid2 = H5Fopen(fname2, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0) + if ((fid2 = h5tools_fopen(fname2, H5F_ACC_RDONLY, fname2_fapl, TRUE, NULL, 0)) < 0) H5TOOLS_GOTO_ERROR((-1), "h5tools_fopen failed <%s>: %s", fname2, H5FOPENERROR); /*------------------------------------------------------------------------- diff --git a/tools/src/h5stat/h5stat.c b/tools/src/h5stat/h5stat.c index adc905a..01e86fe 100644 --- a/tools/src/h5stat/h5stat.c +++ b/tools/src/h5stat/h5stat.c @@ -118,30 +118,28 @@ typedef struct iter_t { } iter_t; -static const char *drivername = ""; +static const char *drivername = NULL; #ifdef H5_HAVE_ROS3_VFD -/* default "anonymous" s3 configuration - */ +/* Default "anonymous" S3 configuration */ static H5FD_ros3_fapl_t ros3_fa = { - 1, /* fapl version */ - false, /* authenticate */ - "", /* aws region */ - "", /* access key id */ - "", /* secret access key */ + 1, /* FAPL Version */ + false, /* Authenticate? */ + "", /* AWS Region */ + "", /* Access Key ID */ + "", /* Secret Access Key */ }; #endif /* H5_HAVE_ROS3_VFD */ #ifdef H5_HAVE_LIBHDFS -/* default HDFS access configuration - */ +/* "Default" HDFS configuration */ static H5FD_hdfs_fapl_t hdfs_fa = { - 1, /* fapl version */ - "localhost", /* namenode name */ - 0, /* namenode port */ - "", /* kerberos ticket cache */ - "", /* user name */ - 2048, /* stream buffer size */ + 1, /* FAPL Version */ + "localhost", /* Namenode Name */ + 0, /* Namenode Port */ + "", /* Kerberos ticket cache */ + "", /* User name */ + 2048, /* Stream buffer size */ }; #endif /* H5_HAVE_LIBHDFS */ @@ -1065,103 +1063,32 @@ parse_command_line(int argc, const char *argv[], struct handler_t **hand_ret) break; case 'w': -#ifndef H5_HAVE_ROS3_VFD +#ifdef H5_HAVE_ROS3_VFD + if (h5tools_parse_ros3_fapl_tuple(opt_arg, ',', &ros3_fa) < 0) { + error_msg("failed to parse S3 VFD credential info\n"); + goto error; + } + + drivername = drivernames[ROS3_VFD_IDX]; +#else error_msg("Read-Only S3 VFD not enabled.\n"); goto error; -#else - { - char *cred_str = NULL; - unsigned nelems = 0; - char **cred = NULL; - char const *ccred[3]; - - if (FAIL == parse_tuple((const char *)opt_arg, ',', &cred_str, &nelems, &cred)) { - error_msg("Unable to parse s3 credential\n"); - goto error; - } - if (nelems != 3) { - error_msg("s3 credential must have three elements\n"); - goto error; - } - ccred[0] = (const char *)cred[0]; - ccred[1] = (const char *)cred[1]; - ccred[2] = (const char *)cred[2]; - if (0 == h5tools_populate_ros3_fapl(&ros3_fa, ccred)) { - error_msg("Unable to set ros3 fapl config\n"); - goto error; - } - HDfree(cred); - HDfree(cred_str); - } /* parse s3-cred block */ - drivername = "ros3"; +#endif break; -#endif /* H5_HAVE_ROS3_VFD */ case 'H': -#ifndef H5_HAVE_LIBHDFS - error_msg("HDFS VFD is not enabled.\n"); - goto error; -#else - { - unsigned nelems = 0; - char *props_src = NULL; - char **props = NULL; - unsigned long k = 0; - if (FAIL == parse_tuple((const char *)opt_arg, - ',', &props_src, &nelems, &props)) { - error_msg("unable to parse hdfs properties tuple\n"); - goto error; - } - /* sanity-check tuple count - */ - if (nelems != 5) { - char str[64] = ""; - HDsprintf(str, - "expected 5 elements in hdfs properties tuple " - "but found %u\n", - nelems); - HDfree(props); - HDfree(props_src); - error_msg(str); - goto error; - } - /* Populate fapl configuration structure with given - * properties. - * TODO/WARNING: No error-checking is done on length of - * input strings... Silent overflow is possible, - * albeit unlikely. - */ - if (HDstrncmp(props[0], "", 1)) { - HDstrncpy(hdfs_fa.namenode_name,(const char *)props[0], HDstrlen(props[0])); - } - if (HDstrncmp(props[1], "", 1)) { - k = strtoul((const char *)props[1], NULL, 0); - if (errno == ERANGE) { - error_msg("supposed port number wasn't.\n"); - goto error; - } - hdfs_fa.namenode_port = (int32_t)k; - } - if (HDstrncmp(props[2], "", 1)) { - HDstrncpy(hdfs_fa.kerberos_ticket_cache, (const char *)props[2], HDstrlen(props[2])); - } - if (HDstrncmp(props[3], "", 1)) { - HDstrncpy(hdfs_fa.user_name, (const char *)props[3], HDstrlen(props[3])); - } - if (strncmp(props[4], "", 1)) { - k = HDstrtoul((const char *)props[4], NULL, 0); - if (errno == ERANGE) { - error_msg("supposed buffersize number wasn't.\n"); - goto error; - } - hdfs_fa.stream_buffer_size = (int32_t)k; - } - HDfree(props); - HDfree(props_src); - drivername = "hdfs"; +#ifdef H5_HAVE_LIBHDFS + if (h5tools_parse_hdfs_fapl_tuple(opt_arg, ',', &hdfs_fa) < 0) { + error_msg("failed to parse HDFS VFD configuration info\n"); + goto error; } + + drivername = drivernames[HDFS_VFD_IDX]; +#else + error_msg("HDFS VFD not enabled.\n"); + goto error; +#endif break; -#endif /* H5_HAVE_LIBHDFS */ default: usage(h5tools_getprogname()); @@ -1885,41 +1812,36 @@ main(int argc, const char *argv[]) if(parse_command_line(argc, argv, &hand) < 0) goto done; - /* if drivername is not null, probably need to set the fapl */ - if (HDstrcmp(drivername, "")) { - void *conf_fa = NULL; + if (drivername) { + h5tools_get_fapl_info_t get_fapl_info; - if (!HDstrcmp(drivername, "ros3")) { -#ifndef H5_HAVE_ROS3_VFD - error_msg("Read-Only S3 VFD not enabled.\n\n"); - goto done; -#else - conf_fa = (void *)&ros3_fa; -#endif /* H5_HAVE_ROS3_VFD */ + /* Currently, only retrieval of VFDs is supported. */ + get_fapl_info.get_type = GET_VFD_BY_NAME; + get_fapl_info.info = NULL; + get_fapl_info.u.name = drivername; - } - else if (!HDstrcmp(drivername, "hdfs")) { -#ifndef H5_HAVE_LIBHDFS - error_msg("HDFS VFD not enabled.\n\n"); + if (!HDstrcmp(drivername, drivernames[ROS3_VFD_IDX])) { +#ifdef H5_HAVE_ROS3_VFD + get_fapl_info.info = (void *)&ros3_fa; +#else + error_msg("Read-Only S3 VFD not enabled.\n"); goto done; +#endif + } + else if (!HDstrcmp(drivername, drivernames[HDFS_VFD_IDX])) { +#ifdef H5_HAVE_LIBHDFS + get_fapl_info.info = (void *)&hdfs_fa; #else - conf_fa = (void *)&hdfs_fa; -#endif /* H5_HAVE_LIBHDFS */ + error_msg("HDFS VFD not enabled.\n"); + goto done; +#endif } - if (conf_fa != NULL) { - HDassert(fapl_id == H5P_DEFAULT); - fapl_id = H5Pcreate(H5P_FILE_ACCESS); - if (fapl_id < 0) { - error_msg("Unable to create fapl entry\n"); - goto done; - } - if (1 > h5tools_set_configured_fapl(fapl_id, drivername, conf_fa)) { - error_msg("Unable to set fapl\n"); - goto done; - } + if ((fapl_id = h5tools_get_fapl(H5P_DEFAULT, &get_fapl_info)) < 0) { + error_msg("Unable to create FAPL for file access\n"); + goto done; } - } /* drivername set */ + } fname = argv[opt_ind]; @@ -1935,7 +1857,9 @@ main(int argc, const char *argv[]) HDprintf("Filename: %s\n", fname); - fid = H5Fopen(fname, H5F_ACC_RDONLY, fapl_id); + fid = h5tools_fopen(fname, H5F_ACC_RDONLY, fapl_id, + (fapl_id == H5P_DEFAULT) ? FALSE : TRUE, NULL, 0); + if(fid < 0) { error_msg("unable to open file \"%s\"\n", fname); h5tools_setstatus(EXIT_FAILURE); diff --git a/tools/src/misc/h5clear.c b/tools/src/misc/h5clear.c index 38fa6a2..2c85e75 100644 --- a/tools/src/misc/h5clear.c +++ b/tools/src/misc/h5clear.c @@ -267,6 +267,8 @@ main (int argc, const char *argv[]) /* initialize h5tools lib */ h5tools_init(); + H5Eset_auto2(H5tools_ERR_STACK_g, NULL, NULL); + /* Parse command line options */ if(parse_command_line(argc, argv) < 0) goto done; @@ -339,7 +341,7 @@ main (int argc, const char *argv[]) } /* Open the file */ - if((fid = h5tools_fopen(fname, flags, fapl, NULL, NULL, (size_t)0)) < 0) { + if((fid = h5tools_fopen(fname, flags, fapl, FALSE, NULL, (size_t)0)) < 0) { error_msg("h5tools_fopen\n"); h5tools_setstatus(EXIT_FAILURE); goto done; diff --git a/tools/src/misc/h5mkgrp.c b/tools/src/misc/h5mkgrp.c index feb60d4..a2cb68b 100644 --- a/tools/src/misc/h5mkgrp.c +++ b/tools/src/misc/h5mkgrp.c @@ -255,7 +255,7 @@ main(int argc, const char *argv[]) } /* end if */ /* Attempt to open an existing HDF5 file first */ - fid = h5tools_fopen(params.fname, H5F_ACC_RDWR, fapl_id, NULL, NULL, 0); + fid = h5tools_fopen(params.fname, H5F_ACC_RDWR, fapl_id, FALSE, NULL, 0); /* If we couldn't open an existing file, try creating file */ /* (use "EXCL" instead of "TRUNC", so we don't blow away existing non-HDF5 file) */ diff --git a/tools/test/h5format_convert/h5fc_chk_idx.c b/tools/test/h5format_convert/h5fc_chk_idx.c index ad1742b..02cc25f 100644 --- a/tools/test/h5format_convert/h5fc_chk_idx.c +++ b/tools/test/h5format_convert/h5fc_chk_idx.c @@ -60,7 +60,7 @@ main(int argc, char *argv[]) dname = HDstrdup(argv[2]); /* Try opening the file */ - if((fid = h5tools_fopen(fname, H5F_ACC_RDONLY, H5P_DEFAULT, NULL, NULL, (size_t)0)) < 0) { + if((fid = h5tools_fopen(fname, H5F_ACC_RDONLY, H5P_DEFAULT, FALSE, NULL, (size_t)0)) < 0) { HDfprintf(stderr, "h5fc_chk_idx: unable to open the file\n"); HDexit(EXIT_FAILURE); } /* end if */ diff --git a/tools/test/h5repack/h5repacktst.c b/tools/test/h5repack/h5repacktst.c index 2654685..ac1fbe0 100644 --- a/tools/test/h5repack/h5repacktst.c +++ b/tools/test/h5repack/h5repacktst.c @@ -382,7 +382,7 @@ int main (void) GOERROR; if (h5repack_verify(FNAME0, FNAME0OUT, &pack_options) <= 0) GOERROR; - if (h5repack_cmp_pl(FNAME0, FNAME0OUT) <= 0) + if (h5repack_cmp_pl(FNAME0, pack_options.fin_fapl, FNAME0OUT, pack_options.fout_fapl) <= 0) GOERROR; if (h5repack_end(&pack_options) < 0) GOERROR; @@ -402,7 +402,7 @@ int main (void) GOERROR; if (h5repack_verify(FNAME1, FNAME1OUT, &pack_options) <= 0) GOERROR; - if (h5repack_cmp_pl(FNAME1, FNAME1OUT) <= 0) + if (h5repack_cmp_pl(FNAME1, pack_options.fin_fapl, FNAME1OUT, pack_options.fout_fapl) <= 0) GOERROR; if (h5repack_end(&pack_options) < 0) GOERROR; @@ -422,7 +422,7 @@ int main (void) GOERROR; if (h5repack_verify(FNAME2, FNAME2OUT, &pack_options) <= 0) GOERROR; - if (h5repack_cmp_pl(FNAME2, FNAME2OUT) <= 0) + if (h5repack_cmp_pl(FNAME2, pack_options.fin_fapl, FNAME2OUT, pack_options.fout_fapl) <= 0) GOERROR; if (h5repack_end(&pack_options) < 0) GOERROR; @@ -441,7 +441,7 @@ int main (void) GOERROR; if (h5repack_verify(FNAME3, FNAME3OUT, &pack_options) <= 0) GOERROR; - if (h5repack_cmp_pl(FNAME3, FNAME3OUT) <= 0) + if (h5repack_cmp_pl(FNAME3, pack_options.fin_fapl, FNAME3OUT, pack_options.fout_fapl) <= 0) GOERROR; if (h5repack_end(&pack_options) < 0) GOERROR; @@ -1132,7 +1132,7 @@ int main (void) GOERROR; if (h5repack_verify(FNAME7, FNAME7OUT, &pack_options) <= 0) GOERROR; - if (h5repack_cmp_pl(FNAME7, FNAME7OUT) <= 0) + if (h5repack_cmp_pl(FNAME7, pack_options.fin_fapl, FNAME7OUT, pack_options.fout_fapl) <= 0) GOERROR; if (h5repack_end(&pack_options) < 0) GOERROR; diff --git a/tools/test/h5repack/testfiles/h5repack-help.txt b/tools/test/h5repack/testfiles/h5repack-help.txt index 130cd72..fe02584 100644 --- a/tools/test/h5repack/testfiles/h5repack-help.txt +++ b/tools/test/h5repack/testfiles/h5repack-help.txt @@ -8,6 +8,18 @@ usage: h5repack [OPTIONS] file1 file2 -n, --native Use a native HDF5 type when repacking --enable-error-stack Prints messages from the HDF5 error stack as they occur + --src-vol-id ID of the VOL connector to use for opening the input + HDF5 file specified + --src-vol-name Name of the VOL connector to use for opening the input + HDF5 file specified + --src-vol-info VOL-specific info to pass to the VOL connector used for + opening the input HDF5 file specified + --dst-vol-id ID of the VOL connector to use for opening the output + HDF5 file specified + --dst-vol-name Name of the VOL connector to use for opening the output + HDF5 file specified + --dst-vol-info VOL-specific info to pass to the VOL connector used for + opening the output HDF5 file specified -L, --latest Use latest version of file format This option will take precedence over the options --low and --high diff --git a/tools/test/misc/clear_open_chk.c b/tools/test/misc/clear_open_chk.c index 3a61385..7d22ca6 100644 --- a/tools/test/misc/clear_open_chk.c +++ b/tools/test/misc/clear_open_chk.c @@ -53,7 +53,7 @@ main(int argc, char *argv[]) fname = HDstrdup(argv[1]); /* Try opening the file */ - if((fid = h5tools_fopen(fname, H5F_ACC_RDONLY, H5P_DEFAULT, NULL, NULL, (size_t)0)) < 0) { + if((fid = h5tools_fopen(fname, H5F_ACC_RDONLY, H5P_DEFAULT, FALSE, NULL, (size_t)0)) < 0) { HDfprintf(stderr, "clear_open_chk: unable to open the file\n"); HDfree(fname); HDexit(EXIT_FAILURE); -- cgit v0.12