diff options
author | Allen Byrne <50328838+byrnHDF@users.noreply.github.com> | 2021-08-12 16:04:06 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-08-12 16:04:06 (GMT) |
commit | cc866bc154d761157ad0a1dbc96b20df946b8970 (patch) | |
tree | edce8936fd05b34efbda1c15609fd06b21f42cf2 /src | |
parent | 7a0776dcff17330f2999420de888fd156a24239b (diff) | |
download | hdf5-cc866bc154d761157ad0a1dbc96b20df946b8970.zip hdf5-cc866bc154d761157ad0a1dbc96b20df946b8970.tar.gz hdf5-cc866bc154d761157ad0a1dbc96b20df946b8970.tar.bz2 |
Rework version-check for relnum in H5checkversion function (#896)
Diffstat (limited to 'src')
-rw-r--r-- | src/H5.c | 228 |
1 files changed, 143 insertions, 85 deletions
@@ -63,6 +63,10 @@ hbool_t H5_PKG_INIT_VAR = FALSE; /* Library Private Variables */ /*****************************/ +/* Library incompatible release versions */ +const unsigned VERS_RELEASE_EXCEPTIONS[] = {0, 1, 2, 4}; +const unsigned VERS_RELEASE_EXCEPTIONS_SIZE = 4; + /* statically initialize block for pthread_once call used in initializing */ /* the first global mutex */ #ifdef H5_HAVE_THREADSAFE @@ -228,13 +232,13 @@ done: } /* end H5_init_library() */ /*------------------------------------------------------------------------- - * Function: H5_term_library + * Function: H5_term_library * - * Purpose: Terminate interfaces in a well-defined order due to - * dependencies among the interfaces, then terminate - * library-specific data. + * Purpose: Terminate interfaces in a well-defined order due to + * dependencies among the interfaces, then terminate + * library-specific data. * - * Return: void + * Return: void * *------------------------------------------------------------------------- */ @@ -416,22 +420,22 @@ done: } /* end H5_term_library() */ /*------------------------------------------------------------------------- - * Function: H5dont_atexit + * Function: H5dont_atexit * - * Purpose: Indicates that the library is not to clean up after itself - * when the application exits by calling exit() or returning - * from main(). This function must be called before any other - * HDF5 function or constant is used or it will have no effect. + * Purpose: Indicates that the library is not to clean up after itself + * when the application exits by calling exit() or returning + * from main(). This function must be called before any other + * HDF5 function or constant is used or it will have no effect. * - * If this function is used then certain memory buffers will not - * be de-allocated nor will open files be flushed automatically. - * The application may still call H5close() explicitly to - * accomplish these things. + * If this function is used then certain memory buffers will not + * be de-allocated nor will open files be flushed automatically. + * The application may still call H5close() explicitly to + * accomplish these things. * - * Return: Success: non-negative + * Return: Success: non-negative * - * Failure: negative if this function is called more than - * once or if it is called too late. + * Failure: negative if this function is called more than + * once or if it is called too late. * *------------------------------------------------------------------------- */ @@ -452,19 +456,19 @@ H5dont_atexit(void) } /* end H5dont_atexit() */ /*------------------------------------------------------------------------- - * Function: H5garbage_collect + * Function: H5garbage_collect * - * Purpose: Walks through all the garbage collection routines for the - * library, which are supposed to free any unused memory they have - * allocated. + * Purpose: Walks through all the garbage collection routines for the + * library, which are supposed to free any unused memory they have + * allocated. * * These should probably be registered dynamically in a linked list of * functions to call, but there aren't that many right now, so we * hard-wire them... * - * Return: Success: non-negative + * Return: Success: non-negative * - * Failure: negative + * Failure: negative * *------------------------------------------------------------------------- */ @@ -485,9 +489,9 @@ done: } /* end H5garbage_collect() */ /*------------------------------------------------------------------------- - * Function: H5set_free_list_limits + * Function: H5set_free_list_limits * - * Purpose: Sets limits on the different kinds of free lists. Setting a value + * Purpose: Sets limits on the different kinds of free lists. Setting a value * of -1 for a limit means no limit of that type. These limits are global * for the entire library. Each "global" limit only applies to free lists * of that type, so if an application sets a limit of 1 MB on each of the @@ -505,9 +509,9 @@ done: * int blk_global_lim; IN: The limit on all "block" free list memory used * int blk_list_lim; IN: The limit on memory used in each "block" free list * - * Return: Success: non-negative + * Return: Success: non-negative * - * Failure: negative + * Failure: negative * *------------------------------------------------------------------------- */ @@ -531,11 +535,11 @@ done: } /* end H5set_free_list_limits() */ /*------------------------------------------------------------------------- - * Function: H5get_free_list_sizes + * Function: H5get_free_list_sizes * - * Purpose: Gets the current size of the different kinds of free lists that - * the library uses to manage memory. The free list sizes can be set with - * H5set_free_list_limits and garbage collected with H5garbage_collect. + * Purpose: Gets the current size of the different kinds of free lists that + * the library uses to manage memory. The free list sizes can be set with + * H5set_free_list_limits and garbage collected with H5garbage_collect. * These lists are global for the entire library. * * Parameters: @@ -544,8 +548,8 @@ done: * size_t *blk_size; OUT: The current size of all "block" free list memory used * size_t *fac_size; OUT: The current size of all "factory" free list memory used * - * Return: Success: non-negative - * Failure: negative + * Return: Success: non-negative + * Failure: negative * * Programmer: Quincey Koziol * Friday, March 6, 2020 @@ -569,23 +573,23 @@ done: } /* end H5get_free_list_sizes() */ /*------------------------------------------------------------------------- - * Function: H5get_alloc_stats + * Function: H5get_alloc_stats * - * Purpose: Gets the memory allocation statistics for the library, if the - * --enable-memory-alloc-sanity-check option was given when building the + * Purpose: Gets the memory allocation statistics for the library, if the + * --enable-memory-alloc-sanity-check option was given when building the * library. Applications can check whether this option was enabled by - * detecting if the 'H5_MEMORY_ALLOC_SANITY_CHECK' macro is defined. This - * option is enabled by default for debug builds of the library and - * disabled by default for non-debug builds. If the option is not enabled, - * all the values returned with be 0. These statistics are global for the - * entire library, but don't include allocations from chunked dataset I/O - * filters or non-native VOL connectors. + * detecting if the 'H5_MEMORY_ALLOC_SANITY_CHECK' macro is defined. This + * option is enabled by default for debug builds of the library and + * disabled by default for non-debug builds. If the option is not enabled, + * all the values returned with be 0. These statistics are global for the + * entire library, but don't include allocations from chunked dataset I/O + * filters or non-native VOL connectors. * * Parameters: * H5_alloc_stats_t *stats; OUT: Memory allocation statistics * - * Return: Success: non-negative - * Failure: negative + * Return: Success: non-negative + * Failure: negative * * Programmer: Quincey Koziol * Saturday, March 7, 2020 @@ -718,12 +722,12 @@ H5__debug_mask(const char *s) #ifdef H5_HAVE_PARALLEL /*------------------------------------------------------------------------- - * Function: H5__mpi_delete_cb + * Function: H5__mpi_delete_cb * - * Purpose: Callback attribute on MPI_COMM_SELF to terminate the HDF5 + * Purpose: Callback attribute on MPI_COMM_SELF to terminate the HDF5 * library when the communicator is destroyed, i.e. on MPI_Finalize. * - * Return: MPI_SUCCESS + * Return: MPI_SUCCESS * *------------------------------------------------------------------------- */ @@ -737,18 +741,18 @@ H5__mpi_delete_cb(MPI_Comm H5_ATTR_UNUSED comm, int H5_ATTR_UNUSED keyval, void #endif /*H5_HAVE_PARALLEL*/ /*------------------------------------------------------------------------- - * Function: H5get_libversion + * Function: H5get_libversion * - * Purpose: Returns the library version numbers through arguments. MAJNUM - * will be the major revision number of the library, MINNUM the - * minor revision number, and RELNUM the release revision number. + * Purpose: Returns the library version numbers through arguments. MAJNUM + * will be the major revision number of the library, MINNUM the + * minor revision number, and RELNUM the release revision number. * - * Note: When printing an HDF5 version number it should be printed as + * Note: When printing an HDF5 version number it should be printed as * - * printf("%u.%u.%u", maj, min, rel) or - * printf("version %u.%u release %u", maj, min, rel) + * printf("%u.%u.%u", maj, min, rel) or + * printf("version %u.%u release %u", maj, min, rel) * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * *------------------------------------------------------------------------- */ @@ -773,17 +777,20 @@ done: } /* end H5get_libversion() */ /*------------------------------------------------------------------------- - * Function: H5check_version + * Function: H5check_version * - * Purpose: Verifies that the arguments match the version numbers - * compiled into the library. This function is intended to be - * called from user to verify that the versions of header files - * compiled into the application match the version of the hdf5 - * library. + * Purpose: Verifies that the arguments match the version numbers + * compiled into the library. This function is intended to be + * called from user to verify that the versions of header files + * compiled into the application match the version of the hdf5 + * library. + * Within major.minor.release version, the expectation + * is that all release versions are compatible, exceptions to + * this rule must be added to the VERS_RELEASE_EXCEPTIONS list. * - * Return: Success: SUCCEED + * Return: Success: SUCCEED * - * Failure: abort() + * Failure: abort() * *------------------------------------------------------------------------- */ @@ -796,6 +803,15 @@ done: "linked with a different version of static or shared HDF5 library.\n" \ "You should recompile the application or check your shared library related\n" \ "settings such as 'LD_LIBRARY_PATH'.\n" +#define RELEASE_MISMATCH_WARNING \ + "Warning! ***HDF5 library release mismatched error***\n" \ + "The HDF5 header files used to compile this application are not compatible with\n" \ + "the version used by the HDF5 library to which this application is linked.\n" \ + "Data corruption or segmentation faults may occur if the application continues.\n" \ + "This can happen when an application was compiled by one version of HDF5 but\n" \ + "linked with an incompatible version of static or shared HDF5 library.\n" \ + "You should recompile the application or check your shared library related\n" \ + "settings such as 'LD_LIBRARY_PATH'.\n" herr_t H5check_version(unsigned majnum, unsigned minnum, unsigned relnum) @@ -824,7 +840,8 @@ H5check_version(unsigned majnum, unsigned minnum, unsigned relnum) disable_version_check = (unsigned int)HDstrtol(s, NULL, 0); } - if (H5_VERS_MAJOR != majnum || H5_VERS_MINOR != minnum || H5_VERS_RELEASE != relnum) { + /* H5_VERS_MAJOR and H5_VERS_MINOR must match */ + if (H5_VERS_MAJOR != majnum || H5_VERS_MINOR != minnum || H5_VERS_RELEASE > relnum) { switch (disable_version_check) { case 0: HDfprintf(stderr, "%s%s", version_mismatch_warning, @@ -859,7 +876,51 @@ H5check_version(unsigned majnum, unsigned minnum, unsigned relnum) break; } /* end switch */ - } /* end if */ + } /* end if (H5_VERS_MAJOR != majnum || H5_VERS_MINOR != minnum || H5_VERS_RELEASE > relnum) */ + + /* H5_VERS_RELEASE should be compatible, we will only add checks for exceptions */ + if (H5_VERS_RELEASE != relnum) { + for (unsigned i = 0; i < VERS_RELEASE_EXCEPTIONS_SIZE; i++) { + /* Check for incompatible headers or incompatible library */ + if (VERS_RELEASE_EXCEPTIONS[i] == relnum || VERS_RELEASE_EXCEPTIONS[i] == H5_VERS_RELEASE) { + switch (disable_version_check) { + case 0: + HDfprintf( + stderr, "%s%s", version_mismatch_warning, + "You can, at your own risk, disable this warning by setting the environment\n" + "variable 'HDF5_DISABLE_VERSION_CHECK' to a value of '1'.\n" + "Setting it to 2 or higher will suppress the warning messages totally.\n"); + /* Mention the versions we are referring to */ + HDfprintf(stderr, "Headers are %u.%u.%u, library is %u.%u.%u\n", majnum, minnum, + relnum, (unsigned)H5_VERS_MAJOR, (unsigned)H5_VERS_MINOR, + (unsigned)H5_VERS_RELEASE); + + /* Bail out now. */ + HDfputs("Bye...\n", stderr); + HDabort(); + case 1: + /* continue with a warning */ + /* Note that the warning message is embedded in the format string.*/ + HDfprintf(stderr, + "%s'HDF5_DISABLE_VERSION_CHECK' " + "environment variable is set to %d, application will\n" + "continue at your own risk.\n", + version_mismatch_warning, disable_version_check); + /* Mention the versions we are referring to */ + HDfprintf(stderr, "Headers are %u.%u.%u, library is %u.%u.%u\n", majnum, minnum, + relnum, (unsigned)H5_VERS_MAJOR, (unsigned)H5_VERS_MINOR, + (unsigned)H5_VERS_RELEASE); + break; + default: + /* 2 or higher: continue silently */ + break; + } /* end switch */ + + } /* end if */ + + } /* end for */ + + } /* end if (H5_VERS_RELEASE != relnum) */ /* Indicate that the version check has been performed */ checked = 1; @@ -870,12 +931,9 @@ H5check_version(unsigned majnum, unsigned minnum, unsigned relnum) * Check only the first sizeof(lib_str) char. Assume the information * will fit within this size or enough significance. */ - HDsnprintf(lib_str, sizeof(lib_str), "HDF5 library version: %d.%d.%d", H5_VERS_MAJOR, H5_VERS_MINOR, - H5_VERS_RELEASE); - if (*substr) { - HDstrncat(lib_str, "-", (size_t)1); - HDstrncat(lib_str, substr, (sizeof(lib_str) - HDstrlen(lib_str)) - 1); - } /* end if */ + HDsnprintf(lib_str, sizeof(lib_str), "HDF5 library version: %d.%d.%d%s%s", H5_VERS_MAJOR, + H5_VERS_MINOR, H5_VERS_RELEASE, (*substr ? "-" : ""), substr); + if (HDstrcmp(lib_str, H5_lib_vers_info_g) != 0) { HDfputs("Warning! Library version information error.\n" "The HDF5 library version information are not " @@ -904,7 +962,7 @@ done: * is failing inexplicably, then try calling this function * first. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * *------------------------------------------------------------------------- */ @@ -923,11 +981,11 @@ done: } /* end H5open() */ /*------------------------------------------------------------------------- - * Function: H5close + * Function: H5close * - * Purpose: Terminate the library and release all resources. + * Purpose: Terminate the library and release all resources. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * *------------------------------------------------------------------------- */ @@ -948,9 +1006,9 @@ H5close(void) } /* end H5close() */ /*------------------------------------------------------------------------- - * Function: H5allocate_memory + * Function: H5allocate_memory * - * Purpose: Allocate a memory buffer with the semantics of malloc(). + * Purpose: Allocate a memory buffer with the semantics of malloc(). * * NOTE: This function is intended for use with filter * plugins so that all allocation and free operations @@ -988,9 +1046,9 @@ H5allocate_memory(size_t size, hbool_t clear) } /* end H5allocate_memory() */ /*------------------------------------------------------------------------- - * Function: H5resize_memory + * Function: H5resize_memory * - * Purpose: Resize a memory buffer with the semantics of realloc(). + * Purpose: Resize a memory buffer with the semantics of realloc(). * * NOTE: This function is intended for use with filter * plugins so that all allocation and free operations @@ -1025,14 +1083,14 @@ H5resize_memory(void *mem, size_t size) } /* end H5resize_memory() */ /*------------------------------------------------------------------------- - * Function: H5free_memory + * Function: H5free_memory * - * Purpose: Frees memory allocated by the library that it is the user's + * Purpose: Frees memory allocated by the library that it is the user's * responsibility to free. Ensures that the same library * that was used to allocate the memory frees it. Passing * NULL pointers is allowed. * - * Return: SUCCEED/FAIL + * Return: SUCCEED/FAIL * *------------------------------------------------------------------------- */ @@ -1049,12 +1107,12 @@ H5free_memory(void *mem) } /* end H5free_memory() */ /*------------------------------------------------------------------------- - * Function: H5is_library_threadsafe + * Function: H5is_library_threadsafe * - * Purpose: Checks to see if the library was built with thread-safety + * Purpose: Checks to see if the library was built with thread-safety * enabled. * - * Return: SUCCEED/FAIL + * Return: SUCCEED/FAIL * *------------------------------------------------------------------------- */ |