From d9742cfc30c888b2379880645a76638ad542c2a8 Mon Sep 17 00:00:00 2001 From: mattjala <124107509+mattjala@users.noreply.github.com> Date: Fri, 7 Jun 2024 11:04:40 -0500 Subject: [PATCH 01/45] Fix typos in context/property documentation (#4550) --- src/H5CX.c | 20 ++++++++++---------- src/H5Ppublic.h | 2 +- test/tgenprop.c | 8 ++++---- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/H5CX.c b/src/H5CX.c index bbd205ca0f6..f23c90486e3 100644 --- a/src/H5CX.c +++ b/src/H5CX.c @@ -289,18 +289,18 @@ typedef struct H5CX_t { (H5D_XFER_COLL_CHUNK_MULTI_RATIO_IND_NAME) */ bool mpio_coll_chunk_multi_ratio_ind_set; /* Whether instrumented "collective chunk multi ratio ind" value is set */ - bool mpio_coll_rank0_bcast; /* Instrumented "collective chunk multi ratio ind" value - (H5D_XFER_COLL_CHUNK_MULTI_RATIO_IND_NAME) */ - bool mpio_coll_rank0_bcast_set; /* Whether instrumented "collective chunk multi ratio ind" value is set */ -#endif /* H5_HAVE_INSTRUMENTED_LIBRARY */ -#endif /* H5_HAVE_PARALLEL */ - uint32_t no_selection_io_cause; /* Reason for not performing selection I/O - (H5D_XFER_NO_SELECTION_IO_CAUSE_NAME) */ - bool no_selection_io_cause_set; /* Whether reason for not performing selection I/O is set */ + bool mpio_coll_rank0_bcast; /* Instrumented "collective rank 0 broadcast" value + (H5D_XFER_COLL_RANK0_BCAST_NAME) */ + bool mpio_coll_rank0_bcast_set; /* Whether instrumented "collective rank 0 broadcast" value is set */ +#endif /* H5_HAVE_INSTRUMENTED_LIBRARY */ +#endif /* H5_HAVE_PARALLEL */ + uint32_t no_selection_io_cause; /* Reason for not performing selection I/O + (H5D_XFER_NO_SELECTION_IO_CAUSE_NAME) */ + bool no_selection_io_cause_set; /* Whether reason for not performing selection I/O is set */ bool no_selection_io_cause_valid; /* Whether reason for not performing selection I/O is valid */ - uint32_t - actual_selection_io_mode; /* Actual selection I/O mode used (H5D_ACTUAL_SELECTION_IO_MODE_NAME) */ + uint32_t actual_selection_io_mode; /* Actual selection I/O mode used + (H5D_XFER_ACTUAL_SELECTION_IO_MODE_NAME) */ bool actual_selection_io_mode_set; /* Whether actual selection I/O mode is set */ bool actual_selection_io_mode_valid; /* Whether actual selection I/O mode is valid */ diff --git a/src/H5Ppublic.h b/src/H5Ppublic.h index 0f05977cec3..2f7bc409fc0 100644 --- a/src/H5Ppublic.h +++ b/src/H5Ppublic.h @@ -287,7 +287,7 @@ typedef herr_t (*H5P_cls_copy_func_t)(hid_t new_prop_id, hid_t old_prop_id, void /** * \brief Callback function for H5Pcreate_class() * - * \param[in] prop_id The identifier of the property list class being created + * \param[in] prop_id The identifier of the property list class being closed * \param[in] close_data User pointer to any close data required * \return \herr_t * diff --git a/test/tgenprop.c b/test/tgenprop.c index 586ab335e7f..4f4f60e79ab 100644 --- a/test/tgenprop.c +++ b/test/tgenprop.c @@ -413,9 +413,9 @@ test_genprop_cls_cpy_cb1(hid_t new_list_id, hid_t H5_ATTR_UNUSED old_list_id, vo } static herr_t -test_genprop_cls_cls_cb1(hid_t list_id, void *create_data) +test_genprop_cls_cls_cb1(hid_t list_id, void *close_data) { - count_data_t *cdata = (count_data_t *)create_data; + count_data_t *cdata = (count_data_t *)close_data; cdata->count++; cdata->id = list_id; @@ -1006,9 +1006,9 @@ static prop_cb_info prop3_cb_info; /* Callback statistics for property #3 */ ** ****************************************************************/ static herr_t -test_genprop_cls_cpy_cb2(hid_t new_list_id, hid_t H5_ATTR_UNUSED old_list_id, void *create_data) +test_genprop_cls_cpy_cb2(hid_t new_list_id, hid_t H5_ATTR_UNUSED old_list_id, void *copy_data) { - count_data_t *cdata = (count_data_t *)create_data; + count_data_t *cdata = (count_data_t *)copy_data; cdata->count++; cdata->id = new_list_id; From 0aa4fe306dfb62f3aec6b281df3d0f87094ab4a8 Mon Sep 17 00:00:00 2001 From: Dana Robinson <43805+derobins@users.noreply.github.com> Date: Fri, 7 Jun 2024 13:08:50 -0700 Subject: [PATCH 02/45] Fix CI markdown link check http 500 errors (#4556) Sites like GitLab can have internal problems that return http 500 errors while they fix their problems. Some sites also return http 200 OK, which is fine. This PR adds a config file to the markdown link check so those are considered "passing" and don't break the CI. --- .github/workflows/markdown-link-check.yml | 4 ++++ .github/workflows/markdown_config.json | 3 +++ 2 files changed, 7 insertions(+) create mode 100644 .github/workflows/markdown_config.json diff --git a/.github/workflows/markdown-link-check.yml b/.github/workflows/markdown-link-check.yml index 70bb035deaa..f925017bf10 100644 --- a/.github/workflows/markdown-link-check.yml +++ b/.github/workflows/markdown-link-check.yml @@ -6,9 +6,13 @@ on: pull_request: branches: [ hdf5_1_14 ] +# The config file handles things like http 500 errors from sites like GitLab +# and http 200 responses jobs: markdown-link-check: runs-on: ubuntu-latest steps: - uses: actions/checkout@master - uses: gaurav-nelson/github-action-markdown-link-check@v1 + with: + config-file: '.github/workflows/markdown_config.json' diff --git a/.github/workflows/markdown_config.json b/.github/workflows/markdown_config.json new file mode 100644 index 00000000000..1ae40f89e5a --- /dev/null +++ b/.github/workflows/markdown_config.json @@ -0,0 +1,3 @@ +{ + "aliveStatusCodes": [200, 500] +} From 1a936e775562d5077d3e54d80556f517d190cf9c Mon Sep 17 00:00:00 2001 From: mattjala <124107509+mattjala@users.noreply.github.com> Date: Fri, 7 Jun 2024 18:59:49 -0500 Subject: [PATCH 03/45] Simplify property copying between lists internally (#4551) --- src/H5P.c | 4 ++-- src/H5Pint.c | 51 ++++++++++++++++++++++----------------------------- 2 files changed, 24 insertions(+), 31 deletions(-) diff --git a/src/H5P.c b/src/H5P.c index b69ffd6de33..a6514af265b 100644 --- a/src/H5P.c +++ b/src/H5P.c @@ -1331,8 +1331,8 @@ H5Premove(hid_t plist_id, const char *name) property information will be copied from the source class into the destination class. - If a property is copied from one list to another, the property will be - first deleted from the destination list (generating a call to the 'close' + If a property is copied from one list to another list that already contains the property, + the property will be first deleted from the destination list (generating a call to the 'del' callback for the property, if one exists) and then the property is copied from the source list to the destination list (generating a call to the 'copy' callback for the property, if one exists). diff --git a/src/H5Pint.c b/src/H5Pint.c index 8f9f5125847..032bfdce038 100644 --- a/src/H5Pint.c +++ b/src/H5Pint.c @@ -4862,15 +4862,16 @@ H5P_remove(H5P_genplist_t *plist, const char *name) DESCRIPTION Copies a property from one property list to another. - If a property is copied from one list to another, the property will be - first deleted from the destination list (generating a call to the 'close' + If the property exists in the destination list, the property will be + first deleted from the destination list (generating a call to the 'del' callback for the property, if one exists) and then the property is copied from the source list to the destination list (generating a call to the 'copy' callback for the property, if one exists). - If the property does not exist in the destination list, this call is - equivalent to calling H5Pinsert2 and the 'create' callback will be called - (if such a callback exists for the property). + If the property does not exist in the destination list, a new instance + of the property is created, the 'create' callback is called + (if such a callback exists for the property), and the new property is + inserted into the destination list. GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS @@ -4895,15 +4896,16 @@ H5P__copy_prop_plist(hid_t dst_id, hid_t src_id, const char *name) NULL == (dst_plist = (H5P_genplist_t *)H5I_object(dst_id))) HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "property object doesn't exist"); + /* Get the pointer to the source property */ + if (NULL == (prop = H5P__find_prop_plist(src_plist, name))) + HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "property doesn't exist"); + /* If the property exists in the destination already */ if (NULL != H5P__find_prop_plist(dst_plist, name)) { - /* Delete the property from the destination list, calling the 'close' callback if necessary */ + /* Delete the property from the destination list, calling the 'del' callback if necessary */ if (H5P_remove(dst_plist, name) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTDELETE, FAIL, "unable to remove property"); - /* Get the pointer to the source property */ - prop = H5P__find_prop_plist(src_plist, name); - /* Make a copy of the source property */ if ((new_prop = H5P__dup_prop(prop, H5P_PROP_WITHIN_LIST)) == NULL) HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "Can't copy property"); @@ -4913,21 +4915,12 @@ H5P__copy_prop_plist(hid_t dst_id, hid_t src_id, const char *name) if ((new_prop->copy)(new_prop->name, new_prop->size, new_prop->value) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "Can't copy property"); } /* end if */ - - /* Insert the initialized property into the property list */ - if (H5P__add_prop(dst_plist->props, new_prop) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "Can't insert property into list"); - - /* Increment the number of properties in list */ - dst_plist->nprops++; - } /* end if */ - /* If not, get the information required to do an H5Pinsert2 with the property into the destination list */ + } /* end if */ + /* If property doesn't exist in destination */ else { - /* Get the pointer to the source property */ - if (NULL == (prop = H5P__find_prop_plist(src_plist, name))) - HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "property doesn't exist"); - - /* Create property object from parameters */ + /* Create property object from parameters. This is very similar to the property + * duplication call above, but the property's name is treated differently depending on + * whether the source property is defined on a plist or a plist class */ if (NULL == (new_prop = H5P__create_prop(prop->name, prop->size, H5P_PROP_WITHIN_LIST, prop->value, prop->create, prop->set, prop->get, prop->encode, prop->decode, @@ -4939,14 +4932,14 @@ H5P__copy_prop_plist(hid_t dst_id, hid_t src_id, const char *name) if ((new_prop->create)(new_prop->name, new_prop->size, new_prop->value) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "Can't initialize property"); } /* end if */ + } /* end else */ - /* Insert property into property list class */ - if (H5P__add_prop(dst_plist->props, new_prop) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "Can't insert property into class"); + /* Insert the initialized property into the property list */ + if (H5P__add_prop(dst_plist->props, new_prop) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "Can't insert property into list"); - /* Increment property count for class */ - dst_plist->nprops++; - } /* end else */ + /* Increment the number of properties in list */ + dst_plist->nprops++; done: /* Cleanup, if necessary */ From 10e33753207cf49b7cd3cf4b4c2acfe89a18f1b5 Mon Sep 17 00:00:00 2001 From: bmribler <39579120+bmribler@users.noreply.github.com> Date: Fri, 7 Jun 2024 20:03:05 -0400 Subject: [PATCH 04/45] Add Python examples (#4546) These examples are referred to from the replacement page of https://portal.hdfgroup.org/display/HDF5/Other+Examples. --- HDF5Examples/PYTHON/h5_compound.py | 33 +++++++++++++ HDF5Examples/PYTHON/h5_crtdat.py | 22 +++++++++ HDF5Examples/PYTHON/h5_gzip.py | 37 ++++++++++++++ HDF5Examples/PYTHON/h5_hype.py | 54 ++++++++++++++++++++ HDF5Examples/PYTHON/h5_hypeb.py | 31 ++++++++++++ HDF5Examples/PYTHON/h5_links.py | 71 +++++++++++++++++++++++++++ HDF5Examples/PYTHON/h5_objref.py | 37 ++++++++++++++ HDF5Examples/PYTHON/h5_readtofloat.py | 31 ++++++++++++ HDF5Examples/PYTHON/h5_regref.py | 52 ++++++++++++++++++++ HDF5Examples/PYTHON/h5_selecelem.py | 44 +++++++++++++++++ HDF5Examples/PYTHON/h5_string.py | 29 +++++++++++ HDF5Examples/PYTHON/h5_unlim.py | 46 +++++++++++++++++ HDF5Examples/PYTHON/h5_visit.py | 9 ++++ HDF5Examples/PYTHON/h5_visita.py | 9 ++++ HDF5Examples/PYTHON/h5_vlstring.py | 28 +++++++++++ doxygen/aliases | 2 +- 16 files changed, 534 insertions(+), 1 deletion(-) create mode 100644 HDF5Examples/PYTHON/h5_compound.py create mode 100644 HDF5Examples/PYTHON/h5_crtdat.py create mode 100644 HDF5Examples/PYTHON/h5_gzip.py create mode 100644 HDF5Examples/PYTHON/h5_hype.py create mode 100644 HDF5Examples/PYTHON/h5_hypeb.py create mode 100644 HDF5Examples/PYTHON/h5_links.py create mode 100644 HDF5Examples/PYTHON/h5_objref.py create mode 100644 HDF5Examples/PYTHON/h5_readtofloat.py create mode 100644 HDF5Examples/PYTHON/h5_regref.py create mode 100644 HDF5Examples/PYTHON/h5_selecelem.py create mode 100644 HDF5Examples/PYTHON/h5_string.py create mode 100644 HDF5Examples/PYTHON/h5_unlim.py create mode 100644 HDF5Examples/PYTHON/h5_visit.py create mode 100644 HDF5Examples/PYTHON/h5_visita.py create mode 100644 HDF5Examples/PYTHON/h5_vlstring.py diff --git a/HDF5Examples/PYTHON/h5_compound.py b/HDF5Examples/PYTHON/h5_compound.py new file mode 100644 index 00000000000..9dca016b287 --- /dev/null +++ b/HDF5Examples/PYTHON/h5_compound.py @@ -0,0 +1,33 @@ +# +# This example creates an HDF5 file compound.h5 and an empty datasets /DSC in it. +# +import h5py +import numpy as np +# +# Create a new file using default properties. +# +file = h5py.File('compound.h5','w') +# +# Create a dataset under the Root group. +# +comp_type = np.dtype([('Orbit', 'i'), ('Location', np.str_, 6), ('Temperature (F)', 'f8'), ('Pressure (inHg)', 'f8')]) +dataset = file.create_dataset("DSC",(4,), comp_type) +data = np.array([(1153, "Sun ", 53.23, 24.57), (1184, "Moon ", 55.12, 22.95), (1027, "Venus ", 103.55, 31.23), (1313, "Mars ", 1252.89, 84.11)], dtype = comp_type) +dataset[...] = data +# +# Close the file before exiting +# +file.close() +file = h5py.File('compound.h5', 'r') +dataset = file["DSC"] +print("Reading Orbit and Location fields...") +orbit = dataset['Orbit'] +print("Orbit: ", orbit) +location = dataset['Location'] +print("Location: ", location) +data = dataset[...] +print("Reading all records:") +print(data) +print("Second element of the third record:", dataset[2, 'Location']) +file.close() + diff --git a/HDF5Examples/PYTHON/h5_crtdat.py b/HDF5Examples/PYTHON/h5_crtdat.py new file mode 100644 index 00000000000..65705087fde --- /dev/null +++ b/HDF5Examples/PYTHON/h5_crtdat.py @@ -0,0 +1,22 @@ +# +# This examaple creates an HDF5 file dset.h5 and an empty datasets /dset in it. +# +import h5py +# +# Create a new file using default properties. +# +file = h5py.File('dset.h5','w') +# +# Create a dataset under the Root group. +# +dataset = file.create_dataset("dset",(4, 6), h5py.h5t.STD_I32BE) +print("Dataset dataspace is", dataset.shape) +print("Dataset Numpy datatype is", dataset.dtype) +print("Dataset name is", dataset.name) +print("Dataset is a member of the group", dataset.parent) +print("Dataset was created in the file", dataset.file) +# +# Close the file before exiting +# +file.close() + diff --git a/HDF5Examples/PYTHON/h5_gzip.py b/HDF5Examples/PYTHON/h5_gzip.py new file mode 100644 index 00000000000..1b4a0b5f08d --- /dev/null +++ b/HDF5Examples/PYTHON/h5_gzip.py @@ -0,0 +1,37 @@ +# +# This example creates and writes GZIP compressed dataset. +# +import h5py +import numpy as np +# +# Create gzip.h5 file. +# +file = h5py.File('gzip.h5','w') +# +# Create /DS1 dataset; in order to use compression, dataset has to be chunked. +# +dataset = file.create_dataset('DS1',(32,64),'i',chunks=(4,8),compression='gzip',compression_opts=9) +# +# Initialize data. +# +data = np.zeros((32,64)) +for i in range(32): + for j in range(64): + data[i][j]= i*j-j +# +# Write data. +# +print("Writing data...") +dataset[...] = data +file.close() +# +# Read data back; display compression properties and dataset max value. +# +file = h5py.File('gzip.h5','r') +dataset = file['DS1'] +print("Compression method is", dataset.compression) +print("Compression parameter is", dataset.compression_opts) +data = dataset[...] +print("Maximum value in", dataset.name, "is:", max(data.ravel())) +file.close() + diff --git a/HDF5Examples/PYTHON/h5_hype.py b/HDF5Examples/PYTHON/h5_hype.py new file mode 100644 index 00000000000..093162c7369 --- /dev/null +++ b/HDF5Examples/PYTHON/h5_hype.py @@ -0,0 +1,54 @@ +# +# This example shows how to write a hyperslab to an existing dataset. +# +import h5py +import numpy as np +# +# Create a file using default properties. +# +file = h5py.File('hype.h5','w') +# +# Create "IntArray" dataset. +# +dim0 = 8 +dim1 = 10 +dataset = file.create_dataset("IntArray", (dim0,dim1), "i") +# +# Initialize data object with 0. +# +data = np.zeros((dim0, dim1)) +# +# Initialize data for writing. +# +for i in range(dim0): + for j in range(dim1): + if j < dim1/2: + data[i][j]= 1 + else: + data[i][j] = 2 +# +# Write data +# +dataset[...] = data +print("Data written to file:") +print(dataset[...]) +# +# Close the file before exiting +# +file.close() +# +# Open the file and dataset. +# +file = h5py.File('hype.h5','r+') +dataset = file['IntArray'] +# +# Write a selection. +# +dataset[1:4, 2:6] = 5 +print("Data after selection is written:") +print(dataset[...]) +# +# Close the file before exiting +# +file.close() + diff --git a/HDF5Examples/PYTHON/h5_hypeb.py b/HDF5Examples/PYTHON/h5_hypeb.py new file mode 100644 index 00000000000..6bc226a4c61 --- /dev/null +++ b/HDF5Examples/PYTHON/h5_hypeb.py @@ -0,0 +1,31 @@ +# +# This example shows how to read a hyperslab from an existing dataset. +# +import h5py +import numpy as np +# +# Open file and read dataset. +# +file = h5py.File('hype.h5', 'r') +dataset = file['IntArray'] +data_in_file = dataset[...] +print("Data in file ...") +print(data_in_file[...]) +# +# Initialize data with 0s. +# +data_selected = np.zeros((8,10), dtype=np.int32) +# +# Read selection. +# +space_id = dataset.id.get_space() +space_id.select_hyperslab((1,1), (2,2), stride=(4,4), block=(2,2)) +#---> Doesn't work dataset.id.read(space_id, space_id, data_selected, h5py.h5t.STD_I32LE) +dataset.id.read(space_id, space_id, data_selected) +print("Selected data read from file....") +print(data_selected[...]) +# +# Close the file before exiting +# +file.close() + diff --git a/HDF5Examples/PYTHON/h5_links.py b/HDF5Examples/PYTHON/h5_links.py new file mode 100644 index 00000000000..54a6702ba4e --- /dev/null +++ b/HDF5Examples/PYTHON/h5_links.py @@ -0,0 +1,71 @@ +# +# This example demonstrates the concepts of hard, soft and external links. +# +# We will create file links.h5 with the following members and then will try to access objects +# using hard, soft and external links. +# / Group +# /A Group +# /A/a Dataset {10} +# /B Group +# /B/External External Link {dset.h5//dset} +# /a Dataset, same as /A/a +# /dangling Soft Link {/B/XXX} +# /soft Soft Link {/A/a} + +import h5py +import numpy as np +file = h5py.File('links.h5', 'w') +# +# Create a group structure in the file +# +A = file.create_group("A") +B = file.create_group("B") +a = A.create_dataset("a", (10,), 'i') +# +# Create a hard link in a root group pointing to dataset /A/a +# +file["a"] = a +# +# Create a soft link (alias) in a root group with a value /A/a +# +file["soft"] = h5py.SoftLink('/A/a') +# +# Create a soft link (alias) in a root group with a value /B/XXX that cannot be resolved +# +file["dangling"] = h5py.SoftLink('/B/XXX') +# +# Create an external link to a dataset "dset" in file dset.h5 +# +B['External'] = h5py.ExternalLink("dset.h5", "/dset") +# +# List objects in the root group in the file +# +print("Root group members in links.h5:") +try: + print("Trying to get the items...") + print(list(file.items())) +except: + print("...but can only get the keys...") + print(list(file.keys())) + print(" ") + print("Why? Because the library cannot resolve the dangling link.") + print("We will delete the 'dangling' link and try again.") + del file["dangling"] +print(list(file.items())) +print(" ") +print("Group A members:") +print(list(A.items())) +print(" ") +print("Group B members:") +print(list(B.items())) +print(" ") +print("Reading dataset pointed by the external link...") +dset = B['External'] +data = np.zeros((4,6)) +data = dset[...] +print(data) +# +# Copy link to /A/a to /B/b +# +B["b"]=A["a"] +file.close() diff --git a/HDF5Examples/PYTHON/h5_objref.py b/HDF5Examples/PYTHON/h5_objref.py new file mode 100644 index 00000000000..f8fb8d5a031 --- /dev/null +++ b/HDF5Examples/PYTHON/h5_objref.py @@ -0,0 +1,37 @@ +# +# This example shows how to create dataset with object references +# +import h5py +import numpy as np +# +# Create a new file using default properties. +# +file = h5py.File('objref.h5','w') +# +# Create a group and scalar datasets under the Root group. +# +group = file.create_group("G1") +dataset = file.create_dataset("DS2",(), 'i') +# +# Create references to the group and the dataset and store them in another dataset. +# +refs = (group.ref, dataset.ref) +ref_type = h5py.h5t.special_dtype(ref=h5py.Reference) +dataset_ref = file.create_dataset("DS1", (2,),ref_type) +dataset_ref[...] = refs + +# +# Close the file before exiting +# +file.close() + +file = h5py.File('objref.h5','r') +dataset_ref = file["DS1"] +refs = dataset_ref[...] +refs_list = list(refs) +for obj in refs_list: + index = refs_list.index(obj) + print("DS["+str(index)+"]:") + print(file[obj]) +file.close() + diff --git a/HDF5Examples/PYTHON/h5_readtofloat.py b/HDF5Examples/PYTHON/h5_readtofloat.py new file mode 100644 index 00000000000..f7fdf44920c --- /dev/null +++ b/HDF5Examples/PYTHON/h5_readtofloat.py @@ -0,0 +1,31 @@ +# +# This example reads integer data from dset.h5 file into Python floatng buffers. +# +import h5py +import numpy as np +# +# Open an existing file using default properties. +# +file = h5py.File('dset.h5','r+') +# +# Open "dset" dataset under the root group. +# +dataset = file['/dset'] +# +# Initialize buffers,read and print data. +# +# Python float type is 64-bit, one needs to use NATIVE_DOUBLE HDF5 type to read data. +data_read64 = np.zeros((4,6,), dtype=float) +dataset.id.read(h5py.h5s.ALL, h5py.h5s.ALL, data_read64, mtype=h5py.h5t.NATIVE_DOUBLE) +print("Printing data 64-bit floating numbers...") +print(data_read64) + +data_read32 = np.zeros((4,6,), dtype=np.float32) +dataset.id.read(h5py.h5s.ALL, h5py.h5s.ALL, data_read32, mtype=h5py.h5t.NATIVE_FLOAT) +print("Printing data 32-bit floating numbers...") +print(data_read32) +# +# Close the file before exiting +# +file.close() + diff --git a/HDF5Examples/PYTHON/h5_regref.py b/HDF5Examples/PYTHON/h5_regref.py new file mode 100644 index 00000000000..587e446a87d --- /dev/null +++ b/HDF5Examples/PYTHON/h5_regref.py @@ -0,0 +1,52 @@ +# +# This example shows how to create a dataset with region references. +# +import h5py +import numpy as np +# +# Create a new file using default properties. +# +file = h5py.File('regref.h5','w') +# +# Create a group and (3x2) dataset under the Root group. +# +dataset = file.create_dataset("DS2",(3,2), h5py.h5t.STD_I8LE) +dataset[...] = np.array([[1,1], [2,2], [3,3]]) +# +# Create references to each row in the dataset. +# +refs = (dataset.regionref[0,:],dataset.regionref[1,:],dataset.regionref[2,:]) +# +# Create a dataset to store region references. +# +ref_type = h5py.h5t.special_dtype(ref=h5py.RegionReference) +dataset_ref = file.create_dataset("DS1", (3,),ref_type) +dataset_ref[...] = refs +# +# Close the file before exiting. +# +file.close() +# +# Open the file, read the second element of the dataset with the region references +# and dereference it to get data. +# +file = h5py.File('regref.h5', 'r') +dataset = file["DS1"] +regref = dataset[1] +# +# Region reference can be used to find a dataset it points to. +# +dataset_name = file[regref].name +print(dataset_name) +# +# Get hyperslab the reference points to. +# +data = file[dataset_name] +# +# Region reference can be used as a slicing argument! +print(data[regref]) +file.close() + + + + diff --git a/HDF5Examples/PYTHON/h5_selecelem.py b/HDF5Examples/PYTHON/h5_selecelem.py new file mode 100644 index 00000000000..d02426c07db --- /dev/null +++ b/HDF5Examples/PYTHON/h5_selecelem.py @@ -0,0 +1,44 @@ +# +# This example demonstrates how to do point selection in Python. +# +import h5py +import numpy as np +file1 = h5py.File('copy1.h5','w') +file2 = h5py.File('copy2.h5','w') +dataset1 = file1.create_dataset('Copy1', (3,4), 'i') +dataset2 = file2.create_dataset('Copy2', (3,4), 'i') +# +# Initialize data object with 0. +# +data1 = np.zeros((3,4)) +data2 = np.ones((3,4)) +val = (55,59) +# +# Write data +# +dataset1[...] = data1 +dataset2[...] = data2 +# +# Modify two elements with the new values. We can choose any number of elements along one dimension. +# +dataset1[0, [1,3]] = val +dataset2[0, [1,3]] = val +file1.close() +file2.close() +# +# Reopen the files and read data back +# +file1 = h5py.File('copy1.h5', 'r') +dataset1 = file1['Copy1'] +data1 = dataset1[...] +print "Dataset Copy1 in copy1.h5:" +print data1 + +file2 = h5py.File('copy2.h5', 'r') +dataset2 = file2['Copy2'] +data2 = dataset2[...] +print "Dataset Copy2 in copy2.h5:" +print data2 + +file1.close() +file2.close() diff --git a/HDF5Examples/PYTHON/h5_string.py b/HDF5Examples/PYTHON/h5_string.py new file mode 100644 index 00000000000..08c34e3a554 --- /dev/null +++ b/HDF5Examples/PYTHON/h5_string.py @@ -0,0 +1,29 @@ +# +# This example creates an HDF5 file string.h5 and DSfixed dataset in it. +# Then it opens the file and reads data back. +# +import h5py +import numpy as np +# +# Create a new file using default properties. +# +file = h5py.File('string.h5','w') +# +# Create a dataset under the Root group using variable-length string type. +# + +fixed_string = np.dtype('a10') +dataset = file.create_dataset("DSfixed",(4,), dtype=fixed_string) +data = ("Parting ", ".is such ", ".sweet ", ".sorrow...") +dataset[...] = data +# +# Close the file before exiting +# +file.close() +file = h5py.File('string.h5', 'r') +dataset = file['DSfixed'] +data_out = dataset[...] +for i in range(4): + print("DSfixed[i] = ",data_out[i]) + +file.close() diff --git a/HDF5Examples/PYTHON/h5_unlim.py b/HDF5Examples/PYTHON/h5_unlim.py new file mode 100644 index 00000000000..83b15735d7f --- /dev/null +++ b/HDF5Examples/PYTHON/h5_unlim.py @@ -0,0 +1,46 @@ +# +# This example creates a dataset and then extends it by rows and then by columns. +# +import h5py +import numpy as np +# +# Create unlim.h5 file. +# +file = h5py.File('unlim.h5','w') +# +# Create /DS1 dataset; in order to use compression, dataset has to be chunked. +# +dataset = file.create_dataset('DS1',(4,7),'i',chunks=(3,3), maxshape=(None, None)) +# +# Initialize data. +# +data = np.zeros((4,7)) +# +# Write data. +# +print("Writing data...") +dataset[...] = data +file.close() +# +# Read data back; display compression properties and dataset max value. +# +file = h5py.File('unlim.h5','r+') +dataset = file['DS1'] +data = dataset[...] +print("Data before extension: ") +print(data) +# +# Add two rows filled with 1 +# +dataset.resize((6,7)) +dataset[4:6] = 1 +# +# Add three columns filled with 2 +# +dataset.resize((6,10)) +dataset[:,7:10] = 2 +data = dataset[...] +print("Data after extension: ") +print(data) +file.close() + diff --git a/HDF5Examples/PYTHON/h5_visit.py b/HDF5Examples/PYTHON/h5_visit.py new file mode 100644 index 00000000000..40e20cf2074 --- /dev/null +++ b/HDF5Examples/PYTHON/h5_visit.py @@ -0,0 +1,9 @@ +import h5py +f = h5py.File('GATMO-SATMS-npp.h5', 'r+') +list(f.keys()) +list(f.values()) +members = [] +f.visit(members.append) +for i in range(len(members)): + print(members[i]) + diff --git a/HDF5Examples/PYTHON/h5_visita.py b/HDF5Examples/PYTHON/h5_visita.py new file mode 100644 index 00000000000..a21b4d94728 --- /dev/null +++ b/HDF5Examples/PYTHON/h5_visita.py @@ -0,0 +1,9 @@ +import h5py +def print_info(name, obj): + print(name) + for name, value in obj.attrs.items(): + print(name+":", value) + +f = h5py.File('GATMO-SATMS-npp.h5', 'r+') +f.visititems(print_info) +f.close() diff --git a/HDF5Examples/PYTHON/h5_vlstring.py b/HDF5Examples/PYTHON/h5_vlstring.py new file mode 100644 index 00000000000..ccb7c44ed8d --- /dev/null +++ b/HDF5Examples/PYTHON/h5_vlstring.py @@ -0,0 +1,28 @@ +# +# This example creates an HDF5 file vlstring.h5 and DSvariable dataset in it. +# Then it opens the file and reads data back. +# +import h5py +# +# Create a new file using default properties. +# +file = h5py.File('vlstring.h5','w') +# +# Create a dataset under the Root group using variable-length string type. +# +str_type = h5py.new_vlen(str) +dataset = file.create_dataset("DSvariable",(4,), dtype=str_type) +data = ("Parting", " is such", " sweet", " sorrow...") +dataset[...] = data +# +# Close the file before exiting +# +file.close() +file = h5py.File('vlstring.h5', 'r') +dataset = file['DSvariable'] +data_out = dataset[...] +for i in range(4): + print("DSvariable[",i,"]", "'"+data_out[i]+"'", "has length", len(data_out[i])) + +print(data_out) +file.close() diff --git a/doxygen/aliases b/doxygen/aliases index dd62cb44195..a65fe36cf52 100644 --- a/doxygen/aliases +++ b/doxygen/aliases @@ -252,7 +252,7 @@ ALIASES += sa_metadata_ops="\sa \li H5Pget_all_coll_metadata_ops() \li H5Pget_co ALIASES += ref_cons_semantics="Enabling a Strict Consistency Semantics Model in Parallel HDF5" ALIASES += ref_file_image_ops="HDF5 File Image Operations" ALIASES += ref_filter_pipe="Data Flow Pipeline for H5Dread()" -ALIASES += ref_group_impls="Group implementations in HDF5" +ALIASES += ref_group_impls="Group implementations in HDF5" ALIASES += ref_h5lib_relver="HDF5 Library Release Version Numbers" ALIASES += ref_mdc_in_hdf5="Metadata Caching in HDF5" ALIASES += ref_mdc_logging="Metadata Cache Logging" From 541c72405adb49013afd44cd7a09066c28d2a59d Mon Sep 17 00:00:00 2001 From: mattjala <124107509+mattjala@users.noreply.github.com> Date: Fri, 7 Jun 2024 19:09:32 -0500 Subject: [PATCH 05/45] Correct property cb signatures in docs (#4554) * Correct property cb signatures in docs * Correct delete callback type name in docs * add missing word to H5P__free_prop doc --- src/H5P.c | 8 ++++---- src/H5Pdeprec.c | 8 ++++---- src/H5Pint.c | 49 +++++++++++++++++++++---------------------------- src/H5Ppublic.h | 2 +- 4 files changed, 30 insertions(+), 37 deletions(-) diff --git a/src/H5P.c b/src/H5P.c index a6514af265b..b2d27bba997 100644 --- a/src/H5P.c +++ b/src/H5P.c @@ -323,8 +323,8 @@ H5Pcreate(hid_t cls_id) routine returns an error value. The 'delete' callback is called when a property is deleted from a - property list. H5P_prp_del_func_t is defined as: - typedef herr_t (*H5P_prp_del_func_t)(hid_t prop_id, const char *name, + property list. H5P_prp_delete_func_t is defined as: + typedef herr_t (*H5P_prp_delete_func_t)(hid_t prop_id, const char *name, size_t size, void *value); where the parameters to the callback function are: hid_t prop_id; IN: The ID of the property list the property is deleted from. @@ -502,8 +502,8 @@ H5Pregister2(hid_t cls_id, const char *name, size_t size, void *def_value, H5P_p routine returns an error value. The 'delete' callback is called when a property is deleted from a - property list. H5P_prp_del_func_t is defined as: - typedef herr_t (*H5P_prp_del_func_t)(hid_t prop_id, const char *name, + property list. H5P_prp_delete_func_t is defined as: + typedef herr_t (*H5P_prp_delete_func_t)(hid_t prop_id, const char *name, size_t size, void *value); where the parameters to the callback function are: hid_t prop_id; IN: The ID of the property list the property is deleted from. diff --git a/src/H5Pdeprec.c b/src/H5Pdeprec.c index 2888ad6012c..3332a35a9b9 100644 --- a/src/H5Pdeprec.c +++ b/src/H5Pdeprec.c @@ -149,8 +149,8 @@ routine returns an error value. The 'delete' callback is called when a property is deleted from a - property list. H5P_prp_del_func_t is defined as: - typedef herr_t (*H5P_prp_del_func_t)(hid_t prop_id, const char *name, + property list. H5P_prp_delete_func_t is defined as: + typedef herr_t (*H5P_prp_delete_func_t)(hid_t prop_id, const char *name, size_t size, void *value); where the parameters to the callback function are: hid_t prop_id; IN: The ID of the property list the property is deleted from. @@ -314,8 +314,8 @@ H5Pregister1(hid_t cls_id, const char *name, size_t size, void *def_value, H5P_p routine returns an error value. The 'delete' callback is called when a property is deleted from a - property list. H5P_prp_del_func_t is defined as: - typedef herr_t (*H5P_prp_del_func_t)(hid_t prop_id, const char *name, + property list. H5P_prp_delete_func_t is defined as: + typedef herr_t (*H5P_prp_delete_func_t)(hid_t prop_id, const char *name, size_t size, void *value); where the parameters to the callback function are: hid_t prop_id; IN: The ID of the property list the property is deleted from. diff --git a/src/H5Pint.c b/src/H5Pint.c index 032bfdce038..f8c79bf022f 100644 --- a/src/H5Pint.c +++ b/src/H5Pint.c @@ -1475,7 +1475,7 @@ H5P__free_prop(H5P_genprop_t *prop) NAME H5P__free_prop_cb PURPOSE - Internal routine to properties from a property skip list + Internal routine to free properties from a property skip list USAGE herr_t H5P__free_prop_cb(item, key, op_data) void *item; IN/OUT: Pointer to property @@ -2048,13 +2048,11 @@ H5P_create_id(H5P_genclass_t *pclass, bool app_ref) The 'create' callback is called when a new property list with this property is being created. H5P_prp_create_func_t is defined as: - typedef herr_t (*H5P_prp_create_func_t)(hid_t prop_id, const char *name, - size_t size, void *initial_value); + typedef herr_t (*H5P_prp_create_func_t)(const char *name, size_t size, void *value); where the parameters to the callback function are: - hid_t prop_id; IN: The ID of the property list being created. const char *name; IN: The name of the property being modified. size_t size; IN: The size of the property value - void *initial_value; IN/OUT: The initial value for the property being created. + void *value; IN/OUT: The initial value for the property being created. (The 'default' value passed to H5Pregister2) The 'create' routine may modify the value to be set and those changes will be stored as the initial value of the property. If the 'create' routine @@ -2069,7 +2067,7 @@ H5P_create_id(H5P_genclass_t *pclass, bool app_ref) hid_t prop_id; IN: The ID of the property list being modified. const char *name; IN: The name of the property being modified. size_t size; IN: The size of the property value - void *new_value; IN/OUT: The value being set for the property. + void *value; IN/OUT: The value being set for the property. The 'set' routine may modify the value to be set and those changes will be stored as the value of the property. If the 'set' routine returns a negative value, the new property value is not copied into the property and @@ -2090,8 +2088,8 @@ H5P_create_id(H5P_genclass_t *pclass, bool app_ref) routine returns an error value. The 'delete' callback is called when a property is deleted from a - property list. H5P_prp_del_func_t is defined as: - typedef herr_t (*H5P_prp_del_func_t)(hid_t prop_id, const char *name, + property list. H5P_prp_delete_func_t is defined as: + typedef herr_t (*H5P_prp_delete_func_t)(hid_t prop_id, const char *name, size_t size, void *value); where the parameters to the callback function are: hid_t prop_id; IN: The ID of the property list the property is deleted from. @@ -2119,7 +2117,7 @@ H5P_create_id(H5P_genclass_t *pclass, bool app_ref) The 'compare' callback is called when a property list with this property is compared to another property list. H5P_prp_compare_func_t is defined as: - typedef int (*H5P_prp_compare_func_t)( void *value1, void *value2, + typedef int (*H5P_prp_compare_func_t)(const void *value1, const void *value2, size_t size); where the parameters to the callback function are: const void *value1; IN: The value of the first property being compared. @@ -2145,30 +2143,25 @@ H5P_create_id(H5P_genclass_t *pclass, bool app_ref) The 'encode' callback is called when a property list with this property is being encoded. H5P_prp_encode_func_t is defined as: - typedef herr_t (*H5P_prp_encode_func_t)(void *f, size_t *size, - void *value, void *plist, uint8_t **buf); + typedef herr_t (*H5P_prp_encode_func_t)(const void *value, void **buf, size_t *size); where the parameters to the callback function are: - void *f; IN: A fake file structure used to encode. - size_t *size; IN/OUT: The size of the buffer to encode the property. void *value; IN: The value of the property being encoded. - void *plist; IN: The property list structure. - uint8_t **buf; OUT: The buffer that holds the encoded property; + void **buf; OUT: Pointer to encoding buffer pointer. + size_t *size; IN/OUT: The size of the buffer needed to encode the property. The 'encode' routine returns the size needed to encode the property value if the buffer passed in is NULL or the size is zero. Otherwise it encodes - the property value into binary in buf. + the property value as binary in *buf. The 'decode' callback is called when a property list with this property is being decoded. H5P_prp_encode_func_t is defined as: - typedef herr_t (*H5P_prp_encode_func_t)(void *f, size_t *size, - void *value, void *plist, uint8_t **buf); + typedef herr_t (*H5P_prp_encode_func_t)(const void **buf, void *value); where the parameters to the callback function are: - void *f; IN: A fake file structure used to decode. - size_t *size; IN: H5_ATTR_UNUSED - void *value; IN: H5_ATTR_UNUSED - void *plist; IN: The property list structure. - uint8_t **buf; IN: The buffer that holds the binary encoded property; + void **buf; IN: Pointer to encoded buffer pointer. + void *value; OUT: The buffer the property value is decoded into. The 'decode' routine decodes the binary buffer passed in and transforms it into corresponding property values that are set in the property list passed in. + After the value is decoded, (*buf) must be incremented + by the size of the encoded value. GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS @@ -2346,8 +2339,8 @@ H5P__register_real(H5P_genclass_t *pclass, const char *name, size_t size, const corresponding property values that are set in the property list passed in. The 'delete' callback is called when a property is deleted from a - property list. H5P_prp_del_func_t is defined as: - typedef herr_t (*H5P_prp_del_func_t)(hid_t prop_id, const char *name, + property list. H5P_prp_delete_func_t is defined as: + typedef herr_t (*H5P_prp_delete_func_t)(hid_t prop_id, const char *name, size_t size, void *value); where the parameters to the callback function are: hid_t prop_id; IN: The ID of the property list the property is deleted from. @@ -2584,8 +2577,8 @@ H5P__register(H5P_genclass_t **ppclass, const char *name, size_t size, const voi corresponding property values that are set in the property list passed in. The 'delete' callback is called when a property is deleted from a - property list. H5P_prp_del_func_t is defined as: - typedef herr_t (*H5P_prp_del_func_t)(hid_t prop_id, const char *name, + property list. H5P_prp_delete_func_t is defined as: + typedef herr_t (*H5P_prp_delete_func_t)(hid_t prop_id, const char *name, size_t size, void *value); where the parameters to the callback function are: hid_t prop_id; IN: The ID of the property list the property is deleted from. @@ -2613,7 +2606,7 @@ H5P__register(H5P_genclass_t **ppclass, const char *name, size_t size, const voi The 'compare' callback is called when a property list with this property is compared to another property list. H5P_prp_compare_func_t is defined as: - typedef int (*H5P_prp_compare_func_t)( void *value1, void *value2, + typedef int (*H5P_prp_compare_func_t)(void *value1, void *value2, size_t size); where the parameters to the callback function are: const void *value1; IN: The value of the first property being compared. diff --git a/src/H5Ppublic.h b/src/H5Ppublic.h index 2f7bc409fc0..e3977225ef6 100644 --- a/src/H5Ppublic.h +++ b/src/H5Ppublic.h @@ -352,7 +352,7 @@ typedef H5P_prp_cb2_t H5P_prp_get_func_t; * \brief Callback function for encoding property values * * \param[in] value The property value to be encoded - * \param[out] buf The encoded property value + * \param[out] buf Pointer to encoding buffer pointer * \param[out] size The size of \p buf * \return \herr_t * From 00cdb1a550c491e74cd12b5cc2764d7e47a998eb Mon Sep 17 00:00:00 2001 From: Allen Byrne <50328838+byrnHDF@users.noreply.github.com> Date: Sat, 8 Jun 2024 06:46:09 -0500 Subject: [PATCH 06/45] Move C++ and Fortran and examples to HDF5Examples folder (#4552) --- HDF5Examples/C/CMakeLists.txt | 3 +- HDF5Examples/C/H5D/CMakeLists.txt | 2 +- HDF5Examples/C/H5FLT/CMakeLists.txt | 2 +- HDF5Examples/C/H5G/CMakeLists.txt | 2 +- HDF5Examples/C/H5PAR/CMakeLists.txt | 2 +- HDF5Examples/C/H5T/CMakeLists.txt | 2 +- HDF5Examples/C/H5VDS/CMakeLists.txt | 2 +- HDF5Examples/C/Perf/CMakeLists.txt | 2 +- .../C/TUTR}/Attributes.txt | 0 HDF5Examples/C/TUTR/CMakeLists.txt | 113 +++++++ .../C/TUTR}/CMakeTests.cmake | 0 HDF5Examples/C/TUTR/C_sourcefiles.cmake | 32 ++ {examples => HDF5Examples/C/TUTR}/Makefile.am | 0 {examples => HDF5Examples/C/TUTR}/README | 0 .../C/TUTR}/h5_attribute.c | 0 .../C/TUTR}/h5_chunk_read.c | 0 {examples => HDF5Examples/C/TUTR}/h5_cmprss.c | 0 .../C/TUTR}/h5_compound.c | 0 {examples => HDF5Examples/C/TUTR}/h5_crtatt.c | 0 {examples => HDF5Examples/C/TUTR}/h5_crtdat.c | 0 {examples => HDF5Examples/C/TUTR}/h5_crtgrp.c | 0 .../C/TUTR}/h5_crtgrpar.c | 0 .../C/TUTR}/h5_crtgrpd.c | 0 .../C/TUTR}/h5_debug_trace.c | 0 .../C/TUTR}/h5_drivers.c | 0 .../C/TUTR}/h5_dtransform.c | 0 .../C/TUTR}/h5_elink_unix2win.c | 0 {examples => HDF5Examples/C/TUTR}/h5_extend.c | 0 .../C/TUTR}/h5_extend_write.c | 0 .../C/TUTR}/h5_extlink.c | 0 {examples => HDF5Examples/C/TUTR}/h5_group.c | 0 .../C/TUTR}/h5_interm_group.c | 0 {examples => HDF5Examples/C/TUTR}/h5_mount.c | 0 {examples => HDF5Examples/C/TUTR}/h5_rdwt.c | 0 {examples => HDF5Examples/C/TUTR}/h5_read.c | 0 .../C/TUTR}/h5_ref2reg_deprec.c | 0 .../C/TUTR}/h5_ref_compat.c | 0 .../C/TUTR}/h5_ref_extern.c | 0 .../C/TUTR}/h5_reference_deprec.c | 0 {examples => HDF5Examples/C/TUTR}/h5_select.c | 0 .../C/TUTR}/h5_shared_mesg.c | 0 {examples => HDF5Examples/C/TUTR}/h5_subset.c | 0 {examples => HDF5Examples/C/TUTR}/h5_write.c | 0 .../C/TUTR}/run-all-ex.sh | 0 .../C/TUTR}/run-c-ex.sh.in | 0 .../C/TUTR}/testh5cc.sh.in | 0 HDF5Examples/CMakeLists.txt | 22 +- HDF5Examples/CXX/CMakeLists.txt | 5 + HDF5Examples/CXX/H5D/CMakeLists.txt | 83 ++++++ HDF5Examples/CXX/H5D/C_sourcefiles.cmake | 12 + .../CXX/H5D}/Makefile.am | 0 .../CXX/H5D}/chunks.cpp | 0 .../CXX/H5D}/compound.cpp | 0 .../CXX/H5D}/create.cpp | 0 .../CXX/H5D}/expected.out | 0 .../CXX/H5D}/extend_ds.cpp | 0 .../CXX/H5D}/h5group.cpp | 0 .../CXX/H5D}/readdata.cpp | 0 .../CXX/H5D}/testh5c++.sh.in | 0 .../CXX/H5D}/writedata.cpp | 0 HDF5Examples/CXX/Makefile.am | 28 ++ HDF5Examples/CXX/TUTR/CMakeLists.txt | 64 ++++ HDF5Examples/CXX/TUTR/C_sourcefiles.cmake | 14 + HDF5Examples/CXX/TUTR/Makefile.am | 81 +++++ .../CXX/TUTR}/h5tutr_cmprss.cpp | 0 .../CXX/TUTR}/h5tutr_crtatt.cpp | 0 .../CXX/TUTR}/h5tutr_crtdat.cpp | 0 .../CXX/TUTR}/h5tutr_crtgrp.cpp | 0 .../CXX/TUTR}/h5tutr_crtgrpar.cpp | 0 .../CXX/TUTR}/h5tutr_crtgrpd.cpp | 0 .../CXX/TUTR}/h5tutr_extend.cpp | 0 .../CXX/TUTR}/h5tutr_rdwt.cpp | 0 .../CXX/TUTR}/h5tutr_subset.cpp | 0 HDF5Examples/CXX/TUTR/testh5c++.sh.in | 277 ++++++++++++++++++ HDF5Examples/FORTRAN/CMakeLists.txt | 3 +- HDF5Examples/FORTRAN/H5D/CMakeLists.txt | 29 +- HDF5Examples/FORTRAN/H5G/CMakeLists.txt | 89 ++++-- HDF5Examples/FORTRAN/H5PAR/CMakeLists.txt | 18 +- HDF5Examples/FORTRAN/H5T/CMakeLists.txt | 36 ++- HDF5Examples/FORTRAN/TUTR/CMakeLists.txt | 120 ++++++++ .../FORTRAN/TUTR/Fortran_sourcefiles.cmake | 27 ++ .../FORTRAN/TUTR}/Makefile.am | 11 - .../FORTRAN/TUTR}/compound.f90 | 0 .../TUTR}/compound_complex_fortran2003.f90 | 0 .../FORTRAN/TUTR}/compound_fortran2003.f90 | 0 .../FORTRAN/TUTR}/h5_cmprss.f90 | 0 .../FORTRAN/TUTR}/h5_crtatt.f90 | 0 .../FORTRAN/TUTR}/h5_crtdat.f90 | 0 .../FORTRAN/TUTR}/h5_crtgrp.f90 | 0 .../FORTRAN/TUTR}/h5_crtgrpar.f90 | 0 .../FORTRAN/TUTR}/h5_crtgrpd.f90 | 0 .../FORTRAN/TUTR}/h5_extend.f90 | 0 .../FORTRAN/TUTR}/h5_rdwt.f90 | 0 .../FORTRAN/TUTR}/h5_subset.f90 | 0 .../FORTRAN/TUTR}/hyperslab.f90 | 0 .../FORTRAN/TUTR}/mountexample.f90 | 0 .../FORTRAN/TUTR}/nested_derived_type.f90 | 0 .../FORTRAN/TUTR}/refobjexample.f90 | 0 .../FORTRAN/TUTR}/refregexample.f90 | 0 .../FORTRAN/TUTR}/run-fortran-ex.sh.in | 0 .../FORTRAN/TUTR}/rwdset_fortran2003.f90 | 0 .../FORTRAN/TUTR}/selectele.f90 | 0 .../FORTRAN/TUTR}/testh5fc.sh.in | 0 HDF5Examples/JAVA/CMakeLists.txt | 2 +- HDF5Examples/JAVA/H5D/CMakeLists.txt | 13 +- HDF5Examples/JAVA/H5G/CMakeLists.txt | 13 +- HDF5Examples/JAVA/H5T/CMakeLists.txt | 13 +- HDF5Examples/JAVA/Makefile.am | 2 +- .../{H5J => TUTR}/110/HDF5FileStructure.java | 0 .../JAVA/{H5J => TUTR}/CMakeLists.txt | 17 +- .../H5_CreateGroupAbsoluteRelative.java | 0 .../{H5J => TUTR}/HDF5AttributeCreate.java | 0 .../JAVA/{H5J => TUTR}/HDF5DatasetCreate.java | 0 .../JAVA/{H5J => TUTR}/HDF5DatasetRead.java | 0 .../JAVA/{H5J => TUTR}/HDF5FileCreate.java | 0 .../JAVA/{H5J => TUTR}/HDF5FileStructure.java | 0 .../JAVA/{H5J => TUTR}/HDF5GroupCreate.java | 0 .../{H5J => TUTR}/HDF5GroupDatasetCreate.java | 0 .../JAVA/{H5J => TUTR}/HDF5SubsetSelect.java | 0 .../JAVA/{H5J => TUTR}/Java_sourcefiles.cmake | 0 HDF5Examples/JAVA/{H5J => TUTR}/Makefile.am | 0 .../JAVA/{H5J => TUTR}/runExample.sh.in | 0 .../tfiles/110/HDF5AttributeCreate.txt | 0 .../tfiles/110/HDF5DatasetCreate.txt | 0 .../tfiles/110/HDF5DatasetRead.txt | 0 .../tfiles/110/HDF5FileCreate.txt | 0 .../tfiles/110/HDF5FileStructure.txt | 0 .../tfiles/110/HDF5GroupCreate.txt | 0 .../tfiles/110/HDF5GroupDatasetCreate.txt | 0 .../tfiles/110/HDF5SubsetSelect.txt | 0 .../config/cmake/HDFExampleMacros.cmake | 6 + Makefile.am | 40 +-- c++/CMakeLists.txt | 7 - c++/Makefile.am | 18 +- c++/examples/CMakeLists.txt | 87 ------ c++/examples/CMakeTests.cmake | 122 -------- c++/examples/run-c++-ex.sh.in | 145 --------- config/cmake/HDF5ExampleCache.cmake | 6 + configure.ac | 9 - doxygen/dox/ExamplesAPI.dox | 32 +- doxygen/dox/LearnBasics.dox | 22 +- examples/CMakeLists.txt | 59 ---- fortran/Makefile.am | 20 +- fortran/examples/CMakeLists.txt | 182 ------------ fortran/examples/CMakeTests.cmake | 105 ------- fortran/examples/ph5example.f90 | 138 --------- java/src/Makefile.am | 3 - release_docs/RELEASE.txt | 6 + 148 files changed, 1119 insertions(+), 1029 deletions(-) rename {examples => HDF5Examples/C/TUTR}/Attributes.txt (100%) create mode 100644 HDF5Examples/C/TUTR/CMakeLists.txt rename {examples => HDF5Examples/C/TUTR}/CMakeTests.cmake (100%) create mode 100644 HDF5Examples/C/TUTR/C_sourcefiles.cmake rename {examples => HDF5Examples/C/TUTR}/Makefile.am (100%) rename {examples => HDF5Examples/C/TUTR}/README (100%) rename {examples => HDF5Examples/C/TUTR}/h5_attribute.c (100%) rename {examples => HDF5Examples/C/TUTR}/h5_chunk_read.c (100%) rename {examples => HDF5Examples/C/TUTR}/h5_cmprss.c (100%) rename {examples => HDF5Examples/C/TUTR}/h5_compound.c (100%) rename {examples => HDF5Examples/C/TUTR}/h5_crtatt.c (100%) rename {examples => HDF5Examples/C/TUTR}/h5_crtdat.c (100%) rename {examples => HDF5Examples/C/TUTR}/h5_crtgrp.c (100%) rename {examples => HDF5Examples/C/TUTR}/h5_crtgrpar.c (100%) rename {examples => HDF5Examples/C/TUTR}/h5_crtgrpd.c (100%) rename {examples => HDF5Examples/C/TUTR}/h5_debug_trace.c (100%) rename {examples => HDF5Examples/C/TUTR}/h5_drivers.c (100%) rename {examples => HDF5Examples/C/TUTR}/h5_dtransform.c (100%) rename {examples => HDF5Examples/C/TUTR}/h5_elink_unix2win.c (100%) rename {examples => HDF5Examples/C/TUTR}/h5_extend.c (100%) rename {examples => HDF5Examples/C/TUTR}/h5_extend_write.c (100%) rename {examples => HDF5Examples/C/TUTR}/h5_extlink.c (100%) rename {examples => HDF5Examples/C/TUTR}/h5_group.c (100%) rename {examples => HDF5Examples/C/TUTR}/h5_interm_group.c (100%) rename {examples => HDF5Examples/C/TUTR}/h5_mount.c (100%) rename {examples => HDF5Examples/C/TUTR}/h5_rdwt.c (100%) rename {examples => HDF5Examples/C/TUTR}/h5_read.c (100%) rename {examples => HDF5Examples/C/TUTR}/h5_ref2reg_deprec.c (100%) rename {examples => HDF5Examples/C/TUTR}/h5_ref_compat.c (100%) rename {examples => HDF5Examples/C/TUTR}/h5_ref_extern.c (100%) rename {examples => HDF5Examples/C/TUTR}/h5_reference_deprec.c (100%) rename {examples => HDF5Examples/C/TUTR}/h5_select.c (100%) rename {examples => HDF5Examples/C/TUTR}/h5_shared_mesg.c (100%) rename {examples => HDF5Examples/C/TUTR}/h5_subset.c (100%) rename {examples => HDF5Examples/C/TUTR}/h5_write.c (100%) rename {examples => HDF5Examples/C/TUTR}/run-all-ex.sh (100%) rename {examples => HDF5Examples/C/TUTR}/run-c-ex.sh.in (100%) rename {examples => HDF5Examples/C/TUTR}/testh5cc.sh.in (100%) create mode 100644 HDF5Examples/CXX/CMakeLists.txt create mode 100644 HDF5Examples/CXX/H5D/CMakeLists.txt create mode 100644 HDF5Examples/CXX/H5D/C_sourcefiles.cmake rename {c++/examples => HDF5Examples/CXX/H5D}/Makefile.am (100%) rename {c++/examples => HDF5Examples/CXX/H5D}/chunks.cpp (100%) rename {c++/examples => HDF5Examples/CXX/H5D}/compound.cpp (100%) rename {c++/examples => HDF5Examples/CXX/H5D}/create.cpp (100%) rename {c++/examples => HDF5Examples/CXX/H5D}/expected.out (100%) rename {c++/examples => HDF5Examples/CXX/H5D}/extend_ds.cpp (100%) rename {c++/examples => HDF5Examples/CXX/H5D}/h5group.cpp (100%) rename {c++/examples => HDF5Examples/CXX/H5D}/readdata.cpp (100%) rename {c++/examples => HDF5Examples/CXX/H5D}/testh5c++.sh.in (100%) rename {c++/examples => HDF5Examples/CXX/H5D}/writedata.cpp (100%) create mode 100644 HDF5Examples/CXX/Makefile.am create mode 100644 HDF5Examples/CXX/TUTR/CMakeLists.txt create mode 100644 HDF5Examples/CXX/TUTR/C_sourcefiles.cmake create mode 100644 HDF5Examples/CXX/TUTR/Makefile.am rename {c++/examples => HDF5Examples/CXX/TUTR}/h5tutr_cmprss.cpp (100%) rename {c++/examples => HDF5Examples/CXX/TUTR}/h5tutr_crtatt.cpp (100%) rename {c++/examples => HDF5Examples/CXX/TUTR}/h5tutr_crtdat.cpp (100%) rename {c++/examples => HDF5Examples/CXX/TUTR}/h5tutr_crtgrp.cpp (100%) rename {c++/examples => HDF5Examples/CXX/TUTR}/h5tutr_crtgrpar.cpp (100%) rename {c++/examples => HDF5Examples/CXX/TUTR}/h5tutr_crtgrpd.cpp (100%) rename {c++/examples => HDF5Examples/CXX/TUTR}/h5tutr_extend.cpp (100%) rename {c++/examples => HDF5Examples/CXX/TUTR}/h5tutr_rdwt.cpp (100%) rename {c++/examples => HDF5Examples/CXX/TUTR}/h5tutr_subset.cpp (100%) create mode 100644 HDF5Examples/CXX/TUTR/testh5c++.sh.in create mode 100644 HDF5Examples/FORTRAN/TUTR/CMakeLists.txt create mode 100644 HDF5Examples/FORTRAN/TUTR/Fortran_sourcefiles.cmake rename {fortran/examples => HDF5Examples/FORTRAN/TUTR}/Makefile.am (92%) rename {fortran/examples => HDF5Examples/FORTRAN/TUTR}/compound.f90 (100%) rename {fortran/examples => HDF5Examples/FORTRAN/TUTR}/compound_complex_fortran2003.f90 (100%) rename {fortran/examples => HDF5Examples/FORTRAN/TUTR}/compound_fortran2003.f90 (100%) rename {fortran/examples => HDF5Examples/FORTRAN/TUTR}/h5_cmprss.f90 (100%) rename {fortran/examples => HDF5Examples/FORTRAN/TUTR}/h5_crtatt.f90 (100%) rename {fortran/examples => HDF5Examples/FORTRAN/TUTR}/h5_crtdat.f90 (100%) rename {fortran/examples => HDF5Examples/FORTRAN/TUTR}/h5_crtgrp.f90 (100%) rename {fortran/examples => HDF5Examples/FORTRAN/TUTR}/h5_crtgrpar.f90 (100%) rename {fortran/examples => HDF5Examples/FORTRAN/TUTR}/h5_crtgrpd.f90 (100%) rename {fortran/examples => HDF5Examples/FORTRAN/TUTR}/h5_extend.f90 (100%) rename {fortran/examples => HDF5Examples/FORTRAN/TUTR}/h5_rdwt.f90 (100%) rename {fortran/examples => HDF5Examples/FORTRAN/TUTR}/h5_subset.f90 (100%) rename {fortran/examples => HDF5Examples/FORTRAN/TUTR}/hyperslab.f90 (100%) rename {fortran/examples => HDF5Examples/FORTRAN/TUTR}/mountexample.f90 (100%) rename {fortran/examples => HDF5Examples/FORTRAN/TUTR}/nested_derived_type.f90 (100%) rename {fortran/examples => HDF5Examples/FORTRAN/TUTR}/refobjexample.f90 (100%) rename {fortran/examples => HDF5Examples/FORTRAN/TUTR}/refregexample.f90 (100%) rename {fortran/examples => HDF5Examples/FORTRAN/TUTR}/run-fortran-ex.sh.in (100%) rename {fortran/examples => HDF5Examples/FORTRAN/TUTR}/rwdset_fortran2003.f90 (100%) rename {fortran/examples => HDF5Examples/FORTRAN/TUTR}/selectele.f90 (100%) rename {fortran/examples => HDF5Examples/FORTRAN/TUTR}/testh5fc.sh.in (100%) rename HDF5Examples/JAVA/{H5J => TUTR}/110/HDF5FileStructure.java (100%) rename HDF5Examples/JAVA/{H5J => TUTR}/CMakeLists.txt (86%) rename HDF5Examples/JAVA/{H5J => TUTR}/H5_CreateGroupAbsoluteRelative.java (100%) rename HDF5Examples/JAVA/{H5J => TUTR}/HDF5AttributeCreate.java (100%) rename HDF5Examples/JAVA/{H5J => TUTR}/HDF5DatasetCreate.java (100%) rename HDF5Examples/JAVA/{H5J => TUTR}/HDF5DatasetRead.java (100%) rename HDF5Examples/JAVA/{H5J => TUTR}/HDF5FileCreate.java (100%) rename HDF5Examples/JAVA/{H5J => TUTR}/HDF5FileStructure.java (100%) rename HDF5Examples/JAVA/{H5J => TUTR}/HDF5GroupCreate.java (100%) rename HDF5Examples/JAVA/{H5J => TUTR}/HDF5GroupDatasetCreate.java (100%) rename HDF5Examples/JAVA/{H5J => TUTR}/HDF5SubsetSelect.java (100%) rename HDF5Examples/JAVA/{H5J => TUTR}/Java_sourcefiles.cmake (100%) rename HDF5Examples/JAVA/{H5J => TUTR}/Makefile.am (100%) rename HDF5Examples/JAVA/{H5J => TUTR}/runExample.sh.in (100%) rename HDF5Examples/JAVA/{H5J => TUTR}/tfiles/110/HDF5AttributeCreate.txt (100%) rename HDF5Examples/JAVA/{H5J => TUTR}/tfiles/110/HDF5DatasetCreate.txt (100%) rename HDF5Examples/JAVA/{H5J => TUTR}/tfiles/110/HDF5DatasetRead.txt (100%) rename HDF5Examples/JAVA/{H5J => TUTR}/tfiles/110/HDF5FileCreate.txt (100%) rename HDF5Examples/JAVA/{H5J => TUTR}/tfiles/110/HDF5FileStructure.txt (100%) rename HDF5Examples/JAVA/{H5J => TUTR}/tfiles/110/HDF5GroupCreate.txt (100%) rename HDF5Examples/JAVA/{H5J => TUTR}/tfiles/110/HDF5GroupDatasetCreate.txt (100%) rename HDF5Examples/JAVA/{H5J => TUTR}/tfiles/110/HDF5SubsetSelect.txt (100%) delete mode 100644 c++/examples/CMakeLists.txt delete mode 100644 c++/examples/CMakeTests.cmake delete mode 100644 c++/examples/run-c++-ex.sh.in delete mode 100644 examples/CMakeLists.txt delete mode 100644 fortran/examples/CMakeLists.txt delete mode 100644 fortran/examples/CMakeTests.cmake delete mode 100644 fortran/examples/ph5example.f90 diff --git a/HDF5Examples/C/CMakeLists.txt b/HDF5Examples/C/CMakeLists.txt index 12882cfa5fa..97a9ea1f672 100644 --- a/HDF5Examples/C/CMakeLists.txt +++ b/HDF5Examples/C/CMakeLists.txt @@ -1,9 +1,10 @@ -cmake_minimum_required (VERSION 3.12) +cmake_minimum_required (VERSION 3.18) project (HDF5Examples_C C) #----------------------------------------------------------------------------- # Build the C Examples #----------------------------------------------------------------------------- +add_subdirectory (${PROJECT_SOURCE_DIR}/TUTR) add_subdirectory (${PROJECT_SOURCE_DIR}/H5D) add_subdirectory (${PROJECT_SOURCE_DIR}/H5G) add_subdirectory (${PROJECT_SOURCE_DIR}/H5T) diff --git a/HDF5Examples/C/H5D/CMakeLists.txt b/HDF5Examples/C/H5D/CMakeLists.txt index bde15d19f1e..6f6086b3939 100644 --- a/HDF5Examples/C/H5D/CMakeLists.txt +++ b/HDF5Examples/C/H5D/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required (VERSION 3.12) +cmake_minimum_required (VERSION 3.18) project (HDF5Examples_C_H5D C) #----------------------------------------------------------------------------- diff --git a/HDF5Examples/C/H5FLT/CMakeLists.txt b/HDF5Examples/C/H5FLT/CMakeLists.txt index fb2c4fd4989..e289bf70ba9 100644 --- a/HDF5Examples/C/H5FLT/CMakeLists.txt +++ b/HDF5Examples/C/H5FLT/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required (VERSION 3.12) +cmake_minimum_required (VERSION 3.18) project (HDF5Examples_C_H5FLT C) set (dyn_examples) diff --git a/HDF5Examples/C/H5G/CMakeLists.txt b/HDF5Examples/C/H5G/CMakeLists.txt index 436bd3a0e2b..91281d5f0a4 100644 --- a/HDF5Examples/C/H5G/CMakeLists.txt +++ b/HDF5Examples/C/H5G/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required (VERSION 3.12) +cmake_minimum_required (VERSION 3.18) project (HDF5Examples_C_H5G C) #----------------------------------------------------------------------------- diff --git a/HDF5Examples/C/H5PAR/CMakeLists.txt b/HDF5Examples/C/H5PAR/CMakeLists.txt index be48139f316..662cd70d295 100644 --- a/HDF5Examples/C/H5PAR/CMakeLists.txt +++ b/HDF5Examples/C/H5PAR/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required (VERSION 3.12) +cmake_minimum_required (VERSION 3.18) project (H5PAR_C C) #----------------------------------------------------------------------------- diff --git a/HDF5Examples/C/H5T/CMakeLists.txt b/HDF5Examples/C/H5T/CMakeLists.txt index 2fd71ffcd20..caf612b0d40 100644 --- a/HDF5Examples/C/H5T/CMakeLists.txt +++ b/HDF5Examples/C/H5T/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required (VERSION 3.12) +cmake_minimum_required (VERSION 3.18) project (HDF5Examples_C_H5T C) #----------------------------------------------------------------------------- diff --git a/HDF5Examples/C/H5VDS/CMakeLists.txt b/HDF5Examples/C/H5VDS/CMakeLists.txt index 33dafb47979..fb3bd000d4f 100644 --- a/HDF5Examples/C/H5VDS/CMakeLists.txt +++ b/HDF5Examples/C/H5VDS/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required (VERSION 3.12) +cmake_minimum_required (VERSION 3.18) project (HDF5Examples_C_H5VDS C) #----------------------------------------------------------------------------- diff --git a/HDF5Examples/C/Perf/CMakeLists.txt b/HDF5Examples/C/Perf/CMakeLists.txt index 66f93273629..bf66de3f6de 100644 --- a/HDF5Examples/C/Perf/CMakeLists.txt +++ b/HDF5Examples/C/Perf/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required (VERSION 3.12) +cmake_minimum_required (VERSION 3.18) project (HDF5Examples_C_PERFORM C) #----------------------------------------------------------------------------- diff --git a/examples/Attributes.txt b/HDF5Examples/C/TUTR/Attributes.txt similarity index 100% rename from examples/Attributes.txt rename to HDF5Examples/C/TUTR/Attributes.txt diff --git a/HDF5Examples/C/TUTR/CMakeLists.txt b/HDF5Examples/C/TUTR/CMakeLists.txt new file mode 100644 index 00000000000..064db8b75b6 --- /dev/null +++ b/HDF5Examples/C/TUTR/CMakeLists.txt @@ -0,0 +1,113 @@ +cmake_minimum_required (VERSION 3.18) +project (HDF5Examples_C_TUTR C) + +#----------------------------------------------------------------------------- +# Define Sources +#----------------------------------------------------------------------------- +include (C_sourcefiles.cmake) + +foreach (example_name ${examples}) + add_executable (${EXAMPLE_VARNAME}_tutr_${example_name} ${PROJECT_SOURCE_DIR}/${example_name}.c) + target_compile_options(${EXAMPLE_VARNAME}_tutr_${example_name} + PRIVATE + "$<$:-DH5_USE_16_API>" + "$<$:-DH5_USE_18_API>" + "$<$:-DH5_USE_110_API>" + "$<$:-DH5_USE_112_API>" + "$<$:-DH5_USE_114_API>" + "$<$:-DH5_USE_116_API>" + ) + if (H5_HAVE_PARALLEL) + target_include_directories (${EXAMPLE_VARNAME}_tutr_${example_name} PUBLIC ${MPI_C_INCLUDE_DIRS}) + endif () + target_link_libraries (${EXAMPLE_VARNAME}_tutr_${example_name} ${H5EX_HDF5_LINK_LIBS}) +endforeach () + + +if (H5EX_BUILD_TESTING) + file (MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/red ${PROJECT_BINARY_DIR}/blue ${PROJECT_BINARY_DIR}/u2w) + + set (${EXAMPLE_VARNAME}_tutr_CLEANFILES + Attributes.h5 + btrees_file.h5 + cmprss.h5 + default_file.h5 + dset.h5 + extend.h5 + extlink_prefix_source.h5 + extlink_source.h5 + extlink_target.h5 + group.h5 + groups.h5 + hard_link.h5 + mount1.h5 + mount2.h5 + one_index_file.h5 + only_dspaces_and_attrs_file.h5 + only_huge_mesgs_file.h5 + REF_REG.h5 + refere.h5 + refer_deprec.h5 + refer_extern1.h5 + refer_extern2.h5 + SDS.h5 + SDScompound.h5 + SDSextendible.h5 + Select.h5 + separate_indexes_file.h5 + small_lists_file.h5 + soft_link.h5 + subset.h5 + unix2win.h5 + blue/prefix_target.h5 + red/prefix_target.h5 + u2w/u2w_target.h5 + ) + + # Remove any output file left over from previous test run + add_test ( + NAME ${EXAMPLE_VARNAME}_tutr-clear-objects + COMMAND ${CMAKE_COMMAND} -E remove ${${EXAMPLE_VARNAME}_tutr_CLEANFILES} + ) + set_tests_properties (${EXAMPLE_VARNAME}_tutr-clear-objects PROPERTIES + FIXTURES_SETUP clear_${EXAMPLE_VARNAME}_tutr + WORKING_DIRECTORY ${PROJECT_BINARY_DIR} + ) + add_test ( + NAME ${EXAMPLE_VARNAME}_tutr-clean-objects + COMMAND ${CMAKE_COMMAND} -E remove ${${EXAMPLE_VARNAME}_tutr_CLEANFILES} + ) + set_tests_properties (${EXAMPLE_VARNAME}_tutr-clean-objects PROPERTIES + FIXTURES_CLEANUP clear_${EXAMPLE_VARNAME}_tutr + WORKING_DIRECTORY ${PROJECT_BINARY_DIR} + ) + + macro (ADD_H5_TEST testname) + if (HDF5_USING_ANALYSIS_TOOL) + add_test (NAME ${EXAMPLE_VARNAME}_tutr_${testname} COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $) + else () + add_test ( + NAME ${EXAMPLE_VARNAME}_tutr_${testname} + COMMAND "${CMAKE_COMMAND}" + -D "TEST_EMULATOR=${CMAKE_CROSSCOMPILING_EMULATOR}" + -D "TEST_PROGRAM=$" + -D "TEST_ARGS:STRING=" + -D "TEST_FOLDER=${PROJECT_BINARY_DIR}" + -D "TEST_EXPECT=0" + -D "TEST_SKIP_COMPARE=TRUE" + -D "TEST_OUTPUT=${testname}.out" + -D "TEST_LIBRARY_DIRECTORY=${CMAKE_TEST_LIB_DIRECTORY}" + -P "${H5EX_RESOURCES_DIR}/runTest.cmake" + ) + endif () + set_tests_properties (${EXAMPLE_VARNAME}_tutr_${testname} PROPERTIES FIXTURES_REQUIRED clear_${EXAMPLE_VARNAME}_tutr) + if (last_test) + set_tests_properties (${EXAMPLE_VARNAME}_tutr_${testname} PROPERTIES DEPENDS ${last_test}) + endif () + set (last_test "${EXAMPLE_VARNAME}_tutr_${testname}") + endmacro () + + foreach (example_name ${examples}) + ADD_H5_TEST (${example_name}) + endforeach () +endif () diff --git a/examples/CMakeTests.cmake b/HDF5Examples/C/TUTR/CMakeTests.cmake similarity index 100% rename from examples/CMakeTests.cmake rename to HDF5Examples/C/TUTR/CMakeTests.cmake diff --git a/HDF5Examples/C/TUTR/C_sourcefiles.cmake b/HDF5Examples/C/TUTR/C_sourcefiles.cmake new file mode 100644 index 00000000000..147ee7ab4aa --- /dev/null +++ b/HDF5Examples/C/TUTR/C_sourcefiles.cmake @@ -0,0 +1,32 @@ +#----------------------------------------------------------------------------- +# Define Sources, one file per application +#----------------------------------------------------------------------------- +set (examples + h5_crtdat + h5_rdwt + h5_crtatt + h5_crtgrp + h5_crtgrpar + h5_crtgrpd + h5_cmprss + h5_extend + h5_subset + h5_write + h5_read + h5_extend_write + h5_chunk_read + h5_compound + h5_group + h5_select + h5_attribute + h5_mount + h5_ref_extern + h5_ref_compat + h5_reference_deprec + h5_drivers + h5_ref2reg_deprec + h5_extlink + h5_elink_unix2win + h5_shared_mesg + h5_debug_trace +) diff --git a/examples/Makefile.am b/HDF5Examples/C/TUTR/Makefile.am similarity index 100% rename from examples/Makefile.am rename to HDF5Examples/C/TUTR/Makefile.am diff --git a/examples/README b/HDF5Examples/C/TUTR/README similarity index 100% rename from examples/README rename to HDF5Examples/C/TUTR/README diff --git a/examples/h5_attribute.c b/HDF5Examples/C/TUTR/h5_attribute.c similarity index 100% rename from examples/h5_attribute.c rename to HDF5Examples/C/TUTR/h5_attribute.c diff --git a/examples/h5_chunk_read.c b/HDF5Examples/C/TUTR/h5_chunk_read.c similarity index 100% rename from examples/h5_chunk_read.c rename to HDF5Examples/C/TUTR/h5_chunk_read.c diff --git a/examples/h5_cmprss.c b/HDF5Examples/C/TUTR/h5_cmprss.c similarity index 100% rename from examples/h5_cmprss.c rename to HDF5Examples/C/TUTR/h5_cmprss.c diff --git a/examples/h5_compound.c b/HDF5Examples/C/TUTR/h5_compound.c similarity index 100% rename from examples/h5_compound.c rename to HDF5Examples/C/TUTR/h5_compound.c diff --git a/examples/h5_crtatt.c b/HDF5Examples/C/TUTR/h5_crtatt.c similarity index 100% rename from examples/h5_crtatt.c rename to HDF5Examples/C/TUTR/h5_crtatt.c diff --git a/examples/h5_crtdat.c b/HDF5Examples/C/TUTR/h5_crtdat.c similarity index 100% rename from examples/h5_crtdat.c rename to HDF5Examples/C/TUTR/h5_crtdat.c diff --git a/examples/h5_crtgrp.c b/HDF5Examples/C/TUTR/h5_crtgrp.c similarity index 100% rename from examples/h5_crtgrp.c rename to HDF5Examples/C/TUTR/h5_crtgrp.c diff --git a/examples/h5_crtgrpar.c b/HDF5Examples/C/TUTR/h5_crtgrpar.c similarity index 100% rename from examples/h5_crtgrpar.c rename to HDF5Examples/C/TUTR/h5_crtgrpar.c diff --git a/examples/h5_crtgrpd.c b/HDF5Examples/C/TUTR/h5_crtgrpd.c similarity index 100% rename from examples/h5_crtgrpd.c rename to HDF5Examples/C/TUTR/h5_crtgrpd.c diff --git a/examples/h5_debug_trace.c b/HDF5Examples/C/TUTR/h5_debug_trace.c similarity index 100% rename from examples/h5_debug_trace.c rename to HDF5Examples/C/TUTR/h5_debug_trace.c diff --git a/examples/h5_drivers.c b/HDF5Examples/C/TUTR/h5_drivers.c similarity index 100% rename from examples/h5_drivers.c rename to HDF5Examples/C/TUTR/h5_drivers.c diff --git a/examples/h5_dtransform.c b/HDF5Examples/C/TUTR/h5_dtransform.c similarity index 100% rename from examples/h5_dtransform.c rename to HDF5Examples/C/TUTR/h5_dtransform.c diff --git a/examples/h5_elink_unix2win.c b/HDF5Examples/C/TUTR/h5_elink_unix2win.c similarity index 100% rename from examples/h5_elink_unix2win.c rename to HDF5Examples/C/TUTR/h5_elink_unix2win.c diff --git a/examples/h5_extend.c b/HDF5Examples/C/TUTR/h5_extend.c similarity index 100% rename from examples/h5_extend.c rename to HDF5Examples/C/TUTR/h5_extend.c diff --git a/examples/h5_extend_write.c b/HDF5Examples/C/TUTR/h5_extend_write.c similarity index 100% rename from examples/h5_extend_write.c rename to HDF5Examples/C/TUTR/h5_extend_write.c diff --git a/examples/h5_extlink.c b/HDF5Examples/C/TUTR/h5_extlink.c similarity index 100% rename from examples/h5_extlink.c rename to HDF5Examples/C/TUTR/h5_extlink.c diff --git a/examples/h5_group.c b/HDF5Examples/C/TUTR/h5_group.c similarity index 100% rename from examples/h5_group.c rename to HDF5Examples/C/TUTR/h5_group.c diff --git a/examples/h5_interm_group.c b/HDF5Examples/C/TUTR/h5_interm_group.c similarity index 100% rename from examples/h5_interm_group.c rename to HDF5Examples/C/TUTR/h5_interm_group.c diff --git a/examples/h5_mount.c b/HDF5Examples/C/TUTR/h5_mount.c similarity index 100% rename from examples/h5_mount.c rename to HDF5Examples/C/TUTR/h5_mount.c diff --git a/examples/h5_rdwt.c b/HDF5Examples/C/TUTR/h5_rdwt.c similarity index 100% rename from examples/h5_rdwt.c rename to HDF5Examples/C/TUTR/h5_rdwt.c diff --git a/examples/h5_read.c b/HDF5Examples/C/TUTR/h5_read.c similarity index 100% rename from examples/h5_read.c rename to HDF5Examples/C/TUTR/h5_read.c diff --git a/examples/h5_ref2reg_deprec.c b/HDF5Examples/C/TUTR/h5_ref2reg_deprec.c similarity index 100% rename from examples/h5_ref2reg_deprec.c rename to HDF5Examples/C/TUTR/h5_ref2reg_deprec.c diff --git a/examples/h5_ref_compat.c b/HDF5Examples/C/TUTR/h5_ref_compat.c similarity index 100% rename from examples/h5_ref_compat.c rename to HDF5Examples/C/TUTR/h5_ref_compat.c diff --git a/examples/h5_ref_extern.c b/HDF5Examples/C/TUTR/h5_ref_extern.c similarity index 100% rename from examples/h5_ref_extern.c rename to HDF5Examples/C/TUTR/h5_ref_extern.c diff --git a/examples/h5_reference_deprec.c b/HDF5Examples/C/TUTR/h5_reference_deprec.c similarity index 100% rename from examples/h5_reference_deprec.c rename to HDF5Examples/C/TUTR/h5_reference_deprec.c diff --git a/examples/h5_select.c b/HDF5Examples/C/TUTR/h5_select.c similarity index 100% rename from examples/h5_select.c rename to HDF5Examples/C/TUTR/h5_select.c diff --git a/examples/h5_shared_mesg.c b/HDF5Examples/C/TUTR/h5_shared_mesg.c similarity index 100% rename from examples/h5_shared_mesg.c rename to HDF5Examples/C/TUTR/h5_shared_mesg.c diff --git a/examples/h5_subset.c b/HDF5Examples/C/TUTR/h5_subset.c similarity index 100% rename from examples/h5_subset.c rename to HDF5Examples/C/TUTR/h5_subset.c diff --git a/examples/h5_write.c b/HDF5Examples/C/TUTR/h5_write.c similarity index 100% rename from examples/h5_write.c rename to HDF5Examples/C/TUTR/h5_write.c diff --git a/examples/run-all-ex.sh b/HDF5Examples/C/TUTR/run-all-ex.sh similarity index 100% rename from examples/run-all-ex.sh rename to HDF5Examples/C/TUTR/run-all-ex.sh diff --git a/examples/run-c-ex.sh.in b/HDF5Examples/C/TUTR/run-c-ex.sh.in similarity index 100% rename from examples/run-c-ex.sh.in rename to HDF5Examples/C/TUTR/run-c-ex.sh.in diff --git a/examples/testh5cc.sh.in b/HDF5Examples/C/TUTR/testh5cc.sh.in similarity index 100% rename from examples/testh5cc.sh.in rename to HDF5Examples/C/TUTR/testh5cc.sh.in diff --git a/HDF5Examples/CMakeLists.txt b/HDF5Examples/CMakeLists.txt index 4752dc39952..eca67915d29 100644 --- a/HDF5Examples/CMakeLists.txt +++ b/HDF5Examples/CMakeLists.txt @@ -1,10 +1,11 @@ -cmake_minimum_required (VERSION 3.12) +cmake_minimum_required (VERSION 3.18) project (H5EXAMPLES C) #----------------------------------------------------------------------------- # Define some CMake variables for use later in the project #----------------------------------------------------------------------------- set (H5EX_C_SRC_DIR ${H5EXAMPLES_SOURCE_DIR}/C) +set (H5EX_CXX_SRC_DIR ${H5EXAMPLES_SOURCE_DIR}/CXX) set (H5EX_F90_SRC_DIR ${H5EXAMPLES_SOURCE_DIR}/FORTRAN) set (H5EX_JAVA_DIR ${H5EXAMPLES_SOURCE_DIR}/JAVA) #----------------------------------------------------------------------------- @@ -144,7 +145,7 @@ if (${H5_LIBVER_DIR} GREATER 16) set (H5_FC_FUNC "H5_FC_FUNC(name,NAME) name ## _") set (H5_FC_FUNC_ "H5_FC_FUNC_(name,NAME) name ## _") if (EXISTS "${H5EXAMPLES_SOURCE_DIR}/FORTRAN" AND IS_DIRECTORY "${H5EXAMPLES_SOURCE_DIR}/FORTRAN") - option (HDF_BUILD_FORTRAN "Build FORTRAN support" OFF) + option (HDF_BUILD_FORTRAN "Build examples FORTRAN support" OFF) if (HDF_BUILD_FORTRAN AND HDF5_BUILD_FORTRAN) set (H5EX_LINK_Fortran_LIBS ${H5EX_HDF5_LINK_LIBS}) @@ -170,7 +171,7 @@ if (${H5_LIBVER_DIR} GREATER 16) # Option to build JAVA examples #----------------------------------------------------------------------------- if (EXISTS "${H5EXAMPLES_SOURCE_DIR}/JAVA" AND IS_DIRECTORY "${H5EXAMPLES_SOURCE_DIR}/JAVA") - option (HDF_BUILD_JAVA "Build JAVA support" OFF) + option (HDF_BUILD_JAVA "Build examples JAVA support" OFF) else () set (HDF_BUILD_JAVA OFF CACHE BOOL "Build examples JAVA support" FORCE) endif () @@ -178,11 +179,20 @@ if (${H5_LIBVER_DIR} GREATER 16) set (HDF_BUILD_JAVA OFF CACHE BOOL "Build examples JAVA support" FORCE) endif () + #----------------------------------------------------------------------------- + # Build the CPP Examples + #----------------------------------------------------------------------------- + if (EXISTS "${H5EXAMPLES_SOURCE_DIR}/CXX" AND IS_DIRECTORY "${H5EXAMPLES_SOURCE_DIR}/CXX") + option (HDF_BUILD_CPP_LIB "Build examples C++ support" OFF) + else () + set (HDF_BUILD_CPP_LIB OFF CACHE BOOL "Build examples C++ support" FORCE) + endif () + #----------------------------------------------------------------------------- # Option to build filter examples #----------------------------------------------------------------------------- if (EXISTS "${H5EXAMPLES_SOURCE_DIR}/C/H5FLT" AND IS_DIRECTORY "${H5EXAMPLES_SOURCE_DIR}/C/H5FLT") - option (HDF_BUILD_FILTERS "Test filter support" OFF) + option (HDF_BUILD_FILTERS "Build examples PLUGIN filter support" OFF) if (HDF_BUILD_FILTERS AND HDF5_ENABLE_PLUGIN_SUPPORT) if(DEFINED ENV{HDF5_PLUGIN_PATH}) message (STATUS "ENV PATH=$ENV{HDF5_PLUGIN_PATH}") @@ -203,6 +213,7 @@ if (${H5_LIBVER_DIR} GREATER 16) else () set (HDF_BUILD_FORTRAN OFF} CACHE BOOL "Build examples FORTRAN support" FORCE) set (HDF_BUILD_JAVA OFF CACHE BOOL "Build examples JAVA support" FORCE) + set (HDF_BUILD_CPP_LIB OFF CACHE BOOL "Build examples C++ support" FORCE) set (HDF_BUILD_FILTERS OFF CACHE BOOL "Build examples PLUGIN filter support" FORCE) endif () @@ -216,4 +227,7 @@ endif () if (HDF_BUILD_JAVA AND HDF5_BUILD_JAVA) add_subdirectory (JAVA) endif () +if (HDF_BUILD_CPP_LIB AND HDF5_BUILD_CPP_LIB) + add_subdirectory (CXX) +endif () diff --git a/HDF5Examples/CXX/CMakeLists.txt b/HDF5Examples/CXX/CMakeLists.txt new file mode 100644 index 00000000000..79e8f6e6e8c --- /dev/null +++ b/HDF5Examples/CXX/CMakeLists.txt @@ -0,0 +1,5 @@ +cmake_minimum_required (VERSION 3.18) +project (HDFCXX_EXAMPLES CXX) + +add_subdirectory (H5D) +add_subdirectory (TUTR) diff --git a/HDF5Examples/CXX/H5D/CMakeLists.txt b/HDF5Examples/CXX/H5D/CMakeLists.txt new file mode 100644 index 00000000000..32201d6b344 --- /dev/null +++ b/HDF5Examples/CXX/H5D/CMakeLists.txt @@ -0,0 +1,83 @@ +cmake_minimum_required (VERSION 3.18) +project (HDF5Examples_CXX_H5D CXX) + +#----------------------------------------------------------------------------- +# Define Sources +#----------------------------------------------------------------------------- +include (C_sourcefiles.cmake) + +if (HDF5_VERSION_MAJOR VERSION_GREATER_EQUAL "1.8") + foreach (example_name ${examples}) + add_executable (${EXAMPLE_VARNAME}_cpp_ex_${example_name} ${PROJECT_SOURCE_DIR}/${example_name}.cpp) + target_compile_options(${EXAMPLE_VARNAME}_cpp_ex_${example_name} + PRIVATE + "$<$:-DH5_USE_16_API>" + "$<$:-DH5_USE_18_API>" + "$<$:-DH5_USE_110_API>" + "$<$:-DH5_USE_112_API>" + "$<$:-DH5_USE_114_API>" + "$<$:-DH5_USE_116_API>" + ) + if (H5_HAVE_PARALLEL) + target_include_directories (${EXAMPLE_VARNAME}_cpp_ex_${example_name} PUBLIC ${MPI_C_INCLUDE_DIRS}) + endif () + target_link_libraries (${EXAMPLE_VARNAME}_cpp_ex_${example_name} ${H5EX_HDF5_LINK_LIBS}) + endforeach () +endif () + +if (H5EX_BUILD_TESTING) + set (${EXAMPLE_VARNAME}_cpp_ex_CLEANFILES + Group.h5 + SDS.h5 + SDScompound.h5 + SDSextendible.h5 + Select.h5 + ) + add_test ( + NAME ${EXAMPLE_VARNAME}_cpp_ex-clear-objects + COMMAND ${CMAKE_COMMAND} + -E remove ${${EXAMPLE_VARNAME}_cpp_ex_CLEANFILES} + ) + set_tests_properties (${EXAMPLE_VARNAME}_cpp_ex-clear-objects PROPERTIES + FIXTURES_SETUP clear_${EXAMPLE_VARNAME}_cpp_ex + WORKING_DIRECTORY ${PROJECT_BINARY_DIR} + ) + add_test ( + NAME ${EXAMPLE_VARNAME}_cpp_ex-clean-objects + COMMAND ${CMAKE_COMMAND} + -E remove ${${EXAMPLE_VARNAME}_cpp_ex_CLEANFILES} + ) + set_tests_properties (${EXAMPLE_VARNAME}_cpp_ex-clean-objects PROPERTIES + FIXTURES_CLEANUP clear_${EXAMPLE_VARNAME}_cpp_ex + WORKING_DIRECTORY ${PROJECT_BINARY_DIR} + ) + + macro (ADD_H5_TEST testname) + if (HDF5_USING_ANALYSIS_TOOL) + add_test (NAME ${EXAMPLE_VARNAME}_cpp_ex_${testname} COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $) + else () + add_test ( + NAME ${EXAMPLE_VARNAME}_cpp_ex_${testname} + COMMAND "${CMAKE_COMMAND}" + -D "TEST_EMULATOR=${CMAKE_CROSSCOMPILING_EMULATOR}" + -D "TEST_PROGRAM=$" + -D "TEST_ARGS:STRING=" + -D "TEST_FOLDER=${PROJECT_BINARY_DIR}" + -D "TEST_EXPECT=0" + -D "TEST_SKIP_COMPARE=TRUE" + -D "TEST_OUTPUT=${testname}.out" + -D "TEST_LIBRARY_DIRECTORY=${CMAKE_TEST_LIB_DIRECTORY}" + -P "${H5EX_RESOURCES_DIR}/runTest.cmake" + ) + endif () + set_tests_properties (${EXAMPLE_VARNAME}_cpp_ex_${testname} PROPERTIES FIXTURES_REQUIRED clear_${EXAMPLE_VARNAME}_cpp_ex) + if (last_test) + set_tests_properties (${EXAMPLE_VARNAME}_cpp_ex_${testname} PROPERTIES DEPENDS ${last_test}) + endif () + set (last_test "${EXAMPLE_VARNAME}_cpp_ex_${testname}") + endmacro () + + foreach (example_name ${examples}) + ADD_H5_TEST (${example_name}) + endforeach () +endif () diff --git a/HDF5Examples/CXX/H5D/C_sourcefiles.cmake b/HDF5Examples/CXX/H5D/C_sourcefiles.cmake new file mode 100644 index 00000000000..8ba4661e271 --- /dev/null +++ b/HDF5Examples/CXX/H5D/C_sourcefiles.cmake @@ -0,0 +1,12 @@ +#----------------------------------------------------------------------------- +# Define Sources, one file per application +#----------------------------------------------------------------------------- +set (examples + create + readdata + writedata + compound + extend_ds + chunks + h5group +) diff --git a/c++/examples/Makefile.am b/HDF5Examples/CXX/H5D/Makefile.am similarity index 100% rename from c++/examples/Makefile.am rename to HDF5Examples/CXX/H5D/Makefile.am diff --git a/c++/examples/chunks.cpp b/HDF5Examples/CXX/H5D/chunks.cpp similarity index 100% rename from c++/examples/chunks.cpp rename to HDF5Examples/CXX/H5D/chunks.cpp diff --git a/c++/examples/compound.cpp b/HDF5Examples/CXX/H5D/compound.cpp similarity index 100% rename from c++/examples/compound.cpp rename to HDF5Examples/CXX/H5D/compound.cpp diff --git a/c++/examples/create.cpp b/HDF5Examples/CXX/H5D/create.cpp similarity index 100% rename from c++/examples/create.cpp rename to HDF5Examples/CXX/H5D/create.cpp diff --git a/c++/examples/expected.out b/HDF5Examples/CXX/H5D/expected.out similarity index 100% rename from c++/examples/expected.out rename to HDF5Examples/CXX/H5D/expected.out diff --git a/c++/examples/extend_ds.cpp b/HDF5Examples/CXX/H5D/extend_ds.cpp similarity index 100% rename from c++/examples/extend_ds.cpp rename to HDF5Examples/CXX/H5D/extend_ds.cpp diff --git a/c++/examples/h5group.cpp b/HDF5Examples/CXX/H5D/h5group.cpp similarity index 100% rename from c++/examples/h5group.cpp rename to HDF5Examples/CXX/H5D/h5group.cpp diff --git a/c++/examples/readdata.cpp b/HDF5Examples/CXX/H5D/readdata.cpp similarity index 100% rename from c++/examples/readdata.cpp rename to HDF5Examples/CXX/H5D/readdata.cpp diff --git a/c++/examples/testh5c++.sh.in b/HDF5Examples/CXX/H5D/testh5c++.sh.in similarity index 100% rename from c++/examples/testh5c++.sh.in rename to HDF5Examples/CXX/H5D/testh5c++.sh.in diff --git a/c++/examples/writedata.cpp b/HDF5Examples/CXX/H5D/writedata.cpp similarity index 100% rename from c++/examples/writedata.cpp rename to HDF5Examples/CXX/H5D/writedata.cpp diff --git a/HDF5Examples/CXX/Makefile.am b/HDF5Examples/CXX/Makefile.am new file mode 100644 index 00000000000..1cbae2e1c5e --- /dev/null +++ b/HDF5Examples/CXX/Makefile.am @@ -0,0 +1,28 @@ +# +# Copyright by The HDF Group. +# All rights reserved. +# +# This file is part of HDF5. The full HDF5 copyright notice, including +# terms governing use, modification, and redistribution, is contained in +# the COPYING file, which can be found at the root of the source code +# distribution tree, or in https://www.hdfgroup.org/licenses. +# If you do not have access to either file, you may request a copy from +# help@hdfgroup.org. +# +# +# This makefile mostly just reinvokes make in the various subdirectories +# but does so in the correct order. You can alternatively invoke make from +# each subdirectory manually. +## +## Makefile.am +## Run automake to generate a Makefile.in from this file. +## +# +# HDF5 CXX Library Examples Makefile(.in) + +include $(top_srcdir)/config/commence.am + +## Only recurse into subdirectories if the CXX interface is enabled. + SUBDIRS=H5D TUTR + +include $(top_srcdir)/config/conclude.am diff --git a/HDF5Examples/CXX/TUTR/CMakeLists.txt b/HDF5Examples/CXX/TUTR/CMakeLists.txt new file mode 100644 index 00000000000..00d6ee6f6f9 --- /dev/null +++ b/HDF5Examples/CXX/TUTR/CMakeLists.txt @@ -0,0 +1,64 @@ +cmake_minimum_required (VERSION 3.18) +project (HDF5Examples_CXX_TUTR CXX) + +#----------------------------------------------------------------------------- +# Define Sources +#----------------------------------------------------------------------------- +include (C_sourcefiles.cmake) + +if (HDF5_VERSION_MAJOR VERSION_GREATER_EQUAL "1.8") + foreach (example_name ${examples}) + add_executable (${EXAMPLE_VARNAME}_cpp_ex_${example_name} ${PROJECT_SOURCE_DIR}/${example_name}.cpp) + target_compile_options(${EXAMPLE_VARNAME}_cpp_ex_${example_name} + PRIVATE + "$<$:-DH5_USE_16_API>" + "$<$:-DH5_USE_18_API>" + "$<$:-DH5_USE_110_API>" + "$<$:-DH5_USE_112_API>" + "$<$:-DH5_USE_114_API>" + "$<$:-DH5_USE_116_API>" + ) + if (H5_HAVE_PARALLEL) + target_include_directories (${EXAMPLE_VARNAME}_cpp_ex_${example_name} PUBLIC ${MPI_C_INCLUDE_DIRS}) + endif () + target_link_libraries (${EXAMPLE_VARNAME}_cpp_ex_${example_name} ${H5EX_HDF5_LINK_LIBS}) + endforeach () +endif () + +if (H5EX_BUILD_TESTING) + macro (ADD_H5_TEST testname) + add_test ( + NAME ${EXAMPLE_VARNAME}_cpp_ex_${testname}-clearall + COMMAND ${CMAKE_COMMAND} + -E remove + ${testname}.h5 + ) + if (HDF5_USING_ANALYSIS_TOOL) + add_test (NAME ${EXAMPLE_VARNAME}_cpp_ex_${testname} COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $) + set_tests_properties (${EXAMPLE_VARNAME}_cpp_ex_${testname} PROPERTIES DEPENDS ${EXAMPLE_VARNAME}_cpp_ex_${testname}-clearall) + else () + add_test ( + NAME ${EXAMPLE_VARNAME}_cpp_ex_${testname} + COMMAND "${CMAKE_COMMAND}" + -D "TEST_EMULATOR=${CMAKE_CROSSCOMPILING_EMULATOR}" + -D "TEST_PROGRAM=$" + -D "TEST_ARGS:STRING=" + -D "TEST_FOLDER=${PROJECT_BINARY_DIR}" + -D "TEST_EXPECT=0" + -D "TEST_SKIP_COMPARE=TRUE" + -D "TEST_OUTPUT=${testname}.out" + -D "TEST_LIBRARY_DIRECTORY=${CMAKE_TEST_LIB_DIRECTORY}" + -P "${H5EX_RESOURCES_DIR}/runTest.cmake" + ) + set_tests_properties (${EXAMPLE_VARNAME}_cpp_ex_${testname} PROPERTIES DEPENDS ${EXAMPLE_VARNAME}_cpp_ex_${testname}-clearall) + endif () + if (last_test) + set_tests_properties (${EXAMPLE_VARNAME}_cpp_ex_${testname} PROPERTIES DEPENDS ${last_test}) + endif () + set (last_test "${EXAMPLE_VARNAME}_cpp_ex_${testname}") + endmacro () + + foreach (example_name ${examples}) + ADD_H5_TEST (${example_name}) + endforeach () +endif () diff --git a/HDF5Examples/CXX/TUTR/C_sourcefiles.cmake b/HDF5Examples/CXX/TUTR/C_sourcefiles.cmake new file mode 100644 index 00000000000..0d8b7b7ffda --- /dev/null +++ b/HDF5Examples/CXX/TUTR/C_sourcefiles.cmake @@ -0,0 +1,14 @@ +#----------------------------------------------------------------------------- +# Define Sources, one file per application +#----------------------------------------------------------------------------- +set (examples + h5tutr_cmprss + h5tutr_crtdat + h5tutr_crtatt + h5tutr_crtgrpar + h5tutr_crtgrp + h5tutr_crtgrpd + h5tutr_extend + h5tutr_rdwt + h5tutr_subset +) diff --git a/HDF5Examples/CXX/TUTR/Makefile.am b/HDF5Examples/CXX/TUTR/Makefile.am new file mode 100644 index 00000000000..b97b5d14cd1 --- /dev/null +++ b/HDF5Examples/CXX/TUTR/Makefile.am @@ -0,0 +1,81 @@ +# +# Copyright by The HDF Group. +# All rights reserved. +# +# This file is part of HDF5. The full HDF5 copyright notice, including +# terms governing use, modification, and redistribution, is contained in +# the COPYING file, which can be found at the root of the source code +# distribution tree, or in https://www.hdfgroup.org/licenses. +# If you do not have access to either file, you may request a copy from +# help@hdfgroup.org. +## +## Makefile.am +## Run automake to generate a Makefile.in from this file. +## +# +# HDF5 Library Examples Makefile(.in) +# + +include $(top_srcdir)/config/commence.am + +INSTALL_SCRIPT_FILES = run-c++-ex.sh + +# These are the programs that 'make all' or 'make prog' will build and +# which 'make check' will run. List them in the order they should be run. +EXAMPLE_PROG=create readdata writedata compound extend_ds chunks h5group \ + h5tutr_cmprss h5tutr_crtatt h5tutr_crtdat h5tutr_crtgrpar \ + h5tutr_crtgrp h5tutr_crtgrpd h5tutr_extend h5tutr_rdwt \ + h5tutr_subset +TEST_SCRIPT=testh5c++.sh +TEST_EXAMPLES_SCRIPT=$(INSTALL_SCRIPT_FILES) + +# These are the example files to be installed +INSTALL_FILES=create.cpp readdata.cpp writedata.cpp compound.cpp \ + extend_ds.cpp chunks.cpp h5group.cpp \ + h5tutr_cmprss.cpp h5tutr_crtatt.cpp h5tutr_crtdat.cpp \ + h5tutr_crtgrpar.cpp h5tutr_crtgrp.cpp h5tutr_crtgrpd.cpp \ + h5tutr_extend.cpp h5tutr_rdwt.cpp h5tutr_subset.cpp + +# Some of the examples depend on files created by running other examples +readdata.chkexe_: create.chkexe_ +chunks.chkexe_: extend_ds.chkexe_ +h5tutr_rdwt.chkexe_: h5tutr_crtdat.chkexe +h5tutrcrtatt.chkexe_: h5tutr_crtdat.chkexe +h5tutr_crtgrpd.chkexe_: h5tutr_crtgrpar.chkexe + +# Tell conclude.am that these are C++ tests. +CXX_API=yes + +# Where to install examples +# Note: no '/' after DESTDIR. Explanation in commence.am +EXAMPLEDIR=${DESTDIR}$(examplesdir)/c++ +EXAMPLETOPDIR=${DESTDIR}$(examplesdir) + +# How to build programs using h5c++ +$(EXTRA_PROG): $(H5CPP) + $(H5CPP) $(H5CCFLAGS) $(CPPFLAGS) -o $@ $(srcdir)/$@.cpp + +# List dependencies for each program. Normally, automake would take +# care of this for us, but if we tell automake about the programs it +# will try to build them with the normal C++ compiler, not h5c++. This is +# an inelegant way of solving the problem, unfortunately. +create: $(srcdir)/create.cpp +readdata: $(srcdir)/readdata.cpp +writedata: $(srcdir)/writedata.cpp +compound: $(srcdir)/compound.cpp +extend_ds: $(srcdir)/extend_ds.cpp +chunks: $(srcdir)/chunks.cpp +h5group: $(srcdir)/h5group.cpp + +h5tutr_cmprss: $(srcdir)/h5tutr_cmprss.cpp +h5tutr_crtatt: $(srcdir)/h5tutr_crtatt.cpp +h5tutr_crtdat: $(srcdir)/h5tutr_crtdat.cpp +h5tutr_crtgrpar: $(srcdir)/h5tutr_crtgrpar.cpp +h5tutr_crtgrp: $(srcdir)/h5tutr_crtgrp.cpp +h5tutr_crtgrpd: $(srcdir)/h5tutr_crtgrpd.cpp +h5tutr_extend: $(srcdir)/h5tutr_extend.cpp +h5tutr_rdwt: $(srcdir)/h5tutr_rdwt.cpp +h5tutr_subset: $(srcdir)/h5tutr_subset.cpp + +include $(top_srcdir)/config/examples.am +include $(top_srcdir)/config/conclude.am diff --git a/c++/examples/h5tutr_cmprss.cpp b/HDF5Examples/CXX/TUTR/h5tutr_cmprss.cpp similarity index 100% rename from c++/examples/h5tutr_cmprss.cpp rename to HDF5Examples/CXX/TUTR/h5tutr_cmprss.cpp diff --git a/c++/examples/h5tutr_crtatt.cpp b/HDF5Examples/CXX/TUTR/h5tutr_crtatt.cpp similarity index 100% rename from c++/examples/h5tutr_crtatt.cpp rename to HDF5Examples/CXX/TUTR/h5tutr_crtatt.cpp diff --git a/c++/examples/h5tutr_crtdat.cpp b/HDF5Examples/CXX/TUTR/h5tutr_crtdat.cpp similarity index 100% rename from c++/examples/h5tutr_crtdat.cpp rename to HDF5Examples/CXX/TUTR/h5tutr_crtdat.cpp diff --git a/c++/examples/h5tutr_crtgrp.cpp b/HDF5Examples/CXX/TUTR/h5tutr_crtgrp.cpp similarity index 100% rename from c++/examples/h5tutr_crtgrp.cpp rename to HDF5Examples/CXX/TUTR/h5tutr_crtgrp.cpp diff --git a/c++/examples/h5tutr_crtgrpar.cpp b/HDF5Examples/CXX/TUTR/h5tutr_crtgrpar.cpp similarity index 100% rename from c++/examples/h5tutr_crtgrpar.cpp rename to HDF5Examples/CXX/TUTR/h5tutr_crtgrpar.cpp diff --git a/c++/examples/h5tutr_crtgrpd.cpp b/HDF5Examples/CXX/TUTR/h5tutr_crtgrpd.cpp similarity index 100% rename from c++/examples/h5tutr_crtgrpd.cpp rename to HDF5Examples/CXX/TUTR/h5tutr_crtgrpd.cpp diff --git a/c++/examples/h5tutr_extend.cpp b/HDF5Examples/CXX/TUTR/h5tutr_extend.cpp similarity index 100% rename from c++/examples/h5tutr_extend.cpp rename to HDF5Examples/CXX/TUTR/h5tutr_extend.cpp diff --git a/c++/examples/h5tutr_rdwt.cpp b/HDF5Examples/CXX/TUTR/h5tutr_rdwt.cpp similarity index 100% rename from c++/examples/h5tutr_rdwt.cpp rename to HDF5Examples/CXX/TUTR/h5tutr_rdwt.cpp diff --git a/c++/examples/h5tutr_subset.cpp b/HDF5Examples/CXX/TUTR/h5tutr_subset.cpp similarity index 100% rename from c++/examples/h5tutr_subset.cpp rename to HDF5Examples/CXX/TUTR/h5tutr_subset.cpp diff --git a/HDF5Examples/CXX/TUTR/testh5c++.sh.in b/HDF5Examples/CXX/TUTR/testh5c++.sh.in new file mode 100644 index 00000000000..f3a973cabc9 --- /dev/null +++ b/HDF5Examples/CXX/TUTR/testh5c++.sh.in @@ -0,0 +1,277 @@ +#! /bin/sh +# +# Copyright by The HDF Group. +# All rights reserved. +# +# This file is part of HDF5. The full HDF5 copyright notice, including +# terms governing use, modification, and redistribution, is contained in +# the COPYING file, which can be found at the root of the source code +# distribution tree, or in https://www.hdfgroup.org/licenses. +# If you do not have access to either file, you may request a copy from +# help@hdfgroup.org. +# +# Tests for the h5c++ compiler tool + +srcdir=@srcdir@ + +# Initializations +TESTNAME=h5c++ +EXIT_SUCCESS=0 +EXIT_FAILURE=1 + +# Where the tool is installed. +prefix="${prefix:-@prefix@}" +AR="@AR@" +RANLIB="@RANLIB@" +H5TOOL="h5c++" # The tool name +H5TOOL_BIN="${prefix}/bin/${H5TOOL}" # The path of the tool binary + +CMP='cmp -s' +DIFF='diff -c' + +nerrors=$EXIT_SUCCESS +verbose=yes + +# setup my machine information. +myos=`uname -s` +myhostnama=`uname -n` + +# Generate some source files and library for tests. +suffix=cpp # source file suffix +hdf5main=${H5TOOL}_hdf5main.$suffix +hdf5main_o=${H5TOOL}_hdf5main.o +appmain=${H5TOOL}_appmain.$suffix +appmain_o=${H5TOOL}_appmain.o +prog1=${H5TOOL}_prog1.$suffix +prog1_o=${H5TOOL}_prog1.o +prog2=${H5TOOL}_prog2.$suffix +prog2_o=${H5TOOL}_prog2.o +applib=libapp${H5TOOL}.a +args=${H5TOOL}_args.$suffix +args_o=${H5TOOL}_args.o + +# short hands +# Caution: if some *.h5 files must be cleaned here, list them by names. +# Don't use the wildcard form of *.h5 as it will wipe out even *.h5 generated +# by other test programs. This will cause a racing condition error when +# parallel make (e.g., gmake -j 4) is used. +temp_SRC="$hdf5main $appmain $prog1 $prog2" +temp_OBJ=`echo $temp_SRC | sed -e "s/\.${suffix}/.o/g"` +temp_FILES="a.out $applib" + +# Generate appmain: +# An application Main that calls hdf5 and application's own functions. +cat > $appmain < + +#include + +#include "H5Cpp.h" + +#ifndef H5_NO_NAMESPACE +using namespace H5; +#endif + +const H5std_string FILE_NAME( "tmpapp.h5" ); +int sub1(void); +int sub2(void); + +int main (void) +{ + sub1(); + sub2(); + H5File file( FILE_NAME, H5F_ACC_TRUNC ); + return 0; +} + +EOF + +# generate prog1 +cat > $prog1 < +#include + +using std::cout; +using std::endl; +int sub1(void) +{ + cout << "in sub1" << endl; + return 0; +} +EOF + +# generate prog2 +cat > $prog2 < +#include + +using std::cout; +using std::endl; +int sub2(void) +{ + cout << "in sub2" << endl; + return 0; +} +EOF + +# Generate HDF5 Main Program: +# An HDF5 sample program that calls hdf5 functions. +cat > $hdf5main < + +#include + +#include "H5Cpp.h" + +#ifndef H5_NO_NAMESPACE +using namespace H5; +#endif + +const H5std_string FILE_NAME( "tmphdf5.h5" ); + +int main (void) +{ + H5File file( FILE_NAME, H5F_ACC_TRUNC ); + return 0; +} +EOF + +# Generate args: +# An application main that test misc command line arguments being passed. +cat > $args < +#include +#include "H5Cpp.h" +#ifndef H5_NO_NAMESPACE +using namespace H5; +#endif + +const H5std_string FILE_NAME( "args.h5" ); + +int main (void) +{ + char c = SGL_QUOTE; // 'H' + char *s = DBL_QUOTE; // "HDF" + int val = MISC; // 42 + + H5File file( FILE_NAME, H5F_ACC_TRUNC ); + return 0; +} +EOF + +# Parse option +# None + +# Print a line-line message left justified in a field of 74 characters +# beginning with the word "Testing". +# +TESTING() { + SPACES=" " + echo "Testing $* $SPACES" | cut -c1-74 | tr -d '\012' +} + + +# Debug printing +# Change : to echo to print the debug statement +DPRINT() { + : $* +} + +# Run a test and print PASS or *FAIL*. If a test fails then increment +# the `nerrors' global variable and (if $verbose is set) display the +# failed output. The actual output is not removed if $HDF5_NOCLEANUP is +# defined. +# +TOOLTEST() { + out=test_$H5TOOL_$$.out + err=test_$H5TOOL_$$.err + + # Run test. + TESTING $H5TOOL $@ + $H5TOOL_BIN $@ > $out 2>&1 + result=$? + if [ $result = 0 ]; then + echo " PASSED" + else + echo "*FAILED*" + nerrors="`expr $nerrors + 1`" + test yes = "$verbose" && \ + ( echo "========== results ==========="; cat $out; + echo "===============================================") |sed 's/^/ /' + fi + + # Clean up output file + if test -z "$HDF5_NOCLEANUP"; then + rm -f $out + fi +} + +# Print a "SKIP" message +SKIP() { + TESTING $H5TOOL $@ + echo " -SKIP-" +} + + +############################################################################## +### T H E T E S T S ### +############################################################################## +# +# HDF5 program that calls HDF5 APIs. +echo "***"Simple Compile and Link in one step. +TOOLTEST $hdf5main +# Application program that calls HDF5 and its own functions. +TOOLTEST $appmain $prog1 $prog2 + +# Compile, then link. +echo "***"Compile and Link in two steps. +TOOLTEST -c $hdf5main +TOOLTEST $hdf5main_o +TOOLTEST -c $appmain $prog1 $prog2 +TOOLTEST $appmain_o $prog1_o $prog2_o + +# Build external library, then link with it. +echo "***"Build external library and link with it. +TOOLTEST -c $prog1 $prog2 +rm -f $applib +$AR cru $applib $prog1_o $prog2_o +$RANLIB $applib +TOOLTEST $appmain $applib +TOOLTEST $appmain_o $applib +# This is peculiar but should work. (See bug ID 729) +TOOLTEST -c $hdf5main +rm -f $applib +$AR cru $applib $hdf5main_o +$RANLIB $applib +# SunOS does not support this. Skip it. +if [ $myos = SunOS ]; then + SKIP -o a.out $applib +else + TOOLTEST -o a.out $applib +fi + +# Just preprocess, no compile, no link. +echo "***"Just preprocess, no compile, no link. +TOOLTEST -E $hdf5main +TOOLTEST -E $appmain $prog1 $prog2 + +# HDF5 program that depends on input args. +echo "***"Simple Compile and Link in one step with user-supplied arguments. +TOOLTEST -DSGL_QUOTE=\'H\' -DDBL_QUOTE=\"HDF\" -DMISC=42 $args + +############################################################################## +# END +############################################################################## + +# Clean up file +if test -z "$HDF5_NOCLEANUP"; then + rm -f $temp_SRC $temp_OBJ $temp_FILES +fi + +if test $nerrors -eq 0 ; then + echo "All $TESTNAME tests passed." + exit $EXIT_SUCCESS +else + echo "$TESTNAME tests failed with $nerrors errors." + exit $EXIT_FAILURE +fi diff --git a/HDF5Examples/FORTRAN/CMakeLists.txt b/HDF5Examples/FORTRAN/CMakeLists.txt index 0f05a0eb08a..c860c877ec0 100644 --- a/HDF5Examples/FORTRAN/CMakeLists.txt +++ b/HDF5Examples/FORTRAN/CMakeLists.txt @@ -1,9 +1,10 @@ -cmake_minimum_required (VERSION 3.12) +cmake_minimum_required (VERSION 3.18) PROJECT (HDF5Examples_F90 Fortran) #----------------------------------------------------------------------------- # Build the Fortran Examples #----------------------------------------------------------------------------- +add_subdirectory (${PROJECT_SOURCE_DIR}/TUTR) add_subdirectory (${PROJECT_SOURCE_DIR}/H5D) add_subdirectory (${PROJECT_SOURCE_DIR}/H5G) add_subdirectory (${PROJECT_SOURCE_DIR}/H5T) diff --git a/HDF5Examples/FORTRAN/H5D/CMakeLists.txt b/HDF5Examples/FORTRAN/H5D/CMakeLists.txt index 3cb0c6e0472..b784df864a2 100644 --- a/HDF5Examples/FORTRAN/H5D/CMakeLists.txt +++ b/HDF5Examples/FORTRAN/H5D/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required (VERSION 3.12) +cmake_minimum_required (VERSION 3.18) project (HDF5Examples_FORTRAN_H5D Fortran) # -------------------------------------------------------------------- @@ -76,9 +76,10 @@ if (HDF5_VERSION_MAJOR VERSION_GREATER_EQUAL "1.10") "$<$:-DH5_USE_116_API>" ) if (H5_HAVE_PARALLEL) - target_include_directories (${EXAMPLE_VARNAME}_f90_${example_name} PUBLIC ${MPI_C_INCLUDE_DIRS}) + target_include_directories (${EXAMPLE_VARNAME}_f90_${example_name} PUBLIC ${MPI_Fortran_INCLUDE_DIRS}) endif () target_link_libraries (${EXAMPLE_VARNAME}_f90_${example_name} ${H5EX_LINK_Fortran_LIBS}) + set_target_properties (${EXAMPLE_VARNAME}_f90_${example_name} PROPERTIES LINKER_LANGUAGE Fortran) if (H5EX_BUILD_TESTING) add_custom_command ( TARGET ${EXAMPLE_VARNAME}_f90_${example_name} @@ -94,7 +95,7 @@ endif () #if (HDF5_VERSION_MAJOR VERSION_GREATER_EQUAL "1.12") # foreach (example_name ${1_12_examples}) # if (H5EX_BUILD_TESTING) -# add_custom_command ( +# add_custom_command ( # TARGET ${EXAMPLE_VARNAME}_f90_${example_name} # POST_BUILD # COMMAND ${CMAKE_COMMAND} @@ -246,6 +247,13 @@ if (H5EX_BUILD_TESTING) if (HDF5_USING_ANALYSIS_TOOL) add_test (NAME ${EXAMPLE_VARNAME}_f90_${testname} COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $) set_tests_properties (${EXAMPLE_VARNAME}_f90_${testname} PROPERTIES DEPENDS ${EXAMPLE_VARNAME}_f90_${testname}-clearall) + add_test ( + NAME ${EXAMPLE_VARNAME}_f90_${testname}-clean + COMMAND ${CMAKE_COMMAND} + -E remove + ${testname}.h5 + ) + set_tests_properties (${EXAMPLE_VARNAME}_f90_${testname}-clean PROPERTIES DEPENDS ${EXAMPLE_VARNAME}_f90_${testname}) else () add_test ( NAME ${EXAMPLE_VARNAME}_f90_${testname} @@ -260,7 +268,10 @@ if (H5EX_BUILD_TESTING) -D "TEST_LIBRARY_DIRECTORY=${CMAKE_TEST_LIB_DIRECTORY}" -P "${H5EX_RESOURCES_DIR}/runTest.cmake" ) - set_tests_properties (${EXAMPLE_VARNAME}_f90_${testname} PROPERTIES DEPENDS ${EXAMPLE_VARNAME}_f90_${testname}-clearall) + if (last_test) + set_tests_properties (${EXAMPLE_VARNAME}_f90_${testname} PROPERTIES DEPENDS ${last_test}) + endif () + set (last_test "${EXAMPLE_VARNAME}_f90_${testname}") if (HDF5_BUILD_TOOLS) add_test ( NAME ${EXAMPLE_VARNAME}_H5DUMP-f90_${testname} @@ -275,8 +286,16 @@ if (H5EX_BUILD_TESTING) -D "TEST_LIBRARY_DIRECTORY=${CMAKE_TEST_LIB_DIRECTORY}" -P "${H5EX_RESOURCES_DIR}/runTest.cmake" ) - set_tests_properties (${EXAMPLE_VARNAME}_H5DUMP-f90_${testname} PROPERTIES DEPENDS ${EXAMPLE_VARNAME}_f90_${testname}) + set_tests_properties (${EXAMPLE_VARNAME}_H5DUMP-f90_${testname} PROPERTIES DEPENDS ${last_test}) + set (last_test "${EXAMPLE_VARNAME}_H5DUMP-f90_${testname}") endif () + add_test ( + NAME ${EXAMPLE_VARNAME}_f90_${testname}-clean + COMMAND ${CMAKE_COMMAND} + -E remove + ${testname}.h5 + ) + set_tests_properties (${EXAMPLE_VARNAME}_f90_${testname}-clean PROPERTIES DEPENDS ${last_test}) endif () endmacro () diff --git a/HDF5Examples/FORTRAN/H5G/CMakeLists.txt b/HDF5Examples/FORTRAN/H5G/CMakeLists.txt index edc4b230171..4b85e4eba37 100644 --- a/HDF5Examples/FORTRAN/H5G/CMakeLists.txt +++ b/HDF5Examples/FORTRAN/H5G/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required (VERSION 3.12) +cmake_minimum_required (VERSION 3.18) project (HDF5Examples_FORTRAN_H5G Fortran) # -------------------------------------------------------------------- @@ -114,7 +114,7 @@ endforeach () # foreach (example_name ${1_16_examples}) # if (H5EX_BUILD_TESTING) # add_custom_command ( -# TARGET ${EXAMPLE_VARNAME}_${example_name} +# TARGET ${EXAMPLE_VARNAME}_f90_${example_name} # POST_BUILD # COMMAND ${CMAKE_COMMAND} # ARGS -E copy_if_different ${PROJECT_SOURCE_DIR}/tfiles/116/${example_name}.tst ${PROJECT_BINARY_DIR}/${example_name}.tst @@ -170,19 +170,19 @@ endif () #endif () if (H5EX_BUILD_TESTING) - set (exfiles - h5ex_g_iterate - h5ex_g_traverse - h5ex_g_visit + set (exfiles + h5ex_g_iterate + h5ex_g_traverse + h5ex_g_visit + ) + foreach (example ${exfiles}) + add_custom_command ( + TARGET ${EXAMPLE_VARNAME}_f90_${example} + POST_BUILD + COMMAND ${CMAKE_COMMAND} + ARGS -E copy_if_different ${PROJECT_SOURCE_DIR}/${example}.h5 ${PROJECT_BINARY_DIR}/${example}.h5 ) - foreach (example ${exfiles}) - add_custom_command ( - TARGET ${EXAMPLE_VARNAME}_f90_${example} - POST_BUILD - COMMAND ${CMAKE_COMMAND} - ARGS -E copy_if_different ${PROJECT_SOURCE_DIR}/${example}.h5 ${PROJECT_BINARY_DIR}/${example}.h5 - ) - endforeach () + endforeach () macro (ADD_DUMP_TEST testname) add_test ( @@ -194,6 +194,13 @@ if (H5EX_BUILD_TESTING) if (HDF5_USING_ANALYSIS_TOOL) add_test (NAME ${EXAMPLE_VARNAME}_f90_${testname} COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $) set_tests_properties (${EXAMPLE_VARNAME}_f90_${testname} PROPERTIES DEPENDS ${EXAMPLE_VARNAME}_f90_${testname}-clearall) + add_test ( + NAME ${EXAMPLE_VARNAME}_f90_${testname}-clean + COMMAND ${CMAKE_COMMAND} + -E remove + ${testname}.h5 + ) + set_tests_properties (${EXAMPLE_VARNAME}_f90_${testname}-clean PROPERTIES DEPENDS ${EXAMPLE_VARNAME}_f90_${testname}) else () add_test ( NAME ${EXAMPLE_VARNAME}_f90_${testname} @@ -208,7 +215,10 @@ if (H5EX_BUILD_TESTING) -D "TEST_LIBRARY_DIRECTORY=${CMAKE_TEST_LIB_DIRECTORY}" -P "${H5EX_RESOURCES_DIR}/runTest.cmake" ) - set_tests_properties (${EXAMPLE_VARNAME}_f90_${testname} PROPERTIES DEPENDS ${EXAMPLE_VARNAME}_f90_${testname}-clearall) + if (last_test) + set_tests_properties (${EXAMPLE_VARNAME}_f90_${testname} PROPERTIES DEPENDS ${last_test}) + endif () + set (last_test "${EXAMPLE_VARNAME}_f90_${testname}") if (HDF5_BUILD_TOOLS) add_test ( NAME ${EXAMPLE_VARNAME}_H5DUMP-f90_${testname} @@ -223,8 +233,16 @@ if (H5EX_BUILD_TESTING) -D "TEST_LIBRARY_DIRECTORY=${CMAKE_TEST_LIB_DIRECTORY}" -P "${H5EX_RESOURCES_DIR}/runTest.cmake" ) - set_tests_properties (${EXAMPLE_VARNAME}_H5DUMP-f90_${testname} PROPERTIES DEPENDS ${EXAMPLE_VARNAME}_f90_${testname}) + set_tests_properties (${EXAMPLE_VARNAME}_H5DUMP-f90_${testname} PROPERTIES DEPENDS ${last_test}) + set (last_test "${EXAMPLE_VARNAME}_H5DUMP-f90_${testname}") endif () + add_test ( + NAME ${EXAMPLE_VARNAME}_f90_${testname}-clean + COMMAND ${CMAKE_COMMAND} + -E remove + ${testname}.h5 + ) + set_tests_properties (${EXAMPLE_VARNAME}_f90_${testname}-clean PROPERTIES DEPENDS ${last_test}) endif () endmacro () @@ -232,6 +250,13 @@ if (H5EX_BUILD_TESTING) if (HDF5_USING_ANALYSIS_TOOL) add_test (NAME ${EXAMPLE_VARNAME}_f90_${testname} COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $) set_tests_properties (${EXAMPLE_VARNAME}_f90_${testname} PROPERTIES DEPENDS ${EXAMPLE_VARNAME}_f90_${testname}-clearall) + add_test ( + NAME ${EXAMPLE_VARNAME}_f90_${testname}-clean + COMMAND ${CMAKE_COMMAND} + -E remove + ${testname}.h5 + ) + set_tests_properties (${EXAMPLE_VARNAME}_f90_${testname}-clean PROPERTIES DEPENDS ${EXAMPLE_VARNAME}_f90_${testname}) else () add_test ( NAME ${EXAMPLE_VARNAME}_f90_${testname} @@ -246,6 +271,10 @@ if (H5EX_BUILD_TESTING) -D "TEST_LIBRARY_DIRECTORY=${CMAKE_TEST_LIB_DIRECTORY}" -P "${H5EX_RESOURCES_DIR}/runTest.cmake" ) + if (last_test) + set_tests_properties (${EXAMPLE_VARNAME}_f90_${testname} PROPERTIES DEPENDS ${last_test}) + endif () + set (last_test "${EXAMPLE_VARNAME}_f90_${testname}") if (HDF5_BUILD_TOOLS) add_test ( NAME ${EXAMPLE_VARNAME}_H5DUMP-f90_${testname} @@ -260,8 +289,16 @@ if (H5EX_BUILD_TESTING) -D "TEST_LIBRARY_DIRECTORY=${CMAKE_TEST_LIB_DIRECTORY}" -P "${H5EX_RESOURCES_DIR}/runTest.cmake" ) - set_tests_properties (${EXAMPLE_VARNAME}_H5DUMP-f90_${testname} PROPERTIES DEPENDS ${EXAMPLE_VARNAME}_f90_${testname}) + set_tests_properties (${EXAMPLE_VARNAME}_H5DUMP-f90_${testname} PROPERTIES DEPENDS ${last_test}) + set (last_test "${EXAMPLE_VARNAME}_H5DUMP-f90_${testname}") endif () + add_test ( + NAME ${EXAMPLE_VARNAME}_f90_${testname}-clean + COMMAND ${CMAKE_COMMAND} + -E remove + ${testname}.h5 + ) + set_tests_properties (${EXAMPLE_VARNAME}_f90_${testname}-clean PROPERTIES DEPENDS ${last_test}) endif () endmacro () @@ -270,12 +307,20 @@ if (H5EX_BUILD_TESTING) NAME ${EXAMPLE_VARNAME}_f90_${testname}-clearall COMMAND ${CMAKE_COMMAND} -E remove + ${testname}.h5 ${testname}1.h5 ${testname}2.h5 ) if (HDF5_USING_ANALYSIS_TOOL) add_test (NAME ${EXAMPLE_VARNAME}_f90_${testname} COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $) set_tests_properties (${EXAMPLE_VARNAME}_f90_${testname} PROPERTIES DEPENDS ${EXAMPLE_VARNAME}_f90_${testname}-clearall) + add_test ( + NAME ${EXAMPLE_VARNAME}_f90_${testname}-clean + COMMAND ${CMAKE_COMMAND} + -E remove + ${testname}.h5 + ) + set_tests_properties (${EXAMPLE_VARNAME}_f90_${testname}-clean PROPERTIES DEPENDS ${EXAMPLE_VARNAME}_f90_${testname}) else () if (${ARGN} STREQUAL "NULL") add_test ( @@ -349,7 +394,6 @@ if (H5EX_BUILD_TESTING) ) if (HDF5_USING_ANALYSIS_TOOL) add_test (NAME ${EXAMPLE_VARNAME}_f90_${testname} COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $) - set_tests_properties (${EXAMPLE_VARNAME}_f90_${testname} PROPERTIES DEPENDS ${EXAMPLE_VARNAME}_f90_${testname}-clearall) else () add_test ( NAME ${EXAMPLE_VARNAME}_f90_${testname} @@ -364,8 +408,15 @@ if (H5EX_BUILD_TESTING) -D "TEST_LIBRARY_DIRECTORY=${CMAKE_TEST_LIB_DIRECTORY}" -P "${H5EX_RESOURCES_DIR}/runTest.cmake" ) - set_tests_properties (${EXAMPLE_VARNAME}_f90_${testname} PROPERTIES DEPENDS ${EXAMPLE_VARNAME}_f90_${testname}-clearall) endif () + set_tests_properties (${EXAMPLE_VARNAME}_f90_${testname} PROPERTIES DEPENDS ${EXAMPLE_VARNAME}_f90_${testname}-clearall) + add_test ( + NAME ${EXAMPLE_VARNAME}_f90_${testname}-clean + COMMAND ${CMAKE_COMMAND} + -E remove + ${testname}.out.tmp + ) + set_tests_properties (${EXAMPLE_VARNAME}_f90_${testname}-clean PROPERTIES DEPENDS ${EXAMPLE_VARNAME}_f90_${testname}) endmacro () ADD_H5_DUMP2_TEST (h5ex_g_compact NULL) diff --git a/HDF5Examples/FORTRAN/H5PAR/CMakeLists.txt b/HDF5Examples/FORTRAN/H5PAR/CMakeLists.txt index a9eee753d5f..c8301c78a5e 100644 --- a/HDF5Examples/FORTRAN/H5PAR/CMakeLists.txt +++ b/HDF5Examples/FORTRAN/H5PAR/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required (VERSION 3.12) +cmake_minimum_required (VERSION 3.18) project (HDF5Examples_FORTRAN_H5PAR Fortran) # -------------------------------------------------------------------- @@ -38,14 +38,11 @@ endforeach () if (H5EX_BUILD_TESTING) macro (ADD_GREP_TEST testname mumprocs) add_test ( - NAME ${EXAMPLE_VARNAME}_f90_${testname}-clearall + NAME MPI_TEST_${EXAMPLE_VARNAME}_f90_${testname}-clearall COMMAND ${CMAKE_COMMAND} -E remove ${testname}.h5 ) - if (last_test) - set_tests_properties (${EXAMPLE_VARNAME}_f90_${testname}-clearall PROPERTIES DEPENDS ${last_test}) - endif () add_test (NAME MPI_TEST_${EXAMPLE_VARNAME}_f90_${testname} COMMAND "${CMAKE_COMMAND}" -D "TEST_PROGRAM=${MPIEXEC_EXECUTABLE};${MPIEXEC_NUMPROC_FLAG};${mumprocs};${MPIEXEC_PREFLAGS};$;${MPIEXEC_POSTFLAGS}" -D "TEST_ARGS:STRING=" @@ -57,8 +54,15 @@ if (H5EX_BUILD_TESTING) -D "TEST_LIBRARY_DIRECTORY=${CMAKE_TEST_LIB_DIRECTORY}" -P "${H5EX_RESOURCES_DIR}/grepTest.cmake" ) - set_tests_properties (MPI_TEST_${EXAMPLE_VARNAME}_f90_${testname} PROPERTIES DEPENDS ${EXAMPLE_VARNAME}_f90_${testname}-clearall) - set (last_test "MPI_TEST_${EXAMPLE_VARNAME}_f90_${testname}") + set_tests_properties (MPI_TEST_${EXAMPLE_VARNAME}_f90_${testname} PROPERTIES DEPENDS MPI_TEST_${EXAMPLE_VARNAME}_f90_${testname}-clearall) + add_test ( + NAME MPI_TEST_${EXAMPLE_VARNAME}_f90_${testname}-clean + COMMAND ${CMAKE_COMMAND} + -E remove + ${testname}.h5 + ) + set_tests_properties (MPI_TEST_${EXAMPLE_VARNAME}_f90_${testname}-clean PROPERTIES DEPENDS MPI_TEST_${EXAMPLE_VARNAME}_f90_${testname}) + set (last_test "MPI_TEST_${EXAMPLE_VARNAME}_f90_${testname}-clean") endmacro () # Ensure that 24 is a multiple of the number of processes. diff --git a/HDF5Examples/FORTRAN/H5T/CMakeLists.txt b/HDF5Examples/FORTRAN/H5T/CMakeLists.txt index 8fa5c57b475..63d4dd78b7b 100644 --- a/HDF5Examples/FORTRAN/H5T/CMakeLists.txt +++ b/HDF5Examples/FORTRAN/H5T/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required (VERSION 3.12) +cmake_minimum_required (VERSION 3.18) project (HDF5Examples_FORTRAN_H5T Fortran) #----------------------------------------------------------------------------- @@ -82,7 +82,7 @@ endforeach () #if (HDF5_VERSION_MAJOR VERSION_GREATER_EQUAL "1.12") # foreach (example_name ${1_12_examples}) # if (H5EX_BUILD_TESTING) -# add_custom_command ( +# add_custom_command ( # TARGET ${EXAMPLE_VARNAME}_f90_${example_name} # POST_BUILD # COMMAND ${CMAKE_COMMAND} @@ -308,6 +308,13 @@ if (H5EX_BUILD_TESTING) if (HDF5_USING_ANALYSIS_TOOL) add_test (NAME ${EXAMPLE_VARNAME}_f90_${testname} COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $) set_tests_properties (${EXAMPLE_VARNAME}_f90_${testname} PROPERTIES DEPENDS ${EXAMPLE_VARNAME}_f90_${testname}-clearall) + add_test ( + NAME ${EXAMPLE_VARNAME}_f90_${testname}-clean + COMMAND ${CMAKE_COMMAND} + -E remove + ${testname}.h5 + ) + set_tests_properties (${EXAMPLE_VARNAME}_f90_${testname}-clean PROPERTIES DEPENDS ${EXAMPLE_VARNAME}_f90_${testname}) else () add_test ( NAME ${EXAMPLE_VARNAME}_f90_${testname} @@ -322,7 +329,10 @@ if (H5EX_BUILD_TESTING) -D "TEST_LIBRARY_DIRECTORY=${CMAKE_TEST_LIB_DIRECTORY}" -P "${H5EX_RESOURCES_DIR}/runTest.cmake" ) - set_tests_properties (${EXAMPLE_VARNAME}_f90_${testname} PROPERTIES DEPENDS ${EXAMPLE_VARNAME}_f90_${testname}-clearall) + if (last_test) + set_tests_properties (${EXAMPLE_VARNAME}_f90_${testname} PROPERTIES DEPENDS ${last_test}) + endif () + set (last_test "${EXAMPLE_VARNAME}_f90_${testname}") if (HDF5_BUILD_TOOLS) add_test ( NAME ${EXAMPLE_VARNAME}_H5DUMP-f90_${testname} @@ -337,8 +347,16 @@ if (H5EX_BUILD_TESTING) -D "TEST_LIBRARY_DIRECTORY=${CMAKE_TEST_LIB_DIRECTORY}" -P "${H5EX_RESOURCES_DIR}/runTest.cmake" ) - set_tests_properties (${EXAMPLE_VARNAME}_H5DUMP-f90_${testname} PROPERTIES DEPENDS ${EXAMPLE_VARNAME}_f90_${testname}) + set_tests_properties (${EXAMPLE_VARNAME}_H5DUMP-f90_${testname} PROPERTIES DEPENDS ${last_test}) + set (last_test "${EXAMPLE_VARNAME}_H5DUMP-f90_${testname}") endif () + add_test ( + NAME ${EXAMPLE_VARNAME}_f90_${testname}-clean + COMMAND ${CMAKE_COMMAND} + -E remove + ${testname}.h5 + ) + set_tests_properties (${EXAMPLE_VARNAME}_f90_${testname}-clean PROPERTIES DEPENDS ${last_test}) endif () endmacro () @@ -351,7 +369,6 @@ if (H5EX_BUILD_TESTING) ) if (HDF5_USING_ANALYSIS_TOOL) add_test (NAME ${EXAMPLE_VARNAME}_f90_${testname} COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $) - set_tests_properties (${EXAMPLE_VARNAME}_f90_${testname} PROPERTIES DEPENDS ${EXAMPLE_VARNAME}_f90_${testname}-clearall) else () add_test ( NAME ${EXAMPLE_VARNAME}_f90_${testname} @@ -366,8 +383,15 @@ if (H5EX_BUILD_TESTING) -D "TEST_LIBRARY_DIRECTORY=${CMAKE_TEST_LIB_DIRECTORY}" -P "${H5EX_RESOURCES_DIR}/runTest.cmake" ) - set_tests_properties (${EXAMPLE_VARNAME}_f90_${testname} PROPERTIES DEPENDS ${EXAMPLE_VARNAME}_f90_${testname}-clearall) endif () + set_tests_properties (${EXAMPLE_VARNAME}_f90_${testname} PROPERTIES DEPENDS ${EXAMPLE_VARNAME}_f90_${testname}-clearall) + add_test ( + NAME ${EXAMPLE_VARNAME}_f90_${testname}-clean + COMMAND ${CMAKE_COMMAND} + -E remove + ${testname}.h5 + ) + set_tests_properties (${EXAMPLE_VARNAME}_f90_${testname}-clean PROPERTIES DEPENDS ${EXAMPLE_VARNAME}_f90_${testname}) endmacro () macro (TEST_EXAMPLE example) diff --git a/HDF5Examples/FORTRAN/TUTR/CMakeLists.txt b/HDF5Examples/FORTRAN/TUTR/CMakeLists.txt new file mode 100644 index 00000000000..4b866d4ec17 --- /dev/null +++ b/HDF5Examples/FORTRAN/TUTR/CMakeLists.txt @@ -0,0 +1,120 @@ +cmake_minimum_required (VERSION 3.18) +project (HDF5Examples_FORTRAN_TUTR Fortran) + +#----------------------------------------------------------------------------- +# Setup include Directories +#----------------------------------------------------------------------------- +set_directory_properties(PROPERTIES INCLUDE_DIRECTORIES + "${CMAKE_Fortran_MODULE_DIRECTORY}${HDF_MOD_EXT};${HDF5_F90_BINARY_DIR};${PROJECT_BINARY_DIR};${CMAKE_LIBRARY_OUTPUT_DIRECTORY}" +) + +#----------------------------------------------------------------------------- +# Define Sources +#----------------------------------------------------------------------------- +include (Fortran_sourcefiles.cmake) + +#if (HDF_ENABLE_F2003) + foreach (example_name ${f03_examples}) + add_executable (${EXAMPLE_VARNAME}_f90_tutr_${example_name} ${PROJECT_SOURCE_DIR}/${example_name}.f90) + target_compile_options(${EXAMPLE_VARNAME}_f90_tutr_${example_name} + PRIVATE + "$<$:-DH5_USE_16_API>" + "$<$:-DH5_USE_18_API>" + "$<$:-DH5_USE_110_API>" + "$<$:-DH5_USE_112_API>" + "$<$:-DH5_USE_114_API>" + "$<$:-DH5_USE_116_API>" + ) + if (H5_HAVE_PARALLEL) + target_include_directories (${EXAMPLE_VARNAME}_f90_tutr_${example_name} PUBLIC ${MPI_Fortran_INCLUDE_DIRS}) + endif () + target_link_libraries (${EXAMPLE_VARNAME}_f90_tutr_${example_name} ${H5EX_LINK_Fortran_LIBS}) + set_target_properties (${EXAMPLE_VARNAME}_f90_tutr_${example_name} PROPERTIES LINKER_LANGUAGE Fortran) + endforeach () +#endif () + +foreach (example_name ${common_examples}) + add_executable (${EXAMPLE_VARNAME}_f90_tutr_${example_name} ${PROJECT_SOURCE_DIR}/${example_name}.f90) + target_compile_options(${EXAMPLE_VARNAME}_f90_tutr_${example_name} + PRIVATE + "$<$:-DH5_USE_16_API>" + "$<$:-DH5_USE_18_API>" + "$<$:-DH5_USE_110_API>" + "$<$:-DH5_USE_112_API>" + "$<$:-DH5_USE_114_API>" + "$<$:-DH5_USE_116_API>" + ) + if (H5_HAVE_PARALLEL) + target_include_directories (${EXAMPLE_VARNAME}_f90_tutr_${example_name} PUBLIC ${MPI_Fortran_INCLUDE_DIRS}) + endif () + target_link_libraries (${EXAMPLE_VARNAME}_f90_tutr_${example_name} ${H5EX_LINK_Fortran_LIBS}) + set_target_properties (${EXAMPLE_VARNAME}_f90_tutr_${example_name} PROPERTIES LINKER_LANGUAGE Fortran) +endforeach () + +if (H5EX_BUILD_TESTING) + set (${EXAMPLE_VARNAME}_f90_tutr_CLEANFILES + compound.h5 + copy1.h5 + copy2.h5 + dsetf.h5 + extend.h5 + FORTRAN.h5 + groupf.h5 + groupsf.h5 + h5_cmprss.h5 + mount1.h5 + mount2.h5 + sdsf.h5 + subset.h5 + SDScompound.h5 + test.h5 + ) + + # Remove any output file left over from previous test run + add_test ( + NAME ${EXAMPLE_VARNAME}_f90_tutr-clear-objects + COMMAND ${CMAKE_COMMAND} -E remove ${${EXAMPLE_VARNAME}_f90_tutr_CLEANFILES} + ) + set_tests_properties (${EXAMPLE_VARNAME}_f90_tutr-clear-objects PROPERTIES + FIXTURES_SETUP clear_${EXAMPLE_VARNAME}_f90_tutr + WORKING_DIRECTORY ${PROJECT_BINARY_DIR} + ) + add_test ( + NAME ${EXAMPLE_VARNAME}_f90_tutr-clean-objects + COMMAND ${CMAKE_COMMAND} -E remove ${${EXAMPLE_VARNAME}_f90_tutr_CLEANFILES} + ) + set_tests_properties (${EXAMPLE_VARNAME}_f90_tutr-clean-objects PROPERTIES + FIXTURES_CLEANUP clear_${EXAMPLE_VARNAME}_f90_tutr + WORKING_DIRECTORY ${PROJECT_BINARY_DIR} + ) + macro (ADD_H5_TEST testname) + if (HDF5_USING_ANALYSIS_TOOL) + add_test (NAME ${EXAMPLE_VARNAME}_f90_tutr_${testname} COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $) + else () + add_test ( + NAME ${EXAMPLE_VARNAME}_f90_tutr_${testname} + COMMAND "${CMAKE_COMMAND}" + -D "TEST_EMULATOR=${CMAKE_CROSSCOMPILING_EMULATOR}" + -D "TEST_PROGRAM=$" + -D "TEST_ARGS:STRING=" + -D "TEST_FOLDER=${PROJECT_BINARY_DIR}" + -D "TEST_EXPECT=0" + -D "TEST_SKIP_COMPARE=TRUE" + -D "TEST_OUTPUT=${testname}.out" + -D "TEST_LIBRARY_DIRECTORY=${CMAKE_TEST_LIB_DIRECTORY}" + -P "${H5EX_RESOURCES_DIR}/runTest.cmake" + ) + endif () + set_tests_properties (${EXAMPLE_VARNAME}_f90_tutr_${testname} PROPERTIES FIXTURES_REQUIRED clear_${EXAMPLE_VARNAME}_f90_tutr) + if (last_test) + set_tests_properties (${EXAMPLE_VARNAME}_f90_tutr_${testname} PROPERTIES DEPENDS ${last_test}) + endif () + set (last_test "${EXAMPLE_VARNAME}_f90_tutr_${testname}") + endmacro () + + #if (HDF_ENABLE_F2003) + foreach (example_name ${f03_examples} ${common_examples}) + ADD_H5_TEST (${example_name}) + endforeach () + #endif () +endif () diff --git a/HDF5Examples/FORTRAN/TUTR/Fortran_sourcefiles.cmake b/HDF5Examples/FORTRAN/TUTR/Fortran_sourcefiles.cmake new file mode 100644 index 00000000000..8027da8149a --- /dev/null +++ b/HDF5Examples/FORTRAN/TUTR/Fortran_sourcefiles.cmake @@ -0,0 +1,27 @@ +#----------------------------------------------------------------------------- +# Define Sources, one file per application +#----------------------------------------------------------------------------- +set (common_examples + h5_cmprss + h5_crtdat + h5_rdwt + h5_crtatt + h5_crtgrp + h5_crtgrpar + h5_crtgrpd + h5_extend + h5_subset + hyperslab + selectele + refobjexample + refregexample + mountexample + compound +) + +set (f03_examples + rwdset_fortran2003 + nested_derived_type + compound_fortran2003 + compound_complex_fortran2003 +) diff --git a/fortran/examples/Makefile.am b/HDF5Examples/FORTRAN/TUTR/Makefile.am similarity index 92% rename from fortran/examples/Makefile.am rename to HDF5Examples/FORTRAN/TUTR/Makefile.am index 9000efc2921..e9a0fac041f 100644 --- a/fortran/examples/Makefile.am +++ b/HDF5Examples/FORTRAN/TUTR/Makefile.am @@ -18,11 +18,6 @@ include $(top_srcdir)/config/commence.am -# Compile parallel fortran examples only if parallel is enabled -if BUILD_PARALLEL_CONDITIONAL - EXAMPLE_PROG_PARA=ph5example -endif - INSTALL_SCRIPT_FILES = run-fortran-ex.sh # These are the programs that 'make all' or 'make tests' will build and @@ -63,13 +58,8 @@ h5_crtatt.chkexe_: h5_rdwt.chkexe_ # Tell automake how to build examples using h5fc # Additional dependencies for the examples are listed below -if BUILD_PARALLEL_CONDITIONAL -$(EXTRA_PROG): $(H5FC_PP) - $(H5FC_PP) $(H5CCFLAGS) -o $@ $(srcdir)/$@.f90; -else $(EXTRA_PROG): $(H5FC) $(H5FC) $(H5CCFLAGS) -o $@ $(srcdir)/$@.f90; -endif # Tell automake how to install examples # Note: no '/' after DESTDIR. Explanation in commence.am @@ -97,7 +87,6 @@ refobjexample: refobjexample.f90 refregexample: refregexample.f90 mountexample: mountexample.f90 compound: compound.f90 -ph5example: ph5example.f90 rwdset_fortran2003: rwdset_fortran2003.f90 nested_derived_type: nested_derived_type.f90 compound_fortran2003: compound_fortran2003.f90 diff --git a/fortran/examples/compound.f90 b/HDF5Examples/FORTRAN/TUTR/compound.f90 similarity index 100% rename from fortran/examples/compound.f90 rename to HDF5Examples/FORTRAN/TUTR/compound.f90 diff --git a/fortran/examples/compound_complex_fortran2003.f90 b/HDF5Examples/FORTRAN/TUTR/compound_complex_fortran2003.f90 similarity index 100% rename from fortran/examples/compound_complex_fortran2003.f90 rename to HDF5Examples/FORTRAN/TUTR/compound_complex_fortran2003.f90 diff --git a/fortran/examples/compound_fortran2003.f90 b/HDF5Examples/FORTRAN/TUTR/compound_fortran2003.f90 similarity index 100% rename from fortran/examples/compound_fortran2003.f90 rename to HDF5Examples/FORTRAN/TUTR/compound_fortran2003.f90 diff --git a/fortran/examples/h5_cmprss.f90 b/HDF5Examples/FORTRAN/TUTR/h5_cmprss.f90 similarity index 100% rename from fortran/examples/h5_cmprss.f90 rename to HDF5Examples/FORTRAN/TUTR/h5_cmprss.f90 diff --git a/fortran/examples/h5_crtatt.f90 b/HDF5Examples/FORTRAN/TUTR/h5_crtatt.f90 similarity index 100% rename from fortran/examples/h5_crtatt.f90 rename to HDF5Examples/FORTRAN/TUTR/h5_crtatt.f90 diff --git a/fortran/examples/h5_crtdat.f90 b/HDF5Examples/FORTRAN/TUTR/h5_crtdat.f90 similarity index 100% rename from fortran/examples/h5_crtdat.f90 rename to HDF5Examples/FORTRAN/TUTR/h5_crtdat.f90 diff --git a/fortran/examples/h5_crtgrp.f90 b/HDF5Examples/FORTRAN/TUTR/h5_crtgrp.f90 similarity index 100% rename from fortran/examples/h5_crtgrp.f90 rename to HDF5Examples/FORTRAN/TUTR/h5_crtgrp.f90 diff --git a/fortran/examples/h5_crtgrpar.f90 b/HDF5Examples/FORTRAN/TUTR/h5_crtgrpar.f90 similarity index 100% rename from fortran/examples/h5_crtgrpar.f90 rename to HDF5Examples/FORTRAN/TUTR/h5_crtgrpar.f90 diff --git a/fortran/examples/h5_crtgrpd.f90 b/HDF5Examples/FORTRAN/TUTR/h5_crtgrpd.f90 similarity index 100% rename from fortran/examples/h5_crtgrpd.f90 rename to HDF5Examples/FORTRAN/TUTR/h5_crtgrpd.f90 diff --git a/fortran/examples/h5_extend.f90 b/HDF5Examples/FORTRAN/TUTR/h5_extend.f90 similarity index 100% rename from fortran/examples/h5_extend.f90 rename to HDF5Examples/FORTRAN/TUTR/h5_extend.f90 diff --git a/fortran/examples/h5_rdwt.f90 b/HDF5Examples/FORTRAN/TUTR/h5_rdwt.f90 similarity index 100% rename from fortran/examples/h5_rdwt.f90 rename to HDF5Examples/FORTRAN/TUTR/h5_rdwt.f90 diff --git a/fortran/examples/h5_subset.f90 b/HDF5Examples/FORTRAN/TUTR/h5_subset.f90 similarity index 100% rename from fortran/examples/h5_subset.f90 rename to HDF5Examples/FORTRAN/TUTR/h5_subset.f90 diff --git a/fortran/examples/hyperslab.f90 b/HDF5Examples/FORTRAN/TUTR/hyperslab.f90 similarity index 100% rename from fortran/examples/hyperslab.f90 rename to HDF5Examples/FORTRAN/TUTR/hyperslab.f90 diff --git a/fortran/examples/mountexample.f90 b/HDF5Examples/FORTRAN/TUTR/mountexample.f90 similarity index 100% rename from fortran/examples/mountexample.f90 rename to HDF5Examples/FORTRAN/TUTR/mountexample.f90 diff --git a/fortran/examples/nested_derived_type.f90 b/HDF5Examples/FORTRAN/TUTR/nested_derived_type.f90 similarity index 100% rename from fortran/examples/nested_derived_type.f90 rename to HDF5Examples/FORTRAN/TUTR/nested_derived_type.f90 diff --git a/fortran/examples/refobjexample.f90 b/HDF5Examples/FORTRAN/TUTR/refobjexample.f90 similarity index 100% rename from fortran/examples/refobjexample.f90 rename to HDF5Examples/FORTRAN/TUTR/refobjexample.f90 diff --git a/fortran/examples/refregexample.f90 b/HDF5Examples/FORTRAN/TUTR/refregexample.f90 similarity index 100% rename from fortran/examples/refregexample.f90 rename to HDF5Examples/FORTRAN/TUTR/refregexample.f90 diff --git a/fortran/examples/run-fortran-ex.sh.in b/HDF5Examples/FORTRAN/TUTR/run-fortran-ex.sh.in similarity index 100% rename from fortran/examples/run-fortran-ex.sh.in rename to HDF5Examples/FORTRAN/TUTR/run-fortran-ex.sh.in diff --git a/fortran/examples/rwdset_fortran2003.f90 b/HDF5Examples/FORTRAN/TUTR/rwdset_fortran2003.f90 similarity index 100% rename from fortran/examples/rwdset_fortran2003.f90 rename to HDF5Examples/FORTRAN/TUTR/rwdset_fortran2003.f90 diff --git a/fortran/examples/selectele.f90 b/HDF5Examples/FORTRAN/TUTR/selectele.f90 similarity index 100% rename from fortran/examples/selectele.f90 rename to HDF5Examples/FORTRAN/TUTR/selectele.f90 diff --git a/fortran/examples/testh5fc.sh.in b/HDF5Examples/FORTRAN/TUTR/testh5fc.sh.in similarity index 100% rename from fortran/examples/testh5fc.sh.in rename to HDF5Examples/FORTRAN/TUTR/testh5fc.sh.in diff --git a/HDF5Examples/JAVA/CMakeLists.txt b/HDF5Examples/JAVA/CMakeLists.txt index 080e50550d9..ddcb13ec586 100644 --- a/HDF5Examples/JAVA/CMakeLists.txt +++ b/HDF5Examples/JAVA/CMakeLists.txt @@ -8,4 +8,4 @@ set_directory_properties(PROPERTIES INCLUDE_DIRECTORIES add_subdirectory (H5D) add_subdirectory (H5T) add_subdirectory (H5G) -add_subdirectory (H5J) +add_subdirectory (TUTR) diff --git a/HDF5Examples/JAVA/H5D/CMakeLists.txt b/HDF5Examples/JAVA/H5D/CMakeLists.txt index d5b3b85ad78..a1991090bc4 100644 --- a/HDF5Examples/JAVA/H5D/CMakeLists.txt +++ b/HDF5Examples/JAVA/H5D/CMakeLists.txt @@ -76,8 +76,8 @@ if (H5EX_BUILD_TESTING) COMMAND ${CMAKE_COMMAND} -E remove ${PROJECT_BINARY_DIR}/${example_name}.h5 - ${example_name}.out - ${example_name}.out.err + ${PROJECT_BINARY_DIR}/${example_name}.out + ${PROJECT_BINARY_DIR}/${example_name}.out.err ) if (NOT "${last_test}" STREQUAL "") set_tests_properties (${EXAMPLE_VARNAME}_jnative-h5-${example_name}-clearall-objects PROPERTIES DEPENDS ${last_test}) @@ -92,6 +92,15 @@ if (H5EX_BUILD_TESTING) set_tests_properties (${EXAMPLE_VARNAME}_jnative-h5-${example_name}-copy-objects PROPERTIES DEPENDS ${EXAMPLE_VARNAME}_jnative-h5-${example_name}-clearall-objects) set (last_test "${EXAMPLE_VARNAME}_jnative-h5-${example_name}-copy-objects") ADD_H5_TEST (${example_name} 0) + add_test ( + NAME ${EXAMPLE_VARNAME}_jnative-h5-${example_name}-clean-objects + COMMAND ${CMAKE_COMMAND} + -E remove + ${PROJECT_BINARY_DIR}/${example_name}.h5 + ${PROJECT_BINARY_DIR}/${example_name}.out + ${PROJECT_BINARY_DIR}/${example_name}.out.err + ) + set_tests_properties (${EXAMPLE_VARNAME}_jnative-h5-${example_name}-clean-objects PROPERTIES DEPENDS ${last_test}) endforeach () endif () diff --git a/HDF5Examples/JAVA/H5G/CMakeLists.txt b/HDF5Examples/JAVA/H5G/CMakeLists.txt index ac35a3a214d..3dcc75d70ee 100644 --- a/HDF5Examples/JAVA/H5G/CMakeLists.txt +++ b/HDF5Examples/JAVA/H5G/CMakeLists.txt @@ -76,8 +76,8 @@ if (H5EX_BUILD_TESTING) COMMAND ${CMAKE_COMMAND} -E remove ${PROJECT_BINARY_DIR}/${example_name}.h5 - ${example_name}.out - ${example_name}.out.err + ${PROJECT_BINARY_DIR}/${example_name}.out + ${PROJECT_BINARY_DIR}/${example_name}.out.err ) if (NOT "${last_test}" STREQUAL "") set_tests_properties (${EXAMPLE_VARNAME}_jnative-h5-${example_name}-clearall-objects PROPERTIES DEPENDS ${last_test}) @@ -92,6 +92,15 @@ if (H5EX_BUILD_TESTING) set_tests_properties (${EXAMPLE_VARNAME}_jnative-h5-${example_name}-copy-objects PROPERTIES DEPENDS ${EXAMPLE_VARNAME}_jnative-h5-${example_name}-clearall-objects) set (last_test "${EXAMPLE_VARNAME}_jnative-h5-${example_name}-copy-objects") ADD_H5_TEST (${example_name} 0) + add_test ( + NAME ${EXAMPLE_VARNAME}_jnative-h5-${example_name}-clean-objects + COMMAND ${CMAKE_COMMAND} + -E remove + ${PROJECT_BINARY_DIR}/${example_name}.h5 + ${PROJECT_BINARY_DIR}/${example_name}.out + ${PROJECT_BINARY_DIR}/${example_name}.out.err + ) + set_tests_properties (${EXAMPLE_VARNAME}_jnative-h5-${example_name}-clean-objects PROPERTIES DEPENDS ${last_test}) endforeach () endif () diff --git a/HDF5Examples/JAVA/H5T/CMakeLists.txt b/HDF5Examples/JAVA/H5T/CMakeLists.txt index d8c8220e098..aa329a8d7a0 100644 --- a/HDF5Examples/JAVA/H5T/CMakeLists.txt +++ b/HDF5Examples/JAVA/H5T/CMakeLists.txt @@ -76,8 +76,8 @@ if (H5EX_BUILD_TESTING) COMMAND ${CMAKE_COMMAND} -E remove ${PROJECT_BINARY_DIR}/${example_name}.h5 - ${example_name}.out - ${example_name}.out.err + ${PROJECT_BINARY_DIR}/${example_name}.out + ${PROJECT_BINARY_DIR}/${example_name}.out.err ) if (NOT "${last_test}" STREQUAL "") set_tests_properties (${EXAMPLE_VARNAME}_jnative-h5-${example_name}-clearall-objects PROPERTIES DEPENDS ${last_test}) @@ -92,6 +92,15 @@ if (H5EX_BUILD_TESTING) set_tests_properties (${EXAMPLE_VARNAME}_jnative-h5-${example_name}-copy-objects PROPERTIES DEPENDS ${EXAMPLE_VARNAME}_jnative-h5-${example_name}-clearall-objects) set (last_test "${EXAMPLE_VARNAME}_jnative-h5-${example_name}-copy-objects") ADD_H5_TEST (${example_name} 0) + add_test ( + NAME ${EXAMPLE_VARNAME}_jnative-h5-${example_name}-clean-objects + COMMAND ${CMAKE_COMMAND} + -E remove + ${PROJECT_BINARY_DIR}/${example_name}.h5 + ${PROJECT_BINARY_DIR}/${example_name}.out + ${PROJECT_BINARY_DIR}/${example_name}.out.err + ) + set_tests_properties (${EXAMPLE_VARNAME}_jnative-h5-${example_name}-clean-objects PROPERTIES DEPENDS ${last_test}) endforeach () endif () diff --git a/HDF5Examples/JAVA/Makefile.am b/HDF5Examples/JAVA/Makefile.am index f34394d1fe5..691c81ca621 100644 --- a/HDF5Examples/JAVA/Makefile.am +++ b/HDF5Examples/JAVA/Makefile.am @@ -23,6 +23,6 @@ include $(top_srcdir)/config/commence.am ## Only recurse into subdirectories if the Java (JNI) interface is enabled. - SUBDIRS=H5J H5G H5D H5T + SUBDIRS=TUTR H5G H5D H5T include $(top_srcdir)/config/conclude.am diff --git a/HDF5Examples/JAVA/H5J/110/HDF5FileStructure.java b/HDF5Examples/JAVA/TUTR/110/HDF5FileStructure.java similarity index 100% rename from HDF5Examples/JAVA/H5J/110/HDF5FileStructure.java rename to HDF5Examples/JAVA/TUTR/110/HDF5FileStructure.java diff --git a/HDF5Examples/JAVA/H5J/CMakeLists.txt b/HDF5Examples/JAVA/TUTR/CMakeLists.txt similarity index 86% rename from HDF5Examples/JAVA/H5J/CMakeLists.txt rename to HDF5Examples/JAVA/TUTR/CMakeLists.txt index 6d155652db1..b50397044ed 100644 --- a/HDF5Examples/JAVA/H5J/CMakeLists.txt +++ b/HDF5Examples/JAVA/TUTR/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required (VERSION 3.18) -project (HDF5Examples_JAVA_INTRO Java) +project (HDF5Examples_JAVA_TUTR Java) set (CMAKE_VERBOSE_MAKEFILE 1) @@ -75,9 +75,9 @@ if (H5EX_BUILD_TESTING) NAME ${EXAMPLE_VARNAME}_jnative-h5-${example_name}-clearall-objects COMMAND ${CMAKE_COMMAND} -E remove - ${HDFJAVA_EXAMPLES_INTRO_BINARY_DIR}/${example_name}.h5 - ${example_name}.out - ${example_name}.out.err + ${PROJECT_BINARY_DIR}/${example_name}.h5 + ${PROJECT_BINARY_DIR}/${example_name}.out + ${PROJECT_BINARY_DIR}/${example_name}.out.err ) if (NOT "${last_test}" STREQUAL "") set_tests_properties (${EXAMPLE_VARNAME}_jnative-h5-${example_name}-clearall-objects PROPERTIES DEPENDS ${last_test}) @@ -92,6 +92,15 @@ if (H5EX_BUILD_TESTING) set_tests_properties (${EXAMPLE_VARNAME}_jnative-h5-${example_name}-copy-objects PROPERTIES DEPENDS ${EXAMPLE_VARNAME}_jnative-h5-${example_name}-clearall-objects) set (last_test "${EXAMPLE_VARNAME}_jnative-h5-${example_name}-copy-objects") ADD_H5_TEST (${example_name} 0) + add_test ( + NAME ${EXAMPLE_VARNAME}_jnative-h5-${example_name}-clean + COMMAND ${CMAKE_COMMAND} + -E remove + ${PROJECT_BINARY_DIR}/${example_name}.h5 + ${PROJECT_BINARY_DIR}/${example_name}.out + ${PROJECT_BINARY_DIR}/${example_name}.out.err + ) + set_tests_properties (${EXAMPLE_VARNAME}_jnative-h5-${example_name}-clean PROPERTIES DEPENDS ${last_test}) endforeach () endif () diff --git a/HDF5Examples/JAVA/H5J/H5_CreateGroupAbsoluteRelative.java b/HDF5Examples/JAVA/TUTR/H5_CreateGroupAbsoluteRelative.java similarity index 100% rename from HDF5Examples/JAVA/H5J/H5_CreateGroupAbsoluteRelative.java rename to HDF5Examples/JAVA/TUTR/H5_CreateGroupAbsoluteRelative.java diff --git a/HDF5Examples/JAVA/H5J/HDF5AttributeCreate.java b/HDF5Examples/JAVA/TUTR/HDF5AttributeCreate.java similarity index 100% rename from HDF5Examples/JAVA/H5J/HDF5AttributeCreate.java rename to HDF5Examples/JAVA/TUTR/HDF5AttributeCreate.java diff --git a/HDF5Examples/JAVA/H5J/HDF5DatasetCreate.java b/HDF5Examples/JAVA/TUTR/HDF5DatasetCreate.java similarity index 100% rename from HDF5Examples/JAVA/H5J/HDF5DatasetCreate.java rename to HDF5Examples/JAVA/TUTR/HDF5DatasetCreate.java diff --git a/HDF5Examples/JAVA/H5J/HDF5DatasetRead.java b/HDF5Examples/JAVA/TUTR/HDF5DatasetRead.java similarity index 100% rename from HDF5Examples/JAVA/H5J/HDF5DatasetRead.java rename to HDF5Examples/JAVA/TUTR/HDF5DatasetRead.java diff --git a/HDF5Examples/JAVA/H5J/HDF5FileCreate.java b/HDF5Examples/JAVA/TUTR/HDF5FileCreate.java similarity index 100% rename from HDF5Examples/JAVA/H5J/HDF5FileCreate.java rename to HDF5Examples/JAVA/TUTR/HDF5FileCreate.java diff --git a/HDF5Examples/JAVA/H5J/HDF5FileStructure.java b/HDF5Examples/JAVA/TUTR/HDF5FileStructure.java similarity index 100% rename from HDF5Examples/JAVA/H5J/HDF5FileStructure.java rename to HDF5Examples/JAVA/TUTR/HDF5FileStructure.java diff --git a/HDF5Examples/JAVA/H5J/HDF5GroupCreate.java b/HDF5Examples/JAVA/TUTR/HDF5GroupCreate.java similarity index 100% rename from HDF5Examples/JAVA/H5J/HDF5GroupCreate.java rename to HDF5Examples/JAVA/TUTR/HDF5GroupCreate.java diff --git a/HDF5Examples/JAVA/H5J/HDF5GroupDatasetCreate.java b/HDF5Examples/JAVA/TUTR/HDF5GroupDatasetCreate.java similarity index 100% rename from HDF5Examples/JAVA/H5J/HDF5GroupDatasetCreate.java rename to HDF5Examples/JAVA/TUTR/HDF5GroupDatasetCreate.java diff --git a/HDF5Examples/JAVA/H5J/HDF5SubsetSelect.java b/HDF5Examples/JAVA/TUTR/HDF5SubsetSelect.java similarity index 100% rename from HDF5Examples/JAVA/H5J/HDF5SubsetSelect.java rename to HDF5Examples/JAVA/TUTR/HDF5SubsetSelect.java diff --git a/HDF5Examples/JAVA/H5J/Java_sourcefiles.cmake b/HDF5Examples/JAVA/TUTR/Java_sourcefiles.cmake similarity index 100% rename from HDF5Examples/JAVA/H5J/Java_sourcefiles.cmake rename to HDF5Examples/JAVA/TUTR/Java_sourcefiles.cmake diff --git a/HDF5Examples/JAVA/H5J/Makefile.am b/HDF5Examples/JAVA/TUTR/Makefile.am similarity index 100% rename from HDF5Examples/JAVA/H5J/Makefile.am rename to HDF5Examples/JAVA/TUTR/Makefile.am diff --git a/HDF5Examples/JAVA/H5J/runExample.sh.in b/HDF5Examples/JAVA/TUTR/runExample.sh.in similarity index 100% rename from HDF5Examples/JAVA/H5J/runExample.sh.in rename to HDF5Examples/JAVA/TUTR/runExample.sh.in diff --git a/HDF5Examples/JAVA/H5J/tfiles/110/HDF5AttributeCreate.txt b/HDF5Examples/JAVA/TUTR/tfiles/110/HDF5AttributeCreate.txt similarity index 100% rename from HDF5Examples/JAVA/H5J/tfiles/110/HDF5AttributeCreate.txt rename to HDF5Examples/JAVA/TUTR/tfiles/110/HDF5AttributeCreate.txt diff --git a/HDF5Examples/JAVA/H5J/tfiles/110/HDF5DatasetCreate.txt b/HDF5Examples/JAVA/TUTR/tfiles/110/HDF5DatasetCreate.txt similarity index 100% rename from HDF5Examples/JAVA/H5J/tfiles/110/HDF5DatasetCreate.txt rename to HDF5Examples/JAVA/TUTR/tfiles/110/HDF5DatasetCreate.txt diff --git a/HDF5Examples/JAVA/H5J/tfiles/110/HDF5DatasetRead.txt b/HDF5Examples/JAVA/TUTR/tfiles/110/HDF5DatasetRead.txt similarity index 100% rename from HDF5Examples/JAVA/H5J/tfiles/110/HDF5DatasetRead.txt rename to HDF5Examples/JAVA/TUTR/tfiles/110/HDF5DatasetRead.txt diff --git a/HDF5Examples/JAVA/H5J/tfiles/110/HDF5FileCreate.txt b/HDF5Examples/JAVA/TUTR/tfiles/110/HDF5FileCreate.txt similarity index 100% rename from HDF5Examples/JAVA/H5J/tfiles/110/HDF5FileCreate.txt rename to HDF5Examples/JAVA/TUTR/tfiles/110/HDF5FileCreate.txt diff --git a/HDF5Examples/JAVA/H5J/tfiles/110/HDF5FileStructure.txt b/HDF5Examples/JAVA/TUTR/tfiles/110/HDF5FileStructure.txt similarity index 100% rename from HDF5Examples/JAVA/H5J/tfiles/110/HDF5FileStructure.txt rename to HDF5Examples/JAVA/TUTR/tfiles/110/HDF5FileStructure.txt diff --git a/HDF5Examples/JAVA/H5J/tfiles/110/HDF5GroupCreate.txt b/HDF5Examples/JAVA/TUTR/tfiles/110/HDF5GroupCreate.txt similarity index 100% rename from HDF5Examples/JAVA/H5J/tfiles/110/HDF5GroupCreate.txt rename to HDF5Examples/JAVA/TUTR/tfiles/110/HDF5GroupCreate.txt diff --git a/HDF5Examples/JAVA/H5J/tfiles/110/HDF5GroupDatasetCreate.txt b/HDF5Examples/JAVA/TUTR/tfiles/110/HDF5GroupDatasetCreate.txt similarity index 100% rename from HDF5Examples/JAVA/H5J/tfiles/110/HDF5GroupDatasetCreate.txt rename to HDF5Examples/JAVA/TUTR/tfiles/110/HDF5GroupDatasetCreate.txt diff --git a/HDF5Examples/JAVA/H5J/tfiles/110/HDF5SubsetSelect.txt b/HDF5Examples/JAVA/TUTR/tfiles/110/HDF5SubsetSelect.txt similarity index 100% rename from HDF5Examples/JAVA/H5J/tfiles/110/HDF5SubsetSelect.txt rename to HDF5Examples/JAVA/TUTR/tfiles/110/HDF5SubsetSelect.txt diff --git a/HDF5Examples/config/cmake/HDFExampleMacros.cmake b/HDF5Examples/config/cmake/HDFExampleMacros.cmake index 8173562de88..811bd2c7b9c 100644 --- a/HDF5Examples/config/cmake/HDFExampleMacros.cmake +++ b/HDF5Examples/config/cmake/HDFExampleMacros.cmake @@ -120,6 +120,9 @@ macro (HDF5_SUPPORT) if (HDF_BUILD_FORTRAN) set (FIND_HDF_COMPONENTS ${FIND_HDF_COMPONENTS} Fortran) endif () + if (HDF_BUILD_CPP_LIB) + set (FIND_HDF_COMPONENTS ${FIND_HDF_COMPONENTS} CXX) + endif () if (HDF_BUILD_JAVA) set (FIND_HDF_COMPONENTS ${FIND_HDF_COMPONENTS} Java) set (HDF5_Java_FOUND 1) #default setting for 1.10.1 and earlier @@ -141,6 +144,9 @@ macro (HDF5_SUPPORT) if (HDF_BUILD_JAVA) set (FIND_HDF_COMPONENTS ${FIND_HDF_COMPONENTS} Java) endif () + if (HDF_BUILD_CPP_LIB) + set (FIND_HDF_COMPONENTS ${FIND_HDF_COMPONENTS} CXX) + endif () message (STATUS "HDF5 find comps: ${FIND_HDF_COMPONENTS}") find_package (HDF5 NAMES ${SEARCH_PACKAGE_NAME} COMPONENTS ${FIND_HDF_COMPONENTS}) diff --git a/Makefile.am b/Makefile.am index 0f2a2472c8d..4805b91f7ab 100644 --- a/Makefile.am +++ b/Makefile.am @@ -40,10 +40,6 @@ include $(top_srcdir)/config/commence.am # Define subdirectories to build. ## Automake understands that `make distclean' should recurse into ## conditional subdirectories even if `make all' does not. -## We need to list the examples directory in the DIST_SUBDIRS variable -## so that it will be visited by `make distclean' -# Add this directory to SUBDIRS so that examples get built after tools -# but before examples in extra interfaces (c++ and fortran). # Since we're explicitly listing DIST_SUBDIRS, we also need to list # directories that are only conditionally built (so that their Makefiles # are cleaned as well). @@ -89,7 +85,7 @@ endif SUBDIRS = src $(TESTSERIAL_DIR) $(TESTPARALLEL_DIR) bin $(TOOLS_DIR) utils . \ $(CXX_DIR) $(FORTRAN_DIR) $(JAVA_DIR) $(HDF5_HL_DIR) -DIST_SUBDIRS = src test testpar bin tools utils . c++ fortran hl examples java +DIST_SUBDIRS = src test testpar bin tools utils . c++ fortran hl java # Some files generated during configure that should be cleaned DISTCLEANFILES=config/stamp1 config/stamp2 @@ -116,14 +112,6 @@ tests: fi; \ done -# Check-clean also recurses into examples directory -check-clean: - for d in $(SUBDIRS) examples; do \ - if test $$d != .; then \ - (cd $$d && $(MAKE) $(AM_MAKEFLAGS) $@) || exit 1; \ - fi; \ - done - $(RM) -rf prefix-tmp destdir-tmp # Some C++ compilers/linkers will create a directory named ii_files in # the root directory, which should be cleaned. @@ -132,37 +120,15 @@ mostlyclean-local: $(RM) -rf ii_files; \ fi -# 'make install' will now install examples, the same as 'make install-all'. # 'make-install-all' will be redundant but will still work. -install: install-recursive install-examples -uninstall: uninstall-recursive uninstall-examples +install: install-recursive +uninstall: uninstall-recursive -# 'make install-all' also installs examples install-all: @$(MAKE) $(AM_MAKEFLAGS) install uninstall-all: @$(MAKE) $(AM_MAKEFLAGS) uninstall -# Install examples in this directory and recursively -install-examples uninstall-examples: - for d in examples $(HDF5_INTERFACES) $(HL); do \ - (cd $$d && $(MAKE) $(AM_MAKEFLAGS) $@) || exit 1; \ - done - -# Placeholder to remind users that docs are now in a separate repository. -install-doc: - @echo "docs no longer live in this tree. Use install-examples to install examples." - -uninstall-doc: - @echo "docs no longer live in this tree. Use install-examples to install examples." - -# `make check-install' or `make installcheck' checks that examples can -# be successfully built -installcheck-local: - if test -n "${DESTDIR}"; then \ - (cd ${DESTDIR}$(bindir) && pwd && ./h5redeploy -force); \ - fi - @(cd examples && $(MAKE) $(AM_MAKEFLAGS) $@) || exit 1; # check-install is just a synonym for installcheck check-install: installcheck diff --git a/c++/CMakeLists.txt b/c++/CMakeLists.txt index b419c805880..5ce26aa9cf7 100644 --- a/c++/CMakeLists.txt +++ b/c++/CMakeLists.txt @@ -3,13 +3,6 @@ project (HDF5_CPP CXX) add_subdirectory (src) -#----------------------------------------------------------------------------- -# Build the CPP Examples -#----------------------------------------------------------------------------- -if (HDF5_BUILD_EXAMPLES) - add_subdirectory (examples) -endif () - #----------------------------------------------------------------------------- # Build the CPP unit tests #----------------------------------------------------------------------------- diff --git a/c++/Makefile.am b/c++/Makefile.am index c6c94f30a63..ef7c285a5ee 100644 --- a/c++/Makefile.am +++ b/c++/Makefile.am @@ -28,22 +28,6 @@ if BUILD_CXX_CONDITIONAL SUBDIRS=src $(TEST_DIR) endif -DIST_SUBDIRS = src test examples - -# Install examples -install-examples uninstall-examples: - @(cd examples && $(MAKE) $(AM_MAKEFLAGS) $@) || exit 1; - -installcheck-local: - @(cd examples && $(MAKE) $(AM_MAKEFLAGS) $@) || exit 1; - -# Clean examples when check-clean is invoked -check-clean :: - @$(MAKE) $(AM_MAKEFLAGS) build-$@ || exit 1; - @for d in X $(SUBDIRS) examples; do \ - if test $$d != X && test $$d != .; then \ - (set -x; cd $$d && $(MAKE) $(AM_MAKEFLAGS) $@) || exit 1; \ - fi; \ - done +DIST_SUBDIRS = src test include $(top_srcdir)/config/conclude.am diff --git a/c++/examples/CMakeLists.txt b/c++/examples/CMakeLists.txt deleted file mode 100644 index c8c4018f937..00000000000 --- a/c++/examples/CMakeLists.txt +++ /dev/null @@ -1,87 +0,0 @@ -cmake_minimum_required (VERSION 3.18) -project (HDF5_CPP_EXAMPLES CXX) - -# -------------------------------------------------------------------- -# Notes: When creating examples they should be prefixed -# with "cpp_ex_". This allows for easier filtering of the examples. -# -------------------------------------------------------------------- - -#----------------------------------------------------------------------------- -# Define examples -#----------------------------------------------------------------------------- - -set (examples - create - readdata - writedata - compound - extend_ds - chunks - h5group -) - -set (tutr_examples - h5tutr_cmprss - h5tutr_crtdat - h5tutr_crtatt - h5tutr_crtgrpar - h5tutr_crtgrp - h5tutr_crtgrpd - h5tutr_extend - h5tutr_rdwt - h5tutr_subset -) - -foreach (example ${examples}) - add_executable (cpp_ex_${example} ${HDF5_CPP_EXAMPLES_SOURCE_DIR}/${example}.cpp) - target_include_directories (cpp_ex_${example} PRIVATE "${HDF5_SRC_INCLUDE_DIRS};${HDF5_SRC_BINARY_DIR};$<$:${MPI_C_INCLUDE_DIRS}>") - if (NOT BUILD_SHARED_LIBS) - TARGET_C_PROPERTIES (cpp_ex_${example} STATIC) - target_link_libraries (cpp_ex_${example} PRIVATE ${HDF5_CPP_LIB_TARGET} ${HDF5_LIB_TARGET}) - else () - TARGET_C_PROPERTIES (cpp_ex_${example} SHARED) - target_link_libraries (cpp_ex_${example} PRIVATE ${HDF5_CPP_LIBSH_TARGET} ${HDF5_LIBSH_TARGET}) - if (MINGW AND HDF5_MINGW_STATIC_GCC_LIBS) - target_link_options (${HDF5_CPP_LIBSH_TARGET} - PRIVATE -static-libgcc -static-libstdc++ - ) - endif () - endif () - set_target_properties (cpp_ex_${example} PROPERTIES FOLDER examples/cpp) - - #----------------------------------------------------------------------------- - # Add Target to clang-format - #----------------------------------------------------------------------------- - if (HDF5_ENABLE_FORMATTERS) - clang_format (HDF5_CPP_EXAMPLES_${example}_FORMAT cpp_ex_${example}) - endif () -endforeach () - -foreach (example ${tutr_examples}) - add_executable (cpp_ex_${example} ${HDF5_CPP_EXAMPLES_SOURCE_DIR}/${example}.cpp) - target_include_directories (cpp_ex_${example} PRIVATE "${HDF5_SRC_INCLUDE_DIRS};${HDF5_SRC_BINARY_DIR};$<$:${MPI_C_INCLUDE_DIRS}>") - if (NOT BUILD_SHARED_LIBS) - TARGET_C_PROPERTIES (cpp_ex_${example} STATIC) - target_link_libraries (cpp_ex_${example} PRIVATE ${HDF5_CPP_LIB_TARGET} ${HDF5_LIB_TARGET}) - else () - TARGET_C_PROPERTIES (cpp_ex_${example} SHARED) - target_link_libraries (cpp_ex_${example} PRIVATE ${HDF5_CPP_LIBSH_TARGET} ${HDF5_LIBSH_TARGET}) - if (MINGW AND HDF5_MINGW_STATIC_GCC_LIBS) - target_link_options (${HDF5_CPP_LIBSH_TARGET} - PRIVATE -static-libgcc -static-libstdc++ - ) - endif () - endif () - set_target_properties (cpp_ex_${example} PROPERTIES FOLDER examples/cpp) - - #----------------------------------------------------------------------------- - # Add Target to clang-format - #----------------------------------------------------------------------------- - if (HDF5_ENABLE_FORMATTERS) - clang_format (HDF5_CPP_EXAMPLES_${example}_FORMAT cpp_ex_${example}) - endif () -endforeach () - -if (BUILD_TESTING AND HDF5_TEST_CPP AND HDF5_TEST_EXAMPLES AND HDF5_TEST_SERIAL) - include (CMakeTests.cmake) -endif () diff --git a/c++/examples/CMakeTests.cmake b/c++/examples/CMakeTests.cmake deleted file mode 100644 index c74ffb58930..00000000000 --- a/c++/examples/CMakeTests.cmake +++ /dev/null @@ -1,122 +0,0 @@ -# -# Copyright by The HDF Group. -# All rights reserved. -# -# This file is part of HDF5. The full HDF5 copyright notice, including -# terms governing use, modification, and redistribution, is contained in -# the COPYING file, which can be found at the root of the source code -# distribution tree, or in https://www.hdfgroup.org/licenses. -# If you do not have access to either file, you may request a copy from -# help@hdfgroup.org. -# - -############################################################################## -############################################################################## -### T E S T I N G ### -############################################################################## -############################################################################## - # Remove any output file left over from previous test run -set (CPP_EX_CLEANFILES - Group.h5 - SDS.h5 - SDScompound.h5 - SDSextendible.h5 - Select.h5 -) -add_test ( - NAME CPP_ex-clear-objects - COMMAND ${CMAKE_COMMAND} - -E remove ${CPP_EX_CLEANFILES} -) -set_tests_properties (CPP_ex-clear-objects PROPERTIES - FIXTURES_SETUP clear_cppex - WORKING_DIRECTORY ${PROJECT_BINARY_DIR} -) -add_test ( - NAME CPP_ex-clean-objects - COMMAND ${CMAKE_COMMAND} - -E remove ${CPP_EX_CLEANFILES} -) -set_tests_properties (CPP_ex-clean-objects PROPERTIES - FIXTURES_CLEANUP clear_cppex - WORKING_DIRECTORY ${PROJECT_BINARY_DIR} -) - -foreach (example ${examples}) - if (HDF5_USING_ANALYSIS_TOOL) - add_test (NAME CPP_ex_${example} COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $) - else () - add_test (NAME CPP_ex_${example} COMMAND "${CMAKE_COMMAND}" - -D "TEST_EMULATOR=${CMAKE_CROSSCOMPILING_EMULATOR}" - -D "TEST_PROGRAM=$" - -D "TEST_ARGS:STRING=" - -D "TEST_EXPECT=0" - -D "TEST_SKIP_COMPARE=TRUE" - -D "TEST_OUTPUT=cpp_ex_${example}.txt" - #-D "TEST_REFERENCE=cpp_ex_${example}.out" - -D "TEST_FOLDER=${PROJECT_BINARY_DIR}" - -P "${HDF_RESOURCES_DIR}/runTest.cmake" - ) - endif () - set_tests_properties (CPP_ex_${example} PROPERTIES FIXTURES_REQUIRED clear_cppex) - if (last_test) - set_tests_properties (CPP_ex_${example} PROPERTIES DEPENDS ${last_test}) - endif () - set (last_test "CPP_ex_${example}") -endforeach () -#the following dependencies are handled by the order of the files -# SET_TESTS_PROPERTIES(CPP_ex_readdata PROPERTIES DEPENDS CPP_ex_create) -# SET_TESTS_PROPERTIES(CPP_ex_chunks PROPERTIES DEPENDS CPP_ex_extend_ds) -set (CPP_EX_TUTR_CLEANFILES - h5tutr_cmprss.h5 - h5tutr_dset.h5 - h5tutr_extend.h5 - h5tutr_group.h5 - h5tutr_groups.h5 - h5tutr_subset.h5 -) -add_test ( - NAME CPP_ex_tutr-clear-objects - COMMAND ${CMAKE_COMMAND} - -E remove ${CPP_EX_TUTR_CLEANFILES} -) -set_tests_properties (CPP_ex_tutr-clear-objects PROPERTIES - FIXTURES_SETUP clear_cppex_tutr - WORKING_DIRECTORY ${PROJECT_BINARY_DIR} -) -add_test ( - NAME CPP_ex_tutr-clean-objects - COMMAND ${CMAKE_COMMAND} - -E remove ${CPP_EX_TUTR_CLEANFILES} -) -set_tests_properties (CPP_ex_tutr-clean-objects PROPERTIES - FIXTURES_CLEANUP clear_cppex_tutr - WORKING_DIRECTORY ${PROJECT_BINARY_DIR} -) - -foreach (example ${tutr_examples}) - if (HDF5_USING_ANALYSIS_TOOL) - add_test (NAME CPP_ex_${example} COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $) - else () - add_test (NAME CPP_ex_${example} COMMAND "${CMAKE_COMMAND}" - -D "TEST_EMULATOR=${CMAKE_CROSSCOMPILING_EMULATOR}" - -D "TEST_PROGRAM=$" - -D "TEST_ARGS:STRING=" - -D "TEST_EXPECT=0" - -D "TEST_SKIP_COMPARE=TRUE" - -D "TEST_OUTPUT=cpp_ex_${example}.txt" - #-D "TEST_REFERENCE=cpp_ex_${example}.out" - -D "TEST_FOLDER=${PROJECT_BINARY_DIR}" - -P "${HDF_RESOURCES_DIR}/runTest.cmake" - ) - endif () - set_tests_properties (CPP_ex_${example} PROPERTIES FIXTURES_REQUIRED clear_cppex_tutr) - if (last_test) - set_tests_properties (CPP_ex_${example} PROPERTIES DEPENDS ${last_test}) - endif () - set (last_test "CPP_ex_${example}") -endforeach () -#the following dependencies are handled by the order of the files -# SET_TESTS_PROPERTIES(CPP_ex_h5tutr_crtatt PROPERTIES DEPENDS CPP_ex_h5tutr_crtdat) -# SET_TESTS_PROPERTIES(CPP_ex_h5tutr_rdwt PROPERTIES DEPENDS CPP_ex_h5tutr_crtdat) -# SET_TESTS_PROPERTIES(CPP_ex_h5tutr_crtgrpd PROPERTIES DEPENDS CPP_ex_h5tutr_crtgrpar) diff --git a/c++/examples/run-c++-ex.sh.in b/c++/examples/run-c++-ex.sh.in deleted file mode 100644 index 45937797764..00000000000 --- a/c++/examples/run-c++-ex.sh.in +++ /dev/null @@ -1,145 +0,0 @@ -#! /bin/sh -# -# Copyright by The HDF Group. -# All rights reserved. -# -# This file is part of HDF5. The full HDF5 copyright notice, including -# terms governing use, modification, and redistribution, is contained in -# the COPYING file, which can be found at the root of the source code -# distribution tree, or in https://www.hdfgroup.org/licenses. -# If you do not have access to either file, you may request a copy from -# help@hdfgroup.org. - -# -# This file: run-c++-ex.sh -# Written by: Larry Knox -# Date: May 11, 2010 -# -# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # -# # -# This script will compile and run the c++ examples from source files # -# installed in @examplesdir@/c++ using h5c++. The # -# order for running programs with RunTest in the MAIN section below is taken # -# from the Makefile. The order is important since some of the test programs # -# use data files created by earlier test programs. Any future additions should # -# be placed accordingly. # -# # -# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # - -# Initializations -EXIT_SUCCESS=0 -EXIT_FAILURE=1 - -# -# Try to derive the path to the installation $prefix established -# by ./configure relative to the examples directory established by -# ./configure. If successful, set `prefix_relto_examplesdir` to the -# relative path. Otherwise, set `prefix_relto_examplesdir` to the -# absolute installation $prefix. -# -# This script uses the value of `prefix` in the user's environment, if -# it is set, below. The content of $() is evaluated in a sub-shell, so -# if `prefix` is set in the user's environment, the shell statements in -# $() won't clobber it. -# -prefix_relto_examplesdir=$( -prefix=@prefix@ -examplesdir=@examplesdir@ -if [ ${examplesdir##${prefix}/} != ${examplesdir} ]; then - echo $(echo ${examplesdir##${prefix}/} | \ - sed 's,[^/][^/]*,..,g') -else - echo $prefix -fi -) - -# Where the tool is installed. -# default is relative path to installed location of the tools -prefix="${prefix:-../${prefix_relto_examplesdir}}" -AR="@AR@" -RANLIB="@RANLIB@" -H5TOOL="h5c++" # The tool name -H5TOOL_BIN="${prefix}/bin/${H5TOOL}" # The path of the tool binary - -#### Run test #### -RunTest() -{ - TEST_EXEC=$1 - Test=$1".cpp" - - echo - echo "################# $1 #################" - ${H5TOOL_BIN} -o $TEST_EXEC $Test - if [ $? -ne 0 ] - then - echo "messed up compiling $Test" - exit 1 - fi - ./$TEST_EXEC -} - - - -################## MAIN ################## - -# Run tests -if [ $? -eq 0 ] -then - echo "*************************************************" - echo "** Run C++ API Examples **" - echo "** **" - echo "*************************************************" - if (RunTest create &&\ - rm create &&\ - RunTest readdata &&\ - rm readdata &&\ - RunTest writedata &&\ - rm writedata &&\ - RunTest compound &&\ - rm compound &&\ - RunTest extend_ds &&\ - rm extend_ds &&\ - RunTest chunks &&\ - rm chunks &&\ - RunTest h5group &&\ - rm h5group); then - EXIT_VALUE=${EXIT_SUCCESS} - else - EXIT_VALUE=${EXIT_FAILURE} - fi - echo - echo "***************************************************" - echo "** Run Tutorial Examples **" - echo "** **" - echo "***************************************************" - if (RunTest h5tutr_crtdat &&\ - rm h5tutr_crtdat &&\ - RunTest h5tutr_rdwt &&\ - rm h5tutr_rdwt &&\ - RunTest h5tutr_crtatt &&\ - rm h5tutr_crtatt &&\ - RunTest h5tutr_crtgrp &&\ - rm h5tutr_crtgrp &&\ - RunTest h5tutr_crtgrpar &&\ - rm h5tutr_crtgrpar &&\ - RunTest h5tutr_crtgrpd &&\ - rm h5tutr_crtgrpd &&\ - RunTest h5tutr_extend &&\ - rm h5tutr_extend &&\ - RunTest h5tutr_subset &&\ - rm h5tutr_subset &&\ - RunTest h5tutr_cmprss &&\ - rm h5tutr_cmprss ); then - EXIT_VALUE=${EXIT_SUCCESS} - else - EXIT_VALUE=${EXIT_FAILURE} - fi -fi - -# Cleanup -rm *.o -rm *.h5 -echo - -exit $EXIT_VALUE - diff --git a/config/cmake/HDF5ExampleCache.cmake b/config/cmake/HDF5ExampleCache.cmake index 9b526ee9f49..7d5b7be0c40 100644 --- a/config/cmake/HDF5ExampleCache.cmake +++ b/config/cmake/HDF5ExampleCache.cmake @@ -48,6 +48,9 @@ if (NOT BUILD_SHARED_LIBS AND BUILD_STATIC_LIBS) set (H5EX_HDF5_LINK_LIBS ${H5EX_HDF5_LINK_LIBS} ${HDF5_F90_LIB_TARGET}) set (HDF_MOD_EXT "/static" CACHE STRING "Use Static Modules for Examples" FORCE) endif () + if (HDF5_BUILD_CPP_LIB) + set (H5EX_HDF5_LINK_LIBS ${H5EX_HDF5_LINK_LIBS} ${HDF5_CPP_LIB_TARGET}) + endif () else () set (USE_SHARED_LIBS ON CACHE BOOL "Use Shared Libraries for Examples" FORCE) set (H5EX_HDF5_LINK_LIBS ${HDF5_LIBSH_TARGET} CACHE STRING "HDF5 target" FORCE) @@ -55,6 +58,9 @@ else () set (H5EX_HDF5_LINK_LIBS ${H5EX_HDF5_LINK_LIBS} ${HDF5_F90_LIBSH_TARGET}) set (HDF_MOD_EXT "/shared" CACHE STRING "Use Shared Modules for Examples" FORCE) endif () + if (HDF5_BUILD_CPP_LIB) + set (H5EX_HDF5_LINK_LIBS ${H5EX_HDF5_LINK_LIBS} ${HDF5_CPP_LIBSH_TARGET}) + endif () if (HDF5_BUILD_JAVA) set (HDF5_JAVA_INCLUDE_DIRS ${HDF5_JAVA_JARS} ${HDF5_JAVA_LOGGING_JAR}) set (H5EX_JAVA_LIBRARY ${HDF5_JAVA_JNI_LIB_TARGET}) diff --git a/configure.ac b/configure.ac index bf7691055dc..52ad5a72b4f 100644 --- a/configure.ac +++ b/configure.ac @@ -4518,9 +4518,6 @@ AC_CONFIG_FILES([Makefile tools/test/h5stat/testh5stat.sh tools/src/h5perf/Makefile tools/test/perform/Makefile - examples/Makefile - examples/run-c-ex.sh - examples/testh5cc.sh bin/h5cc bin/Makefile c++/Makefile @@ -4528,18 +4525,12 @@ AC_CONFIG_FILES([Makefile c++/src/h5c++ c++/test/Makefile c++/test/H5srcdir_str.h - c++/examples/Makefile - c++/examples/run-c++-ex.sh - c++/examples/testh5c++.sh fortran/Makefile fortran/src/h5fc fortran/src/Makefile fortran/src/H5fort_type_defines.h fortran/test/Makefile fortran/testpar/Makefile - fortran/examples/Makefile - fortran/examples/run-fortran-ex.sh - fortran/examples/testh5fc.sh java/Makefile java/src/Makefile java/src/jni/Makefile diff --git a/doxygen/dox/ExamplesAPI.dox b/doxygen/dox/ExamplesAPI.dox index 051ab26e151..d4f50a5c8a8 100644 --- a/doxygen/dox/ExamplesAPI.dox +++ b/doxygen/dox/ExamplesAPI.dox @@ -842,66 +842,66 @@ FORTRAN Create/Read/Write an Attribute -Java +Java JavaObj -HDF5AttributeCreate.txt +HDF5AttributeCreate.txt Create Datasets -Java +Java JavaObj -HDF5DatasetCreate.txt +HDF5DatasetCreate.txt Read/Write Datasets -Java +Java JavaObj -HDF5DatasetRead.txt +HDF5DatasetRead.txt Create an Empty File -Java +Java JavaObj -HDF5FileCreate.txt +HDF5FileCreate.txt Retrieve the File Structure -Java +Java JavaObj -HDF5FileStructure.txt +HDF5FileStructure.txt Create Groups -Java +Java JavaObj -HDF5GroupCreate.txt +HDF5GroupCreate.txt Select a Subset of a Dataset -Java +Java JavaObj -HDF5SubsetSelect.txt +HDF5SubsetSelect.txt Create Two Datasets Within Groups -Java +Java JavaObj -HDF5GroupDatasetCreate.txt +HDF5GroupDatasetCreate.txt diff --git a/doxygen/dox/LearnBasics.dox b/doxygen/dox/LearnBasics.dox index bbdf4224c09..68700b8df83 100644 --- a/doxygen/dox/LearnBasics.dox +++ b/doxygen/dox/LearnBasics.dox @@ -47,7 +47,7 @@ PLEASE NOTE that the example programs are listed in the order they are expected programs use files created in earlier examples. \section secLBExamplesSrc HDF5 Source Code Examples -These examples (C, C++, Fortran) are provided in the HDF5 source code and (Unix) binaries. +These examples (C, C++, Fortran, Java, Python) are provided in the HDF5 source code and binaries. - @@ -67,7 +67,7 @@ These examples (C, C++, Fortran) are provided in the HDF5 source code and (Unix) - @@ -75,7 +75,7 @@ These examples (C, C++, Fortran) are provided in the HDF5 source code and (Unix) - @@ -83,7 +83,7 @@ These examples (C, C++, Fortran) are provided in the HDF5 source code and (Unix) - @@ -91,7 +91,7 @@ These examples (C, C++, Fortran) are provided in the HDF5 source code and (Unix) - @@ -99,7 +99,7 @@ These examples (C, C++, Fortran) are provided in the HDF5 source code and (Unix) - @@ -107,7 +107,7 @@ These examples (C, C++, Fortran) are provided in the HDF5 source code and (Unix) - @@ -115,7 +115,7 @@ These examples (C, C++, Fortran) are provided in the HDF5 source code and (Unix) - @@ -123,7 +123,7 @@ These examples (C, C++, Fortran) are provided in the HDF5 source code and (Unix) - @@ -131,7 +131,7 @@ These examples (C, C++, Fortran) are provided in the HDF5 source code and (Unix) - diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt deleted file mode 100644 index 43d7af223a4..00000000000 --- a/examples/CMakeLists.txt +++ /dev/null @@ -1,59 +0,0 @@ -cmake_minimum_required (VERSION 3.18) -project (HDF5_EXAMPLES C) - -#----------------------------------------------------------------------------- -# Define Sources -#----------------------------------------------------------------------------- -set (examples - h5_crtdat - h5_rdwt - h5_crtatt - h5_crtgrp - h5_crtgrpar - h5_crtgrpd - h5_cmprss - h5_extend - h5_subset - h5_write - h5_read - h5_extend_write - h5_chunk_read - h5_compound - h5_group - h5_select - h5_attribute - h5_mount - h5_ref_extern - h5_ref_compat - h5_reference_deprec - h5_drivers - h5_ref2reg_deprec - h5_extlink - h5_elink_unix2win - h5_shared_mesg - h5_debug_trace -) - -foreach (example ${examples}) - add_executable (${example} ${HDF5_EXAMPLES_SOURCE_DIR}/${example}.c) - target_include_directories (${example} PRIVATE "${HDF5_SRC_INCLUDE_DIRS};${HDF5_SRC_BINARY_DIR};$<$:${MPI_C_INCLUDE_DIRS}>") - if (NOT BUILD_SHARED_LIBS) - TARGET_C_PROPERTIES (${example} STATIC) - target_link_libraries (${example} PRIVATE ${HDF5_LIB_TARGET}) - else () - TARGET_C_PROPERTIES (${example} SHARED) - target_link_libraries (${example} PRIVATE ${HDF5_LIBSH_TARGET}) - endif () - set_target_properties (${example} PROPERTIES FOLDER examples) - - #----------------------------------------------------------------------------- - # Add Target to clang-format - #----------------------------------------------------------------------------- - if (HDF5_ENABLE_FORMATTERS) - clang_format (HDF5_EXAMPLES_${example}_FORMAT ${example}) - endif () -endforeach () - -if (BUILD_TESTING AND HDF5_TEST_EXAMPLES) - include (CMakeTests.cmake) -endif () diff --git a/fortran/Makefile.am b/fortran/Makefile.am index c17245ddba6..631d9edc888 100644 --- a/fortran/Makefile.am +++ b/fortran/Makefile.am @@ -32,7 +32,7 @@ else TESTSERIAL_DIR= endif -# Subdirectories in build order, not including examples directory +# Subdirectories in build order ## Only recurse into subdirectories if HDF5 is configured to use Fortran. if BUILD_FORTRAN_CONDITIONAL SUBDIRS=src $(TESTSERIAL_DIR) $(TESTPARALLEL_DIR) @@ -40,22 +40,6 @@ if BUILD_FORTRAN_CONDITIONAL endif # All directories that have Makefiles -DIST_SUBDIRS=src test testpar examples - -# Install examples -install-examples uninstall-examples: - @(cd examples && $(MAKE) $(AM_MAKEFLAGS) $@) || exit 1; - -installcheck-local: - @(cd examples && $(MAKE) $(AM_MAKEFLAGS) $@) || exit 1; - -# Clean examples when check-clean is invoked -check-clean :: - @$(MAKE) $(AM_MAKEFLAGS) build-$@ || exit 1; - @for d in X $(SUBDIRS) examples; do \ - if test $$d != X && test $$d != .; then \ - (set -x; cd $$d && $(MAKE) $(AM_MAKEFLAGS) $@) || exit 1; \ - fi; \ - done +DIST_SUBDIRS=src test testpar include $(top_srcdir)/config/conclude.am diff --git a/fortran/examples/CMakeLists.txt b/fortran/examples/CMakeLists.txt deleted file mode 100644 index ff3f299f583..00000000000 --- a/fortran/examples/CMakeLists.txt +++ /dev/null @@ -1,182 +0,0 @@ -cmake_minimum_required (VERSION 3.18) -project (HDF5_F90_EXAMPLES C Fortran) -# -------------------------------------------------------------------- -# Notes: When creating examples they should be prefixed -# with "f90_ex_". This allows for easier filtering of the examples. -# -------------------------------------------------------------------- - -#----------------------------------------------------------------------------- -# Define Sources -#----------------------------------------------------------------------------- -set (examples - h5_cmprss - h5_crtdat - h5_rdwt - h5_crtatt - h5_crtgrp - h5_crtgrpar - h5_crtgrpd - h5_extend - h5_subset - hyperslab - selectele - refobjexample - refregexample - mountexample - compound -) - -set (F2003_examples - rwdset_fortran2003 - nested_derived_type - compound_fortran2003 - compound_complex_fortran2003 -) - -foreach (example ${examples}) - add_executable (f90_ex_${example} ${HDF5_F90_EXAMPLES_SOURCE_DIR}/${example}.f90) - target_compile_options(f90_ex_${example} - PRIVATE - "${HDF5_CMAKE_Fortran_FLAGS}" - "$<$:${WIN_COMPILE_FLAGS}>") -# set_property(TARGET f90_ex_${example} APPEND PROPERTY LINK_FLAGS "$<$:-SUBSYSTEM:CONSOLE>") -# set_property(TARGET f90_ex_${example} APPEND PROPERTY LINK_FLAGS "$<$:${WIN_LINK_FLAGS}>") - if(MSVC) - set_property(TARGET f90_ex_${example} PROPERTY LINK_FLAGS "/SUBSYSTEM:CONSOLE ${WIN_LINK_FLAGS}") - endif() - if (NOT BUILD_SHARED_LIBS) - target_include_directories (f90_ex_${example} - PRIVATE - "${CMAKE_Fortran_MODULE_DIRECTORY}/static" - "${HDF5_SRC_INCLUDE_DIRS}" - "${HDF5_SRC_BINARY_DIR}" - "${HDF5_F90_BINARY_DIR}" - "${HDF5_F90_BINARY_DIR}/static" - ) - target_link_libraries (f90_ex_${example} PRIVATE ${HDF5_F90_LIB_TARGET} ${HDF5_LIB_TARGET}) - set_target_properties (f90_ex_${example} PROPERTIES - LINKER_LANGUAGE Fortran - FOLDER examples/fortran - Fortran_MODULE_DIRECTORY ${CMAKE_Fortran_MODULE_DIRECTORY}/static - ) - else () - target_include_directories (f90_ex_${example} - PRIVATE - "${CMAKE_Fortran_MODULE_DIRECTORY}/shared" - "${HDF5_SRC_INCLUDE_DIRS}" - "${HDF5_SRC_BINARY_DIR}" - "${HDF5_F90_BINARY_DIR}" - "${HDF5_F90_BINARY_DIR}/shared" - ) - target_link_libraries (f90_ex_${example} PRIVATE ${HDF5_F90_LIBSH_TARGET} ${HDF5_LIBSH_TARGET}) - set_target_properties (f90_ex_${example} PROPERTIES - LINKER_LANGUAGE Fortran - FOLDER examples/fortran - Fortran_MODULE_DIRECTORY ${CMAKE_Fortran_MODULE_DIRECTORY}/shared - ) - endif () -endforeach () - -foreach (example ${F2003_examples}) - add_executable (f03_ex_${example} ${HDF5_F90_EXAMPLES_SOURCE_DIR}/${example}.f90) - target_compile_options(f03_ex_${example} - PRIVATE - "${HDF5_CMAKE_Fortran_FLAGS}" - "$<$:${WIN_COMPILE_FLAGS}>") -# set_property(TARGET f03_ex_${example} APPEND PROPERTY LINK_FLAGS "$<$:-SUBSYSTEM:CONSOLE>") -# set_property(TARGET f03_ex_${example} APPEND PROPERTY LINK_FLAGS $<$:${WIN_LINK_FLAGS}>") - if(MSVC) - set_property(TARGET f03_ex_${example} PROPERTY LINK_FLAGS "/SUBSYSTEM:CONSOLE ${WIN_LINK_FLAGS}") - endif() - if (BUILD_STATIC_LIBS) - target_include_directories (f03_ex_${example} - PRIVATE - "${CMAKE_Fortran_MODULE_DIRECTORY}/static" - "${HDF5_SRC_INCLUDE_DIRS}" - "${HDF5_SRC_BINARY_DIR}" - "${HDF5_F90_BINARY_DIR}" - "${HDF5_F90_BINARY_DIR}/static" - ) - target_link_libraries (f03_ex_${example} PRIVATE ${HDF5_F90_LIB_TARGET} ${HDF5_LIB_TARGET}) - set_target_properties (f03_ex_${example} PROPERTIES - LINKER_LANGUAGE Fortran - FOLDER examples/fortran03 - Fortran_MODULE_DIRECTORY ${CMAKE_Fortran_MODULE_DIRECTORY}/static - ) - else () - target_include_directories (f03_ex_${example} - PRIVATE - "${CMAKE_Fortran_MODULE_DIRECTORY}/shared" - "${HDF5_SRC_INCLUDE_DIRS}" - "${HDF5_SRC_BINARY_DIR}" - "${HDF5_F90_BINARY_DIR}" - "${HDF5_F90_BINARY_DIR}/shared" - ) - target_link_libraries (f03_ex_${example} PRIVATE ${HDF5_F90_LIBSH_TARGET} ${HDF5_LIBSH_TARGET}) - set_target_properties (f03_ex_${example} PROPERTIES - LINKER_LANGUAGE Fortran - FOLDER examples/fortran03 - Fortran_MODULE_DIRECTORY ${CMAKE_Fortran_MODULE_DIRECTORY}/shared - ) - endif () -endforeach () - -if (H5_HAVE_PARALLEL AND MPI_Fortran_FOUND) - add_executable (f90_ex_ph5example ${HDF5_F90_EXAMPLES_SOURCE_DIR}/ph5example.f90) - target_compile_options(f90_ex_ph5example - PRIVATE - "${HDF5_CMAKE_Fortran_FLAGS}" - "$<$:${WIN_COMPILE_FLAGS}>") -# set_property(TARGET f90_ex_ph5example APPEND PROPERTY LINK_FLAGS "$<$:-SUBSYSTEM:CONSOLE>") -# set_property(TARGET f90_ex_ph5example APPEND PROPERTY LINK_FLAGS "$<$:${WIN_LINK_FLAGS}>") - if(MSVC) - set_property(TARGET f90_ex_ph5example PROPERTY LINK_FLAGS "/SUBSYSTEM:CONSOLE ${WIN_LINK_FLAGS}") - endif() - if (BUILD_STATIC_LIBS) - target_include_directories (f90_ex_ph5example - PRIVATE - "${CMAKE_Fortran_MODULE_DIRECTORY}/static" - "${HDF5_SRC_INCLUDE_DIRS}" - "${HDF5_SRC_BINARY_DIR}" - "${HDF5_F90_BINARY_DIR}" - "${HDF5_F90_BINARY_DIR}/static" - "$<$:${MPI_Fortran_INCLUDE_DIRS}>" - ) - target_link_libraries (f90_ex_ph5example - PRIVATE - ${HDF5_F90_LIB_TARGET} - ${HDF5_LIB_TARGET} - "$<$:${MPI_Fortran_LIBRARIES}>" - ) - set_target_properties (f90_ex_ph5example PROPERTIES - LINKER_LANGUAGE Fortran - FOLDER examples/fortran - Fortran_MODULE_DIRECTORY ${CMAKE_Fortran_MODULE_DIRECTORY}/static - ) - else () - target_include_directories (f90_ex_ph5example - PRIVATE - "${CMAKE_Fortran_MODULE_DIRECTORY}/shared" - "${HDF5_SRC_INCLUDE_DIRS}" - "${HDF5_SRC_BINARY_DIR}" - "${HDF5_F90_BINARY_DIR}" - "${HDF5_F90_BINARY_DIR}/shared" - "$<$:${MPI_Fortran_INCLUDE_DIRS}>" - ) - target_link_libraries (f90_ex_ph5example - PRIVATE - ${HDF5_F90_LIBSH_TARGET} - ${HDF5_LIBSH_TARGET} - "$<$:${MPI_Fortran_LIBRARIES}>" - ) - set_target_properties (f90_ex_ph5example PROPERTIES - LINKER_LANGUAGE Fortran - FOLDER examples/fortran - Fortran_MODULE_DIRECTORY ${CMAKE_Fortran_MODULE_DIRECTORY}/shared - ) - endif () -endif () - -if (BUILD_TESTING AND HDF5_TEST_FORTRAN AND HDF5_TEST_EXAMPLES) - include (CMakeTests.cmake) -endif () diff --git a/fortran/examples/CMakeTests.cmake b/fortran/examples/CMakeTests.cmake deleted file mode 100644 index 26cbc4f061b..00000000000 --- a/fortran/examples/CMakeTests.cmake +++ /dev/null @@ -1,105 +0,0 @@ -# -# Copyright by The HDF Group. -# All rights reserved. -# -# This file is part of HDF5. The full HDF5 copyright notice, including -# terms governing use, modification, and redistribution, is contained in -# the COPYING file, which can be found at the root of the source code -# distribution tree, or in https://www.hdfgroup.org/licenses. -# If you do not have access to either file, you may request a copy from -# help@hdfgroup.org. -# - -############################################################################## -############################################################################## -### T E S T I N G ### -############################################################################## -############################################################################## - -if (HDF5_TEST_SERIAL) - set (test_ex_fortran_CLEANFILES - compound.h5 - copy1.h5 - copy2.h5 - dsetf.h5 - extend.h5 - FORTRAN.h5 - groupf.h5 - groupsf.h5 - h5_cmprss.h5 - mount1.h5 - mount2.h5 - sdsf.h5 - subset.h5 - SDScompound.h5 - test.h5 - ) - - # Remove any output file left over from previous test run - add_test ( - NAME f90_ex-clear-objects - COMMAND ${CMAKE_COMMAND} -E remove ${test_ex_fortran_CLEANFILES} - ) - set_tests_properties (f90_ex-clear-objects PROPERTIES - FIXTURES_SETUP clear_f90_ex - WORKING_DIRECTORY ${PROJECT_BINARY_DIR} - ) - add_test ( - NAME f90_ex-clean-objects - COMMAND ${CMAKE_COMMAND} -E remove ${test_ex_fortran_CLEANFILES} - ) - set_tests_properties (f90_ex-clean-objects PROPERTIES - FIXTURES_CLEANUP clear_f90_ex - WORKING_DIRECTORY ${PROJECT_BINARY_DIR} - ) - - foreach (example ${examples}) - if (HDF5_USING_ANALYSIS_TOOL) - add_test (NAME f90_ex_${example} COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $) - else () - add_test (NAME f90_ex_${example} COMMAND "${CMAKE_COMMAND}" - -D "TEST_EMULATOR=${CMAKE_CROSSCOMPILING_EMULATOR}" - -D "TEST_PROGRAM=$" - -D "TEST_ARGS:STRING=" - -D "TEST_EXPECT=0" - -D "TEST_SKIP_COMPARE=TRUE" - -D "TEST_OUTPUT=f90_ex_${example}.txt" - #-D "TEST_REFERENCE=f90_ex_${example}.out" - -D "TEST_FOLDER=${PROJECT_BINARY_DIR}" - -P "${HDF_RESOURCES_DIR}/runTest.cmake" - ) - endif () - set_tests_properties (f90_ex_${example} PROPERTIES FIXTURES_REQUIRED clear_f90_ex) - if (last_test) - set_tests_properties (f90_ex_${example} PROPERTIES DEPENDS ${last_test}) - endif () - set (last_test "f90_ex_${example}") - endforeach () - - foreach (example ${F2003_examples}) - if (HDF5_USING_ANALYSIS_TOOL) - add_test (NAME f03_ex_${example} COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $) - else () - add_test (NAME f03_ex_${example} COMMAND "${CMAKE_COMMAND}" - -D "TEST_EMULATOR=${CMAKE_CROSSCOMPILING_EMULATOR}" - -D "TEST_PROGRAM=$" - -D "TEST_ARGS:STRING=" - -D "TEST_EXPECT=0" - -D "TEST_SKIP_COMPARE=TRUE" - -D "TEST_OUTPUT=f03_ex_${example}.txt" - #-D "TEST_REFERENCE=f03_ex_${example}.out" - -D "TEST_FOLDER=${PROJECT_BINARY_DIR}" - -P "${HDF_RESOURCES_DIR}/runTest.cmake" - ) - endif () - set_tests_properties (f03_ex_${example} PROPERTIES FIXTURES_REQUIRED clear_f90_ex) - if (last_test) - set_tests_properties (f03_ex_${example} PROPERTIES DEPENDS ${last_test}) - endif () - set (last_test "f03_ex_${example}") - endforeach () -endif () - -if (H5_HAVE_PARALLEL AND HDF5_TEST_PARALLEL AND MPI_Fortran_FOUND) - add_test (NAME MPI_TEST_f90_ex_ph5example COMMAND ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} ${MPIEXEC_MAX_NUMPROCS} ${MPIEXEC_PREFLAGS} $ ${MPIEXEC_POSTFLAGS}) -endif () diff --git a/fortran/examples/ph5example.f90 b/fortran/examples/ph5example.f90 deleted file mode 100644 index 29423b3f547..00000000000 --- a/fortran/examples/ph5example.f90 +++ /dev/null @@ -1,138 +0,0 @@ -! * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -! Copyright by The HDF Group. * -! All rights reserved. * -! * -! This file is part of HDF5. The full HDF5 copyright notice, including * -! terms governing use, modification, and redistribution, is contained in * -! the COPYING file, which can be found at the root of the source code * -! distribution tree, or in https://www.hdfgroup.org/licenses. * -! If you do not have access to either file, you may request a copy from * -! help@hdfgroup.org. * -! * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -! -! Fortran parallel example. Copied from Tutorial's example program of -! dataset.f90. - - PROGRAM DATASET - - USE HDF5 ! This module contains all necessary modules - USE MPI - - IMPLICIT NONE - - CHARACTER(LEN=10), PARAMETER :: default_fname = "sds.h5" ! Default name - CHARACTER(LEN=8), PARAMETER :: dsetname = "IntArray" ! Dataset name - - CHARACTER(LEN=100) :: filename ! File name - INTEGER :: fnamelen ! File name length - INTEGER(HID_T) :: file_id ! File identifier - INTEGER(HID_T) :: dset_id ! Dataset identifier - INTEGER(HID_T) :: filespace ! Dataspace identifier in file - INTEGER(HID_T) :: plist_id ! Property list identifier - - INTEGER(HSIZE_T), DIMENSION(2) :: dimsf = (/5,8/) ! Dataset dimensions. -! INTEGER, DIMENSION(7) :: dimsfi = (/5,8,0,0,0,0,0/) -! INTEGER(HSIZE_T), DIMENSION(2) :: dimsfi = (/5,8/) - INTEGER(HSIZE_T), DIMENSION(2) :: dimsfi - - INTEGER, ALLOCATABLE :: data(:,:) ! Data to write - INTEGER :: rank = 2 ! Dataset rank - - INTEGER :: error, error_n ! Error flags - INTEGER :: i, j - ! - ! MPI definitions and calls. - ! - INTEGER :: mpierror ! MPI error flag - INTEGER :: comm, info - INTEGER :: mpi_size, mpi_rank - comm = MPI_COMM_WORLD - info = MPI_INFO_NULL - CALL MPI_INIT(mpierror) - CALL MPI_COMM_SIZE(comm, mpi_size, mpierror) - CALL MPI_COMM_RANK(comm, mpi_rank, mpierror) - ! - ! Initialize data buffer with trivial data. - ! - ALLOCATE ( data(dimsf(1),dimsf(2))) - do i = 1, dimsf(2) - do j = 1, dimsf(1) - data(j,i) = j - 1 + (i-1)*dimsf(1) - enddo - enddo - ! - ! Initialize FORTRAN interface - ! - CALL h5open_f(error) - - ! - ! Setup file access property list with parallel I/O access. - ! - CALL h5pcreate_f(H5P_FILE_ACCESS_F, plist_id, error) - CALL h5pset_fapl_mpio_f(plist_id, comm, info, error) - - ! - ! Figure out the filename to use. - CALL get_environment_variable("HDF5_PARAPREFIX", filename) - fnamelen = LEN_TRIM(filename) - if ( fnamelen == 0 ) then - filename = default_fname - else - filename = filename(1:fnamelen) // "/" // default_fname - endif - print *, "Using filename = ", filename - - ! - ! Create the file collectively. - ! - CALL h5fcreate_f(filename, H5F_ACC_TRUNC_F, file_id, error, access_prp = plist_id) - CALL h5pclose_f(plist_id, error) - ! - ! Create the data space for the dataset. - ! - CALL h5screate_simple_f(rank, dimsf, filespace, error) - - ! - ! Create the dataset with default properties. - ! - CALL h5dcreate_f(file_id, dsetname, H5T_NATIVE_INTEGER, filespace, & - dset_id, error) - ! - ! Create property list for collective dataset write - ! - CALL h5pcreate_f(H5P_DATASET_XFER_F, plist_id, error) - CALL h5pset_dxpl_mpio_f(plist_id, H5FD_MPIO_COLLECTIVE_F, error) - ! - ! For independent write use - ! CALL h5pset_dxpl_mpio_f(plist_id, H5FD_MPIO_INDEPENDENT_F, error) - ! - - ! - ! Write the dataset collectively. - ! - CALL h5dwrite_f(dset_id, H5T_NATIVE_INTEGER, data, dimsfi, error, & - xfer_prp = plist_id) - ! - ! Deallocate data buffer. - ! - DEALLOCATE(data) - - ! - ! Close resources. - ! - CALL h5sclose_f(filespace, error) - CALL h5dclose_f(dset_id, error) - CALL h5pclose_f(plist_id, error) - CALL h5fclose_f(file_id, error) - ! Attempt to remove the data file. Remove the line if the compiler - ! does not support it. - !CALL unlink(filename) - - ! - ! Close FORTRAN interface - ! - CALL h5close_f(error) - - CALL MPI_FINALIZE(mpierror) - - END PROGRAM DATASET diff --git a/java/src/Makefile.am b/java/src/Makefile.am index aaa40525285..d73cdf2370c 100644 --- a/java/src/Makefile.am +++ b/java/src/Makefile.am @@ -130,7 +130,4 @@ clean: rm -f classhdf5_java.stamp -# Clean examples when check-clean is invoked -check-clean :: ; - #include $(top_srcdir)/config/conclude.am diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt index 39136813326..7b3578b692c 100644 --- a/release_docs/RELEASE.txt +++ b/release_docs/RELEASE.txt @@ -47,6 +47,12 @@ New Features Configuration: ------------- + - Moved examples to the HDF5Examples folder in the source tree. + + Moved the C++ and Fortran examples from the examples folder to the HDF5Examples + folder and renamed to TUTR, tutorial. This is referenced from the LearnBasics + doxygen page. + - Added support for using zlib-ng package as the zlib library: CMake: HDF5_USE_ZLIB_NG From f1baa96a2d9050f8e72440c0bfbad396e99c79d1 Mon Sep 17 00:00:00 2001 From: mattjala <124107509+mattjala@users.noreply.github.com> Date: Wed, 12 Jun 2024 07:57:38 -0500 Subject: [PATCH 07/45] Document 'return-and-read' field in API context (#4560) --- src/H5CX.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/H5CX.c b/src/H5CX.c index f23c90486e3..be31f232bda 100644 --- a/src/H5CX.c +++ b/src/H5CX.c @@ -156,10 +156,10 @@ * application's (non-default) property list. Getting / setting these * properties within the library does _not_ affect the application's * property list. Note that the naming of these fields, and - * _valid, is important for the H5CX_RETRIEVE_PROP_VALID ahd - * H5CX_RETRIEVE_PROP_VALID_SET macros to work properly. + * _valid, is important for the H5CX_RETRIEVE_PROP_VALID + * macro to work properly. * - * - "Return-only"" properties that are returned to the application, mainly + * - "Return-only" properties that are returned to the application, mainly * for sending out "introspection" information ("Why did collective I/O * get broken for this operation?", "Which filters are set on the chunk I * just directly read in?", etc) Setting these fields will cause the @@ -167,6 +167,19 @@ * context is popped, when returning from the API routine. Note that the * naming of these fields, and _set, is important for the * H5CX_TEST_SET_PROP and H5CX_SET_PROP macros to work properly. + * + * - "Return-and-read" properties that are returned to the application to send out introspection information, + * but are also queried by the library internally. Internal queries always retrieve the original value + * from the property list, and update the context's value to match. These properties have both a 'valid' + * and 'set' flag. _valid is true if the field has ever been populated from its underlying property + * list. _set flag is true if this field has ever been set on the context for application + * introspection. The naming of these fields is important for the H5CX_RETRIEVE_PROP_VALID_SET macro to + * work properly. + * + * Note that if a set operation is followed by an internal read, it is possible for _set to be true + * while the value in the context matches the underlying property list, resulting in a redundant write to + * the property list when the context is popped. Similarly, if a field has been set on the context but + * never read internally, _valid will be false despite the context containing a meaningful value. */ typedef struct H5CX_t { /* DXPL */ @@ -1082,7 +1095,7 @@ H5CX_restore_state(const H5CX_state_t *api_state) /*------------------------------------------------------------------------- * Function: H5CX_free_state * - * Purpose: Free a previously retrievedAPI context state + * Purpose: Free a previously retrieved API context state * * Return: Non-negative on success / Negative on failure * From 3b8c0dc5fb25c9e8244f7612e9398c1332fd0f47 Mon Sep 17 00:00:00 2001 From: Allen Byrne <50328838+byrnHDF@users.noreply.github.com> Date: Wed, 12 Jun 2024 07:57:58 -0500 Subject: [PATCH 08/45] Add compression includes to tests needing zlib support (#4561) --- test/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 1d52ae42894..fe860d5ae77 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -480,7 +480,7 @@ endforeach () add_executable (chunk_info ${HDF5_TEST_SOURCE_DIR}/chunk_info.c) target_compile_options(chunk_info PRIVATE "${HDF5_CMAKE_C_FLAGS}") target_compile_definitions(chunk_info PRIVATE "${HDF5_TEST_COMPILE_DEFS_PRIVATE}") -target_include_directories (chunk_info PRIVATE "${HDF5_SRC_INCLUDE_DIRS};${HDF5_SRC_BINARY_DIR};${HDF5_TEST_BINARY_DIR};$<$:${MPI_C_INCLUDE_DIRS}>") +target_include_directories (chunk_info PRIVATE "${HDF5_SRC_INCLUDE_DIRS};${HDF5_COMP_INCLUDE_DIRECTORIES};${HDF5_SRC_BINARY_DIR};${HDF5_TEST_BINARY_DIR};$<$:${MPI_C_INCLUDE_DIRS}>") if (NOT BUILD_SHARED_LIBS) TARGET_C_PROPERTIES (chunk_info STATIC) target_link_libraries (chunk_info PRIVATE ${HDF5_TEST_LIB_TARGET} ${LINK_COMP_LIBS}) @@ -501,7 +501,7 @@ endif () add_executable (direct_chunk ${HDF5_TEST_SOURCE_DIR}/direct_chunk.c) target_compile_options(direct_chunk PRIVATE "${HDF5_CMAKE_C_FLAGS}") target_compile_definitions(direct_chunk PRIVATE "${HDF5_TEST_COMPILE_DEFS_PRIVATE}") -target_include_directories (direct_chunk PRIVATE "${HDF5_SRC_INCLUDE_DIRS};${HDF5_SRC_BINARY_DIR};${HDF5_TEST_BINARY_DIR};$<$:${MPI_C_INCLUDE_DIRS}>") +target_include_directories (direct_chunk PRIVATE "${HDF5_SRC_INCLUDE_DIRS};${HDF5_COMP_INCLUDE_DIRECTORIES};${HDF5_SRC_BINARY_DIR};${HDF5_TEST_BINARY_DIR};$<$:${MPI_C_INCLUDE_DIRS}>") if (NOT BUILD_SHARED_LIBS) TARGET_C_PROPERTIES (direct_chunk STATIC) target_link_libraries (direct_chunk PRIVATE ${HDF5_TEST_LIB_TARGET} ${LINK_COMP_LIBS}) From 4a7f850b031a3cc2bac534733adae7c44406ae45 Mon Sep 17 00:00:00 2001 From: jhendersonHDF Date: Thu, 13 Jun 2024 14:18:31 -0500 Subject: [PATCH 09/45] Allow usage of page buffering for serial file access from parallel HDF5 builds (#4568) --- release_docs/RELEASE.txt | 10 +++ src/H5Fint.c | 33 ++++++---- test/page_buffer.c | 133 --------------------------------------- testpar/t_file.c | 37 ++++++++--- testpar/testphdf5.c | 2 - 5 files changed, 60 insertions(+), 155 deletions(-) diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt index 7b3578b692c..bf0d0daed89 100644 --- a/release_docs/RELEASE.txt +++ b/release_docs/RELEASE.txt @@ -527,6 +527,16 @@ Bug Fixes since HDF5-1.14.4 release =================================== Library ------- + - Fixed library to allow usage of page buffering feature for serial file + access with parallel builds of HDF5 + + When HDF5 is built with parallel support enabled, the library would previously + disallow any usage of page buffering, even if a file was not opened with + parallel access. The library now allows usage of page buffering for serial + file access with parallel builds of HDF5. Usage of page buffering is still + disabled for any form of parallel file access, even if only 1 MPI process + is used. + - Fixed a leak of datatype IDs created internally during datatype conversion Fixed an issue where the library could leak IDs that it creates internally diff --git a/src/H5Fint.c b/src/H5Fint.c index 3c3c4cb8dd3..0cc48c82c9f 100644 --- a/src/H5Fint.c +++ b/src/H5Fint.c @@ -2008,15 +2008,6 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id) if (H5P_get(a_plist, H5F_ACS_PAGE_BUFFER_SIZE_NAME, &page_buf_size) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "can't get page buffer size"); if (page_buf_size) { -#ifdef H5_HAVE_PARALLEL - /* Collective metadata writes are not supported with page buffering */ - if (file->shared->coll_md_write) - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, - "collective metadata writes are not supported with page buffering"); - - /* Temporary: fail file create when page buffering feature is enabled for parallel */ - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "page buffering is disabled for parallel"); -#endif /* H5_HAVE_PARALLEL */ /* Query for other page buffer cache properties */ if (H5P_get(a_plist, H5F_ACS_PAGE_BUFFER_MIN_META_PERC_NAME, &page_buf_min_meta_perc) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "can't get minimum metadata fraction of page buffer"); @@ -2029,14 +2020,30 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get evict on close value"); #ifdef H5_HAVE_PARALLEL - /* Check for evict on close in parallel (currently unsupported) */ + /* Check for unsupported settings in parallel */ assert(file->shared); if (H5F_SHARED_HAS_FEATURE(file->shared, H5FD_FEAT_HAS_MPI)) { int mpi_size = H5F_shared_mpi_get_size(file->shared); - if ((mpi_size > 1) && evict_on_close) - HGOTO_ERROR(H5E_FILE, H5E_UNSUPPORTED, NULL, - "evict on close is currently not supported in parallel HDF5"); + /* + * While there shouldn't be any problems in general with using page buffering + * with only 1 MPI process, there are still some testing issues to be fixed. + * Until then, page buffering is disabled for any form of parallel access. + */ + if (page_buf_size) { + /* Collective metadata writes are not supported with page buffering */ + if (file->shared->coll_md_write) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, + "collective metadata writes are not supported with page buffering"); + + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "page buffering is disabled for parallel"); + } + + if (mpi_size > 1) { + if (evict_on_close) + HGOTO_ERROR(H5E_FILE, H5E_UNSUPPORTED, NULL, + "evict on close is currently not supported in parallel HDF5"); + } } #endif diff --git a/test/page_buffer.c b/test/page_buffer.c index 05fa148a152..4523b2aa904 100644 --- a/test/page_buffer.c +++ b/test/page_buffer.c @@ -38,9 +38,6 @@ #define FILENAME_LEN 1024 /* test routines */ -#ifdef H5_HAVE_PARALLEL -static unsigned verify_page_buffering_disabled(hid_t orig_fapl, const char *driver_name); -#else #define NUM_DSETS 5 #define NX 100 #define NY 50 @@ -54,12 +51,9 @@ static unsigned test_stats_collection(hid_t orig_fapl, const char *driver_name); /* helper routines */ static unsigned create_file(char *filename, hid_t fcpl, hid_t fapl); static unsigned open_file(char *filename, hid_t fapl, hsize_t page_size, size_t page_buffer_size); -#endif /* H5_HAVE_PARALLEL */ static const char *FILENAME[] = {"filepaged", NULL}; -#ifndef H5_HAVE_PARALLEL - /*------------------------------------------------------------------------- * Function: create_file() * @@ -289,7 +283,6 @@ open_file(char *filename, hid_t fapl, hsize_t page_size, size_t page_buffer_size H5E_END_TRY return 1; } -#endif /* H5_HAVE_PARALLEL */ /* * @@ -353,8 +346,6 @@ set_multi_split(const char *driver_name, hid_t fapl, hsize_t pagesize) } /* set_multi_split() */ -#ifndef H5_HAVE_PARALLEL - /*------------------------------------------------------------------------- * Function: test_args() * @@ -2043,121 +2034,6 @@ test_stats_collection(hid_t orig_fapl, const char *driver_name) return 1; } /* test_stats_collection */ -#endif /* #ifndef H5_HAVE_PARALLEL */ - -/*------------------------------------------------------------------------- - * Function: verify_page_buffering_disabled() - * - * Purpose: This function should only be called in parallel - * builds. - * - * At present, page buffering should be disabled in parallel - * builds. Verify this. - * - * Return: 0 if test is successful - * 1 if test fails - * - *------------------------------------------------------------------------- - */ - -#ifdef H5_HAVE_PARALLEL -static unsigned -verify_page_buffering_disabled(hid_t orig_fapl, const char *driver_name) -{ - char filename[FILENAME_LEN]; /* Filename to use */ - hid_t file_id = H5I_INVALID_HID; /* File ID */ - hid_t fcpl = H5I_INVALID_HID; - hid_t fapl = H5I_INVALID_HID; - - TESTING("Page Buffering Disabled"); - h5_fixname(FILENAME[0], orig_fapl, filename, sizeof(filename)); - - /* first, try to create a file with page buffering enabled */ - - if ((fapl = H5Pcopy(orig_fapl)) < 0) - TEST_ERROR; - - if (set_multi_split(driver_name, fapl, 4096) != 0) - TEST_ERROR; - - if ((fcpl = H5Pcreate(H5P_FILE_CREATE)) < 0) - FAIL_STACK_ERROR; - - if (H5Pset_file_space_strategy(fcpl, H5F_FSPACE_STRATEGY_PAGE, 0, (hsize_t)1) < 0) - FAIL_STACK_ERROR; - - if (H5Pset_file_space_page_size(fcpl, 4096) < 0) - FAIL_STACK_ERROR; - - if (H5Pset_page_buffer_size(fapl, 4096 * 8, 0, 0) < 0) - FAIL_STACK_ERROR; - - /* try to create the file -- should fail */ - H5E_BEGIN_TRY - { - file_id = H5Fcreate(filename, H5F_ACC_TRUNC, fcpl, fapl); - } - H5E_END_TRY - - if (file_id >= 0) - TEST_ERROR; - - /* now, create a file, close it, and then try to open it with page - * buffering enabled. - */ - if ((fcpl = H5Pcreate(H5P_FILE_CREATE)) < 0) - FAIL_STACK_ERROR; - - if (H5Pset_file_space_strategy(fcpl, H5F_FSPACE_STRATEGY_PAGE, 0, (hsize_t)1) < 0) - FAIL_STACK_ERROR; - - if (H5Pset_file_space_page_size(fcpl, 4096) < 0) - FAIL_STACK_ERROR; - - /* create the file */ - if ((file_id = H5Fcreate(filename, H5F_ACC_TRUNC, fcpl, H5P_DEFAULT)) < 0) - FAIL_STACK_ERROR; - - /* close the file */ - if (H5Fclose(file_id) < 0) - FAIL_STACK_ERROR; - - /* try to open the file using the fapl prepared above which enables - * page buffering. Should fail. - */ - H5E_BEGIN_TRY - { - file_id = H5Fopen(filename, H5F_ACC_RDWR, fapl); - } - H5E_END_TRY - - if (file_id >= 0) - TEST_ERROR; - - if (H5Pclose(fcpl) < 0) - FAIL_STACK_ERROR; - - if (H5Pclose(fapl) < 0) - FAIL_STACK_ERROR; - - PASSED(); - - return 0; - -error: - - H5E_BEGIN_TRY - { - H5Pclose(fapl); - H5Pclose(fcpl); - H5Fclose(file_id); - } - H5E_END_TRY - - return 1; - -} /* verify_page_buffering_disabled() */ -#endif /* H5_HAVE_PARALLEL */ /*------------------------------------------------------------------------- * Function: main() @@ -2203,13 +2079,6 @@ main(void) FAIL_STACK_ERROR; api_ctx_pushed = true; -#ifdef H5_HAVE_PARALLEL - - puts("Page Buffering is disabled for parallel."); - nerrors += verify_page_buffering_disabled(fapl, driver_name); - -#else /* H5_HAVE_PARALLEL */ - nerrors += test_args(fapl, driver_name); nerrors += test_raw_data_handling(fapl, driver_name); nerrors += test_lru_processing(fapl, driver_name); @@ -2217,8 +2086,6 @@ main(void) nerrors += test_stats_collection(fapl, driver_name); nerrors += test_pb_fapl_tolerance_at_open(); -#endif /* H5_HAVE_PARALLEL */ - h5_clean_files(FILENAME, fapl); if (nerrors) diff --git a/testpar/t_file.c b/testpar/t_file.c index 493e6d2d194..acfb45d30a8 100644 --- a/testpar/t_file.c +++ b/testpar/t_file.c @@ -33,13 +33,17 @@ #define H5MF_FRIEND /*suppress error about including H5MFpkg */ #include "H5MFpkg.h" +#ifdef PB_OUT #define NUM_DSETS 5 +#endif int mpi_size, mpi_rank; +#ifdef PB_OUT static int create_file(const char *filename, hid_t fcpl, hid_t fapl, int metadata_write_strategy); static int open_file(const char *filename, hid_t fapl, int metadata_write_strategy, hsize_t page_size, size_t page_buffer_size); +#endif /* * test file access by communicator besides COMM_WORLD. @@ -132,22 +136,29 @@ test_split_comm_access(void) void test_page_buffer_access(void) { + const char *filename; hid_t file_id = H5I_INVALID_HID; /* File ID */ hid_t fcpl, fapl; - size_t page_count = 0; - int i, num_elements = 200; - haddr_t raw_addr, meta_addr; - int *data; - H5F_t *f = NULL; herr_t ret; /* generic return value */ - const char *filename; - bool api_ctx_pushed = false; /* Whether API context pushed */ +#ifdef PB_OUT + size_t page_count = 0; + int i, num_elements = 200; + haddr_t raw_addr, meta_addr; + int *data; + H5F_t *f = NULL; + bool api_ctx_pushed = false; /* Whether API context pushed */ +#endif MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank); MPI_Comm_size(MPI_COMM_WORLD, &mpi_size); filename = (const char *)GetTestParameters(); + /* Until page buffering is supported in parallel in some form (even if + * just for a single MPI process), this test just will just check to + * make sure that an error is thrown when page buffering is enabled + * with parallel access. + */ if (VERBOSE_MED) printf("Page Buffer Usage in Parallel %s\n", filename); @@ -175,6 +186,15 @@ test_page_buffer_access(void) ret = H5Pset_coll_metadata_write(fapl, false); VRFY((ret >= 0), ""); + /* This should fail due to page buffering not being supported in parallel */ + H5E_BEGIN_TRY + { + file_id = H5Fcreate(filename, H5F_ACC_TRUNC, fcpl, fapl); + } + H5E_END_TRY + VRFY((file_id < 0), "H5Fcreate failed"); + +#ifdef PB_OUT ret = create_file(filename, fcpl, fapl, H5AC_METADATA_WRITE_STRATEGY__DISTRIBUTED); VRFY((ret == 0), ""); ret = open_file(filename, fapl, H5AC_METADATA_WRITE_STRATEGY__DISTRIBUTED, sizeof(int) * 100, @@ -442,8 +462,10 @@ test_page_buffer_access(void) free(data); data = NULL; MPI_Barrier(MPI_COMM_WORLD); +#endif } +#ifdef PB_OUT static int create_file(const char *filename, hid_t fcpl, hid_t fapl, int metadata_write_strategy) { @@ -760,6 +782,7 @@ open_file(const char *filename, hid_t fapl, int metadata_write_strategy, hsize_t return nerrors; } +#endif /* * NOTE: See HDFFV-10894 and add tests later to verify MPI-specific properties in the diff --git a/testpar/testphdf5.c b/testpar/testphdf5.c index 7de274fc230..992b8ee71af 100644 --- a/testpar/testphdf5.c +++ b/testpar/testphdf5.c @@ -402,9 +402,7 @@ main(int argc, char **argv) AddTest("split", test_split_comm_access, NULL, "dataset using split communicators", PARATESTFILE); AddTest("h5oflusherror", test_oflush, NULL, "H5Oflush failure", PARATESTFILE); -#ifdef PB_OUT /* temporary: disable page buffering when parallel */ AddTest("page_buffer", test_page_buffer_access, NULL, "page buffer usage in parallel", PARATESTFILE); -#endif AddTest("props", test_file_properties, NULL, "Coll Metadata file property settings", PARATESTFILE); From 942c3cdb51fdc2b7bc63875b8c636bc73bed3c63 Mon Sep 17 00:00:00 2001 From: Allen Byrne <50328838+byrnHDF@users.noreply.github.com> Date: Fri, 14 Jun 2024 11:03:00 -0500 Subject: [PATCH 10/45] Remove old version of libaec (#4567) --- CMakeFilters.cmake | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/CMakeFilters.cmake b/CMakeFilters.cmake index 55dbd7ccc7b..cccf80b916a 100644 --- a/CMakeFilters.cmake +++ b/CMakeFilters.cmake @@ -133,14 +133,9 @@ if (HDF5_ENABLE_SZIP_SUPPORT) if (NOT SZIP_USE_EXTERNAL) set(libaec_USE_STATIC_LIBS ${HDF5_USE_LIBAEC_STATIC}) set(SZIP_FOUND FALSE) - find_package (libaec 1.0.5 CONFIG) - if (SZIP_FOUND) - set (LINK_COMP_LIBS ${LINK_COMP_LIBS} ${H5_SZIP_LIBRARIES}) - else () - find_package (SZIP NAMES ${LIBAEC_PACKAGE_NAME}${HDF_PACKAGE_EXT} COMPONENTS static shared) - if (NOT SZIP_FOUND) - find_package (SZIP) # Legacy find - endif () + find_package (SZIP NAMES ${LIBAEC_PACKAGE_NAME}${HDF_PACKAGE_EXT} COMPONENTS static shared) + if (NOT SZIP_FOUND) + find_package (SZIP) # Legacy find endif () set(H5_SZIP_FOUND ${SZIP_FOUND}) if (H5_SZIP_FOUND) From 372734543cd15faa5b1e56a88bfd4be6e3234316 Mon Sep 17 00:00:00 2001 From: mattjala <124107509+mattjala@users.noreply.github.com> Date: Fri, 14 Jun 2024 11:04:49 -0500 Subject: [PATCH 11/45] Add property names to context field docs (#4563) --- src/H5CX.c | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/src/H5CX.c b/src/H5CX.c index be31f232bda..2a4a4f6eff1 100644 --- a/src/H5CX.c +++ b/src/H5CX.c @@ -222,15 +222,15 @@ typedef struct H5CX_t { #endif /* H5_HAVE_PARALLEL */ /* Cached DXPL properties */ - size_t max_temp_buf; /* Maximum temporary buffer size */ + size_t max_temp_buf; /* Maximum temporary buffer size (H5D_XFER_MAX_TEMP_BUF_NAME) .*/ bool max_temp_buf_valid; /* Whether maximum temporary buffer size is valid */ void *tconv_buf; /* Temporary conversion buffer (H5D_XFER_TCONV_BUF_NAME) */ bool tconv_buf_valid; /* Whether temporary conversion buffer is valid */ void *bkgr_buf; /* Background conversion buffer (H5D_XFER_BKGR_BUF_NAME) */ bool bkgr_buf_valid; /* Whether background conversion buffer is valid */ - H5T_bkg_t bkgr_buf_type; /* Background buffer type (H5D_XFER_BKGR_BUF_NAME) */ + H5T_bkg_t bkgr_buf_type; /* Background buffer type (H5D_XFER_BKGR_BUF_TYPE_NAME) */ bool bkgr_buf_type_valid; /* Whether background buffer type is valid */ - double btree_split_ratio[3]; /* B-tree split ratios */ + double btree_split_ratio[3]; /* B-tree split ratios (H5D_XFER_BTREE_SPLIT_RATIO_NAME) */ bool btree_split_ratio_valid; /* Whether B-tree split ratios are valid */ size_t vec_size; /* Size of hyperslab vector (H5D_XFER_HYPER_VECTOR_SIZE_NAME) */ bool vec_size_valid; /* Whether hyperslab vector is valid */ @@ -260,8 +260,8 @@ typedef struct H5CX_t { bool dt_conv_cb_valid; /* Whether datatype conversion struct is valid */ H5D_selection_io_mode_t selection_io_mode; /* Selection I/O mode (H5D_XFER_SELECTION_IO_MODE_NAME) */ bool selection_io_mode_valid; /* Whether selection I/O mode is valid */ - bool modify_write_buf; /* Whether the library can modify write buffers */ - bool modify_write_buf_valid; /* Whether the modify_write_buf field is valid */ + bool modify_write_buf; /* Whether the library can modify write buffers (H5D_XFER_MODIFY_WRITE_BUF_NAME)*/ + bool modify_write_buf_valid; /* Whether the modify_write_buf field is valid */ /* Return-only DXPL properties to return to application */ #ifdef H5_HAVE_PARALLEL @@ -318,32 +318,34 @@ typedef struct H5CX_t { bool actual_selection_io_mode_valid; /* Whether actual selection I/O mode is valid */ /* Cached LCPL properties */ - H5T_cset_t encoding; /* Link name character encoding */ - bool encoding_valid; /* Whether link name character encoding is valid */ - unsigned intermediate_group; /* Whether to create intermediate groups */ - bool intermediate_group_valid; /* Whether create intermediate group flag is valid */ + H5T_cset_t encoding; /* Link name character encoding (H5P_STRCRT_CHAR_ENCODING_NAME) */ + bool encoding_valid; /* Whether link name character encoding is valid */ + unsigned intermediate_group; /* Whether to create intermediate groups (H5L_CRT_INTERMEDIATE_GROUP_NAME) */ + bool intermediate_group_valid; /* Whether create intermediate group flag is valid */ /* Cached LAPL properties */ size_t nlinks; /* Number of soft / UD links to traverse (H5L_ACS_NLINKS_NAME) */ bool nlinks_valid; /* Whether number of soft / UD links to traverse is valid */ /* Cached DCPL properties */ - bool do_min_dset_ohdr; /* Whether to minimize dataset object header */ + bool do_min_dset_ohdr; /* Whether to minimize dataset object header (H5D_CRT_MIN_DSET_HDR_SIZE_NAME) */ bool do_min_dset_ohdr_valid; /* Whether minimize dataset object header flag is valid */ - uint8_t ohdr_flags; /* Object header flags */ + uint8_t ohdr_flags; /* Object header flags (H5O_CRT_OHDR_FLAGS_NAME) */ bool ohdr_flags_valid; /* Whether the object headers flags are valid */ /* Cached DAPL properties */ - const char *extfile_prefix; /* Prefix for external file */ + const char *extfile_prefix; /* Prefix for external file (H5D_ACS_EFILE_PREFIX_NAME) */ bool extfile_prefix_valid; /* Whether the prefix for external file is valid */ - const char *vds_prefix; /* Prefix for VDS */ + const char *vds_prefix; /* Prefix for VDS (H5D_ACS_VDS_PREFIX_NAME) */ bool vds_prefix_valid; /* Whether the prefix for VDS is valid */ /* Cached FAPL properties */ - H5F_libver_t low_bound; /* low_bound property for H5Pset_libver_bounds() */ - bool low_bound_valid; /* Whether low_bound property is valid */ - H5F_libver_t high_bound; /* high_bound property for H5Pset_libver_bounds */ - bool high_bound_valid; /* Whether high_bound property is valid */ + H5F_libver_t low_bound; /* low_bound property for H5Pset_libver_bounds() + (H5F_ACS_LIBVER_LOW_BOUND_NAME) */ + bool low_bound_valid; /* Whether low_bound property is valid */ + H5F_libver_t high_bound; /* high_bound property for H5Pset_libver_bounds + (H5F_ACS_LIBVER_HIGH_BOUND_NAME) */ + bool high_bound_valid; /* Whether high_bound property is valid */ /* Cached VOL settings */ H5VL_connector_prop_t vol_connector_prop; /* Property for VOL connector ID & info */ From 8f59301c2fcc6d7da01898df9a5767a320140f43 Mon Sep 17 00:00:00 2001 From: mattjala <124107509+mattjala@users.noreply.github.com> Date: Fri, 14 Jun 2024 11:17:57 -0500 Subject: [PATCH 12/45] Document property shared name behavior (#4565) --- src/H5Ppkg.h | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/H5Ppkg.h b/src/H5Ppkg.h index 63baced637a..aed3c864322 100644 --- a/src/H5Ppkg.h +++ b/src/H5Ppkg.h @@ -58,11 +58,15 @@ typedef enum { /* Define structure to hold property information */ typedef struct H5P_genprop_t { /* Values for this property */ - char *name; /* Name of property */ - size_t size; /* Size of property value */ - void *value; /* Pointer to property value */ - H5P_prop_within_t type; /* Type of object the property is within */ - bool shared_name; /* Whether the name is shared or not */ + char *name; /* Name of property */ + size_t size; /* Size of property value */ + void *value; /* Pointer to property value */ + H5P_prop_within_t type; /* Type of object the property is within */ + bool shared_name; /* Whether the name buffer is owned by a different property. Names are only shared when + duplicating a property from a class to a list, or when duplicating a property with a + shared name from one list to another. The property that owns the name frees it when + that property is closed. The name is guaranteed to stay allocated as long as other + properties share it due to reference counting on property lists classes. */ /* Callback function pointers & info */ H5P_prp_create_func_t create; /* Function to call when a property is created */ From 6edee58d8f4faa08a6cdd450abcd14db2044c757 Mon Sep 17 00:00:00 2001 From: mattjala <124107509+mattjala@users.noreply.github.com> Date: Fri, 14 Jun 2024 11:18:25 -0500 Subject: [PATCH 13/45] Clarify H5CX macro documentation (#4569) --- src/H5CX.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/H5CX.c b/src/H5CX.c index 2a4a4f6eff1..d3d1ab3bed3 100644 --- a/src/H5CX.c +++ b/src/H5CX.c @@ -48,7 +48,7 @@ * be handled by the pthread library. * * In order for this macro to work, H5CX_get_my_context() must be preceded - * by "H5CX_node_t *ctx =". + * by "H5CX_node_t **ctx =". */ #define H5CX_get_my_context() H5CX__get_context() #else /* H5_HAVE_THREADSAFE */ @@ -84,14 +84,15 @@ /* Mark the field as valid */ \ (*head)->ctx.H5_GLUE(PROP_FIELD, _valid) = true; -/* Macro for the duplicated code to retrieve properties from a property list */ +/* Macro for the duplicated code to retrieve a value from a plist if the context value is invalid */ #define H5CX_RETRIEVE_PROP_VALID(PL, DEF_PL, PROP_NAME, PROP_FIELD) \ /* Check if the value has been retrieved already */ \ if (!(*head)->ctx.H5_GLUE(PROP_FIELD, _valid)) { \ H5CX_RETRIEVE_PROP_COMMON(PL, DEF_PL, PROP_NAME, PROP_FIELD) \ } /* end if */ -/* Macro for the duplicated code to retrieve possibly set properties from a property list */ +/* Macro for the duplicated code to retrieve a value from a plist if the context value is invalid, or the + * library has previously modified the context value for return */ #define H5CX_RETRIEVE_PROP_VALID_SET(PL, DEF_PL, PROP_NAME, PROP_FIELD) \ /* Check if the value has been retrieved already */ \ if (!((*head)->ctx.H5_GLUE(PROP_FIELD, _valid) || (*head)->ctx.H5_GLUE(PROP_FIELD, _set))) { \ @@ -99,7 +100,7 @@ } /* end if */ #if defined(H5_HAVE_PARALLEL) && defined(H5_HAVE_INSTRUMENTED_LIBRARY) -/* Macro for the duplicated code to test and set properties for a property list */ +/* Macro for the duplicated code to set a context field that may not exist as a property */ #define H5CX_TEST_SET_PROP(PROP_NAME, PROP_FIELD) \ { \ htri_t check_prop = 0; /* Whether the property exists in the API context's DXPL */ \ @@ -122,7 +123,7 @@ } #endif /* defined(H5_HAVE_PARALLEL) && defined(H5_HAVE_INSTRUMENTED_LIBRARY) */ -/* Macro for the duplicated code to test and set properties for a property list */ +/* Macro for the duplicated code to test and set properties for a property list from the context */ #define H5CX_SET_PROP(PROP_NAME, PROP_FIELD) \ if ((*head)->ctx.H5_GLUE(PROP_FIELD, _set)) { \ /* Retrieve the dataset transfer property list */ \ From 298c069f84f1c57b74dfc616d8e4ece9244c23dd Mon Sep 17 00:00:00 2001 From: mattjala <124107509+mattjala@users.noreply.github.com> Date: Sat, 15 Jun 2024 12:45:12 -0500 Subject: [PATCH 14/45] Document H5Punregister modifying default properties (#4570) --- src/H5P.c | 8 +++++--- src/H5Ppkg.h | 4 ++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/H5P.c b/src/H5P.c index b2d27bba997..f0ccc2fc4ef 100644 --- a/src/H5P.c +++ b/src/H5P.c @@ -1397,8 +1397,10 @@ H5Pcopy_prop(hid_t dst_id, hid_t src_id, const char *name) Returns non-negative on success, negative on failure. DESCRIPTION Removes a property from a property list class. Future property lists - created of that class will not contain this property. Existing property - lists containing this property are not affected. + created of that class will not contain this property. Existing property lists + which still use the default value for this property will have this property removed. + Existing property lists which have modified this property will not be affected. + GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS @@ -1419,7 +1421,7 @@ H5Punregister(hid_t pclass_id, const char *name) if (!name || !*name) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid property name"); - /* Remove the property list from class */ + /* Remove the property from property list class */ if ((ret_value = H5P__unregister(pclass, name)) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to remove property from class"); diff --git a/src/H5Ppkg.h b/src/H5Ppkg.h index aed3c864322..0ff000ba96c 100644 --- a/src/H5Ppkg.h +++ b/src/H5Ppkg.h @@ -108,10 +108,10 @@ struct H5P_genclass_t { struct H5P_genplist_t { H5P_genclass_t *pclass; /* Pointer to class info */ hid_t plist_id; /* Copy of the property list ID (for use in close callback) */ - size_t nprops; /* Number of properties in class */ + size_t nprops; /* Number of properties in this list */ bool class_init; /* Whether the class initialization callback finished successfully */ H5SL_t *del; /* Skip list containing names of deleted properties */ - H5SL_t *props; /* Skip list containing properties */ + H5SL_t *props; /* Skip list containing properties modified from the parent class */ }; /* Property list/class iterator callback function pointer */ From 8d7ae0e2667f3330503fb52d8b38ed87eddda1ef Mon Sep 17 00:00:00 2001 From: "H. Joe Lee" Date: Sat, 15 Jun 2024 13:04:42 -0500 Subject: [PATCH 15/45] Update NVHPC to 24.5 (#4171) We don't test parallel in other GitHub actions, so this also converts the NVHPC check to configure and build only while we discuss how we'll test parallel HDF5 in GitHub. There is a blocking GitHub issue to address the test failures for HDF5 1.14.5 (#4571). --- .github/workflows/nvhpc-auto.yml | 33 ++++++++++--------------------- .github/workflows/nvhpc-cmake.yml | 22 ++++++++------------- 2 files changed, 18 insertions(+), 37 deletions(-) diff --git a/.github/workflows/nvhpc-auto.yml b/.github/workflows/nvhpc-auto.yml index b29cf8f2f55..a73dbcb3c67 100644 --- a/.github/workflows/nvhpc-auto.yml +++ b/.github/workflows/nvhpc-auto.yml @@ -34,21 +34,21 @@ jobs: curl https://developer.download.nvidia.com/hpc-sdk/ubuntu/DEB-GPG-KEY-NVIDIA-HPC-SDK | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-hpcsdk-archive-keyring.gpg echo 'deb [signed-by=/usr/share/keyrings/nvidia-hpcsdk-archive-keyring.gpg] https://developer.download.nvidia.com/hpc-sdk/ubuntu/amd64 /' | sudo tee /etc/apt/sources.list.d/nvhpc.list sudo apt-get update -y - sudo apt-get install -y nvhpc-23-9 + sudo apt-get install -y nvhpc-24-5 echo "NVHPCSDK=/opt/nvidia/hpc_sdk" >> $GITHUB_ENV - echo "OMPI_CXX=/opt/nvidia/hpc_sdk/Linux_x86_64/23.9/compilers/bin/nvc++" >> $GITHUB_ENV - echo "OMPI_CC=/opt/nvidia/hpc_sdk/Linux_x86_64/23.9/compilers/bin/nvc" >> $GITHUB_ENV - echo "OMPI_FC=/opt/nvidia/hpc_sdk/Linux_x86_64/23.9/compilers/bin/nvfortran" >> $GITHUB_ENV - echo "CC=/opt/nvidia/hpc_sdk/Linux_x86_64/23.9/comm_libs/openmpi4/bin/mpicc" >> $GITHUB_ENV - echo "FC=/opt/nvidia/hpc_sdk/Linux_x86_64/23.9/comm_libs/openmpi4/bin/mpifort" >> $GITHUB_ENV - echo "LD_LIBRARY_PATH=/opt/nvidia/hpc_sdk/Linux_x86_64/23.9/compilers/lib" >> $GITHUB_ENV + echo "OMPI_CXX=/opt/nvidia/hpc_sdk/Linux_x86_64/24.5/compilers/bin/nvc++" >> $GITHUB_ENV + echo "OMPI_CC=/opt/nvidia/hpc_sdk/Linux_x86_64/24.5/compilers/bin/nvc" >> $GITHUB_ENV + echo "OMPI_FC=/opt/nvidia/hpc_sdk/Linux_x86_64/24.5/compilers/bin/nvfortran" >> $GITHUB_ENV + echo "CC=/opt/nvidia/hpc_sdk/Linux_x86_64/24.5/comm_libs/openmpi4/bin/mpicc" >> $GITHUB_ENV + echo "FC=/opt/nvidia/hpc_sdk/Linux_x86_64/24.5/comm_libs/openmpi4/bin/mpifort" >> $GITHUB_ENV + echo "LD_LIBRARY_PATH=/opt/nvidia/hpc_sdk/Linux_x86_64/24.5/compilers/lib" >> $GITHUB_ENV echo "DESTDIR=/tmp" >> $GITHUB_ENV - name: Autotools Configure shell: bash run: | export RUNPARALLEL="mpiexec -np 2" - export PATH=/opt/nvidia/hpc_sdk/Linux_x86_64/23.9/comm_libs/openmpi4/bin:/opt/nvidia/hpc_sdk/Linux_x86_64/23.9/compilers/bin:$PATH + export PATH=/opt/nvidia/hpc_sdk/Linux_x86_64/24.5/comm_libs/openmpi4/bin:/opt/nvidia/hpc_sdk/Linux_x86_64/24.5/compilers/bin:$PATH sh ./autogen.sh mkdir "${{ runner.workspace }}/build" cd "${{ runner.workspace }}/build" @@ -62,26 +62,13 @@ jobs: - name: Autotools Build shell: bash run: | - export PATH=/opt/nvidia/hpc_sdk/Linux_x86_64/23.9/comm_libs/openmpi4/bin:/opt/nvidia/hpc_sdk/Linux_x86_64/23.9/compilers/bin:$PATH + export PATH=/opt/nvidia/hpc_sdk/Linux_x86_64/24.5/comm_libs/openmpi4/bin:/opt/nvidia/hpc_sdk/Linux_x86_64/24.5/compilers/bin:$PATH make -j3 working-directory: ${{ runner.workspace }}/build - - name: Autotools Run Tests - shell: bash - run: | - export PATH=/opt/nvidia/hpc_sdk/Linux_x86_64/23.9/comm_libs/openmpi4/bin:/opt/nvidia/hpc_sdk/Linux_x86_64/23.9/compilers/bin:$PATH - make check -j - working-directory: ${{ runner.workspace }}/build - - name: Autotools Install shell: bash run: | - export PATH=/opt/nvidia/hpc_sdk/Linux_x86_64/23.9/comm_libs/openmpi4/bin:/opt/nvidia/hpc_sdk/Linux_x86_64/23.9/compilers/bin:$PATH + export PATH=/opt/nvidia/hpc_sdk/Linux_x86_64/24.5/comm_libs/openmpi4/bin:/opt/nvidia/hpc_sdk/Linux_x86_64/24.5/compilers/bin:$PATH make install working-directory: ${{ runner.workspace }}/build - -# - name: Autotools Verify Install -# run: | -# export PATH=/opt/nvidia/hpc_sdk/Linux_x86_64/23.9/comm_libs/openmpi4/bin:/opt/nvidia/hpc_sdk/Linux_x86_64/23.9/compilers/bin:$PATH -# make check-install -# working-directory: ${{ runner.workspace }}/build diff --git a/.github/workflows/nvhpc-cmake.yml b/.github/workflows/nvhpc-cmake.yml index e365bdab62f..4a99cfd6ac7 100644 --- a/.github/workflows/nvhpc-cmake.yml +++ b/.github/workflows/nvhpc-cmake.yml @@ -33,20 +33,20 @@ jobs: curl https://developer.download.nvidia.com/hpc-sdk/ubuntu/DEB-GPG-KEY-NVIDIA-HPC-SDK | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-hpcsdk-archive-keyring.gpg echo 'deb [signed-by=/usr/share/keyrings/nvidia-hpcsdk-archive-keyring.gpg] https://developer.download.nvidia.com/hpc-sdk/ubuntu/amd64 /' | sudo tee /etc/apt/sources.list.d/nvhpc.list sudo apt-get update -y - sudo apt-get install -y nvhpc-23-9 + sudo apt-get install -y nvhpc-24-5 echo "NVHPCSDK=/opt/nvidia/hpc_sdk" >> $GITHUB_ENV - echo "OMPI_CXX=/opt/nvidia/hpc_sdk/Linux_x86_64/23.9/compilers/bin/nvc++" >> $GITHUB_ENV - echo "OMPI_CC=/opt/nvidia/hpc_sdk/Linux_x86_64/23.9/compilers/bin/nvc" >> $GITHUB_ENV - echo "OMPI_FC=/opt/nvidia/hpc_sdk/Linux_x86_64/23.9/compilers/bin/nvfortran" >> $GITHUB_ENV - echo "CC=/opt/nvidia/hpc_sdk/Linux_x86_64/23.9/comm_libs/openmpi4/bin/mpicc" >> $GITHUB_ENV - echo "FC=/opt/nvidia/hpc_sdk/Linux_x86_64/23.9/comm_libs/openmpi4/bin/mpifort" >> $GITHUB_ENV - echo "LD_LIBRARY_PATH=/opt/nvidia/hpc_sdk/Linux_x86_64/23.9/cuda/12.2/lib64:/opt/nvidia/hpc_sdk/Linux_x86_64/23.9/compilers/lib" >> $GITHUB_ENV + echo "OMPI_CXX=/opt/nvidia/hpc_sdk/Linux_x86_64/24.5/compilers/bin/nvc++" >> $GITHUB_ENV + echo "OMPI_CC=/opt/nvidia/hpc_sdk/Linux_x86_64/24.5/compilers/bin/nvc" >> $GITHUB_ENV + echo "OMPI_FC=/opt/nvidia/hpc_sdk/Linux_x86_64/24.5/compilers/bin/nvfortran" >> $GITHUB_ENV + echo "CC=/opt/nvidia/hpc_sdk/Linux_x86_64/24.5/comm_libs/openmpi4/bin/mpicc" >> $GITHUB_ENV + echo "FC=/opt/nvidia/hpc_sdk/Linux_x86_64/24.5/comm_libs/openmpi4/bin/mpifort" >> $GITHUB_ENV + echo "LD_LIBRARY_PATH=/opt/nvidia/hpc_sdk/Linux_x86_64/24.5/cuda/12.3/lib64:/opt/nvidia/hpc_sdk/Linux_x86_64/24.5/compilers/lib" >> $GITHUB_ENV echo "DESTDIR=/tmp" >> $GITHUB_ENV - name: CMake Configure shell: bash run: | - export PATH=/opt/nvidia/hpc_sdk/Linux_x86_64/23.9/comm_libs/openmpi4/bin:/opt/nvidia/hpc_sdk/Linux_x86_64/23.9/compilers/bin:$PATH + export PATH=/opt/nvidia/hpc_sdk/Linux_x86_64/24.5/comm_libs/openmpi4/bin:/opt/nvidia/hpc_sdk/Linux_x86_64/24.5/compilers/bin:$PATH mkdir "${{ runner.workspace }}/build" cd "${{ runner.workspace }}/build" cmake -C $GITHUB_WORKSPACE/config/cmake/cacheinit.cmake -G Ninja \ @@ -67,9 +67,3 @@ jobs: run: | cmake --build . --parallel 3 --config ${{ inputs.build_mode }} working-directory: ${{ runner.workspace }}/build - - - name: CMake Run Tests - shell: bash - run: | - ctest . --parallel 2 -C ${{ inputs.build_mode }} -V -E "ph5_f90_hyperslab_by_chunk|ph5_f90_hyperslab_by_pattern" - working-directory: ${{ runner.workspace }}/build From abcbd9ee02d84789b363c513fb5c964e105c73e0 Mon Sep 17 00:00:00 2001 From: Dana Robinson <43805+derobins@users.noreply.github.com> Date: Mon, 17 Jun 2024 11:00:22 -0700 Subject: [PATCH 16/45] Clean up comments in H5FDros3.c (#4572) --- src/H5FDros3.c | 404 +++++++++++++++---------------------------------- 1 file changed, 119 insertions(+), 285 deletions(-) diff --git a/src/H5FDros3.c b/src/H5FDros3.c index 9427409e4ed..d3fcd1536af 100644 --- a/src/H5FDros3.c +++ b/src/H5FDros3.c @@ -35,8 +35,7 @@ #ifdef H5_HAVE_ROS3_VFD -/* toggle debugging; pick a level - */ +/* Set debug output level */ #define ROS3_DEBUG_NONE 0 #define ROS3_DEBUG_TRACE_API 1 #define ROS3_DEBUG_TRACE_INTERNAL 2 @@ -49,19 +48,18 @@ /* Max size of the cache, in bytes */ #define ROS3_MAX_CACHE_SIZE 16777216 -/* The driver identification number, initialized at runtime - */ +/* The driver identification number, initialized at runtime */ static hid_t H5FD_ROS3_g = 0; -/* Session/security token property name - */ +/* Session/security token property name */ #define ROS3_TOKEN_PROP_NAME "ros3_token_prop" #if ROS3_STATS -/* arbitrarily large value, such that any reasonable size read will be "less" +/* Arbitrarily large value, such that any reasonable size read will be "less" * than this value and set a true minimum - * not 0 because that may be a valid recorded minimum in degenerate cases + * + * Not 0 because that may be a valid recorded minimum in degenerate cases */ #define ROS3_STATS_STARTING_MIN 0xfffffffful @@ -77,8 +75,7 @@ static hid_t H5FD_ROS3_g = 0; #define ROS3_STATS_START_POWER 10 #define ROS3_STATS_BIN_COUNT 16 /* MUST BE GREATER THAN 0 */ -/* - * Calculate `BASE ^ (START_POWER + (INTERVAL * bin_i))` +/* Calculate `BASE ^ (START_POWER + (INTERVAL * bin_i))` * Stores result at `(unsigned long long *) out_ptr`. * Used in computing boundaries between stats bins. */ @@ -94,19 +91,11 @@ static hid_t H5FD_ROS3_g = 0; *(out_ptr) = donotshadowresult; \ } -/* array to hold pre-computed boundaries for stats bins - */ +/* Array to hold pre-computed boundaries for stats bins */ static unsigned long long ros3_stats_boundaries[ROS3_STATS_BIN_COUNT]; /*************************************************************************** - * - * Structure: ros3_statsbin - * - * Purpose: - * - * Structure for storing per-file ros3 VFD usage statistics. - * - * + * Structure for storing per-file ros3 VFD usage statistics. * * `count` (unsigned long long) * @@ -123,7 +112,6 @@ static unsigned long long ros3_stats_boundaries[ROS3_STATS_BIN_COUNT]; * `max` (unsigned long long) * * Largest read size in this bin. - * ***************************************************************************/ typedef struct { unsigned long long count; @@ -135,19 +123,8 @@ typedef struct { #endif /* ROS3_STATS */ /*************************************************************************** - * - * Structure: H5FD_ros3_t - * - * Purpose: - * - * H5FD_ros3_t is a structure used to store all information needed to - * maintain R/O access to a single HDF5 file that has been stored as a - * S3 object. This structure is created when such a file is "opened" and - * discarded when it is "closed". - * - * Presents an S3 object as a file to the HDF5 library. - * - * + * Stores all information needed to maintain access to a single HDF5 file + * that has been stored as a S3 object. * * `pub` (H5FD_t) * @@ -188,7 +165,6 @@ typedef struct { * reserved for "big" reads, with no defined upper bound. * * *** end ROS3_STATS *** - * ***************************************************************************/ typedef struct H5FD_ros3_t { H5FD_t pub; @@ -203,8 +179,7 @@ typedef struct H5FD_ros3_t { #endif } H5FD_ros3_t; -/* - * These macros check for overflow of various quantities. These macros +/* These macros check for overflow of various quantities. These macros * assume that HDoff_t is signed and haddr_t and size_t are unsigned. * * ADDR_OVERFLOW: Checks whether a file address of type `haddr_t' @@ -294,9 +269,8 @@ H5FL_DEFINE_STATIC(H5FD_ros3_t); * Purpose: Initialize this driver by registering the driver with the * library. * - * Return: Success: The driver ID for the ros3 driver. - * Failure: Negative - * + * Return: Success: The driver ID for the ros3 driver + * Failure: H5I_INVALID_HID *------------------------------------------------------------------------- */ hid_t @@ -320,8 +294,7 @@ H5FD_ros3_init(void) } #if ROS3_STATS - /* pre-compute statsbin boundaries */ - /* do it only during initial registration */ + /* Pre-compute statsbin boundaries */ for (bin_i = 0; bin_i < ROS3_STATS_BIN_COUNT; bin_i++) { unsigned long long value = 0; @@ -343,7 +316,6 @@ H5FD_ros3_init(void) * Purpose: Shut down the VFD * * Returns: SUCCEED (Can't fail) - * *--------------------------------------------------------------------------- */ static herr_t @@ -365,12 +337,9 @@ H5FD__ros3_term(void) * Function: H5Pset_fapl_ros3 * * Purpose: Modify the file access property list to use the H5FD_ROS3 - * driver defined in this source file. All driver specific - * properties are passed in as a pointer to a suitably - * initialized instance of H5FD_ros3_fapl_t + * driver defined in this source file. * * Return: SUCCEED/FAIL - * *------------------------------------------------------------------------- */ herr_t @@ -401,20 +370,12 @@ H5Pset_fapl_ros3(hid_t fapl_id, const H5FD_ros3_fapl_t *fa) } /* end H5Pset_fapl_ros3() */ /*------------------------------------------------------------------------- - * Function: H5FD__ros3_validate_config() + * Function: H5FD__ros3_validate_config * * Purpose: Test to see if the supplied instance of H5FD_ros3_fapl_t - * contains internally consistent data. Return SUCCEED if so, - * and FAIL otherwise. - * - * Note the difference between internally consistent and - * correct. As we will have to try to access the target - * object to determine whether the supplied data is correct, - * we will settle for internal consistency at this point - * - * Return: SUCCEED if instance of H5FD_ros3_fapl_t contains internally - * consistent data, FAIL otherwise. + * contains internally consistent data. * + * Return: SUCCEED/FAIL *------------------------------------------------------------------------- */ static herr_t @@ -429,7 +390,7 @@ H5FD__ros3_validate_config(const H5FD_ros3_fapl_t *fa) if (fa->version != H5FD_CURR_ROS3_FAPL_T_VERSION) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "Unknown H5FD_ros3_fapl_t version"); - /* if set to authenticate, region and id cannot be empty strings */ + /* if set to authenticate, region and secret_id cannot be empty strings */ if (fa->authenticate == true) if ((fa->aws_region[0] == '\0') || (fa->secret_id[0] == '\0')) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "Inconsistent authentication information"); @@ -441,13 +402,9 @@ H5FD__ros3_validate_config(const H5FD_ros3_fapl_t *fa) /*------------------------------------------------------------------------- * Function: H5Pget_fapl_ros3 * - * Purpose: Returns information about the ros3 file access property - * list though the function arguments. - * - * Return: Success: Non-negative - * - * Failure: Negative + * Purpose: Queries properties set by the H5Pset_fapl_ros3() function. * + * Return: Non-negative on success/Negative on failure *------------------------------------------------------------------------- */ herr_t @@ -490,10 +447,8 @@ H5Pget_fapl_ros3(hid_t fapl_id, H5FD_ros3_fapl_t *fa_dst /*out*/) * Purpose: Gets a file access property list which could be used to * create an identical file. * - * Return: Success: Ptr to new file access property list value. - * - * Failure: NULL - * + * Return: Success: Pointer to new file access property list value + * Failure: NULL *------------------------------------------------------------------------- */ static void * @@ -528,10 +483,8 @@ H5FD__ros3_fapl_get(H5FD_t *_file) * * Purpose: Copies the ros3-specific file access properties. * - * Return: Success: Ptr to a new property list - * - * Failure: NULL - * + * Return: Success: Pointer to a new property list + * Failure: NULL *------------------------------------------------------------------------- */ static void * @@ -564,7 +517,6 @@ H5FD__ros3_fapl_copy(const void *_old_fa) * Purpose: Frees the ros3-specific file access properties. * * Return: SUCCEED (cannot fail) - * *------------------------------------------------------------------------- */ static herr_t @@ -574,7 +526,7 @@ H5FD__ros3_fapl_free(void *_fa) FUNC_ENTER_PACKAGE_NOERR - assert(fa != NULL); /* sanity check */ + assert(fa != NULL); H5MM_xfree(fa); @@ -587,13 +539,7 @@ H5FD__ros3_fapl_free(void *_fa) * Purpose: Returns session/security token of the ros3 file access * property list though the function arguments. * - * Return: Success: Non-negative - * - * Failure: Negative - * - * Programmer: Jan-Willem Blokland - * 2023-05-26 - * + * Return: SUCCEED/FAIL *------------------------------------------------------------------------- */ herr_t @@ -640,15 +586,11 @@ H5Pget_fapl_ros3_token(hid_t fapl_id, size_t size, char *token_dst /*out*/) } /* end H5Pget_fapl_ros3_token() */ /*------------------------------------------------------------------------- - * Function: H5FD__ros3_str_token_copy() + * Function: H5FD__ros3_str_token_copy * * Purpose: Create a copy of the token string. * * Return: SUCCEED/FAIL - * - * Programmer: Jan-Willem Blokland - * 2023-05-26 - * *------------------------------------------------------------------------- */ static herr_t @@ -672,17 +614,11 @@ H5FD__ros3_str_token_copy(const char H5_ATTR_UNUSED *name, size_t H5_ATTR_UNUSED } /* H5FD__ros3_str_token_copy() */ /*------------------------------------------------------------------------- - * Function: H5FD__ros3_str_token_cmp() + * Function: H5FD__ros3_str_token_cmp * * Purpose: Compares two token strings with each other. * - * Return: - * - Equivalent: 0 - * - Not Equivalent: non-zero value - * - * Programmer: Jan-Willem Blokland - * 2023-05-26 - * + * Return: A value like strcmp() *------------------------------------------------------------------------- */ static int @@ -711,17 +647,13 @@ H5FD__ros3_str_token_cmp(const void *_value1, const void *_value2, size_t H5_ATT } /* H5FD__ros3_str_token_cmp */ /*------------------------------------------------------------------------- - * Function: H5FD__ros3_str_token_close() + * Function: H5FD__ros3_str_token_close * * Purpose: Closes/frees the memory associated to the token string. * Currently, it is an empty implementation since there no * additional treatment needed for this property. * * Return: SUCCEED/FAIL - * - * Programmer: Jan-Willem Blokland - * 2023-05-26 - * *------------------------------------------------------------------------- */ static herr_t @@ -739,7 +671,7 @@ H5FD__ros3_str_token_close(const char H5_ATTR_UNUSED *name, size_t H5_ATTR_UNUSE } /* H5FD__ros3_str_token_close */ /*------------------------------------------------------------------------- - * Function: H5FD__ros3_str_token_delete() + * Function: H5FD__ros3_str_token_delete * * Purpose: Deletes the property token from the property list and frees * the memory associated to the token string. @@ -747,10 +679,6 @@ H5FD__ros3_str_token_close(const char H5_ATTR_UNUSED *name, size_t H5_ATTR_UNUSE * additional treatment needed for this property. * * Return: SUCCEED/FAIL - * - * Programmer: Jan-Willem Blokland - * 2023-05-26 - * *------------------------------------------------------------------------- */ static herr_t @@ -769,17 +697,13 @@ H5FD__ros3_str_token_delete(hid_t H5_ATTR_UNUSED prop_id, const char H5_ATTR_UNU } /* H5FD__ros3_str_token_delete */ /*------------------------------------------------------------------------- - * Function: H5Pset_fapl_ros3_token() + * Function: H5Pset_fapl_ros3_token * * Purpose: Modify the file access property list to use the H5FD_ROS3 * driver defined in this source file by adding or * modifying the session/security token property. * - * Return: SUCCEED/FAIL - * - * Programmer: Jan-Willem Blokland - * 2023-05-26 - * + * Return: Non-negative on success/Negative on failure *------------------------------------------------------------------------- */ herr_t @@ -832,21 +756,11 @@ H5Pset_fapl_ros3_token(hid_t fapl_id, const char *token) #if ROS3_STATS /*---------------------------------------------------------------------------- + * Function: ros3_reset_stats * - * Function: ros3_reset_stats() - * - * Purpose: - * - * Reset the stats collection elements in this virtual file structure. - * - * Clears any set data in stats bins; initializes/zeroes values. - * - * Return: - * - * - SUCCESS: `SUCCEED` - * - FAILURE: `FAIL` - * - Occurs if the file is invalid somehow + * Purpose: Reset the collected statistics * + * Return: SUCCEED/FAIL *---------------------------------------------------------------------------- */ static herr_t @@ -882,16 +796,13 @@ ros3_reset_stats(H5FD_ros3_t *file) #endif /* ROS3_STATS */ /*------------------------------------------------------------------------- + * Function: H5FD__ros3_open * - * Function: H5FD__ros3_open() - * - * Purpose: - * - * Create and/or opens a file as an HDF5 file. + * Purpose: Create and/or open a file as an HDF5 file. * * Any flag except H5F_ACC_RDONLY will cause an error. * - * Name (as received from `H5FD_open()`) must conform to web url: + * `url` param (as received from `H5FD_open()`) must conform to web url: * NAME :: HTTP "://" DOMAIN [PORT] ["/" [URI] [QUERY] ] * HTTP :: "http" [ "s" ] * DOMAIN :: e.g., "mybucket.host.org" @@ -899,14 +810,8 @@ ros3_reset_stats(H5FD_ros3_t *file) * URI :: (e.g., "path/to/resource.hd5" ) * QUERY :: "?" (e.g., "arg1=param1&arg2=param2") * - * Return: - * - * Success: A pointer to a new file data structure. - * The public fields will be initialized by the caller, which is - * always H5FD_open(). - * - * Failure: NULL - * + * Return: Success: A pointer to a new file data structure + * Failure: NULL *------------------------------------------------------------------------- */ static H5FD_t * @@ -958,13 +863,14 @@ H5FD__ros3_open(const char *url, unsigned flags, hid_t fapl_id, haddr_t maxaddr) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "unable to get token value"); } - /* open file; procedure depends on whether or not the fapl instructs to + /* Open file; procedure depends on whether or not the fapl instructs to * authenticate requests or not. */ if (fa.authenticate == true) { - /* compute signing key (part of AWS/S3 REST API) - * can be re-used by user/key for 7 days after creation. - * find way to reuse/share + /* Compute signing key (part of AWS/S3 REST API). Can be re-used by + * user/key for 7 days after creation. + * + * TODO: Find way to reuse/share? */ now = gmnow(); assert(now != NULL); @@ -991,7 +897,7 @@ H5FD__ros3_open(const char *url, unsigned flags, hid_t fapl_id, haddr_t maxaddr) */ HGOTO_ERROR(H5E_VFL, H5E_CANTOPENFILE, NULL, "could not open"); - /* create new file struct */ + /* Create new file struct */ file = H5FL_CALLOC(H5FD_ros3_t); if (file == NULL) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "unable to allocate file struct"); @@ -1002,7 +908,7 @@ H5FD__ros3_open(const char *url, unsigned flags, hid_t fapl_id, haddr_t maxaddr) #if ROS3_STATS if (FAIL == ros3_reset_stats(file)) HGOTO_ERROR(H5E_INTERNAL, H5E_UNINITIALIZED, NULL, "unable to reset file statistics"); -#endif /* ROS3_STATS */ +#endif /* Cache the initial bytes of the file */ { @@ -1027,20 +933,17 @@ H5FD__ros3_open(const char *url, unsigned flags, hid_t fapl_id, haddr_t maxaddr) H5MM_xfree(file->cache); file = H5FL_FREE(H5FD_ros3_t, file); } - curl_global_cleanup(); /* early cleanup because open failed */ - } /* end if null return value (error) */ + curl_global_cleanup(); + } FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__ros3_open() */ #if ROS3_STATS /*---------------------------------------------------------------------------- + * Function: ros3_fprint_stats * - * Function: ros3_fprint_stats() - * - * Purpose: - * - * Tabulate and pretty-print statistics for this virtual file. + * Purpose: Tabulate and pretty-print statistics for this virtual file. * * Should be called upon file close. * @@ -1077,13 +980,7 @@ H5FD__ros3_open(const char *url, unsigned flags, hid_t fapl_id, haddr_t maxaddr) * - 41080 bytes is represented by 40.177k, not 41.080k * - 1004.831M represents approx. 1052642000 bytes * - * Return: - * - * - SUCCESS: `SUCCEED` - * - FAILURE: `FAIL` - * - occurs if the file passed in is invalid - * - TODO: if stream is invalid? how can we check this? - * + * Return: SUCCEED/FAIL *---------------------------------------------------------------------------- */ static herr_t @@ -1293,13 +1190,13 @@ ros3_fprint_stats(FILE *stream, const H5FD_ros3_t *file) assert(suffix_i < sizeof(suffixes)); fprintf(stream, " %8.3f%c %7llu %7llu %8.3f%c %8.3f%c %8.3f%c %8.3f%c\n", re_dub, - suffixes[suffix_i], /* bin ceiling */ - m->count, /* metadata reads */ - r->count, /* raw data reads */ - bm_val, bm_suffix, /* metadata bytes */ - br_val, br_suffix, /* raw data bytes */ - am_val, am_suffix, /* metadata average */ - ar_val, ar_suffix); /* raw data average */ + suffixes[suffix_i], /* Bin ceiling */ + m->count, /* Metadata reads */ + r->count, /* Raw data reads */ + bm_val, bm_suffix, /* Metadata bytes */ + br_val, br_suffix, /* Raw data bytes */ + am_val, am_suffix, /* Metadata average */ + ar_val, ar_suffix); /* Raw data average */ fflush(stream); } @@ -1311,17 +1208,11 @@ ros3_fprint_stats(FILE *stream, const H5FD_ros3_t *file) #endif /* ROS3_STATS */ /*------------------------------------------------------------------------- + * Function: H5FD__ros3_close * - * Function: H5FD__ros3_close() - * - * Purpose: - * - * Close an HDF5 file. - * - * Return: - * - * SUCCEED/FAIL + * Purpose: Close the file. * + * Return: SUCCEED/FAIL *------------------------------------------------------------------------- */ static herr_t @@ -1336,7 +1227,6 @@ H5FD__ros3_close(H5FD_t H5_ATTR_UNUSED *_file) fprintf(stdout, "H5FD__ros3_close() called.\n"); #endif - /* Sanity checks */ assert(file != NULL); assert(file->s3r_handle != NULL); @@ -1344,10 +1234,9 @@ H5FD__ros3_close(H5FD_t H5_ATTR_UNUSED *_file) /* TODO: mechanism to re-target stats printout */ if (ros3_fprint_stats(stdout, file) == FAIL) HGOTO_ERROR(H5E_INTERNAL, H5E_ERROR, FAIL, "problem while writing file statistics"); -#endif /* ROS3_STATS */ +#endif - /* Close the underlying request handle - */ + /* Close the underlying request handle */ if (FAIL == H5FD_s3comms_s3r_close(file->s3r_handle)) HGOTO_ERROR(H5E_VFL, H5E_CANTCLOSEFILE, FAIL, "unable to close S3 request handle"); @@ -1356,36 +1245,31 @@ H5FD__ros3_close(H5FD_t H5_ATTR_UNUSED *_file) file = H5FL_FREE(H5FD_ros3_t, file); done: - curl_global_cleanup(); /* cleanup to answer init on open */ + curl_global_cleanup(); FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__ros3_close() */ /*------------------------------------------------------------------------- + * Function: H5FD__ros3_cmp * - * Function: H5FD__ros3_cmp() + * Purpose: Compares two files belonging to this driver using an + * arbitrary (but consistent) ordering: * - * Purpose: + * + url scheme + * + url host + * + url port + * + url path + * + url query + * + fapl aws_region + * + fapl secret_id + * + fapl secret_key * - * Compares two files belonging to this driver using an arbitrary - * (but consistent) ordering: - * - * + url scheme - * + url host - * + url port - * + url path - * + url query - * + fapl aws_region - * + fapl secret_id - * + fapl secret_key - * - * tl;dr -> check URL, check credentials - * - * Return: - * - * - Equivalent: 0 - * - Not Equivalent: -1 + * TODO: This should return -1/0/1 like the other VFDs * + * Return: Equivalent: 0 + * Not Equivalent: -1 + * (Can't fail) *------------------------------------------------------------------------- */ static int @@ -1493,14 +1377,7 @@ H5FD__ros3_cmp(const H5FD_t *_f1, const H5FD_t *_f2) * Purpose: Set the flags that this VFL driver is capable of supporting. * (listed in H5FDpublic.h) * - * Note that since the ROS3 VFD is read only, most flags - * are irrelevant. - * - * The term "set" is highly misleading... - * stores/copies the supported flags in the out-pointer `flags`. - * * Return: SUCCEED (Can't fail) - * *------------------------------------------------------------------------- */ static herr_t @@ -1512,30 +1389,27 @@ H5FD__ros3_query(const H5FD_t H5_ATTR_UNUSED *_file, unsigned long *flags) fprintf(stdout, "H5FD__ros3_query() called.\n"); #endif - /* Set the VFL feature flags that this driver supports */ + /* Set the VFL feature flags that this driver supports + * + * Since the ros3 VFD is read-only, many flags are irrelevant. + */ if (flags) { *flags = 0; /* OK to perform data sieving for faster raw data reads & writes */ *flags |= H5FD_FEAT_DATA_SIEVE; - } /* end if */ + } FUNC_LEAVE_NOAPI(SUCCEED) } /* H5FD__ros3_query() */ /*------------------------------------------------------------------------- + * Function: H5FD__ros3_get_eoa * - * Function: H5FD__ros3_get_eoa() - * - * Purpose: - * - * Gets the end-of-address marker for the file. The EOA marker - * is the first address past the last byte allocated in the - * format address space. - * - * Return: - * - * The end-of-address marker. + * Purpose: Gets the end-of-address marker for the file. The EOA marker + * is the first address past the last byte allocated in the + * format address space. * + * Return: The end-of-address marker (Can't fail) *------------------------------------------------------------------------- */ static haddr_t @@ -1553,17 +1427,11 @@ H5FD__ros3_get_eoa(const H5FD_t *_file, H5FD_mem_t H5_ATTR_UNUSED type) } /* end H5FD__ros3_get_eoa() */ /*------------------------------------------------------------------------- + * Function: H5FD__ros3_set_eoa * - * Function: H5FD__ros3_set_eoa() - * - * Purpose: - * - * Set the end-of-address marker for the file. - * - * Return: - * - * SUCCEED (can't fail) + * Purpose: Set the end-of-address marker for the file. * + * Return: SUCCEED (can't fail) *------------------------------------------------------------------------- */ static herr_t @@ -1583,18 +1451,12 @@ H5FD__ros3_set_eoa(H5FD_t *_file, H5FD_mem_t H5_ATTR_UNUSED type, haddr_t addr) } /* H5FD__ros3_set_eoa() */ /*------------------------------------------------------------------------- + * Function: H5FD__ros3_get_eof * - * Function: H5FD__ros3_get_eof() - * - * Purpose: - * - * Returns the end-of-file marker. - * - * Return: - * - * EOF: the first address past the end of the "file", either the - * filesystem file or the HDF5 file. + * Purpose: Returns the end-of-file marker. * + * Return: End of file address, the first address past the end of the + * "file". (Can't fail) *------------------------------------------------------------------------- */ static haddr_t @@ -1612,17 +1474,11 @@ H5FD__ros3_get_eof(const H5FD_t *_file, H5FD_mem_t H5_ATTR_UNUSED type) } /* end H5FD__ros3_get_eof() */ /*------------------------------------------------------------------------- + * Function: H5FD__ros3_get_handle * - * Function: H5FD__ros3_get_handle() - * - * Purpose: - * - * Returns the S3 Request handle (s3r_t) of ros3 file driver. - * - * Returns: - * - * SUCCEED/FAIL + * Purpose: Returns the S3 Request handle (s3r_t) of ros3 file driver. * + * Returns: SUCCEED/FAIL *------------------------------------------------------------------------- */ static herr_t @@ -1647,22 +1503,13 @@ H5FD__ros3_get_handle(H5FD_t *_file, hid_t H5_ATTR_UNUSED fapl, void **file_hand } /* end H5FD__ros3_get_handle() */ /*------------------------------------------------------------------------- + * Function: H5FD__ros3_read * - * Function: H5FD__ros3_read() - * - * Purpose - * - * Reads SIZE bytes of data from FILE beginning at address ADDR - * into buffer BUF according to data transfer properties in DXPL_ID. - * - * Return: - * - * Success: `SUCCEED` - * - Result is stored in caller-supplied buffer BUF. - * Failure: `FAIL` - * - Unable to complete read. - * - Contents of buffer `buf` are undefined. + * Purpose: Reads SIZE bytes of data from FILE beginning at address ADDR + * into buffer BUF according to data transfer properties in + * DXPL_ID. * + * Return: SUCCEED/FAIL *------------------------------------------------------------------------- */ static herr_t @@ -1676,7 +1523,7 @@ H5FD__ros3_read(H5FD_t *_file, H5FD_mem_t H5_ATTR_UNUSED type, hid_t H5_ATTR_UNU /* working variables for storing stats */ ros3_statsbin *bin = NULL; unsigned bin_i = 0; -#endif /* ROS3_STATS */ +#endif FUNC_ENTER_PACKAGE @@ -1705,7 +1552,6 @@ H5FD__ros3_read(H5FD_t *_file, H5FD_mem_t H5_ATTR_UNUSED type, hid_t H5_ATTR_UNU HGOTO_ERROR(H5E_VFL, H5E_READERROR, FAIL, "unable to execute read"); #if ROS3_STATS - /* Find which "bin" this read fits in. Can be "overflow" bin. */ for (bin_i = 0; bin_i < ROS3_STATS_BIN_COUNT; bin_i++) if ((unsigned long long)size < ros3_stats_boundaries[bin_i]) @@ -1725,8 +1571,7 @@ H5FD__ros3_read(H5FD_t *_file, H5FD_mem_t H5_ATTR_UNUSED type, hid_t H5_ATTR_UNU } bin->count++; bin->bytes += (unsigned long long)size; - -#endif /* ROS3_STATS */ +#endif } done: @@ -1734,18 +1579,13 @@ H5FD__ros3_read(H5FD_t *_file, H5FD_mem_t H5_ATTR_UNUSED type, hid_t H5_ATTR_UNU } /* end H5FD__ros3_read() */ /*------------------------------------------------------------------------- + * Function: H5FD__ros3_write * - * Function: H5FD__ros3_write() - * - * Purpose: - * - * Write bytes to file. - * UNSUPPORTED IN READ-ONLY ROS3 VFD. + * Purpose: Write bytes to file * - * Return: - * - * FAIL (Not possible with Read-Only S3 file.) + * UNSUPPORTED IN READ-ONLY ROS3 VFD. * + * Return: FAIL (Not possible with Read-Only S3 file) *------------------------------------------------------------------------- */ static herr_t @@ -1767,20 +1607,14 @@ H5FD__ros3_write(H5FD_t H5_ATTR_UNUSED *_file, H5FD_mem_t H5_ATTR_UNUSED type, h } /* H5FD__ros3_write() */ /*------------------------------------------------------------------------- + * Function: H5FD__ros3_truncate * - * Function: H5FD__ros3_truncate() - * - * Purpose: - * - * Makes sure that the true file size is the same (or larger) - * than the end-of-address. - * - * NOT POSSIBLE ON READ-ONLY S3 FILES. - * - * Return: + * Purpose: Makes sure that the true file size is the same (or larger) + * than the end-of-address. * - * FAIL (Not possible on Read-Only S3 files.) + * NOT POSSIBLE ON READ-ONLY S3 FILES * + * Return: FAIL (Not possible on Read-Only S3 files) *------------------------------------------------------------------------- */ static herr_t From 2f98dfe38da60606819f0299777a9d93d7322fd0 Mon Sep 17 00:00:00 2001 From: Dana Robinson <43805+derobins@users.noreply.github.com> Date: Tue, 18 Jun 2024 10:05:16 -0700 Subject: [PATCH 17/45] Rename INSTALL_Auto.txt to INSTALL_Autotools.txt (#4575) --- release_docs/{INSTALL_Auto.txt => INSTALL_Autotools.txt} | 0 release_docs/INSTALL_CMake.txt | 2 +- release_docs/INSTALL_Cygwin.txt | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) rename release_docs/{INSTALL_Auto.txt => INSTALL_Autotools.txt} (100%) diff --git a/release_docs/INSTALL_Auto.txt b/release_docs/INSTALL_Autotools.txt similarity index 100% rename from release_docs/INSTALL_Auto.txt rename to release_docs/INSTALL_Autotools.txt diff --git a/release_docs/INSTALL_CMake.txt b/release_docs/INSTALL_CMake.txt index 55761bc32c2..4000861da8e 100644 --- a/release_docs/INSTALL_CMake.txt +++ b/release_docs/INSTALL_CMake.txt @@ -1186,7 +1186,7 @@ See RELEASE.txt in the release_notes/ directory for the list of platforms tested for this release. Instructions for building and testing HDF5 using autotools can be found in the -INSTALL_Auto.txt file found in this folder. +INSTALL_Autotools.txt file found in this folder. ======================================================================== diff --git a/release_docs/INSTALL_Cygwin.txt b/release_docs/INSTALL_Cygwin.txt index c246915d5d1..c1ca7e848a7 100644 --- a/release_docs/INSTALL_Cygwin.txt +++ b/release_docs/INSTALL_Cygwin.txt @@ -119,7 +119,7 @@ Build, Test and Install HDF5 on Cygwin 4. Configuring - Notes: See detailed information in hdf5/release_docs/INSTALL_Auto.txt. + Notes: See detailed information in hdf5/release_docs/INSTALL_Autotools.txt. The host configuration file for Cygwin is located in the `config' directory and are based on architecture name, From d73dcf77fdfa1416b08143e38c1978d089f57447 Mon Sep 17 00:00:00 2001 From: Dana Robinson <43805+derobins@users.noreply.github.com> Date: Tue, 18 Jun 2024 11:50:27 -0700 Subject: [PATCH 18/45] Clean up ros3 VFD stats code (#4579) * Removes printf debugging * Simplifies and centralizes stats code * Use #ifdef ROS3_STATS instead of #if * Other misc tidying --- src/H5FDros3.c | 1036 +++++++++++++++++++++--------------------------- 1 file changed, 457 insertions(+), 579 deletions(-) diff --git a/src/H5FDros3.c b/src/H5FDros3.c index d3fcd1536af..108f240142a 100644 --- a/src/H5FDros3.c +++ b/src/H5FDros3.c @@ -13,10 +13,8 @@ /* * Read-Only S3 Virtual File Driver (VFD) * - * Purpose: - * - * Provide read-only access to files hosted on Amazon's S3 service. - * Relies on "s3comms" utility layer to implement the AWS REST API. + * Provides read-only access to files hosted on Amazon's S3 service. + * Relies on "s3comms" utility layer to implement the AWS REST API. */ #ifdef H5_HAVE_ROS3_VFD @@ -35,15 +33,8 @@ #ifdef H5_HAVE_ROS3_VFD -/* Set debug output level */ -#define ROS3_DEBUG_NONE 0 -#define ROS3_DEBUG_TRACE_API 1 -#define ROS3_DEBUG_TRACE_INTERNAL 2 -#define ROS3_DEBUG ROS3_DEBUG_NONE - -/* toggle stats collection and reporting - */ -#define ROS3_STATS 0 +/* Define to turn on stats collection and reporting */ +#define ROS3_STATS /* Max size of the cache, in bytes */ #define ROS3_MAX_CACHE_SIZE 16777216 @@ -54,71 +45,28 @@ static hid_t H5FD_ROS3_g = 0; /* Session/security token property name */ #define ROS3_TOKEN_PROP_NAME "ros3_token_prop" -#if ROS3_STATS +#ifdef ROS3_STATS -/* Arbitrarily large value, such that any reasonable size read will be "less" - * than this value and set a true minimum - * - * Not 0 because that may be a valid recorded minimum in degenerate cases +/* The ros3 VFD can collect some simple I/O stats on a per-file basis. These + * are stored in arrays of bins (one for data and one for metadata) in the the + * VFD's file structure. Each bin contains stats for I/O operations of a given + * I/O size range. The bin boundaries are kept in a global "bin boundaries" + * array that is initialized at VFD startup and does not change. */ -#define ROS3_STATS_STARTING_MIN 0xfffffffful -/* Configuration definitions for stats collection and breakdown - * - * 2^10 = 1024 - * Reads up to 1024 bytes (1 kB) fall in bin 0 - * 2^(10+(1*16)) = 2^26 = 64MB - * Reads of 64MB or greater fall in "overflow" bin[BIN_COUNT] - */ -#define ROS3_STATS_BASE 2 -#define ROS3_STATS_INTERVAL 1 -#define ROS3_STATS_START_POWER 10 -#define ROS3_STATS_BIN_COUNT 16 /* MUST BE GREATER THAN 0 */ - -/* Calculate `BASE ^ (START_POWER + (INTERVAL * bin_i))` - * Stores result at `(unsigned long long *) out_ptr`. - * Used in computing boundaries between stats bins. - */ -#define ROS3_STATS_POW(bin_i, out_ptr) \ - { \ - unsigned long long donotshadowresult = 1; \ - unsigned donotshadowindex = 0; \ - for (donotshadowindex = 0; \ - donotshadowindex < (((bin_i)*ROS3_STATS_INTERVAL) + ROS3_STATS_START_POWER); \ - donotshadowindex++) { \ - donotshadowresult *= ROS3_STATS_BASE; \ - } \ - *(out_ptr) = donotshadowresult; \ - } +/* Number of bins */ +#define ROS3_STATS_BIN_COUNT 16 /* Array to hold pre-computed boundaries for stats bins */ -static unsigned long long ros3_stats_boundaries[ROS3_STATS_BIN_COUNT]; +static uint64_t ros3_stats_boundaries_g[ROS3_STATS_BIN_COUNT]; -/*************************************************************************** - * Structure for storing per-file ros3 VFD usage statistics. - * - * `count` (unsigned long long) - * - * Number of reads with size in this bin's range. - * - * `bytes` (unsigned long long) - * - * Total number of bytes read through this bin. - * - * `min` (unsigned long long) - * - * Smallest read size in this bin. - * - * `max` (unsigned long long) - * - * Largest read size in this bin. - ***************************************************************************/ -typedef struct { - unsigned long long count; - unsigned long long bytes; - unsigned long long min; - unsigned long long max; -} ros3_statsbin; +/* Structure for storing per-file usage statistics */ +typedef struct H5FD_ros3_stats_bin { + uint64_t count; /* # of reads with size in this bin's range */ + uint64_t bytes; /* Total bytes read in this bin */ + uint64_t min; /* Smallest read size in this bin */ + uint64_t max; /* Largest read size in this bin */ +} H5FD_ros3_stats_bin_t; #endif /* ROS3_STATS */ @@ -148,14 +96,13 @@ typedef struct { * Responsible for communicating with remote host and presenting file * contents as indistinguishable from a file on the local filesystem. * - * *** present only if ROS3_SATS is flagged to enable stats collection *** + * *** present only if ROS3_SATS is set to enable stats collection *** * - * `meta` (ros3_statsbin[]) - * `raw` (ros3_statsbin[]) + * `meta` (H5FD_ros3_stats_bin_t[]) + * `raw` (H5FD_ros3_stats_bin_t[]) * - * Only present if ros3 stats collection is enabled. - * - * Arrays of `ros3_statsbin` structures to record raw- and metadata reads. + * Arrays of `H5FD_ros3_stats_bin_t` structures to record raw- and + * metadata reads. * * Records count and size of reads performed by the VFD, and is used to * print formatted usage statistics to stdout upon VFD shutdown. @@ -173,9 +120,9 @@ typedef struct H5FD_ros3_t { s3r_t *s3r_handle; uint8_t *cache; size_t cache_size; -#if ROS3_STATS - ros3_statsbin meta[ROS3_STATS_BIN_COUNT + 1]; - ros3_statsbin raw[ROS3_STATS_BIN_COUNT + 1]; +#ifdef ROS3_STATS + H5FD_ros3_stats_bin_t meta[ROS3_STATS_BIN_COUNT + 1]; + H5FD_ros3_stats_bin_t raw[ROS3_STATS_BIN_COUNT + 1]; #endif } H5FD_ros3_t; @@ -217,6 +164,12 @@ static int H5FD__ros3_str_token_cmp(const void *_value1, const void *_value2, static herr_t H5FD__ros3_str_token_close(const char *name, size_t size, void *_value); static herr_t H5FD__ros3_str_token_delete(hid_t prop_id, const char *name, size_t size, void *_value); +#ifdef ROS3_STATS +static herr_t H5FD__ros3_reset_stats(H5FD_ros3_t *file); +static herr_t H5FD__ros3_log_read_stats(H5FD_ros3_t *file, H5FD_mem_t type, uint64_t size); +static herr_t H5FD__ros3_print_stats(FILE *stream, const H5FD_ros3_t *file); +#endif + static const H5FD_class_t H5FD_ros3_g = { H5FD_CLASS_VERSION, /* struct version */ H5FD_ROS3_VALUE, /* value */ @@ -277,30 +230,19 @@ hid_t H5FD_ros3_init(void) { hid_t ret_value = H5I_INVALID_HID; -#if ROS3_STATS - unsigned int bin_i; -#endif FUNC_ENTER_NOAPI(H5I_INVALID_HID) -#if ROS3_DEBUG - fprintf(stdout, "H5FD_ros3_init() called.\n"); -#endif - if (H5I_VFL != H5I_get_type(H5FD_ROS3_g)) { H5FD_ROS3_g = H5FD_register(&H5FD_ros3_g, sizeof(H5FD_class_t), false); if (H5I_INVALID_HID == H5FD_ROS3_g) { HGOTO_ERROR(H5E_ID, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register ros3"); } -#if ROS3_STATS - /* Pre-compute statsbin boundaries */ - for (bin_i = 0; bin_i < ROS3_STATS_BIN_COUNT; bin_i++) { - unsigned long long value = 0; - - ROS3_STATS_POW(bin_i, &value) - ros3_stats_boundaries[bin_i] = value; - } +#ifdef ROS3_STATS + /* Pre-compute stats bin boundaries on powers of 2 >= 10 */ + for (int i = 0; i < ROS3_STATS_BIN_COUNT; i++) + ros3_stats_boundaries_g[i] = 1 << (10 + i); #endif } @@ -323,10 +265,6 @@ H5FD__ros3_term(void) { FUNC_ENTER_PACKAGE_NOERR -#if ROS3_DEBUG - fprintf(stdout, "H5FD__ros3_term() called.\n"); -#endif - /* Reset VFL ID */ H5FD_ROS3_g = 0; @@ -352,10 +290,6 @@ H5Pset_fapl_ros3(hid_t fapl_id, const H5FD_ros3_fapl_t *fa) assert(fa != NULL); -#if ROS3_DEBUG - fprintf(stdout, "H5Pset_fapl_ros3() called.\n"); -#endif - plist = H5P_object_verify(fapl_id, H5P_FILE_ACCESS); if (plist == NULL) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list"); @@ -416,10 +350,6 @@ H5Pget_fapl_ros3(hid_t fapl_id, H5FD_ros3_fapl_t *fa_dst /*out*/) FUNC_ENTER_API(FAIL) -#if ROS3_DEBUG - fprintf(stdout, "H5Pget_fapl_ros3() called.\n"); -#endif - if (fa_dst == NULL) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "fa_dst is NULL"); @@ -553,10 +483,6 @@ H5Pget_fapl_ros3_token(hid_t fapl_id, size_t size, char *token_dst /*out*/) FUNC_ENTER_API(FAIL) -#if ROS3_DEBUG - fprintf(stdout, "H5Pget_fapl_ros3_token() called.\n"); -#endif - if (size == 0) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "size cannot be zero."); if (token_dst == NULL) @@ -601,10 +527,6 @@ H5FD__ros3_str_token_copy(const char H5_ATTR_UNUSED *name, size_t H5_ATTR_UNUSED FUNC_ENTER_PACKAGE -#if ROS3_DEBUG - fprintf(stdout, "H5FD__ros3_str_token_copy() called.\n"); -#endif - if (*value) if (NULL == (*value = strdup(*value))) HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't copy string property token"); @@ -716,10 +638,6 @@ H5Pset_fapl_ros3_token(hid_t fapl_id, const char *token) FUNC_ENTER_API(FAIL) -#if ROS3_DEBUG - fprintf(stdout, "H5Pset_fapl_ros3_token() called.\n"); -#endif - if (fapl_id == H5P_DEFAULT) HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "can't set values in default property list"); if (NULL == (plist = H5P_object_verify(fapl_id, H5P_FILE_ACCESS))) @@ -754,47 +672,6 @@ H5Pset_fapl_ros3_token(hid_t fapl_id, const char *token) FUNC_LEAVE_API(ret_value) } /* end H5Pset_fapl_ros3_token() */ -#if ROS3_STATS -/*---------------------------------------------------------------------------- - * Function: ros3_reset_stats - * - * Purpose: Reset the collected statistics - * - * Return: SUCCEED/FAIL - *---------------------------------------------------------------------------- - */ -static herr_t -ros3_reset_stats(H5FD_ros3_t *file) -{ - unsigned i = 0; - herr_t ret_value = SUCCEED; - - FUNC_ENTER_PACKAGE - -#if ROS3_DEBUG >= ROS3_DEBUG_TRACE_INTERNAL - printf("ros3_reset_stats() called\n"); -#endif - - if (file == NULL) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "file was null"); - - for (i = 0; i <= ROS3_STATS_BIN_COUNT; i++) { - file->raw[i].bytes = 0; - file->raw[i].count = 0; - file->raw[i].min = (unsigned long long)ROS3_STATS_STARTING_MIN; - file->raw[i].max = 0; - - file->meta[i].bytes = 0; - file->meta[i].count = 0; - file->meta[i].min = (unsigned long long)ROS3_STATS_STARTING_MIN; - file->meta[i].max = 0; - } - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end ros3_reset_stats() */ -#endif /* ROS3_STATS */ - /*------------------------------------------------------------------------- * Function: H5FD__ros3_open * @@ -830,10 +707,6 @@ H5FD__ros3_open(const char *url, unsigned flags, hid_t fapl_id, haddr_t maxaddr) FUNC_ENTER_PACKAGE -#if ROS3_DEBUG - fprintf(stdout, "H5FD__ros3_open() called.\n"); -#endif - /* Sanity check on file offsets */ HDcompile_assert(sizeof(HDoff_t) >= sizeof(size_t)); @@ -905,8 +778,8 @@ H5FD__ros3_open(const char *url, unsigned flags, hid_t fapl_id, haddr_t maxaddr) file->s3r_handle = handle; H5MM_memcpy(&(file->fa), &fa, sizeof(H5FD_ros3_fapl_t)); -#if ROS3_STATS - if (FAIL == ros3_reset_stats(file)) +#ifdef ROS3_STATS + if (FAIL == H5FD__ros3_reset_stats(file)) HGOTO_ERROR(H5E_INTERNAL, H5E_UNINITIALIZED, NULL, "unable to reset file statistics"); #endif @@ -939,383 +812,106 @@ H5FD__ros3_open(const char *url, unsigned flags, hid_t fapl_id, haddr_t maxaddr) FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__ros3_open() */ -#if ROS3_STATS -/*---------------------------------------------------------------------------- - * Function: ros3_fprint_stats - * - * Purpose: Tabulate and pretty-print statistics for this virtual file. - * - * Should be called upon file close. - * - * Shows number of reads and bytes read, broken down by - * "raw" (H5FD_MEM_DRAW) - * or "meta" (any other flag) - * - * Prints filename and listing of total number of reads and bytes read, - * both as a grand total and separate meta- and raw data reads. - * - * If any reads were done, prints out two tables: - * - * 1. overview of raw- and metadata reads - * - min (smallest size read) - * - average of size read - * - k,M,G suffixes by powers of 1024 (2^10) - * - max (largest size read) - * 2. tabulation of "bins", sepraring reads into exponentially-larger - * ranges of size. - * - columns for number of reads, total bytes, and average size, with - * separate sub-colums for raw- and metadata reads. - * - each row represents one bin, identified by the top of its range - * - * Bin ranges can be modified with pound-defines at the top of this file. - * - * Bins without any reads in their bounds are not printed. - * - * An "overflow" bin is also present, to catch "big" reads. - * - * Output for all bins (and range ceiling and average size report) - * is divied by powers of 1024. By corollary, four digits before the decimal - * is valid. +/*------------------------------------------------------------------------- + * Function: H5FD__ros3_close * - * - 41080 bytes is represented by 40.177k, not 41.080k - * - 1004.831M represents approx. 1052642000 bytes + * Purpose: Close the file. * * Return: SUCCEED/FAIL - *---------------------------------------------------------------------------- + *------------------------------------------------------------------------- */ static herr_t -ros3_fprint_stats(FILE *stream, const H5FD_ros3_t *file) +H5FD__ros3_close(H5FD_t H5_ATTR_UNUSED *_file) { - herr_t ret_value = SUCCEED; - parsed_url_t *purl = NULL; - unsigned i = 0; - unsigned long count_meta = 0; - unsigned long count_raw = 0; - double average_meta = 0.0; - double average_raw = 0.0; - unsigned long long min_meta = (unsigned long long)ROS3_STATS_STARTING_MIN; - unsigned long long min_raw = (unsigned long long)ROS3_STATS_STARTING_MIN; - unsigned long long max_meta = 0; - unsigned long long max_raw = 0; - unsigned long long bytes_raw = 0; - unsigned long long bytes_meta = 0; - double re_dub = 0.0; /* reusable double variable */ - unsigned suffix_i = 0; - const char suffixes[] = {' ', 'K', 'M', 'G', 'T', 'P'}; + H5FD_ros3_t *file = (H5FD_ros3_t *)_file; + herr_t ret_value = SUCCEED; FUNC_ENTER_PACKAGE - if (stream == NULL) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "file stream cannot be null"); - if (file == NULL) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "file cannot be null"); - if (file->s3r_handle == NULL) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "s3 request handle cannot be null"); - if (file->s3r_handle->purl == NULL) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "parsed url structure cannot be null"); - purl = file->s3r_handle->purl; + assert(file != NULL); + assert(file->s3r_handle != NULL); - /****************** - * PRINT FILENAME * - ******************/ +#ifdef ROS3_STATS + if (H5FD__ros3_print_stats(stdout, file) == FAIL) + HGOTO_ERROR(H5E_INTERNAL, H5E_ERROR, FAIL, "problem while writing file statistics"); +#endif - fprintf(stream, "stats for %s://%s", purl->scheme, purl->host); - if (purl->port != NULL && purl->port[0] != '\0') - fprintf(stream, ":%s", purl->port); - if (purl->query != NULL && purl->query[0] != '\0') { - if (purl->path != NULL && purl->path[0] != '\0') - fprintf(stream, "/%s", purl->path); - else - fprintf(stream, "/"); - fprintf(stream, "?%s", purl->query); - } - else if (purl->path != NULL && purl->path[0] != '\0') { - fprintf(stream, "/%s", purl->path); - } - fprintf(stream, "\n"); + /* Close the underlying request handle */ + if (FAIL == H5FD_s3comms_s3r_close(file->s3r_handle)) + HGOTO_ERROR(H5E_VFL, H5E_CANTCLOSEFILE, FAIL, "unable to close S3 request handle"); - /******************* - * AGGREGATE STATS * - *******************/ + /* Release the file info */ + H5MM_xfree(file->cache); + file = H5FL_FREE(H5FD_ros3_t, file); - for (i = 0; i <= ROS3_STATS_BIN_COUNT; i++) { - const ros3_statsbin *r = &file->raw[i]; - const ros3_statsbin *m = &file->meta[i]; +done: + curl_global_cleanup(); - if (m->min < min_meta) - min_meta = m->min; - if (r->min < min_raw) - min_raw = r->min; - if (m->max > max_meta) - max_meta = m->max; - if (r->max > max_raw) - max_raw = r->max; + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5FD__ros3_close() */ - count_raw += r->count; - count_meta += m->count; - bytes_raw += r->bytes; - bytes_meta += m->bytes; - } - if (count_raw > 0) - average_raw = (double)bytes_raw / (double)count_raw; - if (count_meta > 0) - average_meta = (double)bytes_meta / (double)count_meta; +/*------------------------------------------------------------------------- + * Function: H5FD__ros3_cmp + * + * Purpose: Compares two files belonging to this driver using an + * arbitrary (but consistent) ordering: + * + * + url scheme + * + url host + * + url port + * + url path + * + url query + * + fapl aws_region + * + fapl secret_id + * + fapl secret_key + * + * TODO: This should return -1/0/1 like the other VFDs + * + * Return: Equivalent: 0 + * Not Equivalent: -1 + * (Can't fail) + *------------------------------------------------------------------------- + */ +static int +H5FD__ros3_cmp(const H5FD_t *_f1, const H5FD_t *_f2) +{ + const H5FD_ros3_t *f1 = (const H5FD_ros3_t *)_f1; + const H5FD_ros3_t *f2 = (const H5FD_ros3_t *)_f2; + const parsed_url_t *purl1 = NULL; + const parsed_url_t *purl2 = NULL; + int ret_value = 0; - /****************** - * PRINT OVERVIEW * - ******************/ + FUNC_ENTER_PACKAGE_NOERR - fprintf(stream, "TOTAL READS: %lu (%lu meta, %lu raw)\n", count_raw + count_meta, count_meta, count_raw); - fprintf(stream, "TOTAL BYTES: %llu (%llu meta, %llu raw)\n", bytes_raw + bytes_meta, bytes_meta, - bytes_raw); + assert(f1->s3r_handle != NULL); + assert(f2->s3r_handle != NULL); - if (count_raw + count_meta == 0) - goto done; + purl1 = (const parsed_url_t *)f1->s3r_handle->purl; + purl2 = (const parsed_url_t *)f2->s3r_handle->purl; + assert(purl1 != NULL); + assert(purl2 != NULL); + assert(purl1->scheme != NULL); + assert(purl2->scheme != NULL); + assert(purl1->host != NULL); + assert(purl2->host != NULL); - /************************* - * PRINT AGGREGATE STATS * - *************************/ + /* URL: SCHEME */ + if (strcmp(purl1->scheme, purl2->scheme)) + HGOTO_DONE(-1); - fprintf(stream, "SIZES meta raw\n"); - fprintf(stream, " min "); - if (count_meta == 0) - fprintf(stream, " 0.000 "); - else { - re_dub = (double)min_meta; - for (suffix_i = 0; re_dub >= 1024.0; suffix_i++) - re_dub /= 1024.0; - assert(suffix_i < sizeof(suffixes)); - fprintf(stream, "%8.3lf%c ", re_dub, suffixes[suffix_i]); - } + /* URL: HOST */ + if (strcmp(purl1->host, purl2->host)) + HGOTO_DONE(-1); - if (count_raw == 0) - fprintf(stream, " 0.000 \n"); - else { - re_dub = (double)min_raw; - for (suffix_i = 0; re_dub >= 1024.0; suffix_i++) - re_dub /= 1024.0; - assert(suffix_i < sizeof(suffixes)); - fprintf(stream, "%8.3lf%c\n", re_dub, suffixes[suffix_i]); + /* URL: PORT */ + if (purl1->port && purl2->port) { + if (strcmp(purl1->port, purl2->port)) + HGOTO_DONE(-1); } - - fprintf(stream, " avg "); - re_dub = (double)average_meta; - for (suffix_i = 0; re_dub >= 1024.0; suffix_i++) - re_dub /= 1024.0; - assert(suffix_i < sizeof(suffixes)); - fprintf(stream, "%8.3lf%c ", re_dub, suffixes[suffix_i]); - - re_dub = (double)average_raw; - for (suffix_i = 0; re_dub >= 1024.0; suffix_i++) - re_dub /= 1024.0; - assert(suffix_i < sizeof(suffixes)); - fprintf(stream, "%8.3lf%c\n", re_dub, suffixes[suffix_i]); - - fprintf(stream, " max "); - re_dub = (double)max_meta; - for (suffix_i = 0; re_dub >= 1024.0; suffix_i++) - re_dub /= 1024.0; - assert(suffix_i < sizeof(suffixes)); - fprintf(stream, "%8.3lf%c ", re_dub, suffixes[suffix_i]); - - re_dub = (double)max_raw; - for (suffix_i = 0; re_dub >= 1024.0; suffix_i++) - re_dub /= 1024.0; - assert(suffix_i < sizeof(suffixes)); - fprintf(stream, "%8.3lf%c\n", re_dub, suffixes[suffix_i]); - - /****************************** - * PRINT INDIVIDUAL BIN STATS * - ******************************/ - - fprintf(stream, "BINS # of reads total bytes average size\n"); - fprintf(stream, " up-to meta raw meta raw meta raw\n"); - - for (i = 0; i <= ROS3_STATS_BIN_COUNT; i++) { - const ros3_statsbin *m; - const ros3_statsbin *r; - unsigned long long range_end = 0; - char bm_suffix = ' '; /* bytes-meta */ - double bm_val = 0.0; - char br_suffix = ' '; /* bytes-raw */ - double br_val = 0.0; - char am_suffix = ' '; /* average-meta */ - double am_val = 0.0; - char ar_suffix = ' '; /* average-raw */ - double ar_val = 0.0; - - m = &file->meta[i]; - r = &file->raw[i]; - if (r->count == 0 && m->count == 0) - continue; - - range_end = ros3_stats_boundaries[i]; - - if (i == ROS3_STATS_BIN_COUNT) { - range_end = ros3_stats_boundaries[i - 1]; - fprintf(stream, ">"); - } - else - fprintf(stream, " "); - - bm_val = (double)m->bytes; - for (suffix_i = 0; bm_val >= 1024.0; suffix_i++) - bm_val /= 1024.0; - assert(suffix_i < sizeof(suffixes)); - bm_suffix = suffixes[suffix_i]; - - br_val = (double)r->bytes; - for (suffix_i = 0; br_val >= 1024.0; suffix_i++) - br_val /= 1024.0; - assert(suffix_i < sizeof(suffixes)); - br_suffix = suffixes[suffix_i]; - - if (m->count > 0) - am_val = (double)(m->bytes) / (double)(m->count); - for (suffix_i = 0; am_val >= 1024.0; suffix_i++) - am_val /= 1024.0; - assert(suffix_i < sizeof(suffixes)); - am_suffix = suffixes[suffix_i]; - - if (r->count > 0) - ar_val = (double)(r->bytes) / (double)(r->count); - for (suffix_i = 0; ar_val >= 1024.0; suffix_i++) - ar_val /= 1024.0; - assert(suffix_i < sizeof(suffixes)); - ar_suffix = suffixes[suffix_i]; - - re_dub = (double)range_end; - for (suffix_i = 0; re_dub >= 1024.0; suffix_i++) - re_dub /= 1024.0; - assert(suffix_i < sizeof(suffixes)); - - fprintf(stream, " %8.3f%c %7llu %7llu %8.3f%c %8.3f%c %8.3f%c %8.3f%c\n", re_dub, - suffixes[suffix_i], /* Bin ceiling */ - m->count, /* Metadata reads */ - r->count, /* Raw data reads */ - bm_val, bm_suffix, /* Metadata bytes */ - br_val, br_suffix, /* Raw data bytes */ - am_val, am_suffix, /* Metadata average */ - ar_val, ar_suffix); /* Raw data average */ - - fflush(stream); - } - -done: - FUNC_LEAVE_NOAPI(ret_value) - -} /* ros3_fprint_stats */ -#endif /* ROS3_STATS */ - -/*------------------------------------------------------------------------- - * Function: H5FD__ros3_close - * - * Purpose: Close the file. - * - * Return: SUCCEED/FAIL - *------------------------------------------------------------------------- - */ -static herr_t -H5FD__ros3_close(H5FD_t H5_ATTR_UNUSED *_file) -{ - H5FD_ros3_t *file = (H5FD_ros3_t *)_file; - herr_t ret_value = SUCCEED; - - FUNC_ENTER_PACKAGE - -#if ROS3_DEBUG - fprintf(stdout, "H5FD__ros3_close() called.\n"); -#endif - - assert(file != NULL); - assert(file->s3r_handle != NULL); - -#if ROS3_STATS - /* TODO: mechanism to re-target stats printout */ - if (ros3_fprint_stats(stdout, file) == FAIL) - HGOTO_ERROR(H5E_INTERNAL, H5E_ERROR, FAIL, "problem while writing file statistics"); -#endif - - /* Close the underlying request handle */ - if (FAIL == H5FD_s3comms_s3r_close(file->s3r_handle)) - HGOTO_ERROR(H5E_VFL, H5E_CANTCLOSEFILE, FAIL, "unable to close S3 request handle"); - - /* Release the file info */ - H5MM_xfree(file->cache); - file = H5FL_FREE(H5FD_ros3_t, file); - -done: - curl_global_cleanup(); - - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5FD__ros3_close() */ - -/*------------------------------------------------------------------------- - * Function: H5FD__ros3_cmp - * - * Purpose: Compares two files belonging to this driver using an - * arbitrary (but consistent) ordering: - * - * + url scheme - * + url host - * + url port - * + url path - * + url query - * + fapl aws_region - * + fapl secret_id - * + fapl secret_key - * - * TODO: This should return -1/0/1 like the other VFDs - * - * Return: Equivalent: 0 - * Not Equivalent: -1 - * (Can't fail) - *------------------------------------------------------------------------- - */ -static int -H5FD__ros3_cmp(const H5FD_t *_f1, const H5FD_t *_f2) -{ - const H5FD_ros3_t *f1 = (const H5FD_ros3_t *)_f1; - const H5FD_ros3_t *f2 = (const H5FD_ros3_t *)_f2; - const parsed_url_t *purl1 = NULL; - const parsed_url_t *purl2 = NULL; - int ret_value = 0; - - FUNC_ENTER_PACKAGE_NOERR - -#if ROS3_DEBUG - fprintf(stdout, "H5FD__ros3_cmp() called.\n"); -#endif - - assert(f1->s3r_handle != NULL); - assert(f2->s3r_handle != NULL); - - purl1 = (const parsed_url_t *)f1->s3r_handle->purl; - purl2 = (const parsed_url_t *)f2->s3r_handle->purl; - assert(purl1 != NULL); - assert(purl2 != NULL); - assert(purl1->scheme != NULL); - assert(purl2->scheme != NULL); - assert(purl1->host != NULL); - assert(purl2->host != NULL); - - /* URL: SCHEME */ - if (strcmp(purl1->scheme, purl2->scheme)) - HGOTO_DONE(-1); - - /* URL: HOST */ - if (strcmp(purl1->host, purl2->host)) - HGOTO_DONE(-1); - - /* URL: PORT */ - if (purl1->port && purl2->port) { - if (strcmp(purl1->port, purl2->port)) - HGOTO_DONE(-1); - } - else if (purl1->port) - HGOTO_DONE(-1); - else if (purl2->port) - HGOTO_DONE(-1); + else if (purl1->port) + HGOTO_DONE(-1); + else if (purl2->port) + HGOTO_DONE(-1); /* URL: PATH */ if (purl1->path && purl2->path) { @@ -1385,10 +981,6 @@ H5FD__ros3_query(const H5FD_t H5_ATTR_UNUSED *_file, unsigned long *flags) { FUNC_ENTER_PACKAGE_NOERR -#if ROS3_DEBUG >= ROS3_DEBUG_TRACE_INTERNAL - fprintf(stdout, "H5FD__ros3_query() called.\n"); -#endif - /* Set the VFL feature flags that this driver supports * * Since the ros3 VFD is read-only, many flags are irrelevant. @@ -1419,10 +1011,6 @@ H5FD__ros3_get_eoa(const H5FD_t *_file, H5FD_mem_t H5_ATTR_UNUSED type) FUNC_ENTER_PACKAGE_NOERR -#if ROS3_DEBUG >= ROS3_DEBUG_TRACE_INTERNAL - fprintf(stdout, "H5FD__ros3_get_eoa() called.\n"); -#endif - FUNC_LEAVE_NOAPI(file->eoa) } /* end H5FD__ros3_get_eoa() */ @@ -1441,10 +1029,6 @@ H5FD__ros3_set_eoa(H5FD_t *_file, H5FD_mem_t H5_ATTR_UNUSED type, haddr_t addr) FUNC_ENTER_PACKAGE_NOERR -#if ROS3_DEBUG >= ROS3_DEBUG_TRACE_INTERNAL - fprintf(stdout, "H5FD__ros3_set_eoa() called.\n"); -#endif - file->eoa = addr; FUNC_LEAVE_NOAPI(SUCCEED) @@ -1466,10 +1050,6 @@ H5FD__ros3_get_eof(const H5FD_t *_file, H5FD_mem_t H5_ATTR_UNUSED type) FUNC_ENTER_PACKAGE_NOERR -#if ROS3_DEBUG >= ROS3_DEBUG_TRACE_INTERNAL - fprintf(stdout, "H5FD__ros3_get_eof() called.\n"); -#endif - FUNC_LEAVE_NOAPI(H5FD_s3comms_s3r_get_filesize(file->s3r_handle)) } /* end H5FD__ros3_get_eof() */ @@ -1489,10 +1069,6 @@ H5FD__ros3_get_handle(H5FD_t *_file, hid_t H5_ATTR_UNUSED fapl, void **file_hand FUNC_ENTER_PACKAGE -#if ROS3_DEBUG - fprintf(stdout, "H5FD__ros3_get_handle() called.\n"); -#endif - if (!file_handle) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "file handle not valid"); @@ -1519,18 +1095,9 @@ H5FD__ros3_read(H5FD_t *_file, H5FD_mem_t H5_ATTR_UNUSED type, hid_t H5_ATTR_UNU H5FD_ros3_t *file = (H5FD_ros3_t *)_file; size_t filesize = 0; herr_t ret_value = SUCCEED; -#if ROS3_STATS - /* working variables for storing stats */ - ros3_statsbin *bin = NULL; - unsigned bin_i = 0; -#endif FUNC_ENTER_PACKAGE -#if ROS3_DEBUG - fprintf(stdout, "H5FD__ros3_read() called.\n"); -#endif - assert(file); assert(file->cache); assert(file->s3r_handle); @@ -1551,26 +1118,9 @@ H5FD__ros3_read(H5FD_t *_file, H5FD_mem_t H5_ATTR_UNUSED type, hid_t H5_ATTR_UNU if (H5FD_s3comms_s3r_read(file->s3r_handle, addr, size, buf) == FAIL) HGOTO_ERROR(H5E_VFL, H5E_READERROR, FAIL, "unable to execute read"); -#if ROS3_STATS - /* Find which "bin" this read fits in. Can be "overflow" bin. */ - for (bin_i = 0; bin_i < ROS3_STATS_BIN_COUNT; bin_i++) - if ((unsigned long long)size < ros3_stats_boundaries[bin_i]) - break; - bin = (type == H5FD_MEM_DRAW) ? &file->raw[bin_i] : &file->meta[bin_i]; - - /* Store collected stats in appropriate bin */ - if (bin->count == 0) { - bin->min = size; - bin->max = size; - } - else { - if (size < bin->min) - bin->min = size; - if (size > bin->max) - bin->max = size; - } - bin->count++; - bin->bytes += (unsigned long long)size; +#ifdef ROS3_STATS + if (H5FD__ros3_log_read_stats(file, type, (uint64_t)size) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTSET, FAIL, "unable to log read stats"); #endif } @@ -1596,10 +1146,6 @@ H5FD__ros3_write(H5FD_t H5_ATTR_UNUSED *_file, H5FD_mem_t H5_ATTR_UNUSED type, h FUNC_ENTER_PACKAGE -#if ROS3_DEBUG - fprintf(stdout, "H5FD__ros3_write() called.\n"); -#endif - HGOTO_ERROR(H5E_VFL, H5E_UNSUPPORTED, FAIL, "cannot write to read-only file."); done: @@ -1624,14 +1170,346 @@ H5FD__ros3_truncate(H5FD_t H5_ATTR_UNUSED *_file, hid_t H5_ATTR_UNUSED dxpl_id, FUNC_ENTER_PACKAGE -#if ROS3_DEBUG - fprintf(stdout, "H5FD__ros3_truncate() called.\n"); -#endif - HGOTO_ERROR(H5E_VFL, H5E_UNSUPPORTED, FAIL, "cannot truncate read-only file."); done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__ros3_truncate() */ +#ifdef ROS3_STATS +/*---------------------------------------------------------------------------- + * Function: H5FD__ros3_reset_stats + * + * Purpose: Reset the collected statistics + * + * Return: SUCCEED/FAIL + *---------------------------------------------------------------------------- + */ +static herr_t +H5FD__ros3_reset_stats(H5FD_ros3_t *file) +{ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_PACKAGE + + if (file == NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "file was null"); + + for (int i = 0; i <= ROS3_STATS_BIN_COUNT; i++) { + file->raw[i].bytes = 0; + file->raw[i].count = 0; + file->raw[i].min = 0; + file->raw[i].max = 0; + + file->meta[i].bytes = 0; + file->meta[i].count = 0; + file->meta[i].min = 0; + file->meta[i].max = 0; + } + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5FD__ros3_reset_stats() */ + +/*---------------------------------------------------------------------------- + * Function: H5FD__ros3_log_read_stats + * + * Purpose: Add data for a read to the ros3 stats + * + * Return: SUCCEED/FAIL + *---------------------------------------------------------------------------- + */ +static herr_t +H5FD__ros3_log_read_stats(H5FD_ros3_t *file, H5FD_mem_t type, uint64_t size) +{ + H5FD_ros3_stats_bin_t *bin = NULL; + int i = 0; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_PACKAGE + + if (file == NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "file was null"); + + /* Find which "bin" this read fits in */ + for (i = 0; i < ROS3_STATS_BIN_COUNT; i++) + if (size < ros3_stats_boundaries_g[i]) + break; + bin = (type == H5FD_MEM_DRAW) ? &file->raw[i] : &file->meta[i]; + + /* Store collected stats in appropriate bin */ + bin->count++; + bin->bytes += size; + if (size < bin->min) + bin->min = size; + if (size > bin->max) + bin->max = size; +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5FD__ros3_log_read_stats() */ + +/*---------------------------------------------------------------------------- + * Function: H5FD__ros3_print_stats + * + * Purpose: Tabulate and pretty-print statistics for this virtual file. + * + * Should be called upon file close. + * + * Shows number of reads and bytes read, broken down by + * "raw" (H5FD_MEM_DRAW) or "meta" (any other flag) + * + * Prints filename and listing of total number of reads and bytes read, + * both as a grand total and separate meta- and raw data reads. + * + * If any reads were done, prints out two tables: + * + * 1. overview of raw- and metadata reads + * - min (smallest size read) + * - average of size read + * - k,M,G suffixes by powers of 1024 (2^10) + * - max (largest size read) + * 2. tabulation of "bins", sepraring reads into exponentially-larger + * ranges of size. + * - columns for number of reads, total bytes, and average size, with + * separate sub-colums for raw- and metadata reads. + * - each row represents one bin, identified by the top of its range + * + * Bins without any reads in their bounds are not printed. + * + * An "overflow" bin is also present, to catch "big" reads. + * + * Output for all bins (and range ceiling and average size report) is + * divied by powers of 1024. By corollary, four digits before the decimal + * is valid. + * + * - 41080 bytes is represented by 40.177k, not 41.080k + * - 1004.831M represents approx. 1052642000 bytes + * + * Return: SUCCEED/FAIL + *---------------------------------------------------------------------------- + */ +static herr_t +H5FD__ros3_print_stats(FILE *stream, const H5FD_ros3_t *file) +{ + herr_t ret_value = SUCCEED; + parsed_url_t *purl = NULL; + unsigned i = 0; + unsigned long count_meta = 0; + unsigned long count_raw = 0; + double average_meta = 0.0; + double average_raw = 0.0; + uint64_t min_meta = 0; + uint64_t min_raw = 0; + uint64_t max_meta = 0; + uint64_t max_raw = 0; + uint64_t bytes_raw = 0; + uint64_t bytes_meta = 0; + double re_dub = 0.0; /* reusable double variable */ + unsigned suffix_i = 0; + const char suffixes[] = {' ', 'K', 'M', 'G', 'T', 'P'}; + + FUNC_ENTER_PACKAGE + + if (stream == NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "file stream cannot be null"); + if (file == NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "file cannot be null"); + if (file->s3r_handle == NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "s3 request handle cannot be null"); + if (file->s3r_handle->purl == NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "parsed url structure cannot be null"); + purl = file->s3r_handle->purl; + + /****************** + * PRINT FILENAME * + ******************/ + + fprintf(stream, "stats for %s://%s", purl->scheme, purl->host); + if (purl->port != NULL && purl->port[0] != '\0') + fprintf(stream, ":%s", purl->port); + if (purl->query != NULL && purl->query[0] != '\0') { + if (purl->path != NULL && purl->path[0] != '\0') + fprintf(stream, "/%s", purl->path); + else + fprintf(stream, "/"); + fprintf(stream, "?%s", purl->query); + } + else if (purl->path != NULL && purl->path[0] != '\0') { + fprintf(stream, "/%s", purl->path); + } + fprintf(stream, "\n"); + + /******************* + * AGGREGATE STATS * + *******************/ + + for (i = 0; i <= ROS3_STATS_BIN_COUNT; i++) { + const H5FD_ros3_stats_bin_t *r = &file->raw[i]; + const H5FD_ros3_stats_bin_t *m = &file->meta[i]; + + if (m->min < min_meta) + min_meta = m->min; + if (r->min < min_raw) + min_raw = r->min; + if (m->max > max_meta) + max_meta = m->max; + if (r->max > max_raw) + max_raw = r->max; + + count_raw += r->count; + count_meta += m->count; + bytes_raw += r->bytes; + bytes_meta += m->bytes; + } + if (count_raw > 0) + average_raw = (double)bytes_raw / (double)count_raw; + if (count_meta > 0) + average_meta = (double)bytes_meta / (double)count_meta; + + /****************** + * PRINT OVERVIEW * + ******************/ + + fprintf(stream, "TOTAL READS: %lu (%lu meta, %lu raw)\n", count_raw + count_meta, count_meta, count_raw); + fprintf(stream, "TOTAL BYTES: %" PRIu64 " (%" PRIu64 " meta, %" PRIu64 " raw)\n", bytes_raw + bytes_meta, + bytes_meta, bytes_raw); + + if (count_raw + count_meta == 0) + goto done; + + /************************* + * PRINT AGGREGATE STATS * + *************************/ + + fprintf(stream, "SIZES meta raw\n"); + fprintf(stream, " min "); + if (count_meta == 0) + fprintf(stream, " 0.000 "); + else { + re_dub = (double)min_meta; + for (suffix_i = 0; re_dub >= 1024.0; suffix_i++) + re_dub /= 1024.0; + assert(suffix_i < sizeof(suffixes)); + fprintf(stream, "%8.3lf%c ", re_dub, suffixes[suffix_i]); + } + + if (count_raw == 0) + fprintf(stream, " 0.000 \n"); + else { + re_dub = (double)min_raw; + for (suffix_i = 0; re_dub >= 1024.0; suffix_i++) + re_dub /= 1024.0; + assert(suffix_i < sizeof(suffixes)); + fprintf(stream, "%8.3lf%c\n", re_dub, suffixes[suffix_i]); + } + + fprintf(stream, " avg "); + re_dub = (double)average_meta; + for (suffix_i = 0; re_dub >= 1024.0; suffix_i++) + re_dub /= 1024.0; + assert(suffix_i < sizeof(suffixes)); + fprintf(stream, "%8.3lf%c ", re_dub, suffixes[suffix_i]); + + re_dub = (double)average_raw; + for (suffix_i = 0; re_dub >= 1024.0; suffix_i++) + re_dub /= 1024.0; + assert(suffix_i < sizeof(suffixes)); + fprintf(stream, "%8.3lf%c\n", re_dub, suffixes[suffix_i]); + + fprintf(stream, " max "); + re_dub = (double)max_meta; + for (suffix_i = 0; re_dub >= 1024.0; suffix_i++) + re_dub /= 1024.0; + assert(suffix_i < sizeof(suffixes)); + fprintf(stream, "%8.3lf%c ", re_dub, suffixes[suffix_i]); + + re_dub = (double)max_raw; + for (suffix_i = 0; re_dub >= 1024.0; suffix_i++) + re_dub /= 1024.0; + assert(suffix_i < sizeof(suffixes)); + fprintf(stream, "%8.3lf%c\n", re_dub, suffixes[suffix_i]); + + /****************************** + * PRINT INDIVIDUAL BIN STATS * + ******************************/ + + fprintf(stream, "BINS # of reads total bytes average size\n"); + fprintf(stream, " up-to meta raw meta raw meta raw\n"); + + for (i = 0; i <= ROS3_STATS_BIN_COUNT; i++) { + const H5FD_ros3_stats_bin_t *m; + const H5FD_ros3_stats_bin_t *r; + uint64_t range_end = 0; + char bm_suffix = ' '; /* bytes-meta */ + double bm_val = 0.0; + char br_suffix = ' '; /* bytes-raw */ + double br_val = 0.0; + char am_suffix = ' '; /* average-meta */ + double am_val = 0.0; + char ar_suffix = ' '; /* average-raw */ + double ar_val = 0.0; + + m = &file->meta[i]; + r = &file->raw[i]; + if (r->count == 0 && m->count == 0) + continue; + + range_end = ros3_stats_boundaries_g[i]; + + if (i == ROS3_STATS_BIN_COUNT) { + range_end = ros3_stats_boundaries_g[i - 1]; + fprintf(stream, ">"); + } + else + fprintf(stream, " "); + + bm_val = (double)m->bytes; + for (suffix_i = 0; bm_val >= 1024.0; suffix_i++) + bm_val /= 1024.0; + assert(suffix_i < sizeof(suffixes)); + bm_suffix = suffixes[suffix_i]; + + br_val = (double)r->bytes; + for (suffix_i = 0; br_val >= 1024.0; suffix_i++) + br_val /= 1024.0; + assert(suffix_i < sizeof(suffixes)); + br_suffix = suffixes[suffix_i]; + + if (m->count > 0) + am_val = (double)(m->bytes) / (double)(m->count); + for (suffix_i = 0; am_val >= 1024.0; suffix_i++) + am_val /= 1024.0; + assert(suffix_i < sizeof(suffixes)); + am_suffix = suffixes[suffix_i]; + + if (r->count > 0) + ar_val = (double)(r->bytes) / (double)(r->count); + for (suffix_i = 0; ar_val >= 1024.0; suffix_i++) + ar_val /= 1024.0; + assert(suffix_i < sizeof(suffixes)); + ar_suffix = suffixes[suffix_i]; + + re_dub = (double)range_end; + for (suffix_i = 0; re_dub >= 1024.0; suffix_i++) + re_dub /= 1024.0; + assert(suffix_i < sizeof(suffixes)); + + fprintf(stream, " %8.3f%c %7" PRIu64 " %7" PRIu64 " %8.3f%c %8.3f%c %8.3f%c %8.3f%c\n", re_dub, + suffixes[suffix_i], /* Bin ceiling */ + m->count, /* Metadata reads */ + r->count, /* Raw data reads */ + bm_val, bm_suffix, /* Metadata bytes */ + br_val, br_suffix, /* Raw data bytes */ + am_val, am_suffix, /* Metadata average */ + ar_val, ar_suffix); /* Raw data average */ + + fflush(stream); + } + +done: + FUNC_LEAVE_NOAPI(ret_value) + +} /* H5FD__ros3_print_stats */ +#endif /* ROS3_STATS */ + #endif /* H5_HAVE_ROS3_VFD */ From 3f9a03b3f9a29bcd6dc95e09254ebaacbbc0afb5 Mon Sep 17 00:00:00 2001 From: Dana Robinson <43805+derobins@users.noreply.github.com> Date: Tue, 18 Jun 2024 14:15:30 -0700 Subject: [PATCH 19/45] Turn off ros3 VFD stat collection by default (#4581) Not a new change - an artifact from a previous check-in. --- src/H5FDros3.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/H5FDros3.c b/src/H5FDros3.c index 108f240142a..6222fef8bf3 100644 --- a/src/H5FDros3.c +++ b/src/H5FDros3.c @@ -34,7 +34,7 @@ #ifdef H5_HAVE_ROS3_VFD /* Define to turn on stats collection and reporting */ -#define ROS3_STATS +/* #define ROS3_STATS */ /* Max size of the cache, in bytes */ #define ROS3_MAX_CACHE_SIZE 16777216 From d2a31935f6cfa218e9d56d0c3c74445500d7223d Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Tue, 18 Jun 2024 16:17:43 -0500 Subject: [PATCH 20/45] Pause recording errors instead of clearing the error stack (#4475) An internal capability that's similar to the H5E_BEGIN_TRY / H5E_END_TRY macros in H5Epublic.h, but more efficient since we can avoid pushing errors on the stack entirely (and those macros use public API routines). This capability (and other techniques) can be used to remove use of H5E_clear_stack() and H5E_BEGIN_TRY / H5E_END_TRY within library routines. We want to remove H5E_clear_stack() because it can trigger calls to the H5I interface from within the H5E code, which creates a great deal of complexity for threadsafe code. And we want to remove H5E_BEGIN_TRY / H5E_END_TRY's because they make public API calls from within the library code. Also some other minor tidying in routines related to removing the use of H5E_clear_stack() and H5E_BEGIN_TRY / H5E_END_TRY from H5Fint.c --- bin/format_source | 6 +- release_docs/RELEASE.txt | 971 +------------------------ src/H5Dvirtual.c | 10 +- src/H5E.c | 179 ++++- src/H5Edeprec.c | 49 +- src/H5Eint.c | 124 +++- src/H5Epkg.h | 1 + src/H5Eprivate.h | 19 + src/H5Epublic.h | 68 +- src/H5FD.c | 102 ++- src/H5FDonion.c | 73 +- src/H5FDprivate.h | 3 +- src/H5FDsplitter.c | 7 +- src/H5FDsubfiling/H5FDsubfiling.c | 2 +- src/H5FDsubfiling/H5subfiling_common.c | 2 +- src/H5Fefc.c | 197 +++-- src/H5Fint.c | 339 +++++---- src/H5Fpkg.h | 11 +- src/H5Fprivate.h | 5 +- src/H5Lexternal.c | 4 +- src/H5VLnative_file.c | 4 +- test/efc.c | 964 ++++++++++++------------ test/error_test.c | 181 ++++- 23 files changed, 1437 insertions(+), 1884 deletions(-) diff --git a/bin/format_source b/bin/format_source index dea771ce7f4..c5aec15bf0f 100755 --- a/bin/format_source +++ b/bin/format_source @@ -25,10 +25,12 @@ find . \( -type d -path ./config -prune -and -not -path ./config \) \ -name H5LTanalyze.c \ -or -name H5LTparse.c \ -or -name H5LTparse.h \ - -or -name H5Epubgen.h \ + -or -name H5Edefin.h \ -or -name H5Einit.h \ + -or -name H5Emajdef.h \ + -or -name H5Emindef.h \ + -or -name H5Epubgen.h \ -or -name H5Eterm.h \ - -or -name H5Edefin.h \ -or -name H5version.h \ -or -name H5overflow.h \ \) \) \ diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt index bf0d0daed89..153c3ee944f 100644 --- a/release_docs/RELEASE.txt +++ b/release_docs/RELEASE.txt @@ -82,357 +82,21 @@ New Features - Added configure options for enabling/disabling non-standard programming language features - * Added a new configuration option that allows enabling or disabling of - support for features that are extensions to programming languages, such - as support for the _Float16 datatype: - - CMake: HDF5_ENABLE_NONSTANDARD_FEATURES (ON/OFF) (Default: ON) - Autotools: --enable-nonstandard-features (yes/no) (Default: yes) - - When this option is enabled, configure time checks are still performed - to ensure that a feature can be used properly, but these checks may not - be sufficient when compiler support for a feature is incomplete or broken, - resulting in library build failures. When set to OFF/no, this option - provides a way to disable support for all non-standard features to avoid - these issues. Individual features can still be re-enabled with their - respective configuration options. - - * Added a new configuration option that allows enabling or disabling of - support for the _Float16 C datatype: - - CMake: HDF5_ENABLE_NONSTANDARD_FEATURE_FLOAT16 (ON/OFF) (Default: ON) - Autotools: --enable-nonstandard-feature-float16 (yes/no) (Default: yes) - - While support for the _Float16 C datatype can generally be detected and - used properly, some compilers have incomplete support for the datatype - and will pass configure time checks while still failing to build HDF5. - This option provides a way to disable support for the _Float16 datatype - when the compiler doesn't have the proper support for it. - - - Deprecate bin/cmakehdf5 script - - With the improvements made in CMake since version 3.23 and the addition - of CMake preset files, this script is no longer necessary. - - See INSTALL_CMake.txt file, Section X: Using CMakePresets.json for compiling - - - Overhauled LFS support checks - - In 2024, we can assume that Large File Support (LFS) exists on all - systems we support, though it may require flags to enable it, - particularly when building 32-bit binaries. The HDF5 source does - not use any of the 64-bit specific API calls (e.g., ftello64) - or explicit 64-bit offsets via off64_t. - - Autotools - - * We now use AC_SYS_LARGEFILE to determine how to support LFS. We - previously used a custom m4 script for this. - - CMake - - * The HDF_ENABLE_LARGE_FILE option (advanced) has been removed - * We no longer run a test program to determine if LFS works, which - will help with cross-compiling - * On Linux we now unilaterally set -D_LARGEFILE_SOURCE and - -D_FILE_OFFSET_BITS=64, regardless of 32/64 bit system. CMake - doesn't offer a nice equivalent to AC_SYS_LARGEFILE and since - those options do nothing on 64-bit systems, this seems safe and - covers all our bases. We don't set -D_LARGEFILE64_SOURCE since - we don't use any of the POSIX 64-bit specific API calls like - ftello64, as noted above. - * We didn't test for LFS support on non-Linux platforms. We've added - comments for how LFS should probably be supported on AIX and Solaris, - which seem to be alive, though uncommon. PRs would be appreciated if - anyone wishes to test this. - - This overhaul also fixes GitHub #2395, which points out that the LFS flags - used when building with CMake differ based on whether CMake has been - run before. The LFS check program that caused this problem no longer exists. - - - The CMake HDF5_ENABLE_DEBUG_H5B option has been removed - - This enabled some additional version-1 B-tree checks. These have been - removed so the option is no longer necessary. - - This option was CMake-only and marked as advanced. - - - New option for building with static CRT in Windows - - The following option has been added: - HDF5_BUILD_STATIC_CRT_LIBS "Build With Static Windows CRT Libraries" OFF - Because our minimum CMake is 3.18, the macro to change runtime flags no longer - works as CMake changed the default behavior in CMake 3.15. - - Fixes GitHub issue #3984 - - - Added support for the new MSVC preprocessor - - Microsoft added support for a new, standards-conformant preprocessor - to MSVC, which can be enabled with the /Zc:preprocessor option. This - preprocessor would trip over our HDopen() variadic function-like - macro, which uses a feature that only works with the legacy preprocessor. - - ifdefs have been added that select the correct HDopen() form and - allow building HDF5 with the /Zc:preprocessor option. - - The HDopen() macro is located in an internal header file and only - affects building the HDF5 library from source. - - Fixes GitHub #2515 - - - Renamed HDF5_ENABLE_USING_MEMCHECKER to HDF5_USING_ANALYSIS_TOOL - - The HDF5_USING_ANALYSIS_TOOL is used to indicate to test macros that - an analysis tool is being used and that the tests should not use - the runTest.cmake macros and it's variations. The analysis tools, - like valgrind, test the macro code instead of the program under test. - - HDF5_ENABLE_USING_MEMCHECKER is still used for controlling the HDF5 - define, H5_USING_MEMCHECKER. - - - New option for building and naming tools in CMake - - The following option has been added: - HDF5_BUILD_STATIC_TOOLS "Build Static Tools Not Shared Tools" OFF - - The default will build shared tools unless BUILD_SHARED_LIBS = OFF. - Tools will no longer have "-shared" as only one set of tools will be created. - - - Incorporated HDF5 examples repository into HDF5 library. - - The HDF5Examples folder is equivalent to the hdf5-examples repository. - This enables building and testing the examples - during the library build process or after the library has been installed. - Previously, the hdf5-examples archives were downloaded - for packaging with the library. Now the examples can be built - and tested without a packaged install of the library. - - However, to maintain the ability to use the HDF5Examples with an installed - library, it is necessary to map the option names used by the library - to those used by the examples. The typical pattern is: - = - HDF_BUILD_FORTRAN = ${HDF5_BUILD_FORTRAN} - - - Added new option for CMake to mark tests as SKIPPED. - - HDF5_DISABLE_TESTS_REGEX is a REGEX string that will be checked with - test names and if there is a match then that test's property will be - set to DISABLED. HDF5_DISABLE_TESTS_REGEX can be initialized on the - command line: "-DHDF5_DISABLE_TESTS_REGEX:STRING=" - See CMake documentation for regex-specification. - - - Added defaults to CMake for long double conversion checks - - HDF5 performs a couple of checks at build time to see if long double - values can be converted correctly (IBM's Power architecture uses a - special format for long doubles). These checks were performed using - TRY_RUN, which is a problem when cross-compiling. - - These checks now use default values appropriate for most non-Power - systems when cross-compiling. The cache values can be pre-set if - necessary, which will preempt both the TRY_RUN and the default. - - Affected values: - H5_LDOUBLE_TO_LONG_SPECIAL (default no) - H5_LONG_TO_LDOUBLE_SPECIAL (default no) - H5_LDOUBLE_TO_LLONG_ACCURATE (default yes) - H5_LLONG_TO_LDOUBLE_CORRECT (default yes) - H5_DISABLE_SOME_LDOUBLE_CONV (default no) - - Fixes GitHub #3585 + - Added the CMake variable HDF5_ENABLE_ROS3_VFD to the HDF5 CMake config + file hdf5-config.cmake. This allows to easily detect if the library + has been built with or without read-only S3 functionality. Library: -------- - - Relaxed behavior of H5Pset_page_buffer_size() when opening files - - This API call sets the size of a file's page buffer cache. This call - was extremely strict about matching its parameters to the file strategy - and page size used to create the file, requiring a separate open of the - file to obtain these parameters. - - These requirements have been relaxed when using the fapl to open - a previously-created file: - - * When opening a file that does not use the H5F_FSPACE_STRATEGY_PAGE - strategy, the setting is ignored and the file will be opened, but - without a page buffer cache. This was previously an error. - - * When opening a file that has a page size larger than the desired - page buffer cache size, the page buffer cache size will be increased - to the file's page size. This was previously an error. - - The behavior when creating a file using H5Pset_page_buffer_size() is - unchanged. - - Fixes GitHub issue #3382 - - - Added support for _Float16 16-bit half-precision floating-point datatype - - Support for the _Float16 C datatype has been added on platforms where: - - - The _Float16 datatype and its associated macros (FLT16_MIN, FLT16_MAX, - FLT16_EPSILON, etc.) are available - - A simple test program that converts between the _Float16 datatype and - other datatypes with casts can be successfully compiled and run at - configure time. Some compilers appear to be buggy or feature-incomplete - in this regard and will generate calls to compiler-internal functions - for converting between the _Float16 datatype and other datatypes, but - will not link these functions into the build, resulting in build - failures. - - The following new macros have been added: - - H5_HAVE__FLOAT16 - This macro is defined in H5pubconf.h and will have - the value 1 if support for the _Float16 datatype is - available. It will not be defined otherwise. - - H5_SIZEOF__FLOAT16 - This macro is defined in H5pubconf.h and will have - a value corresponding to the size of the _Float16 - datatype, as computed by sizeof(). It will have the - value 0 if support for the _Float16 datatype is not - available. - - H5_HAVE_FABSF16 - This macro is defined in H5pubconf.h and will have the - value 1 if the fabsf16 function is available for use. - - H5_LDOUBLE_TO_FLOAT16_CORRECT - This macro is defined in H5pubconf.h and - will have the value 1 if the platform can - correctly convert long double values to - _Float16. Some compilers have issues with - this. - - H5T_NATIVE_FLOAT16 - This macro maps to the ID of an HDF5 datatype representing - the native C _Float16 datatype for the platform. If - support for the _Float16 datatype is not available, the - macro will map to H5I_INVALID_HID and should not be used. - - H5T_IEEE_F16BE - This macro maps to the ID of an HDF5 datatype representing - a big-endian IEEE 754 16-bit floating-point datatype. This - datatype is available regardless of whether _Float16 support - is available or not. - - H5T_IEEE_F16LE - This macro maps to the ID of an HDF5 datatype representing - a little-endian IEEE 754 16-bit floating-point datatype. - This datatype is available regardless of whether _Float16 - support is available or not. - - The following new hard datatype conversion paths have been added, but - will only be used when _Float16 support is available: - - H5T_NATIVE_SCHAR <-> H5T_NATIVE_FLOAT16 | H5T_NATIVE_UCHAR <-> H5T_NATIVE_FLOAT16 - H5T_NATIVE_SHORT <-> H5T_NATIVE_FLOAT16 | H5T_NATIVE_USHORT <-> H5T_NATIVE_FLOAT16 - H5T_NATIVE_INT <-> H5T_NATIVE_FLOAT16 | H5T_NATIVE_UINT <-> H5T_NATIVE_FLOAT16 - H5T_NATIVE_LONG <-> H5T_NATIVE_FLOAT16 | H5T_NATIVE_ULONG <-> H5T_NATIVE_FLOAT16 - H5T_NATIVE_LLONG <-> H5T_NATIVE_FLOAT16 | H5T_NATIVE_ULLONG <-> H5T_NATIVE_FLOAT16 - H5T_NATIVE_FLOAT <-> H5T_NATIVE_FLOAT16 | H5T_NATIVE_DOUBLE <-> H5T_NATIVE_FLOAT16 - H5T_NATIVE_LDOUBLE <-> H5T_NATIVE_FLOAT16 - - The H5T_NATIVE_LDOUBLE -> H5T_NATIVE_FLOAT16 hard conversion path will only - be available and used if H5_LDOUBLE_TO_FLOAT16_CORRECT has a value of 1. Otherwise, - the conversion will be emulated in software by the library. - - Note that in the absence of any compiler flags for architecture-specific - tuning, the generated code for datatype conversions with the _Float16 type - may perform conversions by first promoting the type to float. Use of - architecture-specific tuning compiler flags may instead allow for the - generation of specialized instructions, such as AVX512-FP16 instructions, - if available. - - - Made several improvements to the datatype conversion code - - * The datatype conversion code was refactored to use pointers to - H5T_t datatype structures internally rather than IDs wrapping - the pointers to those structures. These IDs are needed if an - application-registered conversion function or conversion exception - function are involved during the conversion process. For simplicity, - the conversion code simply passed these IDs down and let the internal - code unwrap the IDs as necessary when needing to access the wrapped - H5T_t structures. However, this could cause a significant amount of - repeated ID lookups for compound datatypes and other container-like - datatypes. The code now passes down pointers to the datatype - structures and only creates IDs to wrap those pointers as necessary. - Quick testing showed an average ~3x to ~10x improvement in performance - of conversions on container-like datatypes, depending on the - complexity of the datatype. - - * A conversion "context" structure was added to hold information about - the current conversion being performed. This allows conversions on - container-like datatypes to be optimized better by skipping certain - portions of the conversion process that remain relatively constant - when multiple elements of the container-like datatype are being - converted. - - * After refactoring the datatype conversion code to use pointers - internally rather than IDs, several copies of datatypes that were - made by higher levels of the library were able to be removed. The - internal IDs that were previously registered to wrap those copied - datatypes were also able to be removed. - - - Implemented optimized support for vector I/O in the Subfiling VFD - - Previously, the Subfiling VFD would handle vector I/O requests by - breaking them down into individual I/O requests, one for each entry - in the I/O vectors provided. This could result in poor I/O performance - for features in HDF5 that utilize vector I/O, such as parallel I/O - to filtered datasets. The Subfiling VFD now properly handles vector - I/O requests in their entirety, resulting in fewer I/O calls, improved - vector I/O performance and improved vector I/O memory efficiency. - - - Added support for in-place type conversion in most cases - - In-place type conversion allows the library to perform type conversion - without an intermediate type conversion buffer. This can improve - performance by allowing I/O in a single operation over the entire - selection instead of being limited by the size of the intermediate buffer. - Implemented for I/O on contiguous and chunked datasets when the selection - is contiguous in memory and when the memory datatype is not smaller than - the file datatype. - - - Changed selection I/O to be on by default when using the MPIO file driver - - - Added support for selection I/O in the MPIO file driver - - Previously, only vector I/O operations were supported. Support for - selection I/O should improve performance and reduce memory uses in some - cases. - - - Changed the error handling for a not found path in the find plugin process. - - While attempting to load a plugin the HDF5 library will fail if one of the - directories in the plugin paths does not exist, even if there are more paths - to check. Instead of exiting the function with an error, just logged the error - and continue processing the list of paths to check. - - - Implemented support for temporary security credentials for the Read-Only - S3 (ROS3) file driver. - - When using temporary security credentials, one also needs to specify a - session/security token next to the access key id and secret access key. - This token can be specified by the new API function H5Pset_fapl_ros3_token(). - The API function H5Pget_fapl_ros3_token() can be used to retrieve - the currently set token. - - - Added a Subfiling VFD configuration file prefix environment variable - - The Subfiling VFD now checks for values set in a new environment - variable "H5FD_SUBFILING_CONFIG_FILE_PREFIX" to determine if the - application has specified a pathname prefix to apply to the file - path for its configuration file. For example, this can be useful - for cases where the application wishes to write subfiles to a - machine's node-local storage while placing the subfiling configuration - file on a file system readable by all machine nodes. - - - Added H5Pset_selection_io(), H5Pget_selection_io(), and - H5Pget_no_selection_io_cause() API functions to manage the selection I/O - feature. This can be used to enable collective I/O with type conversion, - or it can be used with custom VFDs that support vector or selection I/O. - - - Added H5Pset_modify_write_buf() and H5Pget_modify_write_buf() API - functions to allow the library to modify the contents of write buffers, in - order to avoid malloc/memcpy. Currently only used for type conversion - with selection I/O. + - Added new routines for interacting with error stacks: H5Epause_stack, + H5Eresume_stack, and H5Eis_paused. These routines can be used to + indicate that errors from a call to an HDF5 routine should not be + pushed on to an error stack. Primarily targeted toward 3rd-party + developers of Virtual File Drivirs (VFDs) and Virtual Object Layer (VOL) + connectors, these routines allow developers to perform "speculative" + operations (such as trying to open a file or object) without requiring + that the error stack be cleared after a speculative operation fails. Parallel Library: @@ -449,36 +113,6 @@ New Features h5rget_file_name_f, h5rget_attr_name_f, h5rget_obj_name_f, h5rcopy_f, h5requal_f, h5rdestroy_f, h5rget_type_f - - Added Fortran H5E APIs: - h5eregister_class_f, h5eunregister_class_f, h5ecreate_msg_f, h5eclose_msg_f - h5eget_msg_f, h5epush_f, h5eget_num_f, h5ewalk_f, h5eget_class_name_f, - h5eappend_stack_f, h5eget_current_stack_f, h5eset_current_stack_f, h5ecreate_stack_f, - h5eclose_stack_f, h5epop_f, h5eprint_f (C h5eprint v2 signature) - - - Added API support for Fortran MPI_F08 module definitions: - Adds support for MPI's MPI_F08 module datatypes: type(MPI_COMM) and type(MPI_INFO) for HDF5 APIs: - H5PSET_FAPL_MPIO_F, H5PGET_FAPL_MPIO_F, H5PSET_MPI_PARAMS_F, H5PGET_MPI_PARAMS_F - Ref. #3951 - - - Added Fortran APIs: - H5FGET_INTENT_F, H5SSEL_ITER_CREATE_F, H5SSEL_ITER_GET_SEQ_LIST_F, - H5SSEL_ITER_CLOSE_F, H5S_mp_H5SSEL_ITER_RESET_F - - - Added Fortran Parameters: - H5S_SEL_ITER_GET_SEQ_LIST_SORTED_F, H5S_SEL_ITER_SHARE_WITH_DATASPACE_F - - - Added Fortran Parameters: - H5S_BLOCK_F and H5S_PLIST_F - - - The configuration definitions file, H5config_f.inc, is now installed - and the HDF5 version number has been added to it. - - - Added Fortran APIs: - h5fdelete_f - - - Added Fortran APIs: - h5vlnative_addr_to_token_f and h5vlnative_token_to_address_f - C++ Library: ------------ @@ -537,23 +171,6 @@ Bug Fixes since HDF5-1.14.4 release disabled for any form of parallel file access, even if only 1 MPI process is used. - - Fixed a leak of datatype IDs created internally during datatype conversion - - Fixed an issue where the library could leak IDs that it creates internally - for compound datatype members during datatype conversion. When the library's - table of datatype conversion functions is modified (such as when a new - conversion function is registered with the library from within an application), - the compound datatype conversion function has to recalculate data that it - has cached. When recalculating that data, the library was registering new - IDs for each of the members of the source and destination compound datatypes - involved in the conversion process and was overwriting the old cached IDs - without first closing them. This would result in use-after-free issues due - to multiple IDs pointing to the same internal H5T_t structure, as well as - crashes due to the library not gracefully handling partially initialized or - partially freed datatypes on library termination. - - Fixes h5py GitHub #2419 - - Fixed function H5Requal actually to compare the reference pointers Fixed an issue with H5Requal always returning true because the @@ -573,496 +190,6 @@ Bug Fixes since HDF5-1.14.4 release Fixes GitHub #3790 - - Fixed many (future) CVE issues - - A partner organization corrected many potential security issues, which - were fixed and reported to us before submission to MITRE. These do - not have formal CVE issues assigned to them yet, so the numbers assigned - here are just placeholders. We will update the HDF5 1.14 CVE list (link - below) when official MITRE CVE tracking numbers are assigned. - - These CVE issues are generally of the same form as other reported HDF5 - CVE issues, and rely on the library failing while attempting to read - a malformed file. Most of them cause the library to segfault and will - probably be assigned "medium (~5/10)" scores by NIST, like the other - HDF5 CVE issues. - - The issues that were reported to us have all been fixed in this release, - so HDF5 will continue to have no unfixed public CVE issues. - - NOTE: HDF5 versions earlier than 1.14.4 should be considered vulnerable - to these issues and users should upgrade to 1.14.4 as soon as - possible. Note that it's possible to build the 1.14 library with - HDF5 1.8, 1.10, etc. API bindings for people who wish to enjoy - the benefits of a more secure library but don't want to upgrade - to the latest API. We will not be bringing the CVE fixes to earlier - versions of the library (they are no longer supported). - - LIST OF CVE ISSUES FIXED IN THIS RELEASE: - - * CVE-2024-0116-001 - HDF5 library versions <=1.14.3 contain a heap buffer overflow in - H5D__scatter_mem resulting in causing denial of service or potential - code execution - - * CVE-2024-0112-001 - HDF5 library versions <=1.14.3 contain a heap buffer overflow in - H5S__point_deserialize resulting in the corruption of the - instruction pointer and causing denial of service or potential code - execution - - * CVE-2024-0111-001 - HDF5 library versions <=1.14.3 contain a heap buffer overflow in - H5T__conv_struct_opt resulting in causing denial of service or - potential code execution - - * CVE-2023-1208-002 - HDF5 library versions <=1.14.3 contain a heap buffer overflow in - H5O__mtime_new_encode resulting in the corruption of the instruction - pointer and causing denial of service or potential code execution - - * CVE-2023-1208-001 - HDF5 library versions <=1.14.3 contain a heap buffer overflow in - H5O__layout_encode resulting in the corruption of the instruction - pointer and causing denial of service or potential code execution - - * CVE-2023-1207-001 - HDF5 library versions <=1.14.3 contain a heap buffer overflow in - H5O__dtype_encode_helper causing denial of service or potential - code execution - - * CVE-2023-1205-001 - HDF5 library versions <=1.14.3 contain a heap buffer overflow in - H5VM_array_fill resulting in the corruption of the instruction - pointer and causing denial of service or potential code execution - - * CVE-2023-1202-002 - HDF5 library versions <=1.14.3 contain a heap buffer overflow in - H5T__get_native_type resulting in the corruption of the instruction - pointer and causing denial of service or potential code execution - - * CVE-2023-1202-001 - HDF5 library versions <=1.14.3 contain a heap buffer overflow in - H5T__ref_mem_setnull resulting in the corruption of the instruction - pointer and causing denial of service or potential code execution - - * CVE-2023-1130-001 - HDF5 library versions <=1.14.3 contain a heap buffer overflow in - H5T_copy_reopen resulting in the corruption of the instruction - pointer and causing denial of service or potential code execution - - * CVE-2023-1125-001 - HDF5 versions <= 1.14.3 contain a heap buffer overflow in - H5Z__nbit_decompress_one_byte caused by the earlier use of an - initialized pointer. This may result in Denial of Service or - potential code execution - - * CVE-2023-1114-001 - HDF5 library versions <=1.14.3 contain a heap buffer overflow in - H5HG_read resulting in the corruption of the instruction pointer - and causing denial of service or potential code execution - - * CVE-2023-1113-002 - HDF5 library versions <=1.14.3 contain a heap buffer overflow in - H5F_addr_decode_len resulting in the corruption of the instruction - pointer and causing denial of service or potential code execution - - * CVE-2023-1113-001 - HDF5 versions <= 1.14.3 contain a heap buffer overflow caused by - the unsafe use of strdup in H5MM_xstrdup, resulting in denial of - service or potential code execution - - * CVE-2023-1108-001 - HDF5 versions <= 1.14.3 contain a out-of-bounds read operation in - H5FL_arr_malloc resulting in denial of service or potential code - execution - - * CVE-2023-1104-004 - HDF5 versions <= 1.14.3 contain a out-of-bounds read operation in - H5T_close_real resulting in denial of service or potential code - execution - - * CVE-2023-1104-003 - HDF5 library versions <=1.14.3 contain a heap buffer overflow flaw - in the function H5HL__fl_deserialize resulting in denial of service - or potential code execution - - * CVE-2023-1104-002 - HDF5 library versions <=1.14.3 contain a heap buffer overflow in - H5HL__fl_deserialize resulting in the corruption of the instruction - pointer and causing denial of service or potential code execution - - * CVE-2023-1104-001 - HDF5 library versions <=1.14.3 contains a stack overflow in the - function H5E_printf_stack resulting in denial of service or - potential code execution - - * CVE-2023-1023-001 - HDF5 library versions <=1.14.3 heap buffer overflow in - H5VM_memcpyvv which may result in denial of service or code - execution - - * CVE-2023-1019-001 - HDF5 library versions <=1.14.3 contain a stack buffer overflow in - H5VM_memcpyvv resulting in the corruption of the instruction - pointer and causing denial of service or potential code execution - - * CVE-2023-1018-001 - HDF5 library versions <=1.14.3 contain a memory corruption in - H5A__close resulting in the corruption of the instruction pointer - and causing denial of service or potential code execution - - * CVE-2023-1017-002 - HDF5 library versions <=1.14.3 may use an uninitialized value - H5A__attr_release_table resulting in denial of service - - * CVE-2023-1017-001 - HDF5 library versions <=1.14.3 may attempt to dereference - uninitialized values in h5tools_str_sprint, which will lead to - denial of service - - * CVE-2023-1013-004 - HDF5 versions <= 1.13.3 contain a stack buffer overflow in - H5HG_read resulting in denial of service or potential code - execution - - * CVE-2023-1013-003 - HDF5 library versions <=1.14.3 contain a buffer overrun in - H5Z__filter_fletcher32 resulting in the corruption of the - instruction pointer and causing denial of service or potential - code execution - - * CVE-2023-1013-002 - HDF5 library versions <=1.14.3 contain a buffer overrun in - H5O__linfo_decode resulting in the corruption of the instruction - pointer and causing denial of service or potential code execution - - * CVE-2023-1013-001 - HDF5 library versions <=1.14.3 contain a buffer overrun in - H5Z__filter_scaleoffset resulting in the corruption of the - instruction pointer and causing denial of service or potential - code execution - - * CVE-2023-1012-001 - HDF5 library versions <=1.14.3 contain a stack buffer overflow in - H5R__decode_heap resulting in the corruption of the instruction - pointer and causing denial of service or potential code execution - - * CVE-2023-1010-001 - HDF5 library versions <=1.14.3 contain a stack buffer overflow in - H5FL_arr_malloc resulting in the corruption of the instruction - pointer and causing denial of service or potential code execution - - * CVE-2023-1009-001 - HDF5 library versions <=1.14.3 contain a stack buffer overflow in - H5FL_arr_malloc resulting in the corruption of the instruction - pointer and causing denial of service or potential code execution - - * CVE-2023-1006-004 - HDF5 library versions <=1.14.3 contain a heap buffer overflow in - H5A__attr_release_table resulting in the corruption of the - instruction pointer and causing denial of service or potential code - execution - - * CVE-2023-1006-003 - HDF5 library versions <=1.14.3 contain a heap buffer overflow in - H5T__bit_find resulting in the corruption of the instruction pointer - and causing denial of service or potential code execution. - - * CVE-2023-1006-002 - HDF5 library versions <=1.14.3 contain a heap buffer overflow in - H5HG_read resulting in the corruption of the instruction pointer - and causing denial of service or potential code execution - - * CVE-2023-1006-001 - HDF5 library versions <=1.14.3 contain a heap buffer overflow in - H5HG__cache_heap_deserialize resulting in the corruption of the - instruction pointer and causing denial of service or potential code - execution - - FULL OFFICIAL HDF5 CVE list (from mitre.org): - - https://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=HDF5 - - 1.14.x CVE tracking list: - - https://github.com/HDFGroup/hdf5/blob/hdf5_1_14/CVE_list_1_14.md - - HDF5 CVE regression test suite (includes proof-of-concept files): - - https://github.com/HDFGroup/cve_hdf5 - - - Fixed a divide-by-zero issue when a corrupt file sets the page size to 0 - - If a corrupt file sets the page buffer size in the superblock to zero, - the library could attempt to divide by zero when allocating space in - the file. The library now checks for valid page buffer sizes when - reading the superblock message. - - Fixes oss-fuzz issue 58762 - - - Fixed a bug when using array datatypes with certain parent types - - Array datatype conversion would never use a background buffer, even if the - array's parent type (what the array is an array of) required a background - buffer for conversion. This resulted in crashes in some cases when using - an array of compound, variable length, or reference datatypes. Array types - now use a background buffer if needed by the parent type. - - - Fixed potential buffer read overflows in H5PB_read - - H5PB_read previously did not account for the fact that the size of the - read it's performing could overflow the page buffer pointer, depending - on the calculated offset for the read. This has been fixed by adjusting - the size of the read if it's determined that it would overflow the page. - - - Fixed CVE-2017-17507 - - This CVE was previously declared fixed, but later testing with a static - build of HDF5 showed that it was not fixed. - - When parsing a malformed (fuzzed) compound type containing variable-length - string members, the library could produce a segmentation fault, crashing - the library. - - This was fixed after GitHub PR #4234 - - Fixes GitHub issue #3446 - - - Fixed a cache assert with very large metadata objects - - If the library tries to load a metadata object that is above a - certain size, this would trip an assert in debug builds. This could - happen if you create a very large number of links in an old-style - group that uses local heaps. - - There is no need for this assert. The library's metadata cache - can handle large objects. The assert has been removed. - - Fixes GitHub #3762 - - - Fixed an issue with the Subfiling VFD and multiple opens of a - file - - An issue with the way the Subfiling VFD handles multiple opens - of the same file caused the file structures for the extra opens - to occasionally get mapped to an incorrect subfiling context - object. The VFD now correctly maps the file structures for - additional opens of an already open file to the same context - object. - - - Fixed a bug that causes the library to incorrectly identify - the endian-ness of 16-bit and smaller C floating-point datatypes - - When detecting the endian-ness of an in-memory C floating-point - datatype, the library previously always assumed that the type - was at least 32 bits in size. This resulted in invalid memory - accesses and would usually cause the library to identify the - datatype as having an endian-ness of H5T_ORDER_VAX. This has - now been fixed. - - - Fixed a bug that causes an invalid memory access issue when - converting 16-bit floating-point values to integers with the - library's software conversion function - - The H5T__conv_f_i function previously always assumed that - floating-point values were at least 32 bits in size and would - access invalid memory when attempting to convert 16-bit - floating-point values to integers. To fix this, parts of the - H5T__conv_f_i function had to be rewritten, which also resulted - in a significant speedup when converting floating-point values - to integers where the library does not have a hard conversion - path. This is the case for any floating-point values with a - datatype not represented by H5T_NATIVE_FLOAT16 (if _Float16 is - supported), H5T_NATIVE_FLOAT, H5T_NATIVE_DOUBLE or - H5T_NATIVE_LDOUBLE. - - - Fixed a bug that can cause incorrect data when overflows occur - while converting integer values to floating-point values with - the library's software conversion function - - The H5T__conv_i_f function had a bug which previously caused it - to return incorrect data when an overflow occurs and an application's - conversion exception callback function decides not to handle the - overflow. Rather than return positive infinity, the library would - return truncated data. This has now been fixed. - - - Corrected H5Soffset_simple() when offset is NULL - - The reference manual states that the offset parameter of H5Soffset_simple() - can be set to NULL to reset the offset of a simple dataspace to 0. This - has never been true, and passing NULL was regarded as an error. - - The library will now accept NULL for the offset parameter and will - correctly set the offset to zero. - - Fixes HDFFV-9299 - - - Fixed an issue where the Subfiling VFD's context object cache could - grow too large - - The Subfiling VFD keeps a cache of its internal context objects to - speed up access to a context object for a particular file, as well - as access to that object across multiple opens of the same file. - However, opening a large amount of files with the Subfiling VFD over - the course of an application's lifetime could cause this cache to grow - too large and result in the application running out of available MPI - communicator objects. On file close, the Subfiling VFD now simply - evicts context objects out of its cache and frees them. It is assumed - that multiple opens of a file will be a less common use case for the - Subfiling VFD, but this can be revisited if it proves to be an issue - for performance. - - - Fixed error when overwriting certain nested variable length types - - Previously, when using a datatype that included a variable length type - within a compound or array within another variable length type, and - overwriting data with a shorter (top level) variable length sequence, an - error could occur. This has been fixed. - - - Take user block into account in H5Dchunk_iter() and H5Dget_chunk_info() - - The address reported by the following functions did not correctly - take the user block into account: - - * H5Dchunk_iter() <-- addr passed to callback - * H5Dget_chunk_info() <-- addr parameter - * H5Dget_chunk_info_by_coord() <-- addr parameter - - This means that these functions reported logical HDF5 file addresses, - which would only be equal to the physical addresses when there is no - user block prepended to the HDF5 file. This is unfortunate, as the - primary use of these functions is to get physical addresses in order - to directly access the chunks. - - The listed functions now correctly take the user block into account, - so they will emit physical addresses that can be used to directly - access the chunks. - - Fixes #3003 - - - Fixed asserts raised by large values of H5Pset_est_link_info() parameters - - If large values for est_num_entries and/or est_name_len were passed - to H5Pset_est_link_info(), the library would attempt to create an - object header NIL message to reserve enough space to hold the links in - compact form (i.e., concatenated), which could exceed allowable object - header message size limits and trip asserts in the library. - - This bug only occurred when using the HDF5 1.8 file format or later and - required the product of the two values to be ~64k more than the size - of any links written to the group, which would cause the library to - write out a too-large NIL spacer message to reserve the space for the - unwritten links. - - The library now inspects the phase change values to see if the dataset - is likely to be compact and checks the size to ensure any NIL spacer - messages won't be larger than the library allows. - - Fixes GitHub #1632 - - - Fixed a bug where H5Tset_fields does not account for any offset - set for a floating-point datatype when determining if values set - for spos, epos, esize, mpos and msize make sense for the datatype - - Previously, H5Tset_fields did not take datatype offsets into account - when determining if the values set make sense for the datatype. - This would cause the function to fail when the precision for a - datatype is correctly set such that the offset bits are not included. - This has now been fixed. - - - Fixed H5Fget_access_plist so that it returns the file locking - settings for a file - - When H5Fget_access_plist (and the internal H5F_get_access_plist) - is called on a file, the returned File Access Property List has - the library's default file locking settings rather than any - settings set for the file. This causes two problems: - - - Opening an HDF5 file through an external link using H5Gopen, - H5Dopen, etc. with H5P_DEFAULT for the Dataset/Group/etc. - Access Property List will cause the external file to be opened - with the library's default file locking settings rather than - inheriting them from the parent file. This can be surprising - when a file is opened with file locking disabled, but its - external files are opened with file locking enabled. - - - An application cannot make use of the H5Pset_elink_fapl - function to match file locking settings between an external - file and its parent file without knowing the correct setting - ahead of time, as calling H5Fget_access_plist on the parent - file will not return the correct settings. - - This has been fixed by copying a file's file locking settings - into the newly-created File Access Property List in H5F_get_access_plist. - - This fix partially addresses GitHub issue #4011 - - - Memory usage growth issue - - Starting with the HDF5 1.12.1 release, an issue (GitHub issue #1256) - was observed where running a simple program that has a loop of opening - a file, reading from an object with a variable-length datatype and - then closing the file would result in the process fairly quickly - running out of memory. Upon further investigation, it was determined - that this memory was being kept around in the library's datatype - conversion pathway cache that is used to speed up datatype conversions - which are repeatedly used within an HDF5 application's lifecycle. For - conversions involving variable-length or reference datatypes, each of - these cached pathway entries keeps a reference to its associated file - for later use. Since the file was being closed and reopened on each - loop iteration, and since the library compares for equality between - instances of opened files (rather than equality of the actual files) - when determining if it can reuse a cached conversion pathway, it was - determining that no cached conversion pathways could be reused and was - creating a new cache entry on each loop iteration during I/O. This - would lead to constant growth of that cache and the memory it consumed, - as well as constant growth of the memory consumed by each cached entry - for the reference to its associated file. - - To fix this issue, the library now removes any cached datatype - conversion path entries for variable-length or reference datatypes - associated with a particular file when that file is closed. - - Fixes GitHub #1256 - - - Suppressed floating-point exceptions in H5T init code - - The floating-point datatype initialization code in H5Tinit_float.c - could raise FE_INVALID exceptions while munging bits and performing - comparisons that might involve NaN. This was not a problem when the - initialization code was executed in H5detect at compile time (prior - to 1.14.3), but now that the code is executed at library startup - (1.14.3+), these exceptions can be caught by user code, as is the - default in the NAG Fortran compiler. - - Starting in 1.14.4, we now suppress floating-point exceptions while - initializing the floating-point types and clear FE_INVALID before - restoring the original environment. - - Fixes GitHub #3831 - - - Fixed a file handle leak in the core VFD - - When opening a file with the core VFD and a file image, if the file - already exists, the file check would leak the POSIX file handle. - - Fixes GitHub issue #635 - - - Dropped support for MPI-2 - - The MPI-2 supporting artifacts have been removed due to the cessation - of MPI-2 maintenance and testing since version HDF5 1.12. - - - - Fixed a segfault when using a user-defined conversion function between compound datatypes - - During type info initialization for compound datatype conversion, the library checked if the - datatypes are subsets of one another in order to perform special conversion handling. - This check uses information that is only defined if a library conversion function is in use. - The library now skips this check for user-defined conversion functions. - - Fixes Github issue #3840 Java Library ------------ @@ -1114,16 +241,6 @@ Bug Fixes since HDF5-1.14.4 release * HDF5_ENABLE_DOXY_WARNINGS: ON/OFF (Default: OFF) * --enable-doxygen-errors: enable/disable (Default: disable) - - Fixed an issue where the h5tools_test_utils test program was being - installed on the system for Autotools builds of HDF5 - - The h5tools_test_utils test program was mistakenly added to bin_PROGRAMS - in its Makefile.am configuration file, causing the executable to be - installed on the system. The executable is now added to noinst_PROGRAMS - instead and will no longer be installed on the system for Autotools builds - of HDF5. The CMake configuration code already avoids installing the - executable on the system. - Tools ----- @@ -1141,10 +258,6 @@ Bug Fixes since HDF5-1.14.4 release preventing the library from setting up an MPI communicator attribute to perform library cleanup on MPI_Finalize - - Renamed h5fuse.sh to h5fuse - - Addresses Discussion #3791 - Performance ------------- @@ -1153,25 +266,12 @@ Bug Fixes since HDF5-1.14.4 release Fortran API ----------- - - Fixed: HDF5 fails to compile with -Werror=lto-type-mismatch - - Removed the use of the offending C stub wrapper. - - Fixes GitHub issue #3987 + - High-Level Library ------------------ - - Fixed a memory leak in H5LTopen_file_image with H5LT_FILE_IMAGE_DONT_COPY flag - - When the H5LT_FILE_IMAGE_DONT_COPY flag is passed to H5LTopen_file_image, the - internally-allocated udata structure gets leaked as the core file driver doesn't - have a way to determine when or if it needs to call the "udata_free" callback. - This has been fixed by freeing the udata structure when the "image_free" callback - gets made during file close, where the file is holding the last reference to the - udata structure. - - Fixes GitHub issue #827 + - Fortran High-Level APIs @@ -1196,50 +296,7 @@ Bug Fixes since HDF5-1.14.4 release Testing ------- - - Fixed a bug in the dt_arith test when H5_WANT_DCONV_EXCEPTION is not - defined - - The dt_arith test program's test_particular_fp_integer sub-test tries - to ensure that the library correctly raises a datatype conversion - exception when converting a floating-point value to an integer overflows. - However, this test would run even when H5_WANT_DCONV_EXCEPTION isn't - defined, causing the test to fail due to the library not raising - datatype conversion exceptions. This has now been fixed by not running - the test when H5_WANT_DCONV_EXCEPTION is not defined. - - - Fixed a testing failure in testphdf5 on Cray machines - - On some Cray machines, what appears to be a bug in Cray MPICH was causing - calls to H5Fis_accessible to create a 0-byte file with strange Unix - permissions. This was causing an H5Fdelete file deletion test in the - testphdf5 program to fail due to a just-deleted HDF5 file appearing to - still be accessible on the file system. The issue in Cray MPICH has been - worked around for the time being by resetting the MPI_Info object on the - File Access Property List used to MPI_INFO_NULL before passing it to the - H5Fis_accessible call. - - - A bug was fixed in the HDF5 API test random datatype generation code - - A bug in the random datatype generation code could cause test failures - when trying to generate an enumeration datatype that has duplicated - name/value pairs in it. This has now been fixed. - - - A bug was fixed in the HDF5 API test VOL connector registration checking code - - The HDF5 API test code checks to see if the VOL connector specified by the - HDF5_VOL_CONNECTOR environment variable (if any) is registered with the library - before attempting to run tests with it so that testing can be skipped and an - error can be returned when a VOL connector fails to register successfully. - Previously, this code didn't account for VOL connectors that specify extra - configuration information in the HDF5_VOL_CONNECTOR environment variable and - would incorrectly report that the specified VOL connector isn't registered - due to including the configuration information as part of the VOL connector - name being checked for registration status. This has now been fixed. - - - Fixed Fortran 2003 test with gfortran-v13, optimization levels O2,O3 - - Fixes failing Fortran 2003 test with gfortran, optimization level O2,O3 - with -fdefault-real-16. Fixes GH #2928. + - Platforms Tested diff --git a/src/H5Dvirtual.c b/src/H5Dvirtual.c index 11874878fd7..ac31231b1e8 100644 --- a/src/H5Dvirtual.c +++ b/src/H5Dvirtual.c @@ -875,16 +875,14 @@ H5D__virtual_open_source_dset(const H5D_t *vdset, H5O_storage_virtual_ent_t *vir intent = H5F_INTENT(vdset->oloc.file); /* Try opening the file */ - src_file = H5F_prefix_open_file(vdset->oloc.file, H5F_PREFIX_VDS, vdset->shared->vds_prefix, - source_dset->file_name, intent, - vdset->shared->layout.storage.u.virt.source_fapl); + if (H5F_prefix_open_file(true, &src_file, vdset->oloc.file, H5F_PREFIX_VDS, vdset->shared->vds_prefix, + source_dset->file_name, intent, + vdset->shared->layout.storage.u.virt.source_fapl) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTOPENFILE, FAIL, "can't try opening file"); /* If we opened the source file here, we should close it when leaving */ if (src_file) src_file_open = true; - else - /* Reset the error stack */ - H5E_clear_stack(); } /* end if */ else /* Source file is ".", use the virtual dataset's file */ diff --git a/src/H5E.c b/src/H5E.c index 0eb256f4ad4..f1b865e7c17 100644 --- a/src/H5E.c +++ b/src/H5E.c @@ -532,8 +532,11 @@ H5Epush2(hid_t err_stack, const char *file, const char *func, unsigned line, hid /* Don't clear the error stack! :-) */ FUNC_ENTER_API_NOCLEAR(FAIL) - if (err_stack == H5E_DEFAULT) - estack = NULL; + /* Check for 'default' error stack */ + if (err_stack == H5E_DEFAULT) { + if (NULL == (estack = H5E__get_my_stack())) + HGOTO_ERROR(H5E_ERROR, H5E_CANTGET, FAIL, "can't get the default error stack"); + } else { /* Only clear the error stack if it's not the default stack */ H5E_clear_stack(); @@ -543,35 +546,33 @@ H5Epush2(hid_t err_stack, const char *file, const char *func, unsigned line, hid HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a error stack ID"); } /* end else */ - /* Note that the variable-argument parsing for the format is identical in - * the H5E_printf_stack() routine - correct errors and make changes in both - * places. -QAK - */ - - /* Format the description */ - va_start(ap, fmt); - va_started = true; - - /* Duplicate string information */ - if (NULL == (tmp_file = strdup(file))) - HGOTO_ERROR(H5E_ERROR, H5E_CANTALLOC, FAIL, "can't duplicate file string"); - if (NULL == (tmp_func = strdup(func))) - HGOTO_ERROR(H5E_ERROR, H5E_CANTALLOC, FAIL, "can't duplicate function string"); - - /* Increment refcount on non-library IDs */ - if (cls_id != H5E_ERR_CLS_g) - if (H5I_inc_ref(cls_id, false) < 0) - HGOTO_ERROR(H5E_ERROR, H5E_CANTINC, FAIL, "can't increment class ID"); - if (maj_id < H5E_first_maj_id_g || maj_id > H5E_last_maj_id_g) - if (H5I_inc_ref(maj_id, false) < 0) - HGOTO_ERROR(H5E_ERROR, H5E_CANTINC, FAIL, "can't increment major error ID"); - if (min_id < H5E_first_min_id_g || min_id > H5E_last_min_id_g) - if (H5I_inc_ref(min_id, false) < 0) - HGOTO_ERROR(H5E_ERROR, H5E_CANTINC, FAIL, "can't increment minor error ID"); - - /* Push the error on the stack */ - if (H5E__push_stack(estack, true, tmp_file, tmp_func, line, cls_id, maj_id, min_id, fmt, &ap) < 0) - HGOTO_ERROR(H5E_ERROR, H5E_CANTSET, FAIL, "can't push error on stack"); + /* Check if error reporting is paused for this stack */ + if (!estack->paused) { + /* Start the variable-argument parsing */ + va_start(ap, fmt); + va_started = true; + + /* Duplicate string information */ + if (NULL == (tmp_file = strdup(file))) + HGOTO_ERROR(H5E_ERROR, H5E_CANTALLOC, FAIL, "can't duplicate file string"); + if (NULL == (tmp_func = strdup(func))) + HGOTO_ERROR(H5E_ERROR, H5E_CANTALLOC, FAIL, "can't duplicate function string"); + + /* Increment refcount on non-library IDs */ + if (cls_id != H5E_ERR_CLS_g) + if (H5I_inc_ref(cls_id, false) < 0) + HGOTO_ERROR(H5E_ERROR, H5E_CANTINC, FAIL, "can't increment class ID"); + if (maj_id < H5E_first_maj_id_g || maj_id > H5E_last_maj_id_g) + if (H5I_inc_ref(maj_id, false) < 0) + HGOTO_ERROR(H5E_ERROR, H5E_CANTINC, FAIL, "can't increment major error ID"); + if (min_id < H5E_first_min_id_g || min_id > H5E_last_min_id_g) + if (H5I_inc_ref(min_id, false) < 0) + HGOTO_ERROR(H5E_ERROR, H5E_CANTINC, FAIL, "can't increment minor error ID"); + + /* Push the error on the stack */ + if (H5E__push_stack(estack, true, tmp_file, tmp_func, line, cls_id, maj_id, min_id, fmt, &ap) < 0) + HGOTO_ERROR(H5E_ERROR, H5E_CANTSET, FAIL, "can't push error on stack"); + } done: if (va_started) @@ -865,7 +866,6 @@ H5Eappend_stack(hid_t dst_stack_id, hid_t src_stack_id, hbool_t close_source_sta H5E_stack_t *dst_stack, *src_stack; /* Error stacks */ herr_t ret_value = SUCCEED; /* Return value */ - /* Don't clear the error stack! :-) */ FUNC_ENTER_API(FAIL) /* Check args */ @@ -889,3 +889,118 @@ H5Eappend_stack(hid_t dst_stack_id, hid_t src_stack_id, hbool_t close_source_sta done: FUNC_LEAVE_API(ret_value) } /* end H5Eappend_stack() */ + +/*------------------------------------------------------------------------- + * Function: H5Eis_paused + * + * Purpose: Check if pushing errors on an error stack is paused + * + * Return: Non-negative value on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5Eis_paused(hid_t stack_id, hbool_t *is_paused) +{ + H5E_stack_t *stack; /* Error stack */ + herr_t ret_value = SUCCEED; /* Return value */ + + /* Don't clear the error stack! :-) */ + FUNC_ENTER_API_NOCLEAR(FAIL) + + /* Get the correct error stack */ + if (stack_id == H5E_DEFAULT) { + if (NULL == (stack = H5E__get_my_stack())) + HGOTO_ERROR(H5E_ERROR, H5E_CANTGET, FAIL, "can't get current error stack"); + } /* end if */ + else { + /* Only clear the error stack if it's not the default stack */ + H5E_clear_stack(); + + /* Get the error stack to operate on */ + if (NULL == (stack = (H5E_stack_t *)H5I_object_verify(stack_id, H5I_ERROR_STACK))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an error stack ID"); + } /* end else */ + + /* Check arguments */ + if (NULL == is_paused) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "is_paused parameter is NULL"); + + /* Check if the stack is paused */ + *is_paused = (stack->paused > 0); + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Eis_paused() */ + +/*------------------------------------------------------------------------- + * Function: H5Epause_stack + * + * Purpose: Pause pushing errors on an error stack + * + * Return: Non-negative value on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5Epause_stack(hid_t stack_id) +{ + H5E_stack_t *stack; /* Error stack */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + + /* Get the correct error stack */ + if (stack_id == H5E_DEFAULT) { + if (NULL == (stack = H5E__get_my_stack())) + HGOTO_ERROR(H5E_ERROR, H5E_CANTGET, FAIL, "can't get current error stack"); + } /* end if */ + else + /* Get the error stack to operate on */ + if (NULL == (stack = (H5E_stack_t *)H5I_object_verify(stack_id, H5I_ERROR_STACK))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an error stack ID"); + + /* Increment pause counter */ + stack->paused++; + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Epause_stack() */ + +/*------------------------------------------------------------------------- + * Function: H5Eresume_stack + * + * Purpose: Resume pushing errors on an error stack + * + * Return: Non-negative value on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5Eresume_stack(hid_t stack_id) +{ + H5E_stack_t *stack; /* Error stack */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + + /* Get the correct error stack */ + if (stack_id == H5E_DEFAULT) { + if (NULL == (stack = H5E__get_my_stack())) + HGOTO_ERROR(H5E_ERROR, H5E_CANTGET, FAIL, "can't get current error stack"); + } /* end if */ + else + /* Get the error stack to operate on */ + if (NULL == (stack = (H5E_stack_t *)H5I_object_verify(stack_id, H5I_ERROR_STACK))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an error stack ID"); + + /* Check for pause/resume imbalance */ + if (0 == stack->paused) + HGOTO_ERROR(H5E_ERROR, H5E_BADRANGE, FAIL, "resuming more than paused"); + + /* Decrement pause counter */ + stack->paused--; + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Eresume_stack() */ diff --git a/src/H5Edeprec.c b/src/H5Edeprec.c index 06648000ae1..87b39e4133f 100644 --- a/src/H5Edeprec.c +++ b/src/H5Edeprec.c @@ -182,30 +182,38 @@ H5Eget_minor(H5E_minor_t min) herr_t H5Epush1(const char *file, const char *func, unsigned line, H5E_major_t maj, H5E_minor_t min, const char *str) { - const char *tmp_file; /* Copy of the file name */ - const char *tmp_func; /* Copy of the function name */ - herr_t ret_value = SUCCEED; /* Return value */ + H5E_stack_t *estack; /* Pointer to error stack to modify */ + const char *tmp_file; /* Copy of the file name */ + const char *tmp_func; /* Copy of the function name */ + herr_t ret_value = SUCCEED; /* Return value */ /* Don't clear the error stack! :-) */ FUNC_ENTER_API_NOCLEAR(FAIL) - /* Duplicate string information */ - if (NULL == (tmp_file = strdup(file))) - HGOTO_ERROR(H5E_ERROR, H5E_CANTALLOC, FAIL, "can't duplicate file string"); - if (NULL == (tmp_func = strdup(func))) - HGOTO_ERROR(H5E_ERROR, H5E_CANTALLOC, FAIL, "can't duplicate function string"); - - /* Increment refcount on non-library IDs */ - if (maj < H5E_first_maj_id_g || maj > H5E_last_maj_id_g) - if (H5I_inc_ref(maj, false) < 0) - HGOTO_ERROR(H5E_ERROR, H5E_CANTINC, FAIL, "can't increment major error ID"); - if (min < H5E_first_min_id_g || min > H5E_last_min_id_g) - if (H5I_inc_ref(min, false) < 0) - HGOTO_ERROR(H5E_ERROR, H5E_CANTINC, FAIL, "can't increment minor error ID"); - - /* Push the error on the default error stack */ - if (H5E__push_stack(NULL, true, tmp_file, tmp_func, line, H5E_ERR_CLS_g, maj, min, str, NULL) < 0) - HGOTO_ERROR(H5E_ERROR, H5E_CANTSET, FAIL, "can't push error on stack"); + /* Get the 'default' error stack */ + if (NULL == (estack = H5E__get_my_stack())) + HGOTO_ERROR(H5E_ERROR, H5E_CANTGET, FAIL, "can't get the default error stack"); + + /* Check if error reporting is paused for this stack */ + if (!estack->paused) { + /* Duplicate string information */ + if (NULL == (tmp_file = strdup(file))) + HGOTO_ERROR(H5E_ERROR, H5E_CANTALLOC, FAIL, "can't duplicate file string"); + if (NULL == (tmp_func = strdup(func))) + HGOTO_ERROR(H5E_ERROR, H5E_CANTALLOC, FAIL, "can't duplicate function string"); + + /* Increment refcount on non-library IDs */ + if (maj < H5E_first_maj_id_g || maj > H5E_last_maj_id_g) + if (H5I_inc_ref(maj, false) < 0) + HGOTO_ERROR(H5E_ERROR, H5E_CANTINC, FAIL, "can't increment major error ID"); + if (min < H5E_first_min_id_g || min > H5E_last_min_id_g) + if (H5I_inc_ref(min, false) < 0) + HGOTO_ERROR(H5E_ERROR, H5E_CANTINC, FAIL, "can't increment minor error ID"); + + /* Push the error on the default error stack */ + if (H5E__push_stack(estack, true, tmp_file, tmp_func, line, H5E_ERR_CLS_g, maj, min, str, NULL) < 0) + HGOTO_ERROR(H5E_ERROR, H5E_CANTSET, FAIL, "can't push error on stack"); + } done: FUNC_LEAVE_API(ret_value) @@ -259,6 +267,7 @@ H5Eprint1(FILE *stream) /* Don't clear the error stack! :-) */ FUNC_ENTER_API_NOCLEAR(FAIL) + /* Get the 'default' error stack */ if (NULL == (estack = H5E__get_my_stack())) HGOTO_ERROR(H5E_ERROR, H5E_CANTGET, FAIL, "can't get current error stack"); diff --git a/src/H5Eint.c b/src/H5Eint.c index 00b6efbe33d..9590f3cbbee 100644 --- a/src/H5Eint.c +++ b/src/H5Eint.c @@ -188,7 +188,6 @@ H5E_init(void) HGOTO_ERROR(H5E_ID, H5E_CANTINIT, FAIL, "unable to initialize ID group"); #ifndef H5_HAVE_THREADSAFE - H5E_stack_g[0].nused = 0; H5E__set_default_auto(H5E_stack_g); #endif /* H5_HAVE_THREADSAFE */ @@ -317,7 +316,6 @@ H5E__get_stack(void) assert(estack); /* Set the thread-specific info */ - estack->nused = 0; H5E__set_default_auto(estack); /* (It's not necessary to release this in this API, it is @@ -821,8 +819,7 @@ H5E__append_stack(H5E_stack_t *dst_stack, const H5E_stack_t *src_stack) /*-------------------------------------------------------------------------- * Function: H5E__set_default_auto * - * Purpose: Initialize "automatic" error stack reporting info to library - * default + * Purpose: Initialize error stack to library default * * Return: SUCCEED/FAIL * @@ -833,6 +830,8 @@ H5E__set_default_auto(H5E_stack_t *stk) { FUNC_ENTER_PACKAGE_NOERR + stk->nused = 0; + #ifndef H5_NO_DEPRECATED_SYMBOLS #ifdef H5_USE_16_API_DEFAULT stk->auto_op.vers = 1; @@ -848,6 +847,7 @@ H5E__set_default_auto(H5E_stack_t *stk) #endif /* H5_NO_DEPRECATED_SYMBOLS */ stk->auto_data = NULL; + stk->paused = 0; FUNC_LEAVE_NOAPI_VOID } /* end H5E__set_default_auto() */ @@ -1383,9 +1383,10 @@ herr_t H5E_printf_stack(const char *file, const char *func, unsigned line, hid_t maj_id, hid_t min_id, const char *fmt, ...) { - va_list ap; /* Varargs info */ - bool va_started = false; /* Whether the variable argument list is open */ - herr_t ret_value = SUCCEED; /* Return value */ + H5E_stack_t *estack; /* Pointer to error stack to modify */ + va_list ap; /* Varargs info */ + bool va_started = false; /* Whether the variable argument list is open */ + herr_t ret_value = SUCCEED; /* Return value */ /* * WARNING: We cannot call HERROR() from within this function or else we @@ -1401,18 +1402,20 @@ H5E_printf_stack(const char *file, const char *func, unsigned line, hid_t maj_id assert(min_id >= H5E_first_min_id_g && min_id <= H5E_last_min_id_g); assert(fmt); - /* Note that the variable-argument parsing for the format is identical in - * the H5Epush2() routine - correct errors and make changes in both - * places. -QAK - */ + /* Get the 'default' error stack */ + if (NULL == (estack = H5E__get_my_stack())) + HGOTO_DONE(FAIL); - /* Start the variable-argument parsing */ - va_start(ap, fmt); - va_started = true; + /* Check if error reporting is paused for this stack */ + if (!estack->paused) { + /* Start the variable-argument parsing */ + va_start(ap, fmt); + va_started = true; - /* Push the error on the stack */ - if (H5E__push_stack(NULL, false, file, func, line, H5E_ERR_CLS_g, maj_id, min_id, fmt, &ap) < 0) - HGOTO_DONE(FAIL); + /* Push the error on the stack */ + if (H5E__push_stack(estack, false, file, func, line, H5E_ERR_CLS_g, maj_id, min_id, fmt, &ap) < 0) + HGOTO_DONE(FAIL); + } done: if (va_started) @@ -1458,11 +1461,6 @@ H5E__push_stack(H5E_stack_t *estack, bool app_entry, const char *file, const cha assert(maj_id > 0); assert(min_id > 0); - /* Check for 'default' error stack */ - if (estack == NULL) - if (NULL == (estack = H5E__get_my_stack())) - HGOTO_DONE(FAIL); - /* * Push the error if there's room. Otherwise just forget it. */ @@ -1688,8 +1686,9 @@ H5E_clear_stack(void) HGOTO_ERROR(H5E_ERROR, H5E_CANTGET, FAIL, "can't get current error stack"); /* Empty the error stack */ - if (H5E__clear_entries(estack, estack->nused) < 0) - HGOTO_ERROR(H5E_ERROR, H5E_CANTSET, FAIL, "can't clear error stack"); + if (estack->nused) + if (H5E__clear_entries(estack, estack->nused) < 0) + HGOTO_ERROR(H5E_ERROR, H5E_CANTSET, FAIL, "can't clear error stack"); done: FUNC_LEAVE_NOAPI(ret_value) @@ -1791,3 +1790,80 @@ H5E_dump_api_stack(void) FUNC_LEAVE_NOAPI(ret_value) } /* end H5E_dump_api_stack() */ + +/*------------------------------------------------------------------------- + * Function: H5E_pause_stack + * + * Purpose: Pause pushing errors on the default error stack. + * + * Generally used via the H5E_PAUSE_ERRORS / H5E_RESUME_ERRORS + * macros. + * + * When one needs to temporarily disable recording errors while + * trying something that's likely or expected to fail. The code + * to try can be nested between these macros like: + * + * H5E_PAUSE_ERRORS { + * ...stuff here that's likely to fail... + * } H5E_RESUME_ERRORS + * + * Warning: don't break, return, or longjmp() from the block of + * code or the error reporting won't be properly restored! + * + * Return: none + * + *------------------------------------------------------------------------- + */ +void +H5E_pause_stack(void) +{ + H5E_stack_t *estack = H5E__get_my_stack(); + + FUNC_ENTER_NOAPI_NOERR + + assert(estack); + + /* Increment pause counter */ + estack->paused++; + + FUNC_LEAVE_NOAPI_VOID +} /* end H5E_pause_stack() */ + +/*------------------------------------------------------------------------- + * Function: H5E_resume_stack + * + * Purpose: Resume pushing errors on the default error stack. + * + * Generally used via the H5E_PAUSE_ERRORS / H5E_RESUME_ERRORS + * macros. + * + * When one needs to temporarily disable recording errors while + * trying something that's likely or expected to fail. The code + * to try can be nested between these macros like: + * + * H5E_PAUSE_ERRORS { + * ...stuff here that's likely to fail... + * } H5E_RESUME_ERRORS + * + * Warning: don't break, return, or longjmp() from the block of + * code or the error reporting won't be properly restored! + * + * Return: none + * + *------------------------------------------------------------------------- + */ +void +H5E_resume_stack(void) +{ + H5E_stack_t *estack = H5E__get_my_stack(); + + FUNC_ENTER_NOAPI_NOERR + + assert(estack); + assert(estack->paused); + + /* Decrement pause counter */ + estack->paused--; + + FUNC_LEAVE_NOAPI_VOID +} /* end H5E_resume_stack() */ diff --git a/src/H5Epkg.h b/src/H5Epkg.h index 2d950ca3d7b..1577939c184 100644 --- a/src/H5Epkg.h +++ b/src/H5Epkg.h @@ -114,6 +114,7 @@ typedef struct H5E_stack_t { H5E_entry_t entries[H5E_MAX_ENTRIES]; /* Array of error entries */ H5E_auto_op_t auto_op; /* Operator for 'automatic' error reporting */ void *auto_data; /* Callback data for 'automatic error reporting */ + unsigned paused; /* Whether error reporting is paused (>0) for this stack */ } H5E_stack_t; /*****************************/ diff --git a/src/H5Eprivate.h b/src/H5Eprivate.h index 3777805aeb9..a3f8b693b33 100644 --- a/src/H5Eprivate.h +++ b/src/H5Eprivate.h @@ -21,6 +21,23 @@ /* Private headers needed by this file */ #include "H5private.h" +/* + * When one needs to temporarily disable recording errors while trying + * something that's likely or expected to fail. The code to try can be nested + * between these macros like: + * + * H5E_PAUSE_ERRORS { + * ...stuff here that's likely to fail... + * } H5E_RESUME_ERRORS + * + * Warning: don't break, return, or longjmp() from the block of code or + * the error reporting won't be properly restored! + * + */ +#define H5E_PAUSE_ERRORS H5E_pause_stack(); + +#define H5E_RESUME_ERRORS H5E_resume_stack(); + /* * HERROR macro, used to facilitate error reporting between a FUNC_ENTER() * and a FUNC_LEAVE() within a function body. The arguments are the major @@ -186,5 +203,7 @@ H5_DLL herr_t H5E_printf_stack(const char *file, const char *func, unsigned line hid_t min_idx, const char *fmt, ...) H5_ATTR_FORMAT(printf, 6, 7); H5_DLL herr_t H5E_clear_stack(void); H5_DLL herr_t H5E_dump_api_stack(void); +H5_DLL void H5E_pause_stack(void); +H5_DLL void H5E_resume_stack(void); #endif /* H5Eprivate_H */ diff --git a/src/H5Epublic.h b/src/H5Epublic.h index 2b0e48dc9fd..49628efb9be 100644 --- a/src/H5Epublic.h +++ b/src/H5Epublic.h @@ -77,11 +77,12 @@ H5_DLLVAR hid_t H5E_ERR_CLS_g; * trying something that's likely or expected to fail. The code to try can * be nested between calls to H5Eget_auto() and H5Eset_auto(), but it's * easier just to use this macro like: + * * H5E_BEGIN_TRY { * ...stuff here that's likely to fail... * } H5E_END_TRY * - * Warning: don't break, return, or longjmp() from the body of the loop or + * Warning: don't break, return, or longjmp() from the block of code or * the error reporting won't be properly restored! * * These two macros still use the old API functions for backward compatibility @@ -322,6 +323,71 @@ H5_DLL hid_t H5Eget_current_stack(void); * \since 1.14.0 */ H5_DLL herr_t H5Eappend_stack(hid_t dst_stack_id, hid_t src_stack_id, hbool_t close_source_stack); +/** + * -------------------------------------------------------------------------- + * \ingroup H5E + * + * \brief * Check if pushing errors on an error stack is paused + * + * \estack_id{stack_id} + * \param[out] is_paused Flag whether stack is paused + * \return \herr_t + * + * \details H5Eis_paused() can be used within HDF5 VOL connectors and other + * dynamically loaded components to check if the HDF5 library, or other + * component has paused pushing error on the default error stack or + * an application stack. + * + * The library may pause pushing errors on the default error stack + * when performing "speculative" operations, such as testing for the + * existence of something that could be located at one of many + * locations. \p stack_id is the error stack to query, and the value + * pointed to by \p is_paused is set to TRUE/FALSE. + * + * If an error occurs while attempting to query the status of \p stack_id, + * the value pointed to by \p is_paused is unchanged. + * + * \since 1.14.5 + */ +H5_DLL herr_t H5Eis_paused(hid_t stack_id, hbool_t *is_paused); +/** + * -------------------------------------------------------------------------- + * \ingroup H5E + * + * \brief * Pause pushing errors on an error stack + * + * \estack_id{stack_id} + * \return \herr_t + * + * \details H5Epause_stack() pauses pushing errors on an error stack. Pushing + * an error on a paused error stack will be ignored (not fail). + * + * H5Eresume_stack() is used to allow errors to be pushed on a stack. + * Calls to H5Epause_stack() and H5Eresume_stack() must be matched. + * + * Calls to H5Epause_stack()/H5Eresume_stack() may be nested. + * + * \since 1.14.5 + */ +H5_DLL herr_t H5Epause_stack(hid_t stack_id); +/** + * -------------------------------------------------------------------------- + * \ingroup H5E + * + * \brief * Resume pushing errors on an error stack + * + * \estack_id{stack_id} + * \return \herr_t + * + * \details H5Eresume_stack() resumes pushing errors on an error stack. + * + * Calls to H5Epause_stack() and H5Eresume_stack() must be matched. + * + * Calls to H5Epause_stack()/H5Eresume_stack() may be nested. + * + * \since 1.14.5 + */ +H5_DLL herr_t H5Eresume_stack(hid_t stack_id); /** * -------------------------------------------------------------------------- * \ingroup H5E diff --git a/src/H5FD.c b/src/H5FD.c index 1f603806b7d..a6f35ad6a87 100644 --- a/src/H5FD.c +++ b/src/H5FD.c @@ -693,7 +693,7 @@ H5FDopen(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file access property list"); /* Call private function */ - if (NULL == (ret_value = H5FD_open(name, flags, fapl_id, maxaddr))) + if (H5FD_open(false, &ret_value, name, flags, fapl_id, maxaddr) < 0) HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, NULL, "unable to open file"); done: @@ -703,64 +703,88 @@ H5FDopen(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr) /*------------------------------------------------------------------------- * Function: H5FD_open * - * Purpose: Private version of H5FDopen() - * - * Return: Success: Pointer to a new file driver struct + * Purpose: Opens a file named NAME for the type(s) of access described + * by the bit vector FLAGS according to a file access + * property list FAPL_ID (which may be the constant H5P_DEFAULT). + * The file should expect to handle format addresses in the range + * [0, MAXADDR] (if MAXADDR is the undefined address then the + * caller doesn't care about the address range). + * + * If the 'try' flag is true, the VFD 'open' callback is called + * with errors paused and not opening the file is not treated as + * an error; SUCCEED is returned, with the file ptr set to NULL. + * If 'try' is false, the VFD 'open' callback is made with errors + * unpaused and a failure generates an error. * - * Failure: NULL + * Return: SUCCEED/FAIL * *------------------------------------------------------------------------- */ -H5FD_t * -H5FD_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr) +herr_t +H5FD_open(bool try, H5FD_t **_file, const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr) { - H5FD_class_t *driver; /* VFD for file */ - H5FD_t *file = NULL; /* VFD file struct */ - H5FD_driver_prop_t driver_prop; /* Property for driver ID & info */ - H5P_genplist_t *plist; /* Property list pointer */ - unsigned long driver_flags = 0; /* File-inspecific driver feature flags */ - H5FD_file_image_info_t file_image_info; /* Initial file image */ - H5FD_t *ret_value = NULL; /* Return value */ + H5FD_t *file = NULL; /* File opened */ + H5FD_class_t *driver; /* VFD for file */ + H5FD_driver_prop_t driver_prop; /* Property for driver ID & info */ + H5P_genplist_t *plist; /* Property list pointer */ + unsigned long driver_flags = 0; /* File-inspecific driver feature flags */ + H5FD_file_image_info_t file_image_info; /* Initial file image */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(NULL) + FUNC_ENTER_NOAPI(FAIL) + + /* Reset 'out' parameter */ + *_file = NULL; /* Sanity checks */ if (0 == maxaddr) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "zero format address range"); + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "zero format address range"); /* Get file access property list */ if (NULL == (plist = (H5P_genplist_t *)H5I_object(fapl_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file access property list"); + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list"); /* Get the VFD to open the file with */ if (H5P_peek(plist, H5F_ACS_FILE_DRV_NAME, &driver_prop) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get driver ID & info"); + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get driver ID & info"); /* Get driver info */ if (NULL == (driver = (H5FD_class_t *)H5I_object(driver_prop.driver_id))) - HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, NULL, "invalid driver ID in file access property list"); + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "invalid driver ID in file access property list"); if (NULL == driver->open) - HGOTO_ERROR(H5E_VFL, H5E_UNSUPPORTED, NULL, "file driver has no `open' method"); + HGOTO_ERROR(H5E_VFL, H5E_UNSUPPORTED, FAIL, "file driver has no `open' method"); /* Query driver flag */ if (H5FD_driver_query(driver, &driver_flags) < 0) - HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, NULL, "can't query VFD flags"); + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "can't query VFD flags"); /* Get initial file image info */ if (H5P_peek(plist, H5F_ACS_FILE_IMAGE_INFO_NAME, &file_image_info) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get file image info"); + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get file image info"); /* If an image is provided, make sure the driver supports this feature */ - assert(((file_image_info.buffer != NULL) && (file_image_info.size > 0)) || - ((file_image_info.buffer == NULL) && (file_image_info.size == 0))); - if ((file_image_info.buffer != NULL) && !(driver_flags & H5FD_FEAT_ALLOW_FILE_IMAGE)) - HGOTO_ERROR(H5E_VFL, H5E_UNSUPPORTED, NULL, "file image set, but not supported."); + assert((file_image_info.buffer && file_image_info.size > 0) || + (!file_image_info.buffer && file_image_info.size == 0)); + if (file_image_info.buffer && !(driver_flags & H5FD_FEAT_ALLOW_FILE_IMAGE)) + HGOTO_ERROR(H5E_VFL, H5E_UNSUPPORTED, FAIL, "file image set, but not supported."); - /* Dispatch to file driver */ if (HADDR_UNDEF == maxaddr) maxaddr = driver->maxaddr; - if (NULL == (file = (driver->open)(name, flags, fapl_id, maxaddr))) - HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, NULL, "open failed"); + + /* Try dispatching to file driver */ + if (try) { + H5E_PAUSE_ERRORS + { + file = (driver->open)(name, flags, fapl_id, maxaddr); + } + H5E_RESUME_ERRORS + + /* Check if file was not opened */ + if (NULL == file) + HGOTO_DONE(SUCCEED); + } + else if (NULL == (file = (driver->open)(name, flags, fapl_id, maxaddr))) + HGOTO_ERROR(H5E_VFL, H5E_CANTOPENFILE, FAIL, "can't open file"); /* Set the file access flags */ file->access_flags = flags; @@ -770,22 +794,22 @@ H5FD_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr) */ file->driver_id = driver_prop.driver_id; if (H5I_inc_ref(file->driver_id, false) < 0) - HGOTO_ERROR(H5E_VFL, H5E_CANTINC, NULL, "unable to increment ref count on VFL driver"); + HGOTO_ERROR(H5E_VFL, H5E_CANTINC, FAIL, "unable to increment ref count on VFL driver"); file->cls = driver; file->maxaddr = maxaddr; - if (H5P_get(plist, H5F_ACS_ALIGN_THRHD_NAME, &(file->threshold)) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get alignment threshold"); - if (H5P_get(plist, H5F_ACS_ALIGN_NAME, &(file->alignment)) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get alignment"); + if (H5P_get(plist, H5F_ACS_ALIGN_THRHD_NAME, &file->threshold) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get alignment threshold"); + if (H5P_get(plist, H5F_ACS_ALIGN_NAME, &file->alignment) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get alignment"); /* Retrieve the VFL driver feature flags */ - if (H5FD__query(file, &(file->feature_flags)) < 0) - HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, NULL, "unable to query file driver"); + if (H5FD__query(file, &file->feature_flags) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "unable to query file driver"); /* Increment the global serial number & assign it to this H5FD_t object */ if (++H5FD_file_serial_no_g == 0) { /* (Just error out if we wrap around for now...) */ - HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, NULL, "unable to get file serial number"); + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "unable to get file serial number"); } /* end if */ file->fileno = H5FD_file_serial_no_g; @@ -793,8 +817,8 @@ H5FD_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr) /* (This will be changed later, when the superblock is located) */ file->base_addr = 0; - /* Set return value */ - ret_value = file; + /* Set 'out' parameter */ + *_file = file; done: /* Can't cleanup 'file' information, since we don't know what type it is */ diff --git a/src/H5FDonion.c b/src/H5FDonion.c index f1b46d83ada..96f9166b244 100644 --- a/src/H5FDonion.c +++ b/src/H5FDonion.c @@ -710,25 +710,20 @@ H5FD__onion_create_truncate_onion(H5FD_onion_t *file, const char *filename, cons HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid backing FAPL ID"); /* Create backing files for onion history */ - - if (NULL == (file->original_file = H5FD_open(filename, flags, backing_fapl_id, maxaddr))) + if (H5FD_open(false, &file->original_file, filename, flags, backing_fapl_id, maxaddr) < 0) HGOTO_ERROR(H5E_VFL, H5E_CANTOPENFILE, FAIL, "cannot open the backing file"); - - if (NULL == (file->onion_file = H5FD_open(name_onion, flags, backing_fapl_id, maxaddr))) + if (H5FD_open(false, &file->onion_file, name_onion, flags, backing_fapl_id, maxaddr) < 0) HGOTO_ERROR(H5E_VFL, H5E_CANTOPENFILE, FAIL, "cannot open the backing onion file"); - - if (NULL == (file->recovery_file = H5FD_open(recovery_file_nameery, flags, backing_fapl_id, maxaddr))) + if (H5FD_open(false, &file->recovery_file, recovery_file_nameery, flags, backing_fapl_id, maxaddr) < 0) HGOTO_ERROR(H5E_VFL, H5E_CANTOPENFILE, FAIL, "cannot open the backing file"); /* Write "empty" .h5 file contents (signature ONIONEOF) */ - if (H5FD_set_eoa(file->original_file, H5FD_MEM_DRAW, 8) < 0) HGOTO_ERROR(H5E_VFL, H5E_CANTSET, FAIL, "can't extend EOA"); if (H5FD_write(file->original_file, H5FD_MEM_DRAW, 0, 8, "ONIONEOF") < 0) HGOTO_ERROR(H5E_VFL, H5E_WRITEERROR, FAIL, "cannot write header to the backing h5 file"); /* Write nascent history (with no revisions) to "recovery" */ - if (NULL == (buf = H5MM_malloc(H5FD_ONION_ENCODED_SIZE_HISTORY))) HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "can't allocate buffer"); size = H5FD__onion_history_encode(history, buf, &history->checksum); @@ -745,7 +740,6 @@ H5FD__onion_create_truncate_onion(H5FD_onion_t *file, const char *filename, cons /* Write history header with "no" history. * Size of the "recovery" history recorded for later use on close. */ - if (NULL == (buf = H5MM_malloc(H5FD_ONION_ENCODED_SIZE_HEADER))) HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "can't allocate buffer"); size = H5FD__onion_header_encode(hdr, buf, &hdr->checksum); @@ -1019,15 +1013,12 @@ H5FD__onion_open(const char *filename, unsigned flags, hid_t fapl_id, haddr_t ma /* Opening an existing onion file */ /* Open the existing file using the specified fapl */ - if (NULL == (file->original_file = H5FD_open(filename, flags, backing_fapl_id, maxaddr))) + if (H5FD_open(false, &file->original_file, filename, flags, backing_fapl_id, maxaddr) < 0) HGOTO_ERROR(H5E_VFL, H5E_CANTOPENFILE, NULL, "unable to open canonical file (does not exist?)"); /* Try to open any existing onion file */ - H5E_BEGIN_TRY - { - file->onion_file = H5FD_open(name_onion, flags, backing_fapl_id, maxaddr); - } - H5E_END_TRY + if (H5FD_open(true, &file->onion_file, name_onion, flags, backing_fapl_id, maxaddr) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTOPENFILE, NULL, "cannot try opening the backing onion file"); /* If that didn't work, create a new onion file */ /* TODO: Move to a new function */ @@ -1054,9 +1045,8 @@ H5FD__onion_open(const char *filename, unsigned flags, hid_t fapl_id, haddr_t ma file->align_history_on_pages = true; } - if (HADDR_UNDEF == (canon_eof = H5FD_get_eof(file->original_file, H5FD_MEM_DEFAULT))) { + if (HADDR_UNDEF == (canon_eof = H5FD_get_eof(file->original_file, H5FD_MEM_DEFAULT))) HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, NULL, "cannot get size of canonical file"); - } if (H5FD_set_eoa(file->original_file, H5FD_MEM_DRAW, canon_eof) < 0) HGOTO_ERROR(H5E_VFL, H5E_CANTSET, NULL, "can't extend EOA"); hdr->origin_eof = canon_eof; @@ -1068,11 +1058,9 @@ H5FD__onion_open(const char *filename, unsigned flags, hid_t fapl_id, haddr_t ma HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "invalid backing FAPL ID"); /* Create backing files for onion history */ - - if ((file->onion_file = H5FD_open(name_onion, (H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC), - backing_fapl_id, maxaddr)) == NULL) { + if (H5FD_open(false, &file->onion_file, name_onion, + (H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC), backing_fapl_id, maxaddr) < 0) HGOTO_ERROR(H5E_VFL, H5E_CANTOPENFILE, NULL, "cannot open the backing onion file"); - } /* Write history header with "no" history */ hdr->history_size = H5FD_ONION_ENCODED_SIZE_HISTORY; /* record for later use */ @@ -1092,16 +1080,14 @@ H5FD__onion_open(const char *filename, unsigned flags, hid_t fapl_id, haddr_t ma history->n_revisions = 0; size = H5FD__onion_history_encode(history, hist_buf, &history->checksum); file->header.history_size = size; /* record for later use */ - if (H5FD_ONION_ENCODED_SIZE_HISTORY != size) { + if (H5FD_ONION_ENCODED_SIZE_HISTORY != size) HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, NULL, "can't encode history"); - } if (H5FD_set_eoa(file->onion_file, H5FD_MEM_DRAW, saved_size + size + 1) < 0) HGOTO_ERROR(H5E_VFL, H5E_CANTSET, NULL, "can't extend EOA"); - if (H5FD_write(file->onion_file, H5FD_MEM_DRAW, 0, saved_size, head_buf) < 0) { + if (H5FD_write(file->onion_file, H5FD_MEM_DRAW, 0, saved_size, head_buf) < 0) HGOTO_ERROR(H5E_VFL, H5E_WRITEERROR, NULL, "cannot write header to the backing onion file"); - } file->onion_eof = (haddr_t)saved_size; if (true == file->align_history_on_pages) @@ -1112,24 +1098,21 @@ H5FD__onion_open(const char *filename, unsigned flags, hid_t fapl_id, haddr_t ma file->header.history_addr = file->onion_eof; /* Write nascent history (with no revisions) to the backing onion file */ - if (H5FD_write(file->onion_file, H5FD_MEM_DRAW, saved_size + 1, size, hist_buf) < 0) { + if (H5FD_write(file->onion_file, H5FD_MEM_DRAW, saved_size + 1, size, hist_buf) < 0) HGOTO_ERROR(H5E_VFL, H5E_WRITEERROR, NULL, "cannot write history to the backing onion file"); - } file->header.history_size = size; /* record for later use */ H5MM_xfree(head_buf); H5MM_xfree(hist_buf); } - else { + else HGOTO_ERROR(H5E_VFL, H5E_CANTOPENFILE, NULL, "unable to open onion file (does not exist?)."); - } } - if (HADDR_UNDEF == (canon_eof = H5FD_get_eof(file->original_file, H5FD_MEM_DEFAULT))) { + if (HADDR_UNDEF == (canon_eof = H5FD_get_eof(file->original_file, H5FD_MEM_DEFAULT))) HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, NULL, "cannot get size of canonical file"); - } if (H5FD_set_eoa(file->original_file, H5FD_MEM_DRAW, canon_eof) < 0) HGOTO_ERROR(H5E_VFL, H5E_CANTSET, NULL, "can't extend EOA"); @@ -1139,10 +1122,9 @@ H5FD__onion_open(const char *filename, unsigned flags, hid_t fapl_id, haddr_t ma file->align_history_on_pages = (file->header.flags & H5FD_ONION_HEADER_FLAG_PAGE_ALIGNMENT) ? true : false; - if (H5FD_ONION_HEADER_FLAG_WRITE_LOCK & file->header.flags) { - /* Opening a file twice in write mode is an error */ + /* Opening a file twice in write mode is an error */ + if (H5FD_ONION_HEADER_FLAG_WRITE_LOCK & file->header.flags) HGOTO_ERROR(H5E_VFL, H5E_UNSUPPORTED, NULL, "Can't open file already opened in write-mode"); - } else { /* Read in the history from the onion file */ if (H5FD__onion_ingest_history(&file->history, file->onion_file, file->header.history_addr, @@ -1154,21 +1136,18 @@ H5FD__onion_open(const char *filename, unsigned flags, hid_t fapl_id, haddr_t ma fa->revision_num != H5FD_ONION_FAPL_INFO_REVISION_ID_LATEST) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "target revision ID out of range"); - if (fa->revision_num == 0) { + if (fa->revision_num == 0) file->curr_rev_record.logical_eof = canon_eof; - } else if (file->history.n_revisions > 0 && H5FD__onion_ingest_revision_record( &file->curr_rev_record, file->onion_file, &file->history, - MIN(fa->revision_num - 1, (file->history.n_revisions - 1))) < 0) { + MIN(fa->revision_num - 1, (file->history.n_revisions - 1))) < 0) HGOTO_ERROR(H5E_VFL, H5E_CANTDECODE, NULL, "can't get revision record from backing store"); - } if (H5F_ACC_RDWR & flags) if (H5FD__onion_open_rw(file, flags, maxaddr, new_open) < 0) HGOTO_ERROR(H5E_VFL, H5E_CANTOPENFILE, NULL, "can't write-open write-locked file"); } - } /* End if opening existing file */ /* Copy comment from FAPL info, if one is given */ @@ -1211,7 +1190,6 @@ H5FD__onion_open(const char *filename, unsigned flags, hid_t fapl_id, haddr_t ma H5I_dec_app_ref(fa->backing_fapl_id); if ((NULL == ret_value) && file) { - if (file->original_file) if (H5FD_close(file->original_file) < 0) HDONE_ERROR(H5E_VFL, H5E_CANTRELEASE, NULL, "can't destroy backing canon"); @@ -1221,13 +1199,11 @@ H5FD__onion_open(const char *filename, unsigned flags, hid_t fapl_id, haddr_t ma if (file->recovery_file) if (H5FD_close(file->recovery_file) < 0) HDONE_ERROR(H5E_VFL, H5E_CANTRELEASE, NULL, "can't destroy backing recov"); - if (file->rev_index) if (H5FD__onion_revision_index_destroy(file->rev_index) < 0) HDONE_ERROR(H5E_VFL, H5E_CANTRELEASE, NULL, "can't destroy revision index"); H5MM_xfree(file->history.record_locs); - H5MM_xfree(file->recovery_file_name); H5MM_xfree(file->curr_rev_record.comment); @@ -1270,10 +1246,8 @@ H5FD__onion_open_rw(H5FD_onion_t *file, unsigned int flags, haddr_t maxaddr, boo HGOTO_ERROR(H5E_VFL, H5E_UNSUPPORTED, FAIL, "can't write-open write-locked file"); /* Copy history to recovery file */ - - if (NULL == - (file->recovery_file = H5FD_open(file->recovery_file_name, (flags | H5F_ACC_CREAT | H5F_ACC_TRUNC), - file->fa.backing_fapl_id, maxaddr))) + if (H5FD_open(false, &file->recovery_file, file->recovery_file_name, + (flags | H5F_ACC_CREAT | H5F_ACC_TRUNC), file->fa.backing_fapl_id, maxaddr) < 0) HGOTO_ERROR(H5E_VFL, H5E_CANTOPENFILE, FAIL, "unable to create recovery file"); if (0 == (size = H5FD__onion_write_history(&file->history, file->recovery_file, 0, 0))) @@ -1282,20 +1256,15 @@ H5FD__onion_open_rw(H5FD_onion_t *file, unsigned int flags, haddr_t maxaddr, boo HGOTO_ERROR(H5E_VFL, H5E_WRITEERROR, FAIL, "written history differed from expected size"); /* Set write-lock flag in onion header */ - if (NULL == (buf = H5MM_malloc(H5FD_ONION_ENCODED_SIZE_HEADER))) HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "can't allocate space for encoded buffer"); - file->header.flags |= H5FD_ONION_HEADER_FLAG_WRITE_LOCK; - if (0 == (size = H5FD__onion_header_encode(&file->header, buf, &checksum))) HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "problem encoding history header"); - if (H5FD_write(file->onion_file, H5FD_MEM_DRAW, 0, size, buf) < 0) HGOTO_ERROR(H5E_VFL, H5E_WRITEERROR, FAIL, "can't write updated history header"); /* Prepare revision index and finalize write-mode open */ - if (NULL == (file->rev_index = H5FD__onion_revision_index_init(file->fa.page_size))) HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "can't initialize revision index"); file->curr_rev_record.parent_revision_num = file->curr_rev_record.revision_num; @@ -1679,7 +1648,7 @@ H5FDonion_get_revision_count(const char *filename, hid_t fapl_id, uint64_t *revi HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a Onion VFL driver"); /* Open the file with the driver */ - if (NULL == (file = H5FD_open(filename, H5F_ACC_RDONLY, fapl_id, HADDR_UNDEF))) + if (H5FD_open(false, &file, filename, H5F_ACC_RDONLY, fapl_id, HADDR_UNDEF) < 0) HGOTO_ERROR(H5E_VFL, H5E_CANTOPENFILE, FAIL, "unable to open file with onion driver"); /* Call the private function */ diff --git a/src/H5FDprivate.h b/src/H5FDprivate.h index 2fe54a588a9..942dc21e2e5 100644 --- a/src/H5FDprivate.h +++ b/src/H5FDprivate.h @@ -124,7 +124,8 @@ H5_DLL htri_t H5FD_is_driver_registered_by_name(const char *driver_name, H5_DLL htri_t H5FD_is_driver_registered_by_value(H5FD_class_value_t driver_value, hid_t *registered_id); H5_DLL hid_t H5FD_get_driver_id_by_name(const char *name, bool is_api); H5_DLL hid_t H5FD_get_driver_id_by_value(H5FD_class_value_t value, bool is_api); -H5_DLL H5FD_t *H5FD_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr); +H5_DLL herr_t H5FD_open(bool try, H5FD_t **file, const char *name, unsigned flags, hid_t fapl_id, + haddr_t maxaddr); H5_DLL herr_t H5FD_close(H5FD_t *file); H5_DLL int H5FD_cmp(const H5FD_t *f1, const H5FD_t *f2); H5_DLL herr_t H5FD_driver_query(const H5FD_class_t *driver, unsigned long *flags /*out*/); diff --git a/src/H5FDsplitter.c b/src/H5FDsplitter.c index 434f870407f..778d112822e 100644 --- a/src/H5FDsplitter.c +++ b/src/H5FDsplitter.c @@ -854,12 +854,9 @@ H5FD__splitter_open(const char *name, unsigned flags, hid_t splitter_fapl_id, ha } /* end if logfile path given */ } /* end if logfile pointer/handle does not exist */ - file_ptr->rw_file = H5FD_open(name, flags, fapl_ptr->rw_fapl_id, HADDR_UNDEF); - if (!file_ptr->rw_file) + if (H5FD_open(false, &file_ptr->rw_file, name, flags, fapl_ptr->rw_fapl_id, HADDR_UNDEF) < 0) HGOTO_ERROR(H5E_VFL, H5E_CANTOPENFILE, NULL, "unable to open R/W file"); - - file_ptr->wo_file = H5FD_open(fapl_ptr->wo_path, flags, fapl_ptr->wo_fapl_id, HADDR_UNDEF); - if (!file_ptr->wo_file) + if (H5FD_open(false, &file_ptr->wo_file, fapl_ptr->wo_path, flags, fapl_ptr->wo_fapl_id, HADDR_UNDEF) < 0) H5FD_SPLITTER_WO_ERROR(file_ptr, __func__, H5E_VFL, H5E_CANTOPENFILE, NULL, "unable to open W/O file") ret_value = (H5FD_t *)file_ptr; diff --git a/src/H5FDsubfiling/H5FDsubfiling.c b/src/H5FDsubfiling/H5FDsubfiling.c index 7971050b1c4..6fbd3696200 100644 --- a/src/H5FDsubfiling/H5FDsubfiling.c +++ b/src/H5FDsubfiling/H5FDsubfiling.c @@ -1235,7 +1235,7 @@ H5FD__subfiling_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t ma H5_SUBFILING_GOTO_ERROR(H5E_PLIST, H5E_CANTSET, NULL, "can't set stub file ID on FAPL"); /* Open the HDF5 file's subfiles */ - if (NULL == (file_ptr->sf_file = H5FD_open(name, flags, file_ptr->fa.ioc_fapl_id, HADDR_UNDEF))) + if (H5FD_open(false, &file_ptr->sf_file, name, flags, file_ptr->fa.ioc_fapl_id, HADDR_UNDEF) < 0) H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTOPENFILE, NULL, "unable to open IOC file"); if (driver->value == H5_VFD_IOC) { diff --git a/src/H5FDsubfiling/H5subfiling_common.c b/src/H5FDsubfiling/H5subfiling_common.c index 0493603f828..53fb0ce3c4c 100644 --- a/src/H5FDsubfiling/H5subfiling_common.c +++ b/src/H5FDsubfiling/H5subfiling_common.c @@ -573,7 +573,7 @@ H5_open_subfiling_stub_file(const char *name, unsigned flags, MPI_Comm file_comm if (H5P_set_driver(plist, H5FD_MPIO, NULL, NULL) < 0) H5_SUBFILING_GOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set MPI I/O driver on FAPL"); - if (NULL == (stub_file = H5FD_open(name, flags, fapl_id, HADDR_UNDEF))) + if (H5FD_open(false, &stub_file, name, flags, fapl_id, HADDR_UNDEF) < 0) H5_SUBFILING_GOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "couldn't open HDF5 stub file"); HDcompile_assert(sizeof(uint64_t) >= sizeof(ino_t)); diff --git a/src/H5Fefc.c b/src/H5Fefc.c index fa7dd1e6d0b..e8ecc6d0efe 100644 --- a/src/H5Fefc.c +++ b/src/H5Fefc.c @@ -62,6 +62,8 @@ struct H5F_efc_t { }; /* Private prototypes */ +static herr_t H5F__efc_open_file(bool try, H5F_t **file, const char *name, unsigned flags, hid_t fcpl_id, + hid_t fapl_id); static herr_t H5F__efc_release_real(H5F_efc_t *efc); static herr_t H5F__efc_remove_ent(H5F_efc_t *efc, H5F_efc_ent_t *ent); static void H5F__efc_try_close_tag1(H5F_shared_t *sf, H5F_shared_t **tail); @@ -114,66 +116,128 @@ H5F__efc_create(unsigned max_nfiles) FUNC_LEAVE_NOAPI(ret_value) } /* end H5F__efc_create() */ +/*------------------------------------------------------------------------- + * Function: H5F__efc_open_file + * + * Purpose: Helper routine to try opening and setting up a file. + * + * If the 'try' flag is true, not opening the file with the + * underlying 'open' call is not treated an error; SUCCEED is + * returned, with the file ptr set to NULL. If 'try' is false, + * failing the 'open' call generates an error. + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ +static herr_t +H5F__efc_open_file(bool try, H5F_t **_file, const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id) +{ + H5F_t *file = NULL; /* File opened */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_PACKAGE + + /* Reset 'out' parameter */ + *_file = NULL; + + /* Open the file */ + if (H5F_open(try, &file, name, flags, fcpl_id, fapl_id) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "can't open file"); + + /* Check if file was not opened */ + if (NULL == file) { + assert(try); + HGOTO_DONE(SUCCEED); + } + + /* Make file post open call */ + if (H5F__post_open(file) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "can't finish opening file"); + + /* Increment the number of open objects to prevent the file from being + * closed out from under us - "simulate" having an open file id. Note + * that this behaviour replaces the calls to H5F_incr_nopen_objs() and + * H5F_decr_nopen_objs() in H5L_extern_traverse(). */ + file->nopen_objs++; + + /* Set 'out' parameter */ + *_file = file; + +done: + if (ret_value < 0) + if (file) + if (H5F_try_close(file, NULL) < 0) + HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't close external file"); + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5F__efc_open_file() */ + /*------------------------------------------------------------------------- * Function: H5F__efc_open * - * Purpose: Opens a file using the external file cache. The target - * file is added to the external file cache of the parent - * if it is not already present. If the target file is in - * the parent's EFC, simply returns the target file. When + * Purpose: Attempts to open a file using the external file cache. + * + * The target file is added to the external file cache of the + * parent if it is not already present. If the target file is + * in the parent's EFC, simply returns the target file. When * the file object is no longer in use, it should be closed * with H5F_efc_close (will not actually close the file * until it is evicted from the EFC). * - * Return: Pointer to open file on success - * NULL on failure + * If the 'try' flag is true, not opening the file with the + * underlying 'open' call is not treated an error; SUCCEED is + * returned, with the file ptr set to NULL. If 'try' is false, + * failing the 'open' call generates an error. + * + * Return: SUCCEED/FAIL * *------------------------------------------------------------------------- */ -H5F_t * -H5F__efc_open(H5F_efc_t *efc, const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id) +herr_t +H5F__efc_open(bool try, H5F_efc_t *efc, H5F_t **_file, const char *name, unsigned flags, hid_t fcpl_id, + hid_t fapl_id) { - H5F_efc_ent_t *ent = NULL; /* Entry for target file in efc */ - bool open_file = false; /* Whether ent->file needs to be closed in case of error */ - H5P_genplist_t *plist; /* Property list pointer for FAPL */ - H5VL_connector_prop_t connector_prop; /* Property for VOL connector ID & info */ - H5F_t *ret_value = NULL; /* Return value */ + H5F_efc_ent_t *ent = NULL; /* Entry for target file in efc */ + bool open_file = false; /* Whether ent->file needs to be closed in case of error */ + H5P_genplist_t *plist; /* Property list pointer for FAPL */ + H5VL_connector_prop_t connector_prop; /* Property for VOL connector ID & info */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE /* Sanity checks */ + assert(_file); assert(name); + /* Reset 'out' parameter */ + *_file = NULL; + /* Get the VOL info from the fapl */ if (NULL == (plist = (H5P_genplist_t *)H5I_object(fapl_id))) - HGOTO_ERROR(H5E_FILE, H5E_BADTYPE, NULL, "not a file access property list"); + HGOTO_ERROR(H5E_FILE, H5E_BADTYPE, FAIL, "not a file access property list"); if (H5P_peek(plist, H5F_ACS_VOL_CONN_NAME, &connector_prop) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "can't get VOL connector info"); + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get VOL connector info"); /* Stash a copy of the "top-level" connector property, before any pass-through * connectors modify or unwrap it. */ if (H5CX_set_vol_connector_prop(&connector_prop) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTSET, NULL, "can't set VOL connector info in API context"); + HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "can't set VOL connector info in API context"); - /* Check if the EFC exists. If it does not, just call H5F_open(). We + /* Check if the EFC exists. If it does not, just open the file. We * support this so clients do not have to make 2 different calls depending * on the state of the efc. */ if (!efc) { - if (NULL == (ret_value = H5F_open(name, flags, fcpl_id, fapl_id))) - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "can't open file"); + if (H5F__efc_open_file(try, _file, name, flags, fcpl_id, fapl_id) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "can't try opening file"); - /* Make file post open call */ - if (H5F__post_open(ret_value) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "can't finish opening file"); + /* Check if file was not opened */ + if (NULL == *_file) + assert(try); - /* Increment the number of open objects to prevent the file from being - * closed out from under us - "simulate" having an open file id. Note - * that this behaviour replaces the calls to H5F_incr_nopen_objs() and - * H5F_decr_nopen_objs() in H5L_extern_traverse(). */ - ret_value->nopen_objs++; - - HGOTO_DONE(ret_value); + /* Done now */ + HGOTO_DONE(SUCCEED); } /* end if */ /* Search the skip list for name if the skip list exists, create the skip @@ -185,7 +249,7 @@ H5F__efc_open(H5F_efc_t *efc, const char *name, unsigned flags, hid_t fcpl_id, h else { assert(efc->nfiles == 0); if (NULL == (efc->slist = H5SL_create(H5SL_TYPE_STR, NULL))) - HGOTO_ERROR(H5E_FILE, H5E_CANTCREATE, NULL, "can't create skip list"); + HGOTO_ERROR(H5E_FILE, H5E_CANTCREATE, FAIL, "can't create skip list"); } /* end else */ /* If we found the file update the LRU list and return the cached file, @@ -231,54 +295,56 @@ H5F__efc_open(H5F_efc_t *efc, const char *name, unsigned flags, hid_t fcpl_id, h * do not add it to cache */ if (ent) { if (H5F__efc_remove_ent(efc, ent) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTREMOVE, NULL, + HGOTO_ERROR(H5E_FILE, H5E_CANTREMOVE, FAIL, "can't remove entry from external file cache"); /* Do not free ent, we will recycle it below */ } /* end if */ else { - /* Cannot cache file, just open file and return */ - if (NULL == (ret_value = H5F_open(name, flags, fcpl_id, fapl_id))) - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "can't open file"); + /* Cannot cache file, just try opening file and return */ + if (H5F__efc_open_file(try, _file, name, flags, fcpl_id, fapl_id) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "can't try opening file"); - /* Make file post open call */ - if (H5F__post_open(ret_value) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "can't finish opening file"); + /* Check if file was not opened */ + if (NULL == *_file) + assert(try); - /* Increment the number of open objects to prevent the file from - * being closed out from under us - "simulate" having an open - * file id */ - ret_value->nopen_objs++; - - HGOTO_DONE(ret_value); + /* Done now */ + HGOTO_DONE(SUCCEED); } /* end else */ } /* end if */ else /* Allocate new entry */ if (NULL == (ent = H5FL_MALLOC(H5F_efc_ent_t))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); + HGOTO_ERROR(H5E_FILE, H5E_CANTALLOC, FAIL, "memory allocation failed"); - /* Build new entry */ - if (NULL == (ent->name = H5MM_strdup(name))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); + /* Reset pointers */ + ent->file = NULL; + ent->name = NULL; - /* Open the file */ - if (NULL == (ent->file = H5F_open(name, flags, fcpl_id, fapl_id))) - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "can't open file"); - open_file = true; + /* Try opening the file */ + if (H5F__efc_open_file(try, &ent->file, name, flags, fcpl_id, fapl_id) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "can't try opening file"); - /* Make file post open call */ - if (H5F__post_open(ent->file) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "can't finish opening file"); + /* Check if file was actually opened */ + if (NULL == ent->file) { + /* Sanity check */ + assert(try); + + ent = H5FL_FREE(H5F_efc_ent_t, ent); + HGOTO_DONE(SUCCEED); + } + else + open_file = true; - /* Increment the number of open objects to prevent the file from being - * closed out from under us - "simulate" having an open file id */ - ent->file->nopen_objs++; + /* Build new entry */ + if (NULL == (ent->name = H5MM_strdup(name))) + HGOTO_ERROR(H5E_FILE, H5E_CANTALLOC, FAIL, "memory allocation failed"); /* Add the file to the cache */ /* Skip list */ if (H5SL_insert(efc->slist, ent, ent->name) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTINSERT, NULL, "can't insert entry into skip list"); + HGOTO_ERROR(H5E_FILE, H5E_CANTINSERT, FAIL, "can't insert entry into skip list"); /* Add to head of LRU list and update tail if necessary */ ent->LRU_next = efc->LRU_head; @@ -300,23 +366,18 @@ H5F__efc_open(H5F_efc_t *efc, const char *name, unsigned flags, hid_t fcpl_id, h ent->file->shared->efc->nrefs++; } /* end else */ - assert(ent); - assert(ent->file); - assert(ent->name); - assert(ent->nopen); - - /* Set the return value */ - ret_value = ent->file; + /* Set 'out' parameter */ + *_file = ent->file; done: - if (!ret_value) + if (ret_value < 0) if (ent) { if (open_file) { ent->file->nopen_objs--; if (H5F_try_close(ent->file, NULL) < 0) - HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, NULL, "can't close external file"); + HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't close external file"); } /* end if */ - ent->name = (char *)H5MM_xfree(ent->name); + ent->name = H5MM_xfree(ent->name); ent = H5FL_FREE(H5F_efc_ent_t, ent); } /* end if */ diff --git a/src/H5Fint.c b/src/H5Fint.c index 0cc48c82c9f..883cc00d857 100644 --- a/src/H5Fint.c +++ b/src/H5Fint.c @@ -819,12 +819,12 @@ H5F__getenv_prefix_name(char **env_prefix /*in,out*/) * * Purpose: Attempts to open a dataset file. * - * Return: Pointer to an opened file on success / NULL on failure + * Return: SUCCEED/FAIL *------------------------------------------------------------------------- */ -H5F_t * -H5F_prefix_open_file(H5F_t *primary_file, H5F_prefix_open_t prefix_type, const char *prop_prefix, - const char *file_name, unsigned file_intent, hid_t fapl_id) +herr_t +H5F_prefix_open_file(bool try, H5F_t **_file, H5F_t *primary_file, H5F_prefix_open_t prefix_type, + const char *prop_prefix, const char *file_name, unsigned file_intent, hid_t fapl_id) { H5F_t *src_file = NULL; /* Source file */ H5F_efc_t *efc = NULL; /* External file cache */ @@ -832,12 +832,14 @@ H5F_prefix_open_file(H5F_t *primary_file, H5F_prefix_open_t prefix_type, const c char *actual_file_name = NULL; /* File's actual name */ char *temp_file_name = NULL; /* Temporary pointer to file name */ size_t temp_file_name_len; /* Length of temporary file name */ - H5F_t *ret_value = NULL; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT + FUNC_ENTER_NOAPI(FAIL) - assert(primary_file); - assert(primary_file->shared); + assert(_file); + + /* Reset 'out' parameter */ + *_file = NULL; efc = primary_file->shared->efc; @@ -846,21 +848,19 @@ H5F_prefix_open_file(H5F_t *primary_file, H5F_prefix_open_t prefix_type, const c /* Copy the file name to use */ if (NULL == (temp_file_name = H5MM_strdup(file_name))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); + HGOTO_ERROR(H5E_FILE, H5E_CANTALLOC, FAIL, "memory allocation failed"); temp_file_name_len = strlen(temp_file_name); /* Target file_name is an absolute pathname: see RM for detailed description */ if (H5_CHECK_ABSOLUTE(file_name) || H5_CHECK_ABS_PATH(file_name)) { /* Try opening file */ - src_file = H5F__efc_open(efc, file_name, file_intent, H5P_FILE_CREATE_DEFAULT, fapl_id); + if (H5F__efc_open(true, efc, &src_file, file_name, file_intent, H5P_FILE_CREATE_DEFAULT, fapl_id) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "can't try opening file"); /* Adjust temporary file name if file not opened */ if (NULL == src_file) { char *ptr; - /* Reset the error stack */ - H5E_clear_stack(); - /* Get last component of file_name */ H5_GET_LAST_DELIMITER(file_name, ptr) assert(ptr); @@ -875,13 +875,11 @@ H5F_prefix_open_file(H5F_t *primary_file, H5F_prefix_open_t prefix_type, const c } /* end if */ else if (H5_CHECK_ABS_DRIVE(file_name)) { /* Try opening file */ - src_file = H5F__efc_open(efc, file_name, file_intent, H5P_FILE_CREATE_DEFAULT, fapl_id); + if (H5F__efc_open(true, efc, &src_file, file_name, file_intent, H5P_FILE_CREATE_DEFAULT, fapl_id) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "can't try opening file"); /* Adjust temporary file name if file not opened */ if (NULL == src_file) { - /* Reset the error stack */ - H5E_clear_stack(); - /* Strip ":" */ strncpy(temp_file_name, &file_name[2], temp_file_name_len); temp_file_name[temp_file_name_len - 1] = '\0'; @@ -898,7 +896,7 @@ H5F_prefix_open_file(H5F_t *primary_file, H5F_prefix_open_t prefix_type, const c else if (H5F_PREFIX_ELINK == prefix_type) env_prefix = getenv("HDF5_EXT_PREFIX"); else - HGOTO_ERROR(H5E_FILE, H5E_BADTYPE, NULL, "prefix type is not sensible"); + HGOTO_ERROR(H5E_FILE, H5E_BADTYPE, FAIL, "prefix type is not sensible"); /* If environment variable is defined, iterate through prefixes it defines */ if (NULL != env_prefix) { @@ -906,7 +904,7 @@ H5F_prefix_open_file(H5F_t *primary_file, H5F_prefix_open_t prefix_type, const c /* Make a copy of the environment variable string */ if (NULL == (saved_env = tmp_env_prefix = H5MM_strdup(env_prefix))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); + HGOTO_ERROR(H5E_FILE, H5E_CANTALLOC, FAIL, "memory allocation failed"); /* Loop over prefixes in environment variable */ while ((tmp_env_prefix) && (*tmp_env_prefix)) { @@ -916,23 +914,20 @@ H5F_prefix_open_file(H5F_t *primary_file, H5F_prefix_open_t prefix_type, const c if (out_prefix_name && (*out_prefix_name)) { if (H5F__build_name(out_prefix_name, temp_file_name, &full_name /*out*/) < 0) { saved_env = (char *)H5MM_xfree(saved_env); - HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "can't prepend prefix to filename"); + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't prepend prefix to filename"); } /* end if */ /* Try opening file */ - src_file = H5F__efc_open(efc, full_name, file_intent, H5P_FILE_CREATE_DEFAULT, fapl_id); + if (H5F__efc_open(true, efc, &src_file, full_name, file_intent, H5P_FILE_CREATE_DEFAULT, + fapl_id) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "can't try opening file"); /* Release copy of file name */ full_name = (char *)H5MM_xfree(full_name); - /* Check for file not opened */ - if (NULL == src_file) - /* Reset the error stack */ - H5E_clear_stack(); /* Leave if file was opened */ - else + if (src_file) break; - H5E_clear_stack(); } /* end if */ } /* end while */ @@ -944,18 +939,14 @@ H5F_prefix_open_file(H5F_t *primary_file, H5F_prefix_open_t prefix_type, const c if (src_file == NULL && prop_prefix) { /* Construct name to open */ if (H5F__build_name(prop_prefix, temp_file_name, &full_name /*out*/) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "can't prepend prefix to filename"); + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't prepend prefix to filename"); /* Try opening file */ - src_file = H5F__efc_open(efc, full_name, file_intent, H5P_FILE_CREATE_DEFAULT, fapl_id); + if (H5F__efc_open(true, efc, &src_file, full_name, file_intent, H5P_FILE_CREATE_DEFAULT, fapl_id) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "can't try opening file"); /* Release name */ full_name = (char *)H5MM_xfree(full_name); - - /* Check for file not opened */ - if (NULL == src_file) - /* Reset the error stack */ - H5E_clear_stack(); } /* end if */ /* Try searching from main file's "extpath": see description in H5F_open() & H5_build_extpath() */ @@ -965,30 +956,24 @@ H5F_prefix_open_file(H5F_t *primary_file, H5F_prefix_open_t prefix_type, const c if (NULL != (dspath = H5F_EXTPATH(primary_file))) { /* Construct name to open */ if (H5F__build_name(dspath, temp_file_name, &full_name /*out*/) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "can't prepend prefix to filename"); + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't prepend prefix to filename"); /* Try opening file */ - src_file = H5F__efc_open(efc, full_name, file_intent, H5P_FILE_CREATE_DEFAULT, fapl_id); + if (H5F__efc_open(true, efc, &src_file, full_name, file_intent, H5P_FILE_CREATE_DEFAULT, + fapl_id) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "can't try opening file"); /* Release name */ full_name = (char *)H5MM_xfree(full_name); - - /* Check for file not opened */ - if (NULL == src_file) - /* Reset the error stack */ - H5E_clear_stack(); } /* end if */ } /* end if */ /* Try the relative file_name stored in temp_file_name */ if (src_file == NULL) { /* Try opening file */ - src_file = H5F__efc_open(efc, temp_file_name, file_intent, H5P_FILE_CREATE_DEFAULT, fapl_id); - - /* Check for file not opened */ - if (NULL == src_file) - /* Reset the error stack */ - H5E_clear_stack(); + if (H5F__efc_open(true, efc, &src_file, temp_file_name, file_intent, H5P_FILE_CREATE_DEFAULT, + fapl_id) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "can't try opening file"); } /* end if */ /* try the 'resolved' name for the virtual file */ @@ -997,7 +982,7 @@ H5F_prefix_open_file(H5F_t *primary_file, H5F_prefix_open_t prefix_type, const c /* Copy resolved file name */ if (NULL == (actual_file_name = H5MM_strdup(H5F_ACTUAL_NAME(primary_file)))) - HGOTO_ERROR(H5E_FILE, H5E_CANTALLOC, NULL, "can't duplicate resolved file name string"); + HGOTO_ERROR(H5E_FILE, H5E_CANTALLOC, FAIL, "can't duplicate resolved file name string"); /* get last component of file_name */ H5_GET_LAST_DELIMITER(actual_file_name, ptr) @@ -1007,28 +992,28 @@ H5F_prefix_open_file(H5F_t *primary_file, H5F_prefix_open_t prefix_type, const c /* Build new file name for the external file */ if (H5F__build_name((ptr ? actual_file_name : ""), temp_file_name, &full_name /*out*/) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "can't prepend prefix to filename"); + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't prepend prefix to filename"); actual_file_name = (char *)H5MM_xfree(actual_file_name); /* Try opening with the resolved name */ - src_file = H5F__efc_open(efc, full_name, file_intent, H5P_FILE_CREATE_DEFAULT, fapl_id); + if (H5F__efc_open(true, efc, &src_file, full_name, file_intent, H5P_FILE_CREATE_DEFAULT, fapl_id) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "can't try opening file"); /* Release name */ full_name = (char *)H5MM_xfree(full_name); - - /* Check for file not opened */ - if (NULL == src_file) - /* Reset the error stack */ - H5E_clear_stack(); } /* end if */ - /* Set return value (possibly NULL or valid H5F_t *) */ - ret_value = src_file; + /* Set 'out' parameter */ + *_file = src_file; + + /* See is we should return an error */ + if (NULL == src_file && !try) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "can't open file"); done: - if ((NULL == ret_value) && src_file) - if (H5F_efc_close(primary_file, src_file) < 0) - HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, NULL, "can't close source file"); + if (ret_value < 0) + if (src_file && H5F_efc_close(primary_file, src_file) < 0) + HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't close source file"); if (full_name) full_name = (char *)H5MM_xfree(full_name); if (temp_file_name) @@ -1050,7 +1035,7 @@ H5F_prefix_open_file(H5F_t *primary_file, H5F_prefix_open_t prefix_type, const c htri_t H5F__is_hdf5(const char *name, hid_t fapl_id) { - H5FD_t *file = NULL; /* Low-level file struct */ + H5FD_t *lf = NULL; /* Low-level file struct */ H5F_shared_t *shared = NULL; /* Shared part of file */ haddr_t sig_addr = HADDR_UNDEF; /* Address of hdf5 file signature */ htri_t ret_value = FAIL; /* Return value */ @@ -1061,7 +1046,7 @@ H5F__is_hdf5(const char *name, hid_t fapl_id) /* NOTE: This now uses the fapl_id that was passed in, so H5Fis_accessible() * should work with arbitrary VFDs, unlike H5Fis_hdf5(). */ - if (NULL == (file = H5FD_open(name, H5F_ACC_RDONLY, fapl_id, HADDR_UNDEF))) + if (H5FD_open(false, &lf, name, H5F_ACC_RDONLY, fapl_id, HADDR_UNDEF) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to open file"); /* If the file is already open, it's an HDF5 file @@ -1070,19 +1055,19 @@ H5F__is_hdf5(const char *name, hid_t fapl_id) * mandatory file locks (like Windows), creating a new file handle and attempting * to read through it will fail so we have to try this first. */ - if ((shared = H5F__sfile_search(file)) != NULL) + if (NULL != (shared = H5F__sfile_search(lf))) ret_value = true; else { /* The file is an HDF5 file if the HDF5 file signature can be found */ - if (H5FD_locate_signature(file, &sig_addr) < 0) + if (H5FD_locate_signature(lf, &sig_addr) < 0) HGOTO_ERROR(H5E_FILE, H5E_NOTHDF5, FAIL, "error while trying to locate file signature"); ret_value = (HADDR_UNDEF != sig_addr); } done: /* Close the file */ - if (file) - if (H5FD_close(file) < 0 && true == ret_value) + if (lf) + if (H5FD_close(lf) < 0 && true == ret_value) HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "unable to close file"); FUNC_LEAVE_NOAPI(ret_value) @@ -1724,10 +1709,10 @@ H5F__check_if_using_file_locks(H5P_genplist_t *fapl, bool *use_file_locking, boo } /* end H5F__check_if_using_file_locks() */ /*------------------------------------------------------------------------- - * Function: H5F_open + * Function: H5F_open * - * Purpose: Opens (or creates) a file. This function understands the - * following flags which are similar in nature to the Posix + * Purpose: Attempts to open (or create) a file. This function understands + * the following flags which are similar in nature to the POSIX * open(2) flags. * * H5F_ACC_RDWR: Open with read/write access. If the file is @@ -1791,13 +1776,17 @@ H5F__check_if_using_file_locks(H5P_genplist_t *fapl, bool *use_file_locking, boo * f: the open fails with flags combination from both the first and second opens * s: the open succeeds with flags combination from both the first and second opens * + * NOTE: If the 'try' flag is true, not opening the file with the + * "non-tentative" VFD 'open' call is not treated an error; SUCCEED is + * returned, with the file ptr set to NULL. If 'try' is false, failing + * the "non-tentative" VFD 'open' call generates an error. + * + * Return: SUCCEED/FAIL * - * Return: Success: A new file pointer. - * Failure: NULL *------------------------------------------------------------------------- */ -H5F_t * -H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id) +herr_t +H5F_open(bool try, H5F_t **_file, const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id) { H5F_t *file = NULL; /*the success return value */ H5F_shared_t *shared = NULL; /*shared part of `file' */ @@ -1809,16 +1798,19 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id) size_t page_buf_size; unsigned page_buf_min_meta_perc = 0; unsigned page_buf_min_raw_perc = 0; - bool set_flag = false; /*set the status_flags in the superblock */ - bool clear = false; /*clear the status_flags */ - bool evict_on_close; /* evict on close value from plist */ - bool use_file_locking = true; /* Using file locks? */ - bool ignore_disabled_locks = false; /* Ignore disabled file locks? */ - bool ci_load = false; /* whether MDC ci load requested */ - bool ci_write = false; /* whether MDC CI write requested */ - H5F_t *ret_value = NULL; /*actual return value */ + bool set_flag = false; /*set the status_flags in the superblock */ + bool clear = false; /*clear the status_flags */ + bool evict_on_close; /* evict on close value from plist */ + bool use_file_locking = true; /* Using file locks? */ + bool ignore_disabled_locks = false; /* Ignore disabled file locks? */ + bool ci_load = false; /* whether MDC ci load requested */ + bool ci_write = false; /* whether MDC CI write requested */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) - FUNC_ENTER_NOAPI(NULL) + /* Reset 'out' parameter */ + *_file = NULL; /* * If the driver has a 'cmp' method then the driver is capable of @@ -1829,15 +1821,15 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id) * same file more than once at a time. */ if (NULL == (drvr = H5FD_get_class(fapl_id))) - HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "unable to retrieve VFL class"); + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to retrieve VFL class"); /* Get the file access property list, for future queries */ if (NULL == (a_plist = (H5P_genplist_t *)H5I_object(fapl_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not file access property list"); + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not file access property list"); /* Check if we are using file locking */ if (H5F__check_if_using_file_locks(a_plist, &use_file_locking, &ignore_disabled_locks) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "unable to get file locking flags"); + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to get file locking flags"); /* * Opening a file is a two step process. First we try to open the @@ -1850,40 +1842,40 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id) * application's responsibility to prevent this situation (there's no * way for us to detect it here anyway). */ - if (drvr->cmp) + if (drvr->cmp) { tent_flags = flags & ~(H5F_ACC_CREAT | H5F_ACC_TRUNC | H5F_ACC_EXCL); - else - tent_flags = flags; - /* - * When performing a tentative open of a file where we have stripped away - * flags such as H5F_ACC_CREAT from the specified file access flags, the - * H5E_BEGIN/END_TRY macros are used to suppress error output since there - * is an expectation that the tentative open might fail. Even though we - * explicitly clear the error stack after such a failure, the underlying - * file driver might maintain its own error stack and choose whether to - * display errors based on whether the library has disabled error reporting. - * Since we wish to suppress that error output as well for the case of - * tentative file opens, surrounding the file open call with the - * H5E_BEGIN/END_TRY macros is an explicit instruction to the file driver - * not to display errors. If the tentative file open call fails, another - * attempt at opening the file will be made without error output being - * suppressed. - * - * However, if stripping away the H5F_ACC_CREAT flag and others left us - * with the same file access flags as before, then we will skip this - * tentative file open and only make a single attempt at opening the file. - * In this case, we don't want to suppress error output since the underlying - * file driver might provide more details on why the file open failed. - */ - if (tent_flags != flags) { - /* Make tentative attempt to open file */ - H5E_BEGIN_TRY - { - lf = H5FD_open(name, tent_flags, fapl_id, HADDR_UNDEF); + /* + * When performing a tentative open of a file where we have stripped + * away flags such as H5F_ACC_CREAT from the specified file access + * flags, use 'try open' operation to avoid pushing error messages + * on the error stack since there is an expectation that the tentative + * open might fail. + * + * If the tentative file open call fails, another attempt at opening + * the file will be made without error output being suppressed. + * + * However, if stripping away the H5F_ACC_CREAT flag and others left + * us with the same file access flags as before, then we will skip + * this tentative file open and only make a single attempt at opening + * the file. In this case, we don't want to suppress errors since + * the underlying file driver might provide more details on why the + * file open failed. + */ + if (tent_flags != flags) { + /* Make tentative attempt to open file */ + if (H5FD_open(true, &lf, name, tent_flags, fapl_id, HADDR_UNDEF) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "can't try opening file"); + + /* If the tentative open failed, reset the file access flags, + * then make another attempt at opening the file. + */ + if (NULL == lf) + tent_flags = flags; } - H5E_END_TRY } + else + tent_flags = flags; /* * If a tentative attempt to open the file wasn't necessary, attempt @@ -1891,15 +1883,15 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id) * the error stack and reset the file access flags, then make another * attempt at opening the file. */ - if ((tent_flags == flags) || (lf == NULL)) { - if (tent_flags != flags) { - H5E_clear_stack(); - tent_flags = flags; + if (NULL == lf) { + if (H5FD_open(try, &lf, name, tent_flags, fapl_id, HADDR_UNDEF) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "can't try opening file"); + + /* Check if file was not opened */ + if (NULL == lf) { + assert(try); + HGOTO_DONE(SUCCEED); } - - if (NULL == (lf = H5FD_open(name, tent_flags, fapl_id, HADDR_UNDEF))) - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to open file: name = '%s', tent_flags = %x", - name, tent_flags); } /* Is the file already open? */ @@ -1915,26 +1907,26 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id) * SWMR write/read access flags don't agree. */ if (H5FD_close(lf) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to close low-level file info"); + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to close low-level file info"); if (flags & H5F_ACC_TRUNC) - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to truncate a file which is already open"); + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to truncate a file which is already open"); if (flags & H5F_ACC_EXCL) - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "file exists"); + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "file exists"); if ((flags & H5F_ACC_RDWR) && 0 == (shared->flags & H5F_ACC_RDWR)) - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "file is already open for read-only"); + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "file is already open for read-only"); if ((flags & H5F_ACC_SWMR_WRITE) && 0 == (shared->flags & H5F_ACC_SWMR_WRITE)) - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "SWMR write access flag not the same for file that is already open"); if ((flags & H5F_ACC_SWMR_READ) && !((shared->flags & H5F_ACC_SWMR_WRITE) || (shared->flags & H5F_ACC_SWMR_READ) || (shared->flags & H5F_ACC_RDWR))) - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "SWMR read access flag not the same for file that is already open"); /* Allocate new "high-level" file struct */ if ((file = H5F__new(shared, flags, fcpl_id, fapl_id, NULL)) == NULL) - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to create new file object"); + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to create new file object"); } /* end if */ else { /* Check if tentative open was good enough */ @@ -1945,10 +1937,12 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id) * file and open it for real. */ if (H5FD_close(lf) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to close low-level file info"); + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to close low-level file info"); + lf = NULL; - if (NULL == (lf = H5FD_open(name, flags, fapl_id, HADDR_UNDEF))) - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to open file"); + if (H5FD_open(false, &lf, name, flags, fapl_id, HADDR_UNDEF) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to open file"); + assert(lf); } /* end if */ /* Place an advisory lock on the file */ @@ -1956,8 +1950,8 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id) if (H5FD_lock(lf, (bool)((flags & H5F_ACC_RDWR) ? true : false)) < 0) { /* Locking failed - Closing will remove the lock */ if (H5FD_close(lf) < 0) - HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, NULL, "unable to close low-level file info"); - HGOTO_ERROR(H5E_FILE, H5E_CANTLOCKFILE, NULL, "unable to lock the file"); + HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "unable to close low-level file info"); + HGOTO_ERROR(H5E_FILE, H5E_CANTLOCKFILE, FAIL, "unable to lock the file"); } /* end if */ /* Create the 'top' file structure */ @@ -1967,8 +1961,8 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id) * so we have to close lf here before heading to the error handling. */ if (H5FD_close(lf) < 0) - HDONE_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to close low-level file info"); - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to initialize file structure"); + HDONE_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to close low-level file info"); + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to initialize file structure"); } /* end if */ /* Need to set status_flags in the superblock if the driver has a 'lock' method */ @@ -1978,9 +1972,9 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id) /* Check to see if both SWMR and cache image are requested. Fail if so */ if (H5C_cache_image_status(file, &ci_load, &ci_write) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "can't get MDC cache image status"); + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get MDC cache image status"); if ((ci_load || ci_write) && (flags & (H5F_ACC_SWMR_READ | H5F_ACC_SWMR_WRITE))) - HGOTO_ERROR(H5E_FILE, H5E_UNSUPPORTED, NULL, "can't have both SWMR and cache image"); + HGOTO_ERROR(H5E_FILE, H5E_UNSUPPORTED, FAIL, "can't have both SWMR and cache image"); /* Retain the name the file was opened with */ file->open_name = H5MM_xstrdup(name); @@ -1998,26 +1992,26 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id) } else if (shared->nrefs > 1) { if (file->shared->use_file_locking != use_file_locking) - HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "file locking flag values don't match"); + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "file locking flag values don't match"); if (file->shared->use_file_locking && (file->shared->ignore_disabled_locks != ignore_disabled_locks)) - HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "file locking 'ignore disabled locks' flag values don't match"); } /* Check if page buffering is enabled */ if (H5P_get(a_plist, H5F_ACS_PAGE_BUFFER_SIZE_NAME, &page_buf_size) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "can't get page buffer size"); + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get page buffer size"); if (page_buf_size) { /* Query for other page buffer cache properties */ if (H5P_get(a_plist, H5F_ACS_PAGE_BUFFER_MIN_META_PERC_NAME, &page_buf_min_meta_perc) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "can't get minimum metadata fraction of page buffer"); + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get minimum metadata fraction of page buffer"); if (H5P_get(a_plist, H5F_ACS_PAGE_BUFFER_MIN_RAW_PERC_NAME, &page_buf_min_raw_perc) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "can't get minimum raw data fraction of page buffer"); + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get minimum raw data fraction of page buffer"); } /* end if */ /* Get the evict on close setting */ if (H5P_get(a_plist, H5F_ACS_EVICT_ON_CLOSE_FLAG_NAME, &evict_on_close) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get evict on close value"); + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get evict on close value"); #ifdef H5_HAVE_PARALLEL /* Check for unsupported settings in parallel */ @@ -2033,15 +2027,16 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id) if (page_buf_size) { /* Collective metadata writes are not supported with page buffering */ if (file->shared->coll_md_write) - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "collective metadata writes are not supported with page buffering"); - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "page buffering is disabled for parallel"); + /* Temporary: fail file create when page buffering feature is enabled for parallel */ + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "page buffering is disabled for parallel"); } if (mpi_size > 1) { if (evict_on_close) - HGOTO_ERROR(H5E_FILE, H5E_UNSUPPORTED, NULL, + HGOTO_ERROR(H5E_FILE, H5E_UNSUPPORTED, FAIL, "evict on close is currently not supported in parallel HDF5"); } } @@ -2061,24 +2056,24 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id) /* Create the page buffer before initializing the superblock */ if (page_buf_size) if (H5PB_create(shared, page_buf_size, page_buf_min_meta_perc, page_buf_min_raw_perc) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to create page buffer"); + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to create page buffer"); /* Initialize information about the superblock and allocate space for it */ /* (Writes superblock extension messages, if there are any) */ if (H5F__super_init(file) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to allocate file superblock"); + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to allocate file superblock"); /* Create and open the root group */ /* (This must be after the space for the superblock is allocated in * the file, since the superblock must be at offset 0) */ if (H5G_mkroot(file, true) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to create/open root group"); + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to create/open root group"); } /* end if */ else if (1 == shared->nrefs) { /* Read the superblock if it hasn't been read before. */ if (H5F__super_read(file, a_plist, true) < 0) - HGOTO_ERROR(H5E_FILE, H5E_READERROR, NULL, "unable to read superblock"); + HGOTO_ERROR(H5E_FILE, H5E_READERROR, FAIL, "unable to read superblock"); /* Skip trying to create a page buffer if the file space strategy * stored in the superblock isn't paged. @@ -2097,11 +2092,11 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id) /* Create the page buffer *after* reading the superblock */ if (page_buf_size) if (H5PB_create(shared, page_buf_size, page_buf_min_meta_perc, page_buf_min_raw_perc) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to create page buffer"); + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to create page buffer"); /* Open the root group */ if (H5G_mkroot(file, false) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to read root group"); + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to read root group"); } /* end if */ /* @@ -2111,7 +2106,7 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id) * the degree in shared file structure. */ if (H5P_get(a_plist, H5F_ACS_CLOSE_DEGREE_NAME, &fc_degree) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get file close degree"); + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get file close degree"); if (shared->nrefs == 1) { if (fc_degree == H5F_CLOSE_DEFAULT) shared->fc_degree = lf->cls->fc_degree; @@ -2120,16 +2115,16 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id) } /* end if */ else if (shared->nrefs > 1) { if (fc_degree == H5F_CLOSE_DEFAULT && shared->fc_degree != lf->cls->fc_degree) - HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "file close degree doesn't match"); + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "file close degree doesn't match"); if (fc_degree != H5F_CLOSE_DEFAULT && fc_degree != shared->fc_degree) - HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "file close degree doesn't match"); + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "file close degree doesn't match"); } /* end if */ /* This is a private property to clear the status_flags in the super block */ /* Use by h5clear and a routine in test/flush2.c to clear the test file's status_flags */ if (H5P_exist_plist(a_plist, H5F_ACS_CLEAR_STATUS_FLAGS_NAME) > 0) { if (H5P_get(a_plist, H5F_ACS_CLEAR_STATUS_FLAGS_NAME, &clear) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get clearance for status_flags"); + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get clearance for status_flags"); else if (clear) file->shared->sblock->status_flags = 0; } /* end if */ @@ -2143,18 +2138,18 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id) shared->evict_on_close = evict_on_close; else if (shared->nrefs > 1) { if (shared->evict_on_close != evict_on_close) - HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "file evict-on-close value doesn't match"); + HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "file evict-on-close value doesn't match"); } /* end if */ /* Formulate the absolute path for later search of target file for external links */ if (shared->nrefs == 1) { if (H5_build_extpath(name, &file->shared->extpath) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to build extpath"); + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to build extpath"); } /* Formulate the actual file name, after following symlinks, etc. */ if (H5F__build_actual_name(file, a_plist, name, &file->actual_name) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to build actual name"); + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to build actual name"); if (set_flag) { if (H5F_INTENT(file) & H5F_ACC_RDWR) { /* Set and check consistency of status_flags */ @@ -2163,7 +2158,7 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id) if (file->shared->sblock->status_flags & H5F_SUPER_WRITE_ACCESS || file->shared->sblock->status_flags & H5F_SUPER_SWMR_WRITE_ACCESS) - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "file is already open for write/SWMR write (may use to clear " "file consistency flags)"); } /* version 3 superblock */ @@ -2174,16 +2169,16 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id) /* Flush the superblock & superblock extension */ if (H5F_super_dirty(file) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTMARKDIRTY, NULL, "unable to mark superblock as dirty"); + HGOTO_ERROR(H5E_FILE, H5E_CANTMARKDIRTY, FAIL, "unable to mark superblock as dirty"); if (H5F_flush_tagged_metadata(file, H5AC__SUPERBLOCK_TAG) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, NULL, "unable to flush superblock"); + HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to flush superblock"); if (H5F_flush_tagged_metadata(file, file->shared->sblock->ext_addr) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, NULL, "unable to flush superblock extension"); + HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to flush superblock extension"); /* Remove the file lock for SWMR_WRITE */ if (use_file_locking && (H5F_INTENT(file) & H5F_ACC_SWMR_WRITE)) { if (H5FD_unlock(file->shared->lf) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTUNLOCKFILE, NULL, "unable to unlock the file"); + HGOTO_ERROR(H5E_FILE, H5E_CANTUNLOCKFILE, FAIL, "unable to unlock the file"); } /* end if */ } /* end if */ else { /* H5F_ACC_RDONLY: check consistency of status_flags */ @@ -2194,25 +2189,25 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id) !(file->shared->sblock->status_flags & H5F_SUPER_SWMR_WRITE_ACCESS)) || (!(file->shared->sblock->status_flags & H5F_SUPER_WRITE_ACCESS) && file->shared->sblock->status_flags & H5F_SUPER_SWMR_WRITE_ACCESS)) - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "file is not already open for SWMR writing"); } /* end if */ else if ((file->shared->sblock->status_flags & H5F_SUPER_WRITE_ACCESS) || (file->shared->sblock->status_flags & H5F_SUPER_SWMR_WRITE_ACCESS)) - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "file is already open for write (may use to clear file " "consistency flags)"); } /* version 3 superblock */ } /* end else */ } /* end if set_flag */ - /* Success */ - ret_value = file; + /* Set 'out' parameter */ + *_file = file; done: - if ((NULL == ret_value) && file) + if (ret_value < 0 && file) if (H5F__dest(file, false, true) < 0) - HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, NULL, "problems closing file"); + HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "problems closing file"); FUNC_LEAVE_NOAPI(ret_value) } /* end H5F_open() */ diff --git a/src/H5Fpkg.h b/src/H5Fpkg.h index 06d13ebffdd..3ecff5a28bc 100644 --- a/src/H5Fpkg.h +++ b/src/H5Fpkg.h @@ -460,11 +460,12 @@ H5_DLL herr_t H5F__set_mpi_atomicity(H5F_t *file, bool flag); /* External file cache routines */ H5_DLL H5F_efc_t *H5F__efc_create(unsigned max_nfiles); -H5_DLL H5F_t *H5F__efc_open(H5F_efc_t *efc, const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id); -H5_DLL unsigned H5F__efc_max_nfiles(H5F_efc_t *efc); -H5_DLL herr_t H5F__efc_release(H5F_efc_t *efc); -H5_DLL herr_t H5F__efc_destroy(H5F_efc_t *efc); -H5_DLL herr_t H5F__efc_try_close(H5F_t *f); +H5_DLL herr_t H5F__efc_open(bool try, H5F_efc_t *efc, H5F_t **file, const char *name, unsigned flags, + hid_t fcpl_id, hid_t fapl_id); +H5_DLL unsigned H5F__efc_max_nfiles(H5F_efc_t *efc); +H5_DLL herr_t H5F__efc_release(H5F_efc_t *efc); +H5_DLL herr_t H5F__efc_destroy(H5F_efc_t *efc); +H5_DLL herr_t H5F__efc_try_close(H5F_t *f); /* Space allocation routines */ H5_DLL haddr_t H5F__alloc(H5F_t *f, H5F_mem_t type, hsize_t size, haddr_t *frag_addr, hsize_t *frag_size); diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h index d2b1b887a7f..a4ad311a189 100644 --- a/src/H5Fprivate.h +++ b/src/H5Fprivate.h @@ -495,7 +495,8 @@ typedef enum H5F_prefix_open_t { /* Private functions */ H5_DLL herr_t H5F_init(void); -H5_DLL H5F_t *H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id); +H5_DLL herr_t H5F_open(bool try, H5F_t **file, const char *name, unsigned flags, hid_t fcpl_id, + hid_t fapl_id); H5_DLL herr_t H5F_try_close(H5F_t *f, bool *was_closed /*out*/); H5_DLL hid_t H5F_get_file_id(H5VL_object_t *vol_obj, H5I_type_t obj_type, bool app_ref); @@ -659,7 +660,7 @@ H5_DLL herr_t H5F_shared_get_mpi_file_sync_required(const H5F_shared_t *f_sh, H5_DLL herr_t H5F_efc_close(H5F_t *parent, H5F_t *file); /* File prefix routines */ -H5_DLL H5F_t *H5F_prefix_open_file(H5F_t *primary_file, H5F_prefix_open_t prefix_type, +H5_DLL herr_t H5F_prefix_open_file(bool try, H5F_t **file, H5F_t *primary_file, H5F_prefix_open_t prefix_type, const char *prop_prefix, const char *file_name, unsigned file_intent, hid_t fapl_id); diff --git a/src/H5Lexternal.c b/src/H5Lexternal.c index 89484ea1134..88ee6baa201 100644 --- a/src/H5Lexternal.c +++ b/src/H5Lexternal.c @@ -212,8 +212,8 @@ H5L__extern_traverse(const char H5_ATTR_UNUSED *link_name, hid_t cur_group, cons HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, H5I_INVALID_HID, "can't get external link prefix"); /* Search for the target file */ - if (NULL == (ext_file = H5F_prefix_open_file(loc.oloc->file, H5F_PREFIX_ELINK, elink_prefix, file_name, - intent, fapl_id))) + if (H5F_prefix_open_file(false, &ext_file, loc.oloc->file, H5F_PREFIX_ELINK, elink_prefix, file_name, + intent, fapl_id) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTOPENFILE, H5I_INVALID_HID, "unable to open external file, external link file name = '%s'", file_name); diff --git a/src/H5VLnative_file.c b/src/H5VLnative_file.c index b0686d0f1df..cb4841f2595 100644 --- a/src/H5VLnative_file.c +++ b/src/H5VLnative_file.c @@ -90,7 +90,7 @@ H5VL__native_file_create(const char *name, unsigned flags, hid_t fcpl_id, hid_t flags |= H5F_ACC_RDWR | H5F_ACC_CREAT; /* Create the file */ - if (NULL == (new_file = H5F_open(name, flags, fcpl_id, fapl_id))) + if (H5F_open(false, &new_file, name, flags, fcpl_id, fapl_id) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to create file"); new_file->id_exists = true; @@ -124,7 +124,7 @@ H5VL__native_file_open(const char *name, unsigned flags, hid_t fapl_id, hid_t H5 FUNC_ENTER_PACKAGE /* Open the file */ - if (NULL == (new_file = H5F_open(name, flags, H5P_FILE_CREATE_DEFAULT, fapl_id))) + if (H5F_open(false, &new_file, name, flags, H5P_FILE_CREATE_DEFAULT, fapl_id) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to open file"); new_file->id_exists = true; diff --git a/test/efc.c b/test/efc.c index 484320dc3d0..b5399823c89 100644 --- a/test/efc.c +++ b/test/efc.c @@ -66,7 +66,7 @@ test_single(void) TEST_ERROR; /* Open parent file */ - if (NULL == (f0 = H5F_open(filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f0, filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; /* Disable EFC for child files */ @@ -77,12 +77,12 @@ test_single(void) * count = 2, release EFC, verify ref count = 1. Verifies a file can be * held open by the EFC. */ - if (NULL == (f1 = H5F__efc_open(f0->shared->efc, filename[1], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &f1, filename[1], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f0, f1) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp1 = H5F_open(filename[1], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F_open(false, &ftmp1, filename[1], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (ftmp1->shared->nrefs != 2) TEST_ERROR; @@ -96,13 +96,13 @@ test_single(void) /* Test 2: Verify that subsequent efc_open requests return the cached top * level file pointer. Open file 1 through EFC, close, open again, verify * file pointers are the same. */ - if (NULL == (f1 = H5F__efc_open(f0->shared->efc, filename[1], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &f1, filename[1], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; ftmp1 = f1; if (H5F_efc_close(f0, f1) < 0) FAIL_STACK_ERROR; - if (NULL == (f1 = H5F__efc_open(f0->shared->efc, filename[1], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &f1, filename[1], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (f1 != ftmp1) TEST_ERROR; @@ -117,34 +117,34 @@ test_single(void) * that the one added first is evicted. Then reopen files in a different * order. Open each file normally after closing through EFC the first time * to track ref counts. */ - if (NULL == (f1 = H5F__efc_open(f0->shared->efc, filename[1], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &f1, filename[1], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f0, f1) < 0) FAIL_STACK_ERROR; - if (NULL == (f1 = H5F_open(filename[1], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F_open(false, &f1, filename[1], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (f1->shared->nrefs != 2) TEST_ERROR; - if (NULL == (f2 = H5F__efc_open(f0->shared->efc, filename[2], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &f2, filename[2], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f0, f2) < 0) FAIL_STACK_ERROR; - if (NULL == (f2 = H5F_open(filename[2], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F_open(false, &f2, filename[2], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (f1->shared->nrefs != 2) TEST_ERROR; if (f2->shared->nrefs != 2) TEST_ERROR; - if (NULL == (f3 = H5F__efc_open(f0->shared->efc, filename[3], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &f3, filename[3], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f0, f3) < 0) FAIL_STACK_ERROR; - if (NULL == (f3 = H5F_open(filename[3], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F_open(false, &f3, filename[3], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (f1->shared->nrefs != 2) TEST_ERROR; @@ -153,12 +153,12 @@ test_single(void) if (f3->shared->nrefs != 2) TEST_ERROR; - if (NULL == (f4 = H5F__efc_open(f0->shared->efc, filename[4], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &f4, filename[4], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f0, f4) < 0) FAIL_STACK_ERROR; - if (NULL == (f4 = H5F_open(filename[4], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F_open(false, &f4, filename[4], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (f1->shared->nrefs != 1) TEST_ERROR; @@ -169,7 +169,7 @@ test_single(void) if (f4->shared->nrefs != 2) TEST_ERROR; - if (NULL == (ftmp3 = H5F__efc_open(f0->shared->efc, filename[3], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &ftmp3, filename[3], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f0, ftmp3) < 0) FAIL_STACK_ERROR; @@ -182,7 +182,7 @@ test_single(void) if (f4->shared->nrefs != 2) TEST_ERROR; - if (NULL == (ftmp2 = H5F__efc_open(f0->shared->efc, filename[2], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &ftmp2, filename[2], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f0, ftmp2) < 0) FAIL_STACK_ERROR; @@ -195,7 +195,7 @@ test_single(void) if (f4->shared->nrefs != 2) TEST_ERROR; - if (NULL == (ftmp1 = H5F__efc_open(f0->shared->efc, filename[1], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &ftmp1, filename[1], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f0, ftmp1) < 0) FAIL_STACK_ERROR; @@ -208,7 +208,7 @@ test_single(void) if (f4->shared->nrefs != 1) TEST_ERROR; - if (NULL == (ftmp4 = H5F__efc_open(f0->shared->efc, filename[4], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &ftmp4, filename[4], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f0, ftmp4) < 0) FAIL_STACK_ERROR; @@ -242,10 +242,10 @@ test_single(void) /* Test 4: Verify that files kept open through the EFC are not evicted by * H5F__efc_release(). */ - if (NULL == (f1 = H5F__efc_open(f0->shared->efc, filename[1], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &f1, filename[1], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp1 = H5F_open(filename[1], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F_open(false, &ftmp1, filename[1], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (ftmp1->shared->nrefs != 2) TEST_ERROR; @@ -268,36 +268,36 @@ test_single(void) * filling up the cache. Open 4 files while holding the first open. Verify * that the second file is evicted. Close the first file, reopen the * second, and verify that the first file is evicted. */ - if (NULL == (f1 = H5F__efc_open(f0->shared->efc, filename[1], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &f1, filename[1], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp1 = H5F_open(filename[1], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F_open(false, &ftmp1, filename[1], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (ftmp1->shared != f1->shared) TEST_ERROR; if (ftmp1->shared->nrefs != 2) TEST_ERROR; - if (NULL == (f2 = H5F__efc_open(f0->shared->efc, filename[2], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &f2, filename[2], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f0, f2) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp2 = H5F_open(filename[2], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F_open(false, &ftmp2, filename[2], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (ftmp2->shared->nrefs != 2) TEST_ERROR; - if (NULL == (f3 = H5F__efc_open(f0->shared->efc, filename[3], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &f3, filename[3], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f0, f3) < 0) FAIL_STACK_ERROR; if (ftmp2->shared->nrefs != 2) TEST_ERROR; - if (NULL == (f4 = H5F__efc_open(f0->shared->efc, filename[4], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &f4, filename[4], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f0, f4) < 0) FAIL_STACK_ERROR; @@ -310,7 +310,7 @@ test_single(void) FAIL_STACK_ERROR; if (ftmp1->shared->nrefs != 2) TEST_ERROR; - if (NULL == (f2 = H5F__efc_open(f0->shared->efc, filename[2], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &f2, filename[2], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f0, f2) < 0) FAIL_STACK_ERROR; @@ -318,7 +318,7 @@ test_single(void) TEST_ERROR; if (ftmp2->shared->nrefs != 2) TEST_ERROR; - if (NULL == (f1 = H5F__efc_open(f0->shared->efc, filename[1], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &f1, filename[1], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f0, f1) < 0) FAIL_STACK_ERROR; @@ -342,42 +342,42 @@ test_single(void) * prevents further files from being cached. Open and hold open 3 files * through the EFC, then open the fourth and verify that it was not added to * the EFC. */ - if (NULL == (f1 = H5F__efc_open(f0->shared->efc, filename[1], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &f1, filename[1], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp1 = H5F_open(filename[1], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F_open(false, &ftmp1, filename[1], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (ftmp1->shared != f1->shared) TEST_ERROR; if (ftmp1->shared->nrefs != 2) TEST_ERROR; - if (NULL == (f2 = H5F__efc_open(f0->shared->efc, filename[2], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &f2, filename[2], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp2 = H5F_open(filename[2], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F_open(false, &ftmp2, filename[2], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (ftmp2->shared != f2->shared) TEST_ERROR; if (ftmp2->shared->nrefs != 2) TEST_ERROR; - if (NULL == (f3 = H5F__efc_open(f0->shared->efc, filename[3], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &f3, filename[3], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp3 = H5F_open(filename[3], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F_open(false, &ftmp3, filename[3], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (ftmp3->shared != f3->shared) TEST_ERROR; if (ftmp3->shared->nrefs != 2) TEST_ERROR; - if (NULL == (f4 = H5F__efc_open(f0->shared->efc, filename[4], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &f4, filename[4], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f0, f4) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp4 = H5F_open(filename[4], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F_open(false, &ftmp4, filename[4], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (ftmp4->shared->nrefs != 1) TEST_ERROR; @@ -415,13 +415,13 @@ test_single(void) /* Test 7: Test multiple file opens. Open a file twice, close it once, then * verify that it is not evicted by H5F__efc_release(). */ - if (NULL == (f1 = H5F__efc_open(f0->shared->efc, filename[1], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &f1, filename[1], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (f2 = H5F__efc_open(f0->shared->efc, filename[1], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &f2, filename[1], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp1 = H5F_open(filename[1], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F_open(false, &ftmp1, filename[1], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (ftmp1->shared->nrefs != 2) TEST_ERROR; @@ -492,19 +492,19 @@ test_graph_nocycle(void) * ref count reduced (implying file 1 was closed). Do the same with the * opening order reversed. */ - if (NULL == (f0 = H5F_open(filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f0, filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (f1 = H5F__efc_open(f0->shared->efc, filename[1], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &f1, filename[1], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (f2 = H5F__efc_open(f1->shared->efc, filename[2], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f1->shared->efc, &f2, filename[2], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f1, f2) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f0, f1) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp2 = H5F_open(filename[2], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F_open(false, &ftmp2, filename[2], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (ftmp2->shared->nrefs != 2) TEST_ERROR; @@ -517,15 +517,15 @@ test_graph_nocycle(void) if (H5F_try_close(f0, NULL) < 0) FAIL_STACK_ERROR; - if (NULL == (f0 = H5F_open(filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f0, filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == - (ftmp1 = H5F_open(filename[1], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &ftmp1, filename[1], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < + 0) FAIL_STACK_ERROR; - if (NULL == (f2 = H5F__efc_open(ftmp1->shared->efc, filename[2], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, ftmp1->shared->efc, &f2, filename[2], + H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (f1 = H5F__efc_open(f0->shared->efc, filename[1], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &f1, filename[1], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_try_close(ftmp1, NULL) < 0) FAIL_STACK_ERROR; @@ -533,7 +533,7 @@ test_graph_nocycle(void) FAIL_STACK_ERROR; if (H5F_efc_close(f0, f1) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp2 = H5F_open(filename[2], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F_open(false, &ftmp2, filename[2], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (ftmp2->shared->nrefs != 2) TEST_ERROR; @@ -549,35 +549,35 @@ test_graph_nocycle(void) /* Test 2: 5 file chain. The parent file has 2 child files, each of which * has their own child file. Verifies that releasing the parent's EFC * closes all 4 children. */ - if (NULL == (f0 = H5F_open(filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f0, filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (f1 = H5F__efc_open(f0->shared->efc, filename[1], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &f1, filename[1], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (f2 = H5F__efc_open(f1->shared->efc, filename[2], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f1->shared->efc, &f2, filename[2], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f1, f2) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f0, f1) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp2 = H5F_open(filename[2], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F_open(false, &ftmp2, filename[2], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (ftmp2->shared->nrefs != 2) TEST_ERROR; - if (NULL == (f3 = H5F__efc_open(f0->shared->efc, filename[3], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &f3, filename[3], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (f4 = H5F__efc_open(f3->shared->efc, filename[4], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f3->shared->efc, &f4, filename[4], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f3, f4) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f0, f3) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp4 = H5F_open(filename[4], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F_open(false, &ftmp4, filename[4], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (ftmp4->shared->nrefs != 2) TEST_ERROR; @@ -600,17 +600,17 @@ test_graph_nocycle(void) * closed until both parents' EFCs are released. First release through one * parent, then reopen through that parent and release the other, then * re-release the first parent. */ - if (NULL == (f0 = H5F_open(filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f0, filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (f1 = H5F_open(filename[1], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f1, filename[1], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (f2 = H5F__efc_open(f0->shared->efc, filename[2], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &f2, filename[2], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp2 = H5F__efc_open(f1->shared->efc, filename[2], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f1->shared->efc, &ftmp2, filename[2], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (f3 = H5F__efc_open(f2->shared->efc, filename[3], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f2->shared->efc, &f3, filename[3], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f2, f3) < 0) FAIL_STACK_ERROR; @@ -618,7 +618,7 @@ test_graph_nocycle(void) FAIL_STACK_ERROR; if (H5F_efc_close(f1, ftmp2) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp3 = H5F_open(filename[3], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F_open(false, &ftmp3, filename[3], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (ftmp3->shared->nrefs != 2) TEST_ERROR; @@ -628,7 +628,7 @@ test_graph_nocycle(void) if (ftmp3->shared->nrefs != 2) TEST_ERROR; - if (NULL == (f2 = H5F__efc_open(f0->shared->efc, filename[2], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &f2, filename[2], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f0, f2) < 0) FAIL_STACK_ERROR; @@ -652,20 +652,20 @@ test_graph_nocycle(void) /* Test 4: Simple "diamond" tree. The parent file has two children, which * shared the same child. Verify that releasing the parent file closes all * files. */ - if (NULL == (f0 = H5F_open(filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f0, filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (f1 = H5F__efc_open(f0->shared->efc, filename[1], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &f1, filename[1], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (f2 = H5F__efc_open(f0->shared->efc, filename[2], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &f2, filename[2], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (f3 = H5F__efc_open(f2->shared->efc, filename[3], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f2->shared->efc, &f3, filename[3], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f2, f3) < 0) FAIL_STACK_ERROR; - if (NULL == (f3 = H5F__efc_open(f1->shared->efc, filename[3], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f1->shared->efc, &f3, filename[3], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f1, f3) < 0) FAIL_STACK_ERROR; @@ -673,7 +673,7 @@ test_graph_nocycle(void) FAIL_STACK_ERROR; if (H5F_efc_close(f0, f1) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp3 = H5F_open(filename[3], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F_open(false, &ftmp3, filename[3], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (ftmp3->shared->nrefs != 3) TEST_ERROR; @@ -691,27 +691,27 @@ test_graph_nocycle(void) /* Test 5: Dense 5 file graph. f0 caches f1, f2, f3 and f4. f1 and f2 * each cache f3 and f4. f3 caches f4. Verify that releasing f0 closes all * files. */ - if (NULL == (f0 = H5F_open(filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f0, filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (f1 = H5F__efc_open(f0->shared->efc, filename[1], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &f1, filename[1], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (f2 = H5F__efc_open(f0->shared->efc, filename[2], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &f2, filename[2], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (f3 = H5F__efc_open(f0->shared->efc, filename[3], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &f3, filename[3], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (f4 = H5F__efc_open(f0->shared->efc, filename[4], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &f4, filename[4], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f0, f4) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f0, f3) < 0) FAIL_STACK_ERROR; - if (NULL == (f3 = H5F__efc_open(f1->shared->efc, filename[3], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f1->shared->efc, &f3, filename[3], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (f4 = H5F__efc_open(f1->shared->efc, filename[4], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f1->shared->efc, &f4, filename[4], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f1, f4) < 0) FAIL_STACK_ERROR; @@ -719,21 +719,21 @@ test_graph_nocycle(void) FAIL_STACK_ERROR; if (H5F_efc_close(f0, f1) < 0) FAIL_STACK_ERROR; - if (NULL == (f3 = H5F__efc_open(f2->shared->efc, filename[3], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f2->shared->efc, &f3, filename[3], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (f4 = H5F__efc_open(f2->shared->efc, filename[4], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f2->shared->efc, &f4, filename[4], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f2, f4) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f0, f2) < 0) FAIL_STACK_ERROR; - if (NULL == (f4 = H5F__efc_open(f3->shared->efc, filename[4], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f3->shared->efc, &f4, filename[4], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f3, f4) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f2, f3) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp4 = H5F_open(filename[4], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F_open(false, &ftmp4, filename[4], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (ftmp4->shared->nrefs != 5) TEST_ERROR; @@ -742,15 +742,15 @@ test_graph_nocycle(void) FAIL_STACK_ERROR; if (ftmp4->shared->nrefs != 1) TEST_ERROR; - if (NULL == (ftmp1 = H5F_open(filename[1], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F_open(false, &ftmp1, filename[1], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (ftmp1->shared->nrefs != 1) TEST_ERROR; - if (NULL == (ftmp2 = H5F_open(filename[2], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F_open(false, &ftmp2, filename[2], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (ftmp2->shared->nrefs != 1) TEST_ERROR; - if (NULL == (ftmp3 = H5F_open(filename[3], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F_open(false, &ftmp3, filename[3], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (ftmp3->shared->nrefs != 1) TEST_ERROR; @@ -811,9 +811,9 @@ test_graph_cycle(void) /* Test 1: File caches itself. Verify that closing the file causes it to be * actually closed, and there is no other unexpected behavior. */ - if (NULL == (f0 = H5F_open(filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f0, filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp0 = H5F__efc_open(f0->shared->efc, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &ftmp0, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f0, ftmp0) < 0) FAIL_STACK_ERROR; @@ -824,7 +824,7 @@ test_graph_cycle(void) if (f0->shared->nrefs != 1) TEST_ERROR; - if (NULL == (ftmp0 = H5F__efc_open(f0->shared->efc, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &ftmp0, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f0, ftmp0) < 0) FAIL_STACK_ERROR; @@ -832,7 +832,7 @@ test_graph_cycle(void) TEST_ERROR; if (H5F_try_close(f0, NULL) < 0) FAIL_STACK_ERROR; - if (NULL == (f0 = H5F_open(filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f0, filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (f0->shared->nrefs != 1) TEST_ERROR; @@ -842,12 +842,12 @@ test_graph_cycle(void) /* Test 2: Indirectly referenced file caches itself. Same as above except * the file is part of another file's EFC. */ - if (NULL == (f0 = H5F_open(filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f0, filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (f1 = H5F__efc_open(f0->shared->efc, filename[1], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &f1, filename[1], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp1 = H5F__efc_open(f1->shared->efc, filename[1], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f1->shared->efc, &ftmp1, filename[1], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f1, ftmp1) < 0) FAIL_STACK_ERROR; @@ -857,17 +857,17 @@ test_graph_cycle(void) FAIL_STACK_ERROR; if (H5F__efc_release(f0->shared->efc) < 0) FAIL_STACK_ERROR; - if (NULL == (f1 = H5F_open(filename[1], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f1, filename[1], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (f1->shared->nrefs != 1) TEST_ERROR; if (H5F_try_close(f1, NULL) < 0) FAIL_STACK_ERROR; - if (NULL == (f1 = H5F__efc_open(f0->shared->efc, filename[1], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &f1, filename[1], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp1 = H5F__efc_open(f1->shared->efc, filename[1], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f1->shared->efc, &ftmp1, filename[1], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f1, ftmp1) < 0) FAIL_STACK_ERROR; @@ -877,7 +877,7 @@ test_graph_cycle(void) FAIL_STACK_ERROR; if (H5F_try_close(f0, NULL) < 0) FAIL_STACK_ERROR; - if (NULL == (f1 = H5F_open(filename[1], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f1, filename[1], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (f1->shared->nrefs != 1) TEST_ERROR; @@ -885,12 +885,12 @@ test_graph_cycle(void) FAIL_STACK_ERROR; /* Test 3: Simple 2 file cycle */ - if (NULL == (f0 = H5F_open(filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f0, filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (f1 = H5F__efc_open(f0->shared->efc, filename[1], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &f1, filename[1], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp0 = H5F__efc_open(f1->shared->efc, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f1->shared->efc, &ftmp0, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f1, ftmp0) < 0) FAIL_STACK_ERROR; @@ -903,10 +903,10 @@ test_graph_cycle(void) if (f0->shared->nrefs != 1) TEST_ERROR; - if (NULL == (f1 = H5F__efc_open(f0->shared->efc, filename[1], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &f1, filename[1], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp0 = H5F__efc_open(f1->shared->efc, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f1->shared->efc, &ftmp0, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f1, ftmp0) < 0) FAIL_STACK_ERROR; @@ -916,7 +916,7 @@ test_graph_cycle(void) TEST_ERROR; if (H5F_try_close(f0, NULL) < 0) FAIL_STACK_ERROR; - if (NULL == (f0 = H5F_open(filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f0, filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (f0->shared->nrefs != 1) TEST_ERROR; @@ -924,15 +924,15 @@ test_graph_cycle(void) FAIL_STACK_ERROR; /* Test 4: Simple 2 file cycle (indirectly referenced) */ - if (NULL == (f0 = H5F_open(filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f0, filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (f1 = H5F__efc_open(f0->shared->efc, filename[1], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &f1, filename[1], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (f2 = H5F__efc_open(f1->shared->efc, filename[2], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f1->shared->efc, &f2, filename[2], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp1 = H5F__efc_open(f2->shared->efc, filename[1], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f2->shared->efc, &ftmp1, filename[1], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f2, ftmp1) < 0) FAIL_STACK_ERROR; @@ -944,7 +944,7 @@ test_graph_cycle(void) FAIL_STACK_ERROR; if (H5F_try_close(f0, NULL) < 0) FAIL_STACK_ERROR; - if (NULL == (f1 = H5F_open(filename[1], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f1, filename[1], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (f1->shared->nrefs != 1) TEST_ERROR; @@ -952,21 +952,21 @@ test_graph_cycle(void) FAIL_STACK_ERROR; /* Test 5: Parallel double cycle */ - if (NULL == (f0 = H5F_open(filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f0, filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (f1 = H5F__efc_open(f0->shared->efc, filename[1], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &f1, filename[1], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp0 = H5F__efc_open(f1->shared->efc, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f1->shared->efc, &ftmp0, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f1, ftmp0) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f0, f1) < 0) FAIL_STACK_ERROR; - if (NULL == (f2 = H5F__efc_open(f0->shared->efc, filename[2], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &f2, filename[2], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp0 = H5F__efc_open(f2->shared->efc, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f2->shared->efc, &ftmp0, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f2, ftmp0) < 0) FAIL_STACK_ERROR; @@ -976,7 +976,7 @@ test_graph_cycle(void) TEST_ERROR; if (H5F_try_close(f0, NULL) < 0) FAIL_STACK_ERROR; - if (NULL == (f0 = H5F_open(filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f0, filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (f0->shared->nrefs != 1) TEST_ERROR; @@ -984,21 +984,21 @@ test_graph_cycle(void) FAIL_STACK_ERROR; /* Test 6: Parallel double cycle with release */ - if (NULL == (f0 = H5F_open(filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f0, filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (f1 = H5F__efc_open(f0->shared->efc, filename[1], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &f1, filename[1], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp0 = H5F__efc_open(f1->shared->efc, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f1->shared->efc, &ftmp0, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f1, ftmp0) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f0, f1) < 0) FAIL_STACK_ERROR; - if (NULL == (f2 = H5F__efc_open(f0->shared->efc, filename[2], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &f2, filename[2], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp0 = H5F__efc_open(f2->shared->efc, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f2->shared->efc, &ftmp0, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f2, ftmp0) < 0) FAIL_STACK_ERROR; @@ -1014,26 +1014,26 @@ test_graph_cycle(void) FAIL_STACK_ERROR; /* Test 7: Chained parallel double cycle */ - if (NULL == (f0 = H5F_open(filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f0, filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (f1 = H5F__efc_open(f0->shared->efc, filename[1], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &f1, filename[1], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp0 = H5F__efc_open(f1->shared->efc, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f1->shared->efc, &ftmp0, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (f2 = H5F__efc_open(f1->shared->efc, filename[2], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f1->shared->efc, &f2, filename[2], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp1 = H5F__efc_open(f2->shared->efc, filename[1], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f2->shared->efc, &ftmp1, filename[1], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f2, ftmp1) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f1, f2) < 0) FAIL_STACK_ERROR; - if (NULL == (f3 = H5F__efc_open(f1->shared->efc, filename[3], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f1->shared->efc, &f3, filename[3], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp1 = H5F__efc_open(f3->shared->efc, filename[1], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f3->shared->efc, &ftmp1, filename[1], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f3, ftmp1) < 0) FAIL_STACK_ERROR; @@ -1047,7 +1047,7 @@ test_graph_cycle(void) TEST_ERROR; if (H5F_try_close(f0, NULL) < 0) FAIL_STACK_ERROR; - if (NULL == (f0 = H5F_open(filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f0, filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (f0->shared->nrefs != 1) TEST_ERROR; @@ -1055,26 +1055,26 @@ test_graph_cycle(void) FAIL_STACK_ERROR; /* Test 8: Chained parallel double cycle with release */ - if (NULL == (f0 = H5F_open(filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f0, filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (f1 = H5F__efc_open(f0->shared->efc, filename[1], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &f1, filename[1], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp0 = H5F__efc_open(f1->shared->efc, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f1->shared->efc, &ftmp0, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (f2 = H5F__efc_open(f1->shared->efc, filename[2], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f1->shared->efc, &f2, filename[2], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp1 = H5F__efc_open(f2->shared->efc, filename[1], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f2->shared->efc, &ftmp1, filename[1], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f2, ftmp1) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f1, f2) < 0) FAIL_STACK_ERROR; - if (NULL == (f3 = H5F__efc_open(f1->shared->efc, filename[3], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f1->shared->efc, &f3, filename[3], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp1 = H5F__efc_open(f3->shared->efc, filename[1], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f3->shared->efc, &ftmp1, filename[1], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f3, ftmp1) < 0) FAIL_STACK_ERROR; @@ -1094,14 +1094,14 @@ test_graph_cycle(void) FAIL_STACK_ERROR; /* Test 9: Simple 2 file cycle, extra ID on root */ - if (NULL == (f0 = H5F_open(filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f0, filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp0 = H5F_open(filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F_open(false, &ftmp0, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (f1 = H5F__efc_open(f0->shared->efc, filename[1], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &f1, filename[1], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp1 = H5F__efc_open(f1->shared->efc, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f1->shared->efc, &ftmp1, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f1, ftmp1) < 0) FAIL_STACK_ERROR; @@ -1117,7 +1117,7 @@ test_graph_cycle(void) TEST_ERROR; if (H5F_try_close(f0, NULL) < 0) FAIL_STACK_ERROR; - if (NULL == (f0 = H5F_open(filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f0, filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (f0->shared->nrefs != 1) TEST_ERROR; @@ -1125,14 +1125,14 @@ test_graph_cycle(void) FAIL_STACK_ERROR; /* Test 10: Simple 2 file cycle, extra ID on second file */ - if (NULL == (f0 = H5F_open(filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f0, filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (f1 = H5F__efc_open(f0->shared->efc, filename[1], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &f1, filename[1], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp1 = H5F_open(filename[1], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F_open(false, &ftmp1, filename[1], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp0 = H5F__efc_open(f1->shared->efc, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f1->shared->efc, &ftmp0, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f1, ftmp0) < 0) FAIL_STACK_ERROR; @@ -1147,7 +1147,7 @@ test_graph_cycle(void) FAIL_STACK_ERROR; if (ftmp1->shared->nrefs != 2) TEST_ERROR; - if (NULL == (f0 = H5F_open(filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F_open(false, &f0, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (f0->shared->nrefs != 2) TEST_ERROR; @@ -1156,13 +1156,13 @@ test_graph_cycle(void) FAIL_STACK_ERROR; if (H5F_try_close(ftmp1, NULL) < 0) FAIL_STACK_ERROR; - if (NULL == (f0 = H5F_open(filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f0, filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (f0->shared->nrefs != 1) TEST_ERROR; if (H5F_try_close(f0, NULL) < 0) FAIL_STACK_ERROR; - if (NULL == (f1 = H5F_open(filename[1], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f1, filename[1], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (f1->shared->nrefs != 1) TEST_ERROR; @@ -1170,23 +1170,23 @@ test_graph_cycle(void) FAIL_STACK_ERROR; /* Test 11: Parallel double cycle, extra ID on a child file */ - if (NULL == (f0 = H5F_open(filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f0, filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (f1 = H5F__efc_open(f0->shared->efc, filename[1], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &f1, filename[1], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp0 = H5F__efc_open(f1->shared->efc, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f1->shared->efc, &ftmp0, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f1, ftmp0) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f0, f1) < 0) FAIL_STACK_ERROR; - if (NULL == (f2 = H5F__efc_open(f0->shared->efc, filename[2], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &f2, filename[2], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp2 = H5F_open(filename[2], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F_open(false, &ftmp2, filename[2], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp0 = H5F__efc_open(f2->shared->efc, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f2->shared->efc, &ftmp0, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f2, ftmp0) < 0) FAIL_STACK_ERROR; @@ -1201,7 +1201,7 @@ test_graph_cycle(void) FAIL_STACK_ERROR; if (ftmp2->shared->nrefs != 2) TEST_ERROR; - if (NULL == (f0 = H5F_open(filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F_open(false, &f0, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (f0->shared->nrefs != 3) TEST_ERROR; @@ -1210,19 +1210,19 @@ test_graph_cycle(void) FAIL_STACK_ERROR; if (H5F_try_close(ftmp2, NULL) < 0) FAIL_STACK_ERROR; - if (NULL == (f0 = H5F_open(filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f0, filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (f0->shared->nrefs != 1) TEST_ERROR; if (H5F_try_close(f0, NULL) < 0) FAIL_STACK_ERROR; - if (NULL == (f1 = H5F_open(filename[1], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f1, filename[1], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (f1->shared->nrefs != 1) TEST_ERROR; if (H5F_try_close(f1, NULL) < 0) FAIL_STACK_ERROR; - if (NULL == (f2 = H5F_open(filename[2], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f2, filename[2], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (f2->shared->nrefs != 1) TEST_ERROR; @@ -1230,23 +1230,23 @@ test_graph_cycle(void) FAIL_STACK_ERROR; /* Test 12: Parallel double cycle, extra ID on a child file, with release */ - if (NULL == (f0 = H5F_open(filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f0, filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (f1 = H5F__efc_open(f0->shared->efc, filename[1], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &f1, filename[1], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp0 = H5F__efc_open(f1->shared->efc, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f1->shared->efc, &ftmp0, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f1, ftmp0) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f0, f1) < 0) FAIL_STACK_ERROR; - if (NULL == (f2 = H5F__efc_open(f0->shared->efc, filename[2], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &f2, filename[2], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp2 = H5F_open(filename[2], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F_open(false, &ftmp2, filename[2], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp0 = H5F__efc_open(f2->shared->efc, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f2->shared->efc, &ftmp0, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f2, ftmp0) < 0) FAIL_STACK_ERROR; @@ -1276,28 +1276,28 @@ test_graph_cycle(void) FAIL_STACK_ERROR; /* Test 13: Chained parallel double cycle, extra ID on a child file */ - if (NULL == (f0 = H5F_open(filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f0, filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (f1 = H5F__efc_open(f0->shared->efc, filename[1], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &f1, filename[1], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp0 = H5F__efc_open(f1->shared->efc, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f1->shared->efc, &ftmp0, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (f2 = H5F__efc_open(f1->shared->efc, filename[2], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f1->shared->efc, &f2, filename[2], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp1 = H5F__efc_open(f2->shared->efc, filename[1], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f2->shared->efc, &ftmp1, filename[1], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f2, ftmp1) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f1, f2) < 0) FAIL_STACK_ERROR; - if (NULL == (f3 = H5F__efc_open(f1->shared->efc, filename[3], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f1->shared->efc, &f3, filename[3], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp3 = H5F_open(filename[3], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F_open(false, &ftmp3, filename[3], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp1 = H5F__efc_open(f3->shared->efc, filename[1], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f3->shared->efc, &ftmp1, filename[1], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f3, ftmp1) < 0) FAIL_STACK_ERROR; @@ -1316,7 +1316,7 @@ test_graph_cycle(void) FAIL_STACK_ERROR; if (ftmp3->shared->nrefs != 2) TEST_ERROR; - if (NULL == (f0 = H5F_open(filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F_open(false, &f0, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (f0->shared->nrefs != 2) TEST_ERROR; @@ -1325,25 +1325,25 @@ test_graph_cycle(void) FAIL_STACK_ERROR; if (H5F_try_close(ftmp3, NULL) < 0) FAIL_STACK_ERROR; - if (NULL == (f0 = H5F_open(filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f0, filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (f0->shared->nrefs != 1) TEST_ERROR; if (H5F_try_close(f0, NULL) < 0) FAIL_STACK_ERROR; - if (NULL == (f1 = H5F_open(filename[1], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f1, filename[1], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (f1->shared->nrefs != 1) TEST_ERROR; if (H5F_try_close(f1, NULL) < 0) FAIL_STACK_ERROR; - if (NULL == (f2 = H5F_open(filename[2], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f2, filename[2], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (f2->shared->nrefs != 1) TEST_ERROR; if (H5F_try_close(f2, NULL) < 0) FAIL_STACK_ERROR; - if (NULL == (f3 = H5F_open(filename[3], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f3, filename[3], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (f3->shared->nrefs != 1) TEST_ERROR; @@ -1352,28 +1352,28 @@ test_graph_cycle(void) /* Test 14: Chained parallel double cycle, extra ID on a child file, with * release */ - if (NULL == (f0 = H5F_open(filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f0, filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (f1 = H5F__efc_open(f0->shared->efc, filename[1], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &f1, filename[1], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp0 = H5F__efc_open(f1->shared->efc, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f1->shared->efc, &ftmp0, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (f2 = H5F__efc_open(f1->shared->efc, filename[2], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f1->shared->efc, &f2, filename[2], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp1 = H5F__efc_open(f2->shared->efc, filename[1], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f2->shared->efc, &ftmp1, filename[1], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f2, ftmp1) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f1, f2) < 0) FAIL_STACK_ERROR; - if (NULL == (f3 = H5F__efc_open(f1->shared->efc, filename[3], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f1->shared->efc, &f3, filename[3], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp3 = H5F_open(filename[3], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F_open(false, &ftmp3, filename[3], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp1 = H5F__efc_open(f3->shared->efc, filename[1], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f3->shared->efc, &ftmp1, filename[1], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f3, ftmp1) < 0) FAIL_STACK_ERROR; @@ -1407,24 +1407,24 @@ test_graph_cycle(void) FAIL_STACK_ERROR; /* Test 15: One local and one remote cycle */ - if (NULL == (f0 = H5F_open(filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f0, filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (f1 = H5F__efc_open(f0->shared->efc, filename[1], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &f1, filename[1], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp0 = H5F__efc_open(f1->shared->efc, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f1->shared->efc, &ftmp0, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f1, ftmp0) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f0, f1) < 0) FAIL_STACK_ERROR; - if (NULL == (f2 = H5F__efc_open(f0->shared->efc, filename[2], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &f2, filename[2], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (f3 = H5F__efc_open(f2->shared->efc, filename[3], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f2->shared->efc, &f3, filename[3], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp2 = H5F__efc_open(f3->shared->efc, filename[2], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f3->shared->efc, &ftmp2, filename[2], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f3, ftmp2) < 0) FAIL_STACK_ERROR; @@ -1437,25 +1437,25 @@ test_graph_cycle(void) if (H5F_try_close(f0, NULL) < 0) FAIL_STACK_ERROR; - if (NULL == (f0 = H5F_open(filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f0, filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (f0->shared->nrefs != 1) TEST_ERROR; if (H5F_try_close(f0, NULL) < 0) FAIL_STACK_ERROR; - if (NULL == (f1 = H5F_open(filename[1], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f1, filename[1], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (f1->shared->nrefs != 1) TEST_ERROR; if (H5F_try_close(f1, NULL) < 0) FAIL_STACK_ERROR; - if (NULL == (f2 = H5F_open(filename[2], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f2, filename[2], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (f2->shared->nrefs != 1) TEST_ERROR; if (H5F_try_close(f2, NULL) < 0) FAIL_STACK_ERROR; - if (NULL == (f3 = H5F_open(filename[3], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f3, filename[3], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (f3->shared->nrefs != 1) TEST_ERROR; @@ -1463,24 +1463,24 @@ test_graph_cycle(void) FAIL_STACK_ERROR; /* Test 16: One local and one remote cycle, with release */ - if (NULL == (f0 = H5F_open(filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f0, filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (f1 = H5F__efc_open(f0->shared->efc, filename[1], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &f1, filename[1], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp0 = H5F__efc_open(f1->shared->efc, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f1->shared->efc, &ftmp0, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f1, ftmp0) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f0, f1) < 0) FAIL_STACK_ERROR; - if (NULL == (f2 = H5F__efc_open(f0->shared->efc, filename[2], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &f2, filename[2], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (f3 = H5F__efc_open(f2->shared->efc, filename[3], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f2->shared->efc, &f3, filename[3], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp2 = H5F__efc_open(f3->shared->efc, filename[2], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f3->shared->efc, &ftmp2, filename[2], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f3, ftmp2) < 0) FAIL_STACK_ERROR; @@ -1497,19 +1497,19 @@ test_graph_cycle(void) TEST_ERROR; if (H5F_try_close(f0, NULL) < 0) FAIL_STACK_ERROR; - if (NULL == (f1 = H5F_open(filename[1], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f1, filename[1], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (f1->shared->nrefs != 1) TEST_ERROR; if (H5F_try_close(f1, NULL) < 0) FAIL_STACK_ERROR; - if (NULL == (f2 = H5F_open(filename[2], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f2, filename[2], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (f2->shared->nrefs != 1) TEST_ERROR; if (H5F_try_close(f2, NULL) < 0) FAIL_STACK_ERROR; - if (NULL == (f3 = H5F_open(filename[3], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f3, filename[3], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (f3->shared->nrefs != 1) TEST_ERROR; @@ -1517,26 +1517,26 @@ test_graph_cycle(void) FAIL_STACK_ERROR; /* Test 17: One local and one remote cycle, remote cycle held open */ - if (NULL == (f0 = H5F_open(filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f0, filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (f1 = H5F__efc_open(f0->shared->efc, filename[1], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &f1, filename[1], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp0 = H5F__efc_open(f1->shared->efc, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f1->shared->efc, &ftmp0, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f1, ftmp0) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f0, f1) < 0) FAIL_STACK_ERROR; - if (NULL == (f2 = H5F__efc_open(f0->shared->efc, filename[2], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &f2, filename[2], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (f3 = H5F__efc_open(f2->shared->efc, filename[3], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f2->shared->efc, &f3, filename[3], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp3 = H5F_open(filename[3], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F_open(false, &ftmp3, filename[3], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp2 = H5F__efc_open(f3->shared->efc, filename[2], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f3->shared->efc, &ftmp2, filename[2], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f3, ftmp2) < 0) FAIL_STACK_ERROR; @@ -1549,7 +1549,7 @@ test_graph_cycle(void) if (H5F_try_close(f0, NULL) < 0) FAIL_STACK_ERROR; - if (NULL == (f0 = H5F_open(filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f0, filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (f0->shared->nrefs != 1) TEST_ERROR; @@ -1560,19 +1560,19 @@ test_graph_cycle(void) if (H5F_try_close(ftmp3, NULL) < 0) FAIL_STACK_ERROR; - if (NULL == (f1 = H5F_open(filename[1], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f1, filename[1], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (f1->shared->nrefs != 1) TEST_ERROR; if (H5F_try_close(f1, NULL) < 0) FAIL_STACK_ERROR; - if (NULL == (f2 = H5F_open(filename[2], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f2, filename[2], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (f2->shared->nrefs != 1) TEST_ERROR; if (H5F_try_close(f2, NULL) < 0) FAIL_STACK_ERROR; - if (NULL == (f3 = H5F_open(filename[3], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f3, filename[3], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (f3->shared->nrefs != 1) TEST_ERROR; @@ -1581,26 +1581,26 @@ test_graph_cycle(void) /* Test 18: One local and one remote cycle, remote cycle held open, with * release */ - if (NULL == (f0 = H5F_open(filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f0, filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (f1 = H5F__efc_open(f0->shared->efc, filename[1], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &f1, filename[1], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp0 = H5F__efc_open(f1->shared->efc, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f1->shared->efc, &ftmp0, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f1, ftmp0) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f0, f1) < 0) FAIL_STACK_ERROR; - if (NULL == (f2 = H5F__efc_open(f0->shared->efc, filename[2], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &f2, filename[2], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (f3 = H5F__efc_open(f2->shared->efc, filename[3], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f2->shared->efc, &f3, filename[3], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp3 = H5F_open(filename[3], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F_open(false, &ftmp3, filename[3], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp2 = H5F__efc_open(f3->shared->efc, filename[2], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f3->shared->efc, &ftmp2, filename[2], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f3, ftmp2) < 0) FAIL_STACK_ERROR; @@ -1617,13 +1617,13 @@ test_graph_cycle(void) TEST_ERROR; if (ftmp3->shared->nrefs != 2) TEST_ERROR; - if (NULL == (f1 = H5F_open(filename[1], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f1, filename[1], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (f1->shared->nrefs != 1) TEST_ERROR; if (H5F_try_close(f1, NULL) < 0) FAIL_STACK_ERROR; - if (NULL == (f2 = H5F_open(filename[2], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F_open(false, &f2, filename[2], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (f2->shared->nrefs != 2) TEST_ERROR; @@ -1634,7 +1634,7 @@ test_graph_cycle(void) FAIL_STACK_ERROR; if (ftmp3->shared->nrefs != 1) TEST_ERROR; - if (NULL == (f2 = H5F_open(filename[2], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F_open(false, &f2, filename[2], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (f2->shared->nrefs != 1) TEST_ERROR; @@ -1648,44 +1648,44 @@ test_graph_cycle(void) /* Test 19: "Diamond" shape with links moving from bottom (root) to top. * Also cycle between bottom (root) and top and cycles on the sides. */ - if (NULL == (f0 = H5F_open(filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f0, filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (f1 = H5F__efc_open(f0->shared->efc, filename[1], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &f1, filename[1], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (f2 = H5F__efc_open(f0->shared->efc, filename[2], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &f2, filename[2], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (f3 = H5F__efc_open(f1->shared->efc, filename[3], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f1->shared->efc, &f3, filename[3], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f1, f3) < 0) FAIL_STACK_ERROR; - if (NULL == (f3 = H5F__efc_open(f2->shared->efc, filename[3], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f2->shared->efc, &f3, filename[3], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f2, f3) < 0) FAIL_STACK_ERROR; - if (NULL == (f3 = H5F__efc_open(f0->shared->efc, filename[3], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &f3, filename[3], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp0 = H5F__efc_open(f3->shared->efc, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f3->shared->efc, &ftmp0, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f3, ftmp0) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f0, f3) < 0) FAIL_STACK_ERROR; - if (NULL == (f4 = H5F__efc_open(f1->shared->efc, filename[4], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f1->shared->efc, &f4, filename[4], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp1 = H5F__efc_open(f4->shared->efc, filename[1], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f4->shared->efc, &ftmp1, filename[1], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f4, ftmp1) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f1, f4) < 0) FAIL_STACK_ERROR; - if (NULL == (f5 = H5F__efc_open(f2->shared->efc, filename[5], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f2->shared->efc, &f5, filename[5], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp2 = H5F__efc_open(f5->shared->efc, filename[2], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f5->shared->efc, &ftmp2, filename[2], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f5, ftmp2) < 0) FAIL_STACK_ERROR; @@ -1700,37 +1700,37 @@ test_graph_cycle(void) if (H5F_try_close(f0, NULL) < 0) FAIL_STACK_ERROR; - if (NULL == (f0 = H5F_open(filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f0, filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (f0->shared->nrefs != 1) TEST_ERROR; if (H5F_try_close(f0, NULL) < 0) FAIL_STACK_ERROR; - if (NULL == (f1 = H5F_open(filename[1], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f1, filename[1], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (f1->shared->nrefs != 1) TEST_ERROR; if (H5F_try_close(f1, NULL) < 0) FAIL_STACK_ERROR; - if (NULL == (f2 = H5F_open(filename[2], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f2, filename[2], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (f2->shared->nrefs != 1) TEST_ERROR; if (H5F_try_close(f2, NULL) < 0) FAIL_STACK_ERROR; - if (NULL == (f3 = H5F_open(filename[3], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f3, filename[3], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (f3->shared->nrefs != 1) TEST_ERROR; if (H5F_try_close(f3, NULL) < 0) FAIL_STACK_ERROR; - if (NULL == (f4 = H5F_open(filename[4], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f4, filename[4], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (f4->shared->nrefs != 1) TEST_ERROR; if (H5F_try_close(f4, NULL) < 0) FAIL_STACK_ERROR; - if (NULL == (f5 = H5F_open(filename[5], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f5, filename[5], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (f5->shared->nrefs != 1) TEST_ERROR; @@ -1740,44 +1740,44 @@ test_graph_cycle(void) /* Test 20: "Diamond" shape with links moving from bottom (root) to top. * Also cycle between bottom (root) and top, cycles on the sides, and * release the files instead of closing. */ - if (NULL == (f0 = H5F_open(filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f0, filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (f1 = H5F__efc_open(f0->shared->efc, filename[1], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &f1, filename[1], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (f2 = H5F__efc_open(f0->shared->efc, filename[2], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &f2, filename[2], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (f3 = H5F__efc_open(f1->shared->efc, filename[3], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f1->shared->efc, &f3, filename[3], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f1, f3) < 0) FAIL_STACK_ERROR; - if (NULL == (f3 = H5F__efc_open(f2->shared->efc, filename[3], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f2->shared->efc, &f3, filename[3], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f2, f3) < 0) FAIL_STACK_ERROR; - if (NULL == (f3 = H5F__efc_open(f0->shared->efc, filename[3], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &f3, filename[3], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp0 = H5F__efc_open(f3->shared->efc, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f3->shared->efc, &ftmp0, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f3, ftmp0) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f0, f3) < 0) FAIL_STACK_ERROR; - if (NULL == (f4 = H5F__efc_open(f1->shared->efc, filename[4], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f1->shared->efc, &f4, filename[4], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp1 = H5F__efc_open(f4->shared->efc, filename[1], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f4->shared->efc, &ftmp1, filename[1], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f4, ftmp1) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f1, f4) < 0) FAIL_STACK_ERROR; - if (NULL == (f5 = H5F__efc_open(f2->shared->efc, filename[5], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f2->shared->efc, &f5, filename[5], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp2 = H5F__efc_open(f5->shared->efc, filename[2], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f5->shared->efc, &ftmp2, filename[2], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f5, ftmp2) < 0) FAIL_STACK_ERROR; @@ -1796,31 +1796,31 @@ test_graph_cycle(void) TEST_ERROR; if (H5F_try_close(f0, NULL) < 0) FAIL_STACK_ERROR; - if (NULL == (f1 = H5F_open(filename[1], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f1, filename[1], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (f1->shared->nrefs != 1) TEST_ERROR; if (H5F_try_close(f1, NULL) < 0) FAIL_STACK_ERROR; - if (NULL == (f2 = H5F_open(filename[2], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f2, filename[2], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (f2->shared->nrefs != 1) TEST_ERROR; if (H5F_try_close(f2, NULL) < 0) FAIL_STACK_ERROR; - if (NULL == (f3 = H5F_open(filename[3], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f3, filename[3], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (f3->shared->nrefs != 1) TEST_ERROR; if (H5F_try_close(f3, NULL) < 0) FAIL_STACK_ERROR; - if (NULL == (f4 = H5F_open(filename[4], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f4, filename[4], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (f4->shared->nrefs != 1) TEST_ERROR; if (H5F_try_close(f4, NULL) < 0) FAIL_STACK_ERROR; - if (NULL == (f5 = H5F_open(filename[5], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f5, filename[5], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (f5->shared->nrefs != 1) TEST_ERROR; @@ -1829,52 +1829,52 @@ test_graph_cycle(void) /* Test 21: "Diamond" shape with links moving from bottom (root) to top. * Also cycle between bottom (root) and top, cycles on sides held open. */ - if (NULL == (f0 = H5F_open(filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f0, filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (f1 = H5F__efc_open(f0->shared->efc, filename[1], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &f1, filename[1], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (f2 = H5F__efc_open(f0->shared->efc, filename[2], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &f2, filename[2], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (f3 = H5F__efc_open(f1->shared->efc, filename[3], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f1->shared->efc, &f3, filename[3], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f1, f3) < 0) FAIL_STACK_ERROR; - if (NULL == (f3 = H5F__efc_open(f2->shared->efc, filename[3], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f2->shared->efc, &f3, filename[3], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f2, f3) < 0) FAIL_STACK_ERROR; - if (NULL == (f3 = H5F__efc_open(f0->shared->efc, filename[3], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &f3, filename[3], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp0 = H5F__efc_open(f3->shared->efc, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f3->shared->efc, &ftmp0, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f3, ftmp0) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f0, f3) < 0) FAIL_STACK_ERROR; - if (NULL == (f4 = H5F__efc_open(f1->shared->efc, filename[4], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f1->shared->efc, &f4, filename[4], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp1 = H5F__efc_open(f4->shared->efc, filename[1], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f4->shared->efc, &ftmp1, filename[1], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f4, ftmp1) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f1, f4) < 0) FAIL_STACK_ERROR; - if (NULL == (f4 = H5F_open(filename[4], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F_open(false, &f4, filename[4], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (f5 = H5F__efc_open(f2->shared->efc, filename[5], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f2->shared->efc, &f5, filename[5], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp2 = H5F__efc_open(f5->shared->efc, filename[2], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f5->shared->efc, &ftmp2, filename[2], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f5, ftmp2) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f2, f5) < 0) FAIL_STACK_ERROR; - if (NULL == (f5 = H5F_open(filename[5], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F_open(false, &f5, filename[5], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f0, f1) < 0) FAIL_STACK_ERROR; @@ -1893,7 +1893,7 @@ test_graph_cycle(void) TEST_ERROR; if (f5->shared->nrefs != 2) TEST_ERROR; - if (NULL == (f0 = H5F_open(filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F_open(false, &f0, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (f0->shared->nrefs != 2) TEST_ERROR; @@ -1909,7 +1909,7 @@ test_graph_cycle(void) FAIL_STACK_ERROR; if (f5->shared->nrefs != 2) TEST_ERROR; - if (NULL == (f0 = H5F_open(filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F_open(false, &f0, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (f0->shared->nrefs != 2) TEST_ERROR; @@ -1919,37 +1919,37 @@ test_graph_cycle(void) if (H5F_try_close(f5, NULL) < 0) FAIL_STACK_ERROR; - if (NULL == (f0 = H5F_open(filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f0, filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (f0->shared->nrefs != 1) TEST_ERROR; if (H5F_try_close(f0, NULL) < 0) FAIL_STACK_ERROR; - if (NULL == (f1 = H5F_open(filename[1], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f1, filename[1], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (f1->shared->nrefs != 1) TEST_ERROR; if (H5F_try_close(f1, NULL) < 0) FAIL_STACK_ERROR; - if (NULL == (f2 = H5F_open(filename[2], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f2, filename[2], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (f2->shared->nrefs != 1) TEST_ERROR; if (H5F_try_close(f2, NULL) < 0) FAIL_STACK_ERROR; - if (NULL == (f3 = H5F_open(filename[3], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f3, filename[3], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (f3->shared->nrefs != 1) TEST_ERROR; if (H5F_try_close(f3, NULL) < 0) FAIL_STACK_ERROR; - if (NULL == (f4 = H5F_open(filename[4], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f4, filename[4], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (f4->shared->nrefs != 1) TEST_ERROR; if (H5F_try_close(f4, NULL) < 0) FAIL_STACK_ERROR; - if (NULL == (f5 = H5F_open(filename[5], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f5, filename[5], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (f5->shared->nrefs != 1) TEST_ERROR; @@ -1959,52 +1959,52 @@ test_graph_cycle(void) /* Test 22: "Diamond" shape with links moving from bottom (root) to top. * Also cycle between bottom (root) and top, cycles on sides held open. * Also release the files instead of closing. */ - if (NULL == (f0 = H5F_open(filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f0, filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (f1 = H5F__efc_open(f0->shared->efc, filename[1], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &f1, filename[1], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (f2 = H5F__efc_open(f0->shared->efc, filename[2], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &f2, filename[2], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (f3 = H5F__efc_open(f1->shared->efc, filename[3], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f1->shared->efc, &f3, filename[3], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f1, f3) < 0) FAIL_STACK_ERROR; - if (NULL == (f3 = H5F__efc_open(f2->shared->efc, filename[3], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f2->shared->efc, &f3, filename[3], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f2, f3) < 0) FAIL_STACK_ERROR; - if (NULL == (f3 = H5F__efc_open(f0->shared->efc, filename[3], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &f3, filename[3], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp0 = H5F__efc_open(f3->shared->efc, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f3->shared->efc, &ftmp0, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f3, ftmp0) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f0, f3) < 0) FAIL_STACK_ERROR; - if (NULL == (f4 = H5F__efc_open(f1->shared->efc, filename[4], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f1->shared->efc, &f4, filename[4], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp1 = H5F__efc_open(f4->shared->efc, filename[1], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f4->shared->efc, &ftmp1, filename[1], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f4, ftmp1) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f1, f4) < 0) FAIL_STACK_ERROR; - if (NULL == (f4 = H5F_open(filename[4], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F_open(false, &f4, filename[4], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (f5 = H5F__efc_open(f2->shared->efc, filename[5], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f2->shared->efc, &f5, filename[5], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp2 = H5F__efc_open(f5->shared->efc, filename[2], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f5->shared->efc, &ftmp2, filename[2], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f5, ftmp2) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f2, f5) < 0) FAIL_STACK_ERROR; - if (NULL == (f5 = H5F_open(filename[5], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F_open(false, &f5, filename[5], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f0, f1) < 0) FAIL_STACK_ERROR; @@ -2025,7 +2025,7 @@ test_graph_cycle(void) TEST_ERROR; if (f5->shared->nrefs != 2) TEST_ERROR; - if (NULL == (f3 = H5F_open(filename[3], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F_open(false, &f3, filename[3], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (f3->shared->nrefs != 3) TEST_ERROR; @@ -2040,7 +2040,7 @@ test_graph_cycle(void) TEST_ERROR; if (f5->shared->nrefs != 2) TEST_ERROR; - if (NULL == (f3 = H5F_open(filename[3], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F_open(false, &f3, filename[3], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (f3->shared->nrefs != 2) TEST_ERROR; @@ -2055,7 +2055,7 @@ test_graph_cycle(void) TEST_ERROR; if (f5->shared->nrefs != 1) TEST_ERROR; - if (NULL == (f3 = H5F_open(filename[3], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F_open(false, &f3, filename[3], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (f3->shared->nrefs != 1) TEST_ERROR; @@ -2071,69 +2071,69 @@ test_graph_cycle(void) /* Test 23: Dense "ball" of files. 4 files each cache all files (including * itself). */ - if (NULL == (f0 = H5F_open(filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f0, filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp0 = H5F__efc_open(f0->shared->efc, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &ftmp0, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f0, ftmp0) < 0) FAIL_STACK_ERROR; - if (NULL == (f1 = H5F__efc_open(f0->shared->efc, filename[1], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &f1, filename[1], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (f2 = H5F__efc_open(f0->shared->efc, filename[2], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &f2, filename[2], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (f3 = H5F__efc_open(f0->shared->efc, filename[3], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &f3, filename[3], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp0 = H5F__efc_open(f1->shared->efc, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f1->shared->efc, &ftmp0, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f1, ftmp0) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp1 = H5F__efc_open(f1->shared->efc, filename[1], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f1->shared->efc, &ftmp1, filename[1], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f1, ftmp1) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp2 = H5F__efc_open(f1->shared->efc, filename[2], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f1->shared->efc, &ftmp2, filename[2], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f1, ftmp2) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp3 = H5F__efc_open(f1->shared->efc, filename[3], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f1->shared->efc, &ftmp3, filename[3], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f1, ftmp3) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp0 = H5F__efc_open(f2->shared->efc, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f2->shared->efc, &ftmp0, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f2, ftmp0) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp1 = H5F__efc_open(f2->shared->efc, filename[1], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f2->shared->efc, &ftmp1, filename[1], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f2, ftmp1) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp2 = H5F__efc_open(f2->shared->efc, filename[2], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f2->shared->efc, &ftmp2, filename[2], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f2, ftmp2) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp3 = H5F__efc_open(f2->shared->efc, filename[3], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f2->shared->efc, &ftmp3, filename[3], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f2, ftmp3) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp0 = H5F__efc_open(f3->shared->efc, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f3->shared->efc, &ftmp0, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f3, ftmp0) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp1 = H5F__efc_open(f3->shared->efc, filename[1], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f3->shared->efc, &ftmp1, filename[1], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f3, ftmp1) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp2 = H5F__efc_open(f3->shared->efc, filename[2], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f3->shared->efc, &ftmp2, filename[2], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f3, ftmp2) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp3 = H5F__efc_open(f3->shared->efc, filename[3], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f3->shared->efc, &ftmp3, filename[3], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f3, ftmp3) < 0) FAIL_STACK_ERROR; @@ -2147,25 +2147,25 @@ test_graph_cycle(void) if (H5F_try_close(f0, NULL) < 0) FAIL_STACK_ERROR; - if (NULL == (f0 = H5F_open(filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f0, filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (f0->shared->nrefs != 1) TEST_ERROR; if (H5F_try_close(f0, NULL) < 0) FAIL_STACK_ERROR; - if (NULL == (f1 = H5F_open(filename[1], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f1, filename[1], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (f1->shared->nrefs != 1) TEST_ERROR; if (H5F_try_close(f1, NULL) < 0) FAIL_STACK_ERROR; - if (NULL == (f2 = H5F_open(filename[2], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f2, filename[2], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (f2->shared->nrefs != 1) TEST_ERROR; if (H5F_try_close(f2, NULL) < 0) FAIL_STACK_ERROR; - if (NULL == (f3 = H5F_open(filename[3], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f3, filename[3], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (f3->shared->nrefs != 1) TEST_ERROR; @@ -2174,69 +2174,69 @@ test_graph_cycle(void) /* Test 24: Dense "ball" of files. 4 files each cache all files (including * itself). Release the files instead of closing. */ - if (NULL == (f0 = H5F_open(filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f0, filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp0 = H5F__efc_open(f0->shared->efc, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &ftmp0, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f0, ftmp0) < 0) FAIL_STACK_ERROR; - if (NULL == (f1 = H5F__efc_open(f0->shared->efc, filename[1], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &f1, filename[1], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (f2 = H5F__efc_open(f0->shared->efc, filename[2], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &f2, filename[2], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (f3 = H5F__efc_open(f0->shared->efc, filename[3], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &f3, filename[3], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp0 = H5F__efc_open(f1->shared->efc, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f1->shared->efc, &ftmp0, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f1, ftmp0) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp1 = H5F__efc_open(f1->shared->efc, filename[1], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f1->shared->efc, &ftmp1, filename[1], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f1, ftmp1) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp2 = H5F__efc_open(f1->shared->efc, filename[2], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f1->shared->efc, &ftmp2, filename[2], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f1, ftmp2) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp3 = H5F__efc_open(f1->shared->efc, filename[3], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f1->shared->efc, &ftmp3, filename[3], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f1, ftmp3) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp0 = H5F__efc_open(f2->shared->efc, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f2->shared->efc, &ftmp0, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f2, ftmp0) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp1 = H5F__efc_open(f2->shared->efc, filename[1], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f2->shared->efc, &ftmp1, filename[1], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f2, ftmp1) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp2 = H5F__efc_open(f2->shared->efc, filename[2], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f2->shared->efc, &ftmp2, filename[2], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f2, ftmp2) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp3 = H5F__efc_open(f2->shared->efc, filename[3], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f2->shared->efc, &ftmp3, filename[3], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f2, ftmp3) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp0 = H5F__efc_open(f3->shared->efc, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f3->shared->efc, &ftmp0, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f3, ftmp0) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp1 = H5F__efc_open(f3->shared->efc, filename[1], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f3->shared->efc, &ftmp1, filename[1], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f3, ftmp1) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp2 = H5F__efc_open(f3->shared->efc, filename[2], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f3->shared->efc, &ftmp2, filename[2], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f3, ftmp2) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp3 = H5F__efc_open(f3->shared->efc, filename[3], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f3->shared->efc, &ftmp3, filename[3], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f3, ftmp3) < 0) FAIL_STACK_ERROR; @@ -2254,19 +2254,19 @@ test_graph_cycle(void) TEST_ERROR; if (H5F_try_close(f0, NULL) < 0) FAIL_STACK_ERROR; - if (NULL == (f1 = H5F_open(filename[1], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f1, filename[1], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (f1->shared->nrefs != 1) TEST_ERROR; if (H5F_try_close(f1, NULL) < 0) FAIL_STACK_ERROR; - if (NULL == (f2 = H5F_open(filename[2], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f2, filename[2], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (f2->shared->nrefs != 1) TEST_ERROR; if (H5F_try_close(f2, NULL) < 0) FAIL_STACK_ERROR; - if (NULL == (f3 = H5F_open(filename[3], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f3, filename[3], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (f3->shared->nrefs != 1) TEST_ERROR; @@ -2274,12 +2274,12 @@ test_graph_cycle(void) FAIL_STACK_ERROR; /* Test 25: File held open by EFC client interrupts cycle, with release */ - if (NULL == (f0 = H5F_open(filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f0, filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (f1 = H5F__efc_open(f0->shared->efc, filename[1], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &f1, filename[1], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp0 = H5F__efc_open(f1->shared->efc, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f1->shared->efc, &ftmp0, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f1, ftmp0) < 0) FAIL_STACK_ERROR; @@ -2307,19 +2307,19 @@ test_graph_cycle(void) FAIL_STACK_ERROR; /* Test 26: File held open by EFC does not interrupt cycle, with release */ - if (NULL == (f0 = H5F_open(filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f0, filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (f1 = H5F__efc_open(f0->shared->efc, filename[1], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &f1, filename[1], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp0 = H5F__efc_open(f1->shared->efc, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f1->shared->efc, &ftmp0, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f1, ftmp0) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f0, f1) < 0) FAIL_STACK_ERROR; - if (NULL == (f2 = H5F__efc_open(f0->shared->efc, filename[2], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &f2, filename[2], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (f0->shared->nrefs != 2) TEST_ERROR; @@ -2341,23 +2341,23 @@ test_graph_cycle(void) /* Test 27: File held open by EFC client through non-parent file does not * interrupt cycle, but parent file does (no valid way around it) */ - if (NULL == (f0 = H5F_open(filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f0, filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (f1 = H5F__efc_open(f0->shared->efc, filename[1], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &f1, filename[1], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp0 = H5F__efc_open(f1->shared->efc, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f1->shared->efc, &ftmp0, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f1, ftmp0) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f0, f1) < 0) FAIL_STACK_ERROR; - if (NULL == (f2 = H5F_open(filename[2], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f2, filename[2], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (f1 = H5F__efc_open(f2->shared->efc, filename[1], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f2->shared->efc, &f1, filename[1], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (f3 = H5F__efc_open(f1->shared->efc, filename[3], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f1->shared->efc, &f3, filename[3], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (f0->shared->nrefs != 2) TEST_ERROR; @@ -2376,7 +2376,7 @@ test_graph_cycle(void) TEST_ERROR; if (f3->shared->nrefs != 1) TEST_ERROR; - if (NULL == (f0 = H5F_open(filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F_open(false, &f0, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (f0->shared->nrefs != 2) TEST_ERROR; @@ -2389,13 +2389,13 @@ test_graph_cycle(void) TEST_ERROR; if (f2->shared->nrefs != 1) TEST_ERROR; - if (NULL == (f0 = H5F_open(filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F_open(false, &f0, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (f0->shared->nrefs != 2) TEST_ERROR; if (H5F_try_close(f0, NULL) < 0) FAIL_STACK_ERROR; - if (NULL == (f3 = H5F_open(filename[3], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F_open(false, &f3, filename[3], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (f3->shared->nrefs != 2) TEST_ERROR; @@ -2406,19 +2406,19 @@ test_graph_cycle(void) FAIL_STACK_ERROR; if (f2->shared->nrefs != 1) TEST_ERROR; - if (NULL == (f0 = H5F_open(filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F_open(false, &f0, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (f0->shared->nrefs != 2) TEST_ERROR; if (H5F_try_close(f0, NULL) < 0) FAIL_STACK_ERROR; - if (NULL == (f1 = H5F_open(filename[1], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F_open(false, &f1, filename[1], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (f1->shared->nrefs != 3) TEST_ERROR; if (H5F_try_close(f1, NULL) < 0) FAIL_STACK_ERROR; - if (NULL == (f3 = H5F_open(filename[3], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F_open(false, &f3, filename[3], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (f3->shared->nrefs != 2) TEST_ERROR; @@ -2427,25 +2427,25 @@ test_graph_cycle(void) if (H5F_try_close(f2, NULL) < 0) FAIL_STACK_ERROR; - if (NULL == (f0 = H5F_open(filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F_open(false, &f0, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (f0->shared->nrefs != 1) TEST_ERROR; if (H5F_try_close(f0, NULL) < 0) FAIL_STACK_ERROR; - if (NULL == (f1 = H5F_open(filename[1], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F_open(false, &f1, filename[1], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (f1->shared->nrefs != 1) TEST_ERROR; if (H5F_try_close(f1, NULL) < 0) FAIL_STACK_ERROR; - if (NULL == (f2 = H5F_open(filename[2], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F_open(false, &f2, filename[2], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (f2->shared->nrefs != 1) TEST_ERROR; if (H5F_try_close(f2, NULL) < 0) FAIL_STACK_ERROR; - if (NULL == (f3 = H5F_open(filename[3], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F_open(false, &f3, filename[3], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (f3->shared->nrefs != 1) TEST_ERROR; @@ -2455,23 +2455,23 @@ test_graph_cycle(void) /* Test 28: File held open by EFC client through non-parent file does not * interrupt cycle, but parent file does (no valid way around it), with * release */ - if (NULL == (f0 = H5F_open(filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f0, filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (f1 = H5F__efc_open(f0->shared->efc, filename[1], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &f1, filename[1], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp0 = H5F__efc_open(f1->shared->efc, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f1->shared->efc, &ftmp0, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f1, ftmp0) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f0, f1) < 0) FAIL_STACK_ERROR; - if (NULL == (f2 = H5F_open(filename[2], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f2, filename[2], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (f1 = H5F__efc_open(f2->shared->efc, filename[1], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f2->shared->efc, &f1, filename[1], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (f3 = H5F__efc_open(f1->shared->efc, filename[3], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f1->shared->efc, &f3, filename[3], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (f0->shared->nrefs != 2) TEST_ERROR; @@ -2514,13 +2514,13 @@ test_graph_cycle(void) TEST_ERROR; if (f2->shared->nrefs != 1) TEST_ERROR; - if (NULL == (f1 = H5F_open(filename[1], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F_open(false, &f1, filename[1], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (f1->shared->nrefs != 1) TEST_ERROR; if (H5F_try_close(f1, NULL) < 0) FAIL_STACK_ERROR; - if (NULL == (f3 = H5F_open(filename[3], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F_open(false, &f3, filename[3], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (f3->shared->nrefs != 1) TEST_ERROR; @@ -2533,16 +2533,16 @@ test_graph_cycle(void) FAIL_STACK_ERROR; /* Test 29: File without EFC interrupts cycle */ - if (NULL == (f0 = H5F_open(filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f0, filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5Pset_elink_file_cache_size(fapl_id, 0) < 0) TEST_ERROR; - if (NULL == (f1 = H5F__efc_open(f0->shared->efc, filename[1], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &f1, filename[1], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5Pset_elink_file_cache_size(fapl_id, 8) < 0) TEST_ERROR; - if (NULL == (ftmp0 = H5F__efc_open(f1->shared->efc, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f1->shared->efc, &ftmp0, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (f0->shared->nrefs != 2) TEST_ERROR; @@ -2557,13 +2557,13 @@ test_graph_cycle(void) if (H5F_try_close(f0, NULL) < 0) FAIL_STACK_ERROR; - if (NULL == (f0 = H5F_open(filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F_open(false, &f0, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (f0->shared->nrefs != 1) TEST_ERROR; if (H5F_try_close(f0, NULL) < 0) FAIL_STACK_ERROR; - if (NULL == (f1 = H5F_open(filename[1], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F_open(false, &f1, filename[1], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (f1->shared->nrefs != 1) TEST_ERROR; @@ -2571,12 +2571,12 @@ test_graph_cycle(void) FAIL_STACK_ERROR; /* Test 30: File without EFC does not interrupt cycle */ - if (NULL == (f0 = H5F_open(filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F_open(false, &f0, filename[0], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (f1 = H5F__efc_open(f0->shared->efc, filename[1], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f0->shared->efc, &f1, filename[1], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; - if (NULL == (ftmp0 = H5F__efc_open(f1->shared->efc, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f1->shared->efc, &ftmp0, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5F_efc_close(f1, ftmp0) < 0) FAIL_STACK_ERROR; @@ -2584,8 +2584,8 @@ test_graph_cycle(void) FAIL_STACK_ERROR; if (H5Pset_elink_file_cache_size(fapl_id, 0) < 0) TEST_ERROR; - if (NULL == (f2 = H5F__efc_open(f1->shared->efc, filename[2], - H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, fcpl_id, fapl_id))) + if (H5F__efc_open(false, f1->shared->efc, &f2, filename[2], H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC, + fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (H5Pset_elink_file_cache_size(fapl_id, 8) < 0) TEST_ERROR; @@ -2596,19 +2596,19 @@ test_graph_cycle(void) if (H5F_try_close(f0, NULL) < 0) FAIL_STACK_ERROR; - if (NULL == (f0 = H5F_open(filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F_open(false, &f0, filename[0], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (f0->shared->nrefs != 1) TEST_ERROR; if (H5F_try_close(f0, NULL) < 0) FAIL_STACK_ERROR; - if (NULL == (f1 = H5F_open(filename[1], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F_open(false, &f1, filename[1], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (f1->shared->nrefs != 1) TEST_ERROR; if (H5F_try_close(f1, NULL) < 0) FAIL_STACK_ERROR; - if (NULL == (f2 = H5F_open(filename[2], H5F_ACC_RDWR, fcpl_id, fapl_id))) + if (H5F_open(false, &f2, filename[2], H5F_ACC_RDWR, fcpl_id, fapl_id) < 0) FAIL_STACK_ERROR; if (f2->shared->nrefs != 1) TEST_ERROR; diff --git a/test/error_test.c b/test/error_test.c index bb780215574..84db80e3f93 100644 --- a/test/error_test.c +++ b/test/error_test.c @@ -456,8 +456,7 @@ custom_print_cb(unsigned n, const H5E_error2_t *err_desc, void *client_data) static herr_t test_create(void) { - const char *err_func = "test_create"; /* Function name for pushing error */ - const char *err_msg = "Error message"; /* Error message for pushing error */ + const char *err_msg = "Error message"; /* Error message for pushing error */ ssize_t err_num; /* Number of errors on stack */ hid_t estack_id = H5I_INVALID_HID; /* Error stack ID */ @@ -471,7 +470,7 @@ test_create(void) TEST_ERROR; /* Push an error with a long description */ - if (H5Epush(estack_id, __FILE__, err_func, __LINE__, ERR_CLS, ERR_MAJ_TEST, ERR_MIN_SUBROUTINE, "%s", + if (H5Epush(estack_id, __FILE__, __func__, __LINE__, ERR_CLS, ERR_MAJ_TEST, ERR_MIN_SUBROUTINE, "%s", err_msg) < 0) TEST_ERROR; @@ -512,14 +511,13 @@ test_create(void) static herr_t test_copy(void) { - const char *err_func = "test_copy"; /* Function name for pushing error */ - const char *err_msg = "Error message"; /* Error message for pushing error */ + const char *err_msg = "Error message"; /* Error message for pushing error */ ssize_t err_num; /* Number of errors on stack */ hid_t estack_id = H5I_INVALID_HID; /* Error stack ID */ herr_t ret; /* Generic return value */ /* Push an error with a long description */ - if (H5Epush(H5E_DEFAULT, __FILE__, err_func, __LINE__, ERR_CLS, ERR_MAJ_TEST, ERR_MIN_SUBROUTINE, "%s", + if (H5Epush(H5E_DEFAULT, __FILE__, __func__, __LINE__, ERR_CLS, ERR_MAJ_TEST, ERR_MIN_SUBROUTINE, "%s", err_msg) < 0) TEST_ERROR; @@ -581,7 +579,6 @@ test_copy(void) static herr_t test_append(void) { - const char *err_func = "test_append"; /* Function name for pushing error */ const char *err_msg1 = "Error message #1"; /* Error message #1 for pushing error */ const char *err_msg2 = "Error message #2"; /* Error message #2 for pushing error */ ssize_t err_num; /* Number of errors on stack */ @@ -590,7 +587,7 @@ test_append(void) herr_t ret; /* Generic return value */ /* Push an error */ - if (H5Epush(H5E_DEFAULT, __FILE__, err_func, __LINE__, ERR_CLS, ERR_MAJ_TEST, ERR_MIN_SUBROUTINE, "%s", + if (H5Epush(H5E_DEFAULT, __FILE__, __func__, __LINE__, ERR_CLS, ERR_MAJ_TEST, ERR_MIN_SUBROUTINE, "%s", err_msg1) < 0) TEST_ERROR; @@ -613,7 +610,7 @@ test_append(void) TEST_ERROR; /* Push an error on stack #2 */ - if (H5Epush(estack_id2, __FILE__, err_func, __LINE__, ERR_CLS, ERR_MAJ_IO, ERR_MIN_CREATE, "%s", + if (H5Epush(estack_id2, __FILE__, __func__, __LINE__, ERR_CLS, ERR_MAJ_IO, ERR_MIN_CREATE, "%s", err_msg2) < 0) TEST_ERROR; @@ -660,7 +657,7 @@ test_append(void) TEST_ERROR; /* Append error stack #2 to error stack #1, and close stack #2 */ - if (H5Eappend_stack(estack_id1, estack_id2, true) < 0) + if (H5Eappend_stack(estack_id1, estack_id2, TRUE) < 0) TEST_ERROR; /* Try to close error stack #2. Should fail because H5Eappend_stack @@ -685,6 +682,166 @@ test_append(void) return -1; } /* end test_append() */ +/*------------------------------------------------------------------------- + * Function: test_pause + * + * Purpose: Test pausing error stacks + * + * Return: Success: 0 + * Failure: -1 + * + *------------------------------------------------------------------------- + */ +static herr_t +test_pause(void) +{ + const char *err_msg1 = "Error message #1"; /* Error message #1 for pushing error */ + ssize_t err_num; /* Number of errors on stack */ + hid_t estack_id1 = H5I_INVALID_HID; /* Error stack ID */ + hbool_t is_paused; /* Whether error stack is paused */ + herr_t ret; /* Generic return value */ + + /* Push an error */ + if (H5Epush(H5E_DEFAULT, __FILE__, __func__, __LINE__, ERR_CLS, ERR_MAJ_TEST, ERR_MIN_SUBROUTINE, "%s", + err_msg1) < 0) + TEST_ERROR; + + /* Copy error stack, which clears the original */ + if ((estack_id1 = H5Eget_current_stack()) < 0) + TEST_ERROR; + + /* Check the number of errors on stack #1 */ + err_num = H5Eget_num(estack_id1); + if (err_num != 1) + TEST_ERROR; + + /* Check for bad arguments */ + is_paused = TRUE; + H5E_BEGIN_TRY + { + ret = H5Eis_paused(H5I_INVALID_HID, &is_paused); + } + H5E_END_TRY + if (ret >= 0) + TEST_ERROR; + + /* Verify that default stack is not paused */ + is_paused = TRUE; + if (H5Eis_paused(H5E_DEFAULT, &is_paused) < 0) + TEST_ERROR; + if (FALSE != is_paused) + TEST_ERROR; + + /* Verify that application stack is not paused */ + is_paused = TRUE; + if (H5Eis_paused(estack_id1, &is_paused) < 0) + TEST_ERROR; + if (FALSE != is_paused) + TEST_ERROR; + + /* Check for bad arguments */ + H5E_BEGIN_TRY + { + ret = H5Epause_stack(H5I_INVALID_HID); + } + H5E_END_TRY + if (ret >= 0) + TEST_ERROR; + /* Check for bad arguments */ + H5E_BEGIN_TRY + { + ret = H5Eresume_stack(H5I_INVALID_HID); + } + H5E_END_TRY + if (ret >= 0) + TEST_ERROR; + + /* Pause error stack */ + if (H5Epause_stack(estack_id1) < 0) + TEST_ERROR; + + /* Check if stack is paused */ + is_paused = FALSE; + if (H5Eis_paused(estack_id1, &is_paused) < 0) + TEST_ERROR; + if (TRUE != is_paused) + TEST_ERROR; + + /* Resume error stack */ + if (H5Eresume_stack(estack_id1) < 0) + TEST_ERROR; + + /* Check if stack is paused */ + is_paused = TRUE; + if (H5Eis_paused(estack_id1, &is_paused) < 0) + TEST_ERROR; + if (FALSE != is_paused) + TEST_ERROR; + + /* Check for resuming too many times */ + H5E_BEGIN_TRY + { + ret = H5Eresume_stack(estack_id1); + } + H5E_END_TRY + if (ret >= 0) + TEST_ERROR; + + /* Check if stack is paused, after trying to resume too many times */ + is_paused = TRUE; + if (H5Eis_paused(estack_id1, &is_paused) < 0) + TEST_ERROR; + if (FALSE != is_paused) + TEST_ERROR; + + /* Close error stack */ + if (H5Eclose_stack(estack_id1) < 0) + TEST_ERROR; + + /* Pause default error stack */ + if (H5Epause_stack(H5E_DEFAULT) < 0) + TEST_ERROR; + + /* Check if stack is paused */ + is_paused = FALSE; + if (H5Eis_paused(H5E_DEFAULT, &is_paused) < 0) + TEST_ERROR; + if (TRUE != is_paused) + TEST_ERROR; + + /* Resume error stack */ + if (H5Eresume_stack(H5E_DEFAULT) < 0) + TEST_ERROR; + + /* Check if stack is paused */ + is_paused = TRUE; + if (H5Eis_paused(H5E_DEFAULT, &is_paused) < 0) + TEST_ERROR; + if (FALSE != is_paused) + TEST_ERROR; + + /* Check for resuming too many times */ + H5E_BEGIN_TRY + { + ret = H5Eresume_stack(H5E_DEFAULT); + } + H5E_END_TRY + if (ret >= 0) + TEST_ERROR; + + /* Check if stack is paused, after trying to resume too many times */ + is_paused = TRUE; + if (H5Eis_paused(H5E_DEFAULT, &is_paused) < 0) + TEST_ERROR; + if (FALSE != is_paused) + TEST_ERROR; + + return 0; + +error: + return -1; +} /* end test_pause() */ + /*------------------------------------------------------------------------- * Function: close_error * @@ -868,6 +1025,10 @@ main(void) if (test_append() < 0) TEST_ERROR; + /* Test pausing error stacks */ + if (test_pause() < 0) + TEST_ERROR; + /* Close error information */ if (close_error() < 0) TEST_ERROR; From cc91bead610eddf4d0d5665b44fc85ba1aea595b Mon Sep 17 00:00:00 2001 From: Allen Byrne <50328838+byrnHDF@users.noreply.github.com> Date: Wed, 19 Jun 2024 07:38:30 -0500 Subject: [PATCH 21/45] Add page buffer cache command line option to tools (#4562) Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com> --- release_docs/RELEASE.txt | 8 ++ tools/lib/h5diff.c | 70 +++++++---- tools/lib/h5diff.h | 1 + tools/lib/h5tools.c | 45 ++++--- tools/lib/h5tools.h | 5 +- tools/libtest/h5tools_test_utils.c | 11 +- tools/src/h5diff/h5diff_common.c | 12 +- tools/src/h5dump/h5dump.c | 40 ++++++- tools/src/h5ls/h5ls.c | 52 +++++--- tools/src/h5repack/h5repack.c | 6 +- tools/src/h5repack/h5repack.h | 6 +- tools/src/h5repack/h5repack_copy.c | 6 +- tools/src/h5repack/h5repack_main.c | 112 +++++++++++------- tools/src/h5repack/h5repack_verify.c | 10 +- tools/src/h5stat/h5stat.c | 30 ++++- tools/src/misc/h5mkgrp.c | 70 ++++++----- tools/test/h5diff/expected/h5diff_10.txt | 1 + tools/test/h5diff/expected/h5diff_600.txt | 1 + tools/test/h5diff/expected/h5diff_603.txt | 1 + tools/test/h5diff/expected/h5diff_606.txt | 1 + tools/test/h5diff/expected/h5diff_612.txt | 1 + tools/test/h5diff/expected/h5diff_615.txt | 1 + tools/test/h5diff/expected/h5diff_621.txt | 1 + tools/test/h5diff/expected/h5diff_622.txt | 1 + tools/test/h5diff/expected/h5diff_623.txt | 1 + tools/test/h5diff/expected/h5diff_624.txt | 1 + tools/test/h5dump/CMakeTests.cmake | 2 + .../test/h5dump/expected/file_space_cache.ddl | 22 ++++ tools/test/h5dump/expected/h5dump-help.txt | 1 + .../pbits/tnofilename-with-packed-bits.ddl | 1 + .../expected/pbits/tpbitsIncomplete.ddl | 1 + .../expected/pbits/tpbitsLengthExceeded.ddl | 1 + .../expected/pbits/tpbitsLengthPositive.ddl | 1 + .../expected/pbits/tpbitsMaxExceeded.ddl | 1 + .../expected/pbits/tpbitsOffsetExceeded.ddl | 1 + .../expected/pbits/tpbitsOffsetNegative.ddl | 1 + tools/test/h5dump/testh5dump.sh.in | 2 + tools/test/h5ls/CMakeTests.cmake | 3 + tools/test/h5ls/expected/help-1.ls | 1 + tools/test/h5ls/expected/help-2.ls | 1 + tools/test/h5ls/expected/help-3.ls | 1 + .../h5ls/expected/textlinksrc-nodangle-1.ls | 1 + tools/test/h5ls/expected/tgroup-1.ls | 1 + .../test/h5repack/expected/h5repack-help.txt | 1 + tools/test/h5repack/h5repacktst.c | 10 +- tools/test/h5stat/CMakeTests.cmake | 3 + .../h5stat/expected/h5stat_filters-cache.ddl | 99 ++++++++++++++++ tools/test/h5stat/expected/h5stat_help1.ddl | 1 + tools/test/h5stat/expected/h5stat_help2.ddl | 1 + tools/test/h5stat/expected/h5stat_nofile.ddl | 1 + tools/test/h5stat/testh5stat.sh.in | 3 + 51 files changed, 495 insertions(+), 160 deletions(-) create mode 100644 tools/test/h5dump/expected/file_space_cache.ddl create mode 100644 tools/test/h5stat/expected/h5stat_filters-cache.ddl diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt index 153c3ee944f..e29a329c558 100644 --- a/release_docs/RELEASE.txt +++ b/release_docs/RELEASE.txt @@ -126,6 +126,14 @@ New Features Tools: ------ + - Add option to adjust the page buffer size in tools + + The page buffer cache size for a file can now be adjusted using the + --page-buffer-size=N + option in the h5repack, h5diff, h5dump, h5ls, and h5stat tools. This + will call the H5Pset_page_buffer_size() API function with the specified + size in bytes. + - Allow h5repack to reserve space for a user block without a file This is useful for users who want to reserve space diff --git a/tools/lib/h5diff.c b/tools/lib/h5diff.c index 9329872d965..bd8112f2c65 100644 --- a/tools/lib/h5diff.c +++ b/tools/lib/h5diff.c @@ -624,46 +624,72 @@ h5diff(const char *fname1, const char *fname2, const char *objname1, const char *------------------------------------------------------------------------- */ /* open file 1 */ - if (opts->vfd_info[0].u.name) { - if ((fapl1_id = h5tools_get_fapl(H5P_DEFAULT, NULL, &(opts->vfd_info[0]))) < 0) { - parallel_print("h5diff: unable to create fapl for input file\n"); - H5TOOLS_GOTO_ERROR(H5DIFF_ERR, "unable to create input fapl\n"); + if ((fapl1_id = h5tools_get_new_fapl(H5P_DEFAULT)) < 0) { + parallel_print("h5diff: unable to create fapl for input file\n"); + H5TOOLS_GOTO_ERROR(H5DIFF_ERR, "unable to create input fapl\n"); + } + + /* Set non-default virtual file driver, if requested */ + if (opts->custom_vfd[0] && opts->vfd_info[0].u.name) { + if (h5tools_set_fapl_vfd(fapl1_id, &(opts->vfd_info[0])) < 0) { + parallel_print("h5diff: unable to set VFD on fapl for input file\n"); + H5TOOLS_GOTO_ERROR(H5DIFF_ERR, "failed to set VFD on FAPL\n"); + } + } + + /* Set non-default VOL connector, if requested */ + if (opts->custom_vol[0]) { + if (h5tools_set_fapl_vol(fapl1_id, &(opts->vol_info[0])) < 0) { + parallel_print("h5diff: unable to set VOL on fapl for input file\n"); + H5TOOLS_GOTO_ERROR(H5DIFF_ERR, "failed to set VOL on FAPL\n"); } } - if (opts->custom_vol[0] || opts->custom_vfd[0]) { - if ((fapl1_id = h5tools_get_fapl(fapl1_id, opts->custom_vol[0] ? &(opts->vol_info[0]) : NULL, - opts->custom_vfd[0] ? &(opts->vfd_info[0]) : NULL)) < 0) { - parallel_print("h5diff: unable to create fapl for input file\n"); - H5TOOLS_GOTO_ERROR(H5DIFF_ERR, "unable to create input fapl\n"); + if (opts->page_cache > 0) { + if (H5Pset_page_buffer_size(fapl1_id, opts->page_cache, 0, 0) < 0) { + parallel_print("h5diff: unable to set page buffer cache size for fapl for input file\n"); + H5TOOLS_GOTO_ERROR(H5DIFF_ERR, "unable to set page buffer cache size on FAPL\n"); } } - if ((file1_id = h5tools_fopen(fname1, H5F_ACC_RDONLY, fapl1_id, (fapl1_id != H5P_DEFAULT), NULL, - (size_t)0)) < 0) { + if ((file1_id = h5tools_fopen(fname1, H5F_ACC_RDONLY, fapl1_id, + (opts->custom_vol[0] || opts->custom_vfd[0]), 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); } H5TOOLS_DEBUG("file1_id = %s", fname1); /* open file 2 */ - if (opts->vfd_info[1].u.name) { - if ((fapl2_id = h5tools_get_fapl(H5P_DEFAULT, NULL, &(opts->vfd_info[1]))) < 0) { - parallel_print("h5diff: unable to create fapl for output file\n"); - H5TOOLS_GOTO_ERROR(H5DIFF_ERR, "unable to create output fapl\n"); + if ((fapl2_id = h5tools_get_new_fapl(H5P_DEFAULT)) < 0) { + parallel_print("h5diff: unable to create fapl for output file\n"); + H5TOOLS_GOTO_ERROR(H5DIFF_ERR, "unable to create output fapl\n"); + } + + /* Set non-default virtual file driver, if requested */ + if (opts->custom_vfd[1] && opts->vfd_info[1].u.name) { + if (h5tools_set_fapl_vfd(fapl2_id, &(opts->vfd_info[1])) < 0) { + parallel_print("h5diff: unable to set VFD on fapl for output file\n"); + H5TOOLS_GOTO_ERROR(H5DIFF_ERR, "failed to set VFD on FAPL\n"); + } + } + + /* Set non-default VOL connector, if requested */ + if (opts->custom_vol[1]) { + if (h5tools_set_fapl_vol(fapl2_id, &(opts->vol_info[1])) < 0) { + parallel_print("h5diff: unable to set VOL on fapl for output file\n"); + H5TOOLS_GOTO_ERROR(H5DIFF_ERR, "failed to set VOL on FAPL\n"); } } - if (opts->custom_vol[1] || opts->custom_vfd[1]) { - if ((fapl2_id = h5tools_get_fapl(fapl2_id, opts->custom_vol[1] ? &(opts->vol_info[1]) : NULL, - opts->custom_vfd[1] ? &(opts->vfd_info[1]) : NULL)) < 0) { - parallel_print("h5diff: unable to create fapl for output file\n"); - H5TOOLS_GOTO_ERROR(H5DIFF_ERR, "unable to create output fapl\n"); + if (opts->page_cache > 0) { + if (H5Pset_page_buffer_size(fapl2_id, opts->page_cache, 0, 0) < 0) { + parallel_print("h5diff: unable to set page buffer cache size for fapl for output file\n"); + H5TOOLS_GOTO_ERROR(H5DIFF_ERR, "unable to set page buffer cache size for output fapl\n"); } } - if ((file2_id = h5tools_fopen(fname2, H5F_ACC_RDONLY, fapl2_id, (fapl2_id != H5P_DEFAULT), NULL, - (size_t)0)) < 0) { + if ((file2_id = h5tools_fopen(fname2, H5F_ACC_RDONLY, fapl2_id, + (opts->custom_vol[1] || opts->custom_vfd[1]), 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); } diff --git a/tools/lib/h5diff.h b/tools/lib/h5diff.h index 12bf56a8ecd..4b9847a3044 100644 --- a/tools/lib/h5diff.h +++ b/tools/lib/h5diff.h @@ -92,6 +92,7 @@ typedef struct { h5tools_vfd_info_t vfd_info[2]; /* VFD information for input file, output file */ bool custom_vol[2]; /* Using a custom input, output VOL? */ bool custom_vfd[2]; /* Using a custom input, output VFD? */ + size_t page_cache; /* Size to request for page buffer cache */ } diff_opt_t; /*------------------------------------------------------------------------- diff --git a/tools/lib/h5tools.c b/tools/lib/h5tools.c index 16253b195d5..29419e297af 100644 --- a/tools/lib/h5tools.c +++ b/tools/lib/h5tools.c @@ -469,7 +469,7 @@ h5tools_set_error_file(const char *fname, int is_bin) * negative - failed *------------------------------------------------------------------------- */ -static herr_t +herr_t h5tools_set_fapl_vfd(hid_t fapl_id, h5tools_vfd_info_t *vfd_info) { herr_t ret_value = SUCCEED; @@ -650,7 +650,7 @@ h5tools_set_fapl_vfd(hid_t fapl_id, h5tools_vfd_info_t *vfd_info) * negative - failed *------------------------------------------------------------------------- */ -static herr_t +herr_t h5tools_set_fapl_vol(hid_t fapl_id, h5tools_vol_info_t *vol_info) { htri_t connector_is_registered; @@ -746,9 +746,9 @@ h5tools_set_fapl_vol(hid_t fapl_id, h5tools_vol_info_t *vol_info) } /*------------------------------------------------------------------------- - * Function: h5tools_get_fapl + * Function: h5tools_get_new_fapl * - * Purpose: Copies an input fapl and then sets a VOL and/or a VFD on it. + * Purpose: Copies an input fapl. * * The returned fapl must be closed by the caller. * @@ -757,7 +757,7 @@ h5tools_set_fapl_vol(hid_t fapl_id, h5tools_vol_info_t *vol_info) *------------------------------------------------------------------------- */ hid_t -h5tools_get_fapl(hid_t prev_fapl_id, h5tools_vol_info_t *vol_info, h5tools_vfd_info_t *vfd_info) +h5tools_get_new_fapl(hid_t prev_fapl_id) { hid_t new_fapl_id = H5I_INVALID_HID; hid_t ret_value = H5I_INVALID_HID; @@ -775,16 +775,6 @@ h5tools_get_fapl(hid_t prev_fapl_id, h5tools_vol_info_t *vol_info, h5tools_vfd_i H5TOOLS_GOTO_ERROR(H5I_INVALID_HID, "H5Pcopy failed"); } - /* Set non-default VOL connector, if requested */ - if (vol_info) - if (h5tools_set_fapl_vol(new_fapl_id, vol_info) < 0) - H5TOOLS_GOTO_ERROR(H5I_INVALID_HID, "failed to set VOL on FAPL"); - - /* Set non-default virtual file driver, if requested */ - if (vfd_info) - if (h5tools_set_fapl_vfd(new_fapl_id, vfd_info) < 0) - H5TOOLS_GOTO_ERROR(H5I_INVALID_HID, "failed to set VFD on FAPL"); - ret_value = new_fapl_id; done: @@ -1026,9 +1016,23 @@ h5tools_fopen(const char *fname, unsigned flags, hid_t fapl_id, bool use_specifi vfd_info.u.name = drivernames[drivernum]; /* Get a fapl reflecting the selected VOL connector and VFD */ - if ((tmp_fapl_id = h5tools_get_fapl(fapl_id, &vol_info, &vfd_info)) < 0) + if ((tmp_fapl_id = h5tools_get_new_fapl(fapl_id)) < 0) continue; + if (h5tools_set_fapl_vol(tmp_fapl_id, &vol_info) < 0) { + /* Close the temporary fapl */ + H5Pclose(tmp_fapl_id); + tmp_fapl_id = H5I_INVALID_HID; + continue; + } + + if (h5tools_set_fapl_vfd(tmp_fapl_id, &vfd_info) < 0) { + /* Close the temporary fapl */ + H5Pclose(tmp_fapl_id); + tmp_fapl_id = H5I_INVALID_HID; + continue; + } + /* Can we open the file with this combo? */ H5E_BEGIN_TRY { @@ -1051,9 +1055,16 @@ h5tools_fopen(const char *fname, unsigned flags, hid_t fapl_id, bool use_specifi /* NOT the native VOL connector */ /* Get a FAPL for the current VOL connector */ - if ((tmp_fapl_id = h5tools_get_fapl(fapl_id, &vol_info, NULL)) < 0) + if ((tmp_fapl_id = h5tools_get_new_fapl(fapl_id)) < 0) continue; + if (h5tools_set_fapl_vol(tmp_fapl_id, &vol_info) < 0) { + /* Close the temporary fapl */ + H5Pclose(tmp_fapl_id); + tmp_fapl_id = H5I_INVALID_HID; + continue; + } + /* Can we open the file with this connector? */ if ((fid = h5tools_fopen(fname, flags, tmp_fapl_id, true, drivername, drivername_size)) >= 0) { used_fapl_id = tmp_fapl_id; diff --git a/tools/lib/h5tools.h b/tools/lib/h5tools.h index b4ace197d7f..52e3a3659a8 100644 --- a/tools/lib/h5tools.h +++ b/tools/lib/h5tools.h @@ -673,9 +673,10 @@ 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 prev_fapl_id, h5tools_vol_info_t *vol_info, - h5tools_vfd_info_t *vfd_info); +H5TOOLS_DLL hid_t h5tools_get_new_fapl(hid_t prev_fapl_id); H5TOOLS_DLL herr_t h5tools_get_vfd_name(hid_t fid, hid_t fapl_id, char *drivername, size_t drivername_size); +H5TOOLS_DLL herr_t h5tools_set_fapl_vfd(hid_t fapl_id, h5tools_vfd_info_t *vfd_info); +H5TOOLS_DLL herr_t h5tools_set_fapl_vol(hid_t fapl_id, h5tools_vol_info_t *vol_info); H5TOOLS_DLL hid_t h5tools_fopen(const char *fname, unsigned flags, hid_t fapl, bool use_specific_driver, char *drivername, size_t drivername_size); H5TOOLS_DLL hid_t h5tools_get_little_endian_type(hid_t type); diff --git a/tools/libtest/h5tools_test_utils.c b/tools/libtest/h5tools_test_utils.c index 369472e8d86..03c595f66cb 100644 --- a/tools/libtest/h5tools_test_utils.c +++ b/tools/libtest/h5tools_test_utils.c @@ -927,7 +927,7 @@ test_populate_ros3_fa(void) * * Function: test_set_configured_fapl() * - * Purpose: Verify `h5tools_get_fapl()` with ROS3 and HDFS VFDs + * Purpose: Verify `h5tools_get_new_fapl()` with ROS3 and HDFS VFDs * * Return: 0 if test passes * 1 if failure @@ -1111,12 +1111,15 @@ test_set_configured_fapl(void) vfd_info.info = C.conf_fa; vfd_info.u.name = C.vfdname; - if (C.expected == 1) - result = h5tools_get_fapl(H5P_DEFAULT, NULL, &vfd_info); + if (C.expected == 1) { + result = h5tools_get_new_fapl(H5P_DEFAULT); + result = h5tools_set_fapl_vfd(result, &vfd_info); + } else { H5E_BEGIN_TRY { - result = h5tools_get_fapl(H5P_DEFAULT, NULL, &vfd_info); + result = h5tools_get_new_fapl(H5P_DEFAULT); + result = h5tools_set_fapl_vfd(result, &vfd_info); } H5E_END_TRY } diff --git a/tools/src/h5diff/h5diff_common.c b/tools/src/h5diff/h5diff_common.c index 77b83533409..62a8cd2abe5 100644 --- a/tools/src/h5diff/h5diff_common.c +++ b/tools/src/h5diff/h5diff_common.c @@ -24,7 +24,7 @@ static int check_d_input(const char *); * Command-line options: The user can specify short or long-named * parameters. */ -static const char *s_opts = "cd:ehln:p:qrv*xA:CE:NS*V"; +static const char *s_opts = "cd:ehln:p:qrv*xA:CE:K:NS*V"; static struct h5_long_options l_opts[] = {{"compare", no_arg, 'c'}, {"delta", require_arg, 'd'}, {"use-system-epsilon", no_arg, 'e'}, @@ -39,6 +39,7 @@ static struct h5_long_options l_opts[] = {{"compare", no_arg, 'c'}, {"exclude-attribute", require_arg, 'A'}, {"no-compact-subset", no_arg, 'C'}, {"exclude-path", require_arg, 'E'}, + {"page-buffer-size", require_arg, 'K'}, {"nan", no_arg, 'N'}, {"enable-error-stack", optional_arg, 'S'}, {"version", no_arg, 'V'}, @@ -137,6 +138,9 @@ parse_command_line(int argc, const char *const *argv, const char **fname1, const /**this is bad in mixing option with results**/ opts->not_cmp = 0; + /* init for page buffer cache size option */ + opts->page_cache = 0; + /* init for exclude-path option */ exclude_head = NULL; @@ -320,6 +324,10 @@ parse_command_line(int argc, const char *const *argv, const char **fname1, const opts->use_system_epsilon = 1; break; + case 'K': + opts->page_cache = strtoul(H5_optarg, NULL, 0); + break; + case '1': opts->vol_info[0].type = VOL_BY_VALUE; opts->vol_info[0].u.value = (H5VL_class_value_t)atoi(H5_optarg); @@ -622,6 +630,8 @@ usage(void) PRINTVALSTREAM(rawoutstream, " 3 : All level 2 information plus file names.\n"); PRINTVALSTREAM(rawoutstream, " -q, --quiet\n"); PRINTVALSTREAM(rawoutstream, " Quiet mode. Do not produce output.\n"); + PRINTVALSTREAM(rawoutstream, + " --page-buffer-size=N Set the page buffer cache size, N=non-negative integers\n"); PRINTVALSTREAM(rawoutstream, " --vol-value-1 Value (ID) of the VOL connector to use for opening the\n"); PRINTVALSTREAM(rawoutstream, " first HDF5 file specified\n"); diff --git a/tools/src/h5dump/h5dump.c b/tools/src/h5dump/h5dump.c index 40041e3aec9..dc86e526294 100644 --- a/tools/src/h5dump/h5dump.c +++ b/tools/src/h5dump/h5dump.c @@ -17,6 +17,7 @@ /* Name of tool */ #define PROGRAMNAME "h5dump" +size_t page_cache = 0; const char *outfname_g = NULL; static bool doxml_g = false; static bool useschema_g = true; @@ -97,7 +98,7 @@ struct handler_t { */ /* The following initialization makes use of C language concatenating */ /* "xxx" "yyy" into "xxxyyy". */ -static const char *s_opts = "a:b*c:d:ef:g:hik:l:m:n*o*pq:rs:t:uvw:xyz:A*BCD:E*F:G:HM:N:O*RS:VX:"; +static const char *s_opts = "a:b*c:d:ef:g:hik:l:m:n*o*pq:rs:t:uvw:xyz:A*BCD:E*F:G:HK:M:N:O*RS:VX:"; static struct h5_long_options l_opts[] = {{"attribute", require_arg, 'a'}, {"binary", optional_arg, 'b'}, {"count", require_arg, 'c'}, @@ -132,6 +133,7 @@ static struct h5_long_options l_opts[] = {{"attribute", require_arg, 'a'}, {"form", require_arg, 'F'}, {"vds-gap-size", require_arg, 'G'}, {"header", no_arg, 'H'}, + {"page-buffer-size", require_arg, 'K'}, {"packed-bits", require_arg, 'M'}, {"any_path", require_arg, 'N'}, {"ddl", optional_arg, 'O'}, @@ -198,6 +200,8 @@ usage(const char *prog) PRINTVALSTREAM(rawoutstream, " -O F, --ddl=F Output ddl text into file F\n"); PRINTVALSTREAM(rawoutstream, " Use blank(empty) filename F to suppress ddl display\n"); + PRINTVALSTREAM(rawoutstream, + " --page-buffer-size=N Set the page buffer cache size, N=non-negative integers\n"); PRINTVALSTREAM(rawoutstream, " --s3-cred= Supply S3 authentication information to \"ros3\" vfd.\n"); PRINTVALSTREAM(rawoutstream, @@ -1019,6 +1023,9 @@ parse_command_line(int argc, const char *const *argv) goto error; } break; + case 'K': + page_cache = strtoul(H5_optarg, NULL, 0); + break; /** begin XML parameters **/ case 'x': @@ -1368,10 +1375,30 @@ main(int argc, char *argv[]) /* Initialize indexing options */ h5trav_set_index(sort_by, sort_order); - if (use_custom_vol_g || use_custom_vfd_g) { - if ((fapl_id = h5tools_get_fapl(H5P_DEFAULT, use_custom_vol_g ? &vol_info_g : NULL, - use_custom_vfd_g ? &vfd_info_g : NULL)) < 0) { - error_msg("unable to create FAPL for file access\n"); + if ((fapl_id = h5tools_get_new_fapl(H5P_DEFAULT)) < 0) { + error_msg("unable to create FAPL for file access\n"); + h5tools_setstatus(EXIT_FAILURE); + goto done; + } + /* Set non-default VOL connector, if requested */ + if (use_custom_vol_g) { + if (h5tools_set_fapl_vol(fapl_id, &vol_info_g) < 0) { + error_msg("unable to set VOL on fapl for file\n"); + h5tools_setstatus(EXIT_FAILURE); + goto done; + } + } + /* Set non-default virtual file driver, if requested */ + if (use_custom_vfd_g) { + if (h5tools_set_fapl_vfd(fapl_id, &vfd_info_g) < 0) { + error_msg("unable to set VFD on fapl for file\n"); + h5tools_setstatus(EXIT_FAILURE); + goto done; + } + } + if (page_cache > 0) { + if (H5Pset_page_buffer_size(fapl_id, page_cache, 0, 0) < 0) { + error_msg("unable to set page buffer cache size for file access\n"); h5tools_setstatus(EXIT_FAILURE); goto done; } @@ -1394,7 +1421,8 @@ main(int argc, char *argv[]) goto done; } else - fid = h5tools_fopen(fname, H5F_ACC_RDONLY, fapl_id, (fapl_id != H5P_DEFAULT), NULL, 0); + fid = h5tools_fopen(fname, H5F_ACC_RDONLY, fapl_id, (use_custom_vol_g || use_custom_vfd_g), NULL, + 0); if (fid < 0) { error_msg("unable to open file \"%s\"\n", fname); diff --git a/tools/src/h5ls/h5ls.c b/tools/src/h5ls/h5ls.c index bef90cf9061..ef36839f815 100644 --- a/tools/src/h5ls/h5ls.c +++ b/tools/src/h5ls/h5ls.c @@ -25,6 +25,7 @@ #define PROGRAMNAME "h5ls" #define NAME_BUF_SIZE 2048 + /* * Alternative formatting for data dumped by H5LS * @@ -211,6 +212,8 @@ usage(void) PRINTVALSTREAM(rawoutstream, " -wN, --width=N Set the number of columns of output\n"); PRINTVALSTREAM(rawoutstream, " -v, --verbose Generate more verbose output\n"); PRINTVALSTREAM(rawoutstream, " -V, --version Print version number and exit\n"); + PRINTVALSTREAM(rawoutstream, + " --page-buffer-size=N Set the page buffer cache size, N=non-negative integers\n"); PRINTVALSTREAM(rawoutstream, " --vfd=DRIVER Use the specified virtual file driver\n"); PRINTVALSTREAM(rawoutstream, " -x, --hexdump Show raw data in hexadecimal format\n"); PRINTVALSTREAM(rawoutstream, @@ -2659,6 +2662,7 @@ main(int argc, char *argv[]) static char root_name[] = "/"; char drivername[50]; int err_exit = 0; + size_t page_cache = 0; hid_t fapl_id = H5P_DEFAULT; bool custom_vol_fapl = false; bool custom_vfd_fapl = false; @@ -2816,6 +2820,9 @@ main(int argc, char *argv[]) leave(EXIT_FAILURE); } } + else if (!strncmp(argv[argno], "--page-buffer-size=", (size_t)19)) { + page_cache = strtoul(argv[argno] + 19, &rest, 0); + } else if (!strcmp(argv[argno], "--verbose")) { verbose_g++; } @@ -2995,23 +3002,40 @@ main(int argc, char *argv[]) } /* Setup a custom fapl for file accesses */ - if (custom_vol_fapl || custom_vfd_fapl) { #ifdef H5_HAVE_ROS3_VFD - if (custom_vfd_fapl && (0 == strcmp(vfd_info.u.name, drivernames[ROS3_VFD_IDX]))) { - if (!vfd_info.info) - vfd_info.info = &ros3_fa; - } + if (custom_vfd_fapl && (0 == strcmp(vfd_info.u.name, drivernames[ROS3_VFD_IDX]))) { + if (!vfd_info.info) + vfd_info.info = &ros3_fa; + } #endif #ifdef H5_HAVE_LIBHDFS - if (custom_vfd_fapl && (0 == strcmp(vfd_info.u.name, drivernames[HDFS_VFD_IDX]))) { - if (!vfd_info.info) - vfd_info.info = &hdfs_fa; - } + if (custom_vfd_fapl && (0 == strcmp(vfd_info.u.name, drivernames[HDFS_VFD_IDX]))) { + if (!vfd_info.info) + vfd_info.info = &hdfs_fa; + } #endif - if ((fapl_id = h5tools_get_fapl(H5P_DEFAULT, custom_vol_fapl ? &vol_info : NULL, - custom_vfd_fapl ? &vfd_info : NULL)) < 0) { - error_msg("failed to setup file access property list (fapl) for file\n"); + if ((fapl_id = h5tools_get_new_fapl(H5P_DEFAULT)) < 0) { + error_msg("unable to create FAPL for file access\n"); + leave(EXIT_FAILURE); + } + /* Set non-default VOL connector, if requested */ + if (custom_vol_fapl) { + if (h5tools_set_fapl_vol(fapl_id, &vol_info) < 0) { + error_msg("unable to set VOL on fapl for file\n"); + leave(EXIT_FAILURE); + } + } + /* Set non-default virtual file driver, if requested */ + if (custom_vfd_fapl) { + if (h5tools_set_fapl_vfd(fapl_id, &vfd_info) < 0) { + error_msg("unable to set VFD on fapl for file\n"); + leave(EXIT_FAILURE); + } + } + if (page_cache > 0) { + if (H5Pset_page_buffer_size(fapl_id, page_cache, 0, 0) < 0) { + error_msg("unable to set page buffer cache size for file access\n"); leave(EXIT_FAILURE); } } @@ -3040,8 +3064,8 @@ main(int argc, char *argv[]) file_id = H5I_INVALID_HID; while (fname && *fname) { - file_id = h5tools_fopen(fname, H5F_ACC_RDONLY, fapl_id, (fapl_id != H5P_DEFAULT), drivername, - sizeof drivername); + file_id = h5tools_fopen(fname, H5F_ACC_RDONLY, fapl_id, (custom_vol_fapl || custom_vfd_fapl), + 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 30351e220d7..fa1dc90081b 100644 --- a/tools/src/h5repack/h5repack.c +++ b/tools/src/h5repack/h5repack.c @@ -80,6 +80,10 @@ h5repack_init(pack_opt_t *options, int verbose, bool latest) options->high_bound = H5F_LIBVER_LATEST; options->fin_fapl = H5P_DEFAULT; options->fout_fapl = H5P_DEFAULT; + options->fin_vol = false; + options->fin_vfd = false; + options->fout_vol = false; + options->fout_vfd = false; for (n = 0; n < H5_REPACK_MAX_NFILTERS; n++) { options->filter_g[n].filtn = -1; @@ -793,7 +797,7 @@ check_objects(const char *fname, pack_opt_t *options) * open the file *------------------------------------------------------------------------- */ - if ((fid = h5tools_fopen(fname, H5F_ACC_RDONLY, options->fin_fapl, (options->fin_fapl != H5P_DEFAULT), + if ((fid = h5tools_fopen(fname, H5F_ACC_RDONLY, options->fin_fapl, (options->fin_vol || options->fin_vfd), 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 fa79c6f53f5..cc724a067cf 100644 --- a/tools/src/h5repack/h5repack.h +++ b/tools/src/h5repack/h5repack.h @@ -133,6 +133,10 @@ typedef struct { int fs_persist; /* Free space section threshold */ long fs_threshold; /* Free space section threshold */ long long fs_pagesize; /* File space page size */ + bool fin_vol; /* Custom VOL for input file */ + bool fin_vfd; /* Custom VFD for input file */ + bool fout_vol; /* Custom VOL for output file */ + bool fout_vfd; /* Custom VFD for output file */ } pack_opt_t; typedef struct named_dt_t { @@ -156,7 +160,7 @@ int h5repack_addlayout(const char *str, pack_opt_t *options); int h5repack_init(pack_opt_t *options, int verbose, bool 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, hid_t fname1_fapl, const char *fname2, hid_t fname2_fapl); +int h5repack_cmp_pl(const char *fname1, const char *fname2, pack_opt_t *options); /* 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 ca1e76753d4..77442269f6f 100644 --- a/tools/src/h5repack/h5repack_copy.c +++ b/tools/src/h5repack/h5repack_copy.c @@ -81,8 +81,8 @@ copy_objects(const char *fnamein, const char *fnameout, pack_opt_t *options) * open input file *------------------------------------------------------------------------- */ - if ((fidin = h5tools_fopen(fnamein, H5F_ACC_RDONLY, options->fin_fapl, (options->fin_fapl != H5P_DEFAULT), - NULL, (size_t)0)) < 0) + if ((fidin = h5tools_fopen(fnamein, H5F_ACC_RDONLY, options->fin_fapl, + (options->fin_vol || options->fin_vfd), 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 */ @@ -849,7 +849,7 @@ do_copy_objects(hid_t fidin, hid_t fidout, trav_table_t *travt, pack_opt_t *opti * doesn't support this. */ if (use_h5ocopy && - (options->fin_fapl != H5P_DEFAULT || options->fout_fapl != H5P_DEFAULT)) { + (options->fin_vol || options->fout_vol || options->fin_vfd || options->fout_vfd)) { hid_t in_vol_id; hid_t out_vol_id; hid_t default_vol_id; diff --git a/tools/src/h5repack/h5repack_main.c b/tools/src/h5repack/h5repack_main.c index 85ab93a375c..8318fd11be5 100644 --- a/tools/src/h5repack/h5repack_main.c +++ b/tools/src/h5repack/h5repack_main.c @@ -30,7 +30,8 @@ static const char *outfile = NULL; * Command-line options: The user can specify short or long-named * parameters. */ -static const char *s_opts = "a:b:c:d:e:f:hi:j:k:l:m:no:q:s:t:u:v*z:E*G:LM:P:S:T:VXWY:Z:1:2:3:4:5:6:7:8:9:0:"; +static const char *s_opts = + "a:b:c:d:e:f:hi:j:k:l:m:no:q:s:t:u:v*z:E*G:K:LM:P:S:T:VXWY:Z:1:2:3:4:5:6:7:8:9:0:"; static struct h5_long_options l_opts[] = {{"alignment", require_arg, 'a'}, {"block", require_arg, 'b'}, {"compact", require_arg, 'c'}, @@ -53,6 +54,7 @@ static struct h5_long_options l_opts[] = {{"alignment", require_arg, 'a'}, {"sort_order", require_arg, 'z'}, {"enable-error-stack", optional_arg, 'E'}, {"fs_pagesize", require_arg, 'G'}, + {"page-buffer-size", require_arg, 'K'}, {"latest", no_arg, 'L'}, {"metadata_block_size", require_arg, 'M'}, {"fs_persist", require_arg, 'P'}, @@ -113,6 +115,8 @@ usage(const char *prog) PRINTVALSTREAM(rawoutstream, " N - is an integer greater than 1, 2 displays read/write timing\n"); PRINTVALSTREAM(rawoutstream, " -V, --version Print version number and exit\n"); PRINTVALSTREAM(rawoutstream, " -n, --native Use a native HDF5 type when repacking\n"); + PRINTVALSTREAM(rawoutstream, + " --page-buffer-size=N Set the page buffer cache size, N=non-negative integers\n"); PRINTVALSTREAM(rawoutstream, " --src-vol-value Value (ID) of the VOL connector to use for opening the\n"); PRINTVALSTREAM(rawoutstream, " input HDF5 file specified\n"); @@ -525,11 +529,8 @@ parse_command_line(int argc, const char *const *argv, pack_opt_t *options) h5tools_vol_info_t out_vol_info; h5tools_vfd_info_t in_vfd_info; h5tools_vfd_info_t out_vfd_info; - bool custom_in_vol = false; - bool custom_in_vfd = false; - bool custom_out_vol = false; - bool custom_out_vfd = false; - hid_t tmp_fapl = H5I_INVALID_HID; + hid_t tmp_fapl = H5I_INVALID_HID; + size_t page_cache = 0; int bound, opt; int ret_value = 0; @@ -764,6 +765,10 @@ parse_command_line(int argc, const char *const *argv, pack_opt_t *options) options->fs_pagesize = -1; break; + case 'K': + page_cache = strtoul(H5_optarg, NULL, 0); + break; + case 'q': if (H5_INDEX_UNKNOWN == (sort_by = set_sort_by(H5_optarg))) { error_msg("failed to set sort by form <%s>\n", H5_optarg); @@ -792,13 +797,13 @@ parse_command_line(int argc, const char *const *argv, pack_opt_t *options) case '1': in_vol_info.type = VOL_BY_VALUE; in_vol_info.u.value = (H5VL_class_value_t)atoi(H5_optarg); - custom_in_vol = true; + options->fin_vol = true; break; case '2': in_vol_info.type = VOL_BY_NAME; in_vol_info.u.name = H5_optarg; - custom_in_vol = true; + options->fin_vol = true; break; case '3': @@ -808,13 +813,13 @@ parse_command_line(int argc, const char *const *argv, pack_opt_t *options) case '4': out_vol_info.type = VOL_BY_VALUE; out_vol_info.u.value = (H5VL_class_value_t)atoi(H5_optarg); - custom_out_vol = true; + options->fout_vol = true; break; case '5': out_vol_info.type = VOL_BY_NAME; out_vol_info.u.name = H5_optarg; - custom_out_vol = true; + options->fout_vol = true; break; case '6': @@ -824,13 +829,13 @@ parse_command_line(int argc, const char *const *argv, pack_opt_t *options) case '7': in_vfd_info.type = VFD_BY_VALUE; in_vfd_info.u.value = (H5FD_class_value_t)atoi(H5_optarg); - custom_in_vfd = true; + options->fin_vfd = true; break; case '8': in_vfd_info.type = VFD_BY_NAME; in_vfd_info.u.name = H5_optarg; - custom_in_vfd = true; + options->fin_vfd = true; break; case '9': @@ -840,13 +845,13 @@ parse_command_line(int argc, const char *const *argv, pack_opt_t *options) case '0': out_vfd_info.type = VFD_BY_VALUE; out_vfd_info.u.value = (H5FD_class_value_t)atoi(H5_optarg); - custom_out_vfd = true; + options->fout_vfd = true; break; case 'Y': out_vfd_info.type = VFD_BY_NAME; out_vfd_info.u.name = H5_optarg; - custom_out_vfd = true; + options->fout_vfd = true; break; case 'Z': @@ -903,47 +908,68 @@ parse_command_line(int argc, const char *const *argv, pack_opt_t *options) } /* Setup FAPL for input and output file accesses */ - if (custom_in_vol || custom_in_vfd) { - if ((tmp_fapl = h5tools_get_fapl(options->fin_fapl, custom_in_vol ? &in_vol_info : NULL, - custom_in_vfd ? &in_vfd_info : NULL)) < 0) { - error_msg("failed to setup FAPL for input file\n"); + if ((tmp_fapl = h5tools_get_new_fapl(options->fin_fapl)) < 0) { + error_msg("unable to create FAPL for file access for input file\n"); + h5tools_setstatus(EXIT_FAILURE); + ret_value = -1; + goto done; + } + /* Set non-default VOL connector, if requested */ + if (options->fin_vol) { + if (h5tools_set_fapl_vol(tmp_fapl, &in_vol_info) < 0) { + error_msg("unable to set VOL on 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_vol || custom_out_vfd) { - if ((tmp_fapl = h5tools_get_fapl(options->fout_fapl, custom_out_vol ? &out_vol_info : NULL, - custom_out_vfd ? &out_vfd_info : NULL)) < 0) { - error_msg("failed to setup FAPL for output file\n"); + /* Set non-default virtual file driver, if requested */ + if (options->fin_vfd) { + if (h5tools_set_fapl_vfd(tmp_fapl, &in_vfd_info) < 0) { + error_msg("unable to set VFD on fapl for input file\n"); + h5tools_setstatus(EXIT_FAILURE); + ret_value = -1; + goto done; + } + } + if (page_cache > 0) { + if (H5Pset_page_buffer_size(tmp_fapl, page_cache, 0, 0) < 0) { + error_msg("unable to set page buffer cache size for input 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->fin_fapl = tmp_fapl; - options->fout_fapl = tmp_fapl; + /* Setup FAPL for input and output file accesses */ + if ((tmp_fapl = h5tools_get_new_fapl(options->fout_fapl)) < 0) { + error_msg("unable to create FAPL for file access for output file\n"); + h5tools_setstatus(EXIT_FAILURE); + ret_value = -1; + goto done; } + /* Set non-default VOL connector, if requested */ + if (options->fout_vol) { + if (h5tools_set_fapl_vol(tmp_fapl, &out_vol_info) < 0) { + error_msg("unable to set VOL on fapl for output file\n"); + h5tools_setstatus(EXIT_FAILURE); + ret_value = -1; + goto done; + } + } + /* Set non-default virtual file driver, if requested */ + if (options->fout_vfd) { + if (h5tools_set_fapl_vfd(tmp_fapl, &out_vfd_info) < 0) { + error_msg("unable to set VFD on fapl for output file\n"); + h5tools_setstatus(EXIT_FAILURE); + ret_value = -1; + goto done; + } + } + + options->fout_fapl = tmp_fapl; done: return ret_value; diff --git a/tools/src/h5repack/h5repack_verify.c b/tools/src/h5repack/h5repack_verify.c index 819dd94ab26..50604e055cb 100644 --- a/tools/src/h5repack/h5repack_verify.c +++ b/tools/src/h5repack/h5repack_verify.c @@ -356,7 +356,7 @@ verify_layout(hid_t pid, pack_info_t *obj) */ int -h5repack_cmp_pl(const char *fname1, hid_t fname1_fapl, const char *fname2, hid_t fname2_fapl) +h5repack_cmp_pl(const char *fname1, const char *fname2, pack_opt_t *options) { hid_t fid1 = H5I_INVALID_HID; /* file ID */ hid_t fid2 = H5I_INVALID_HID; /* file ID */ @@ -377,11 +377,11 @@ h5repack_cmp_pl(const char *fname1, hid_t fname1_fapl, const char *fname2, hid_t *------------------------------------------------------------------------- */ /* Open the files */ - if ((fid1 = h5tools_fopen(fname1, H5F_ACC_RDONLY, fname1_fapl, (fname1_fapl != H5P_DEFAULT), NULL, 0)) < - 0) + if ((fid1 = h5tools_fopen(fname1, H5F_ACC_RDONLY, options->fin_fapl, + (options->fin_vol || options->fin_vfd), NULL, 0)) < 0) H5TOOLS_GOTO_ERROR((-1), "h5tools_fopen failed <%s>: %s", fname1, H5FOPENERROR); - if ((fid2 = h5tools_fopen(fname2, H5F_ACC_RDONLY, fname2_fapl, (fname2_fapl != H5P_DEFAULT), NULL, 0)) < - 0) + if ((fid2 = h5tools_fopen(fname2, H5F_ACC_RDONLY, options->fout_fapl, + (options->fout_vol || options->fout_vfd), 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 a90ef5e5e8f..71c507801ee 100644 --- a/tools/src/h5stat/h5stat.c +++ b/tools/src/h5stat/h5stat.c @@ -117,6 +117,8 @@ typedef struct iter_t { static const char *drivername = NULL; +size_t page_cache = 0; + #ifdef H5_HAVE_ROS3_VFD /* Default "anonymous" S3 configuration */ static H5FD_ros3_fapl_ext_t ros3_fa = { @@ -171,7 +173,7 @@ struct handler_t { char **obj; }; -static const char *s_opts = "Aa:Ddm:E*FfhGgl:sSTO:Vw:H:"; +static const char *s_opts = "Aa:Ddm:E*FfhGgl:K:sSTO:Vw:H:"; /* e.g. "filemetadata" has to precede "file"; "groupmetadata" has to precede "group" etc. */ static struct h5_long_options l_opts[] = {{"help", no_arg, 'h'}, {"filemetadata", no_arg, 'F'}, @@ -187,6 +189,7 @@ static struct h5_long_options l_opts[] = {{"help", no_arg, 'h'}, {"numattrs", require_arg, 'a'}, {"freespace", no_arg, 's'}, {"summary", no_arg, 'S'}, + {"page-buffer-size", require_arg, 'K'}, {"s3-cred", require_arg, 'w'}, {"hdfs-attrs", require_arg, 'H'}, {NULL, 0, '\0'}}; @@ -239,6 +242,7 @@ usage(const char *prog) fprintf(stdout, " than 0. The default threshold is 10.\n"); fprintf(stdout, " -s, --freespace Print free space information\n"); fprintf(stdout, " -S, --summary Print summary of file space information\n"); + fprintf(stdout, " --page-buffer-size=N Set the page buffer cache size, N=non-negative integers\n"); fprintf(stdout, " --s3-cred= Access file on S3, using provided credential\n"); fprintf(stdout, " :: (region,id,key)\n"); fprintf(stdout, " If == \"(,,)\", no authentication is used.\n"); @@ -967,6 +971,10 @@ parse_command_line(int argc, const char *const *argv, struct handler_t **hand_re #endif break; + case 'K': + page_cache = strtoul(H5_optarg, NULL, 0); + break; + default: usage(h5tools_getprogname()); goto error; @@ -1618,6 +1626,11 @@ main(int argc, char *argv[]) /* enable error reporting if command line option */ h5tools_error_report(); + if ((fapl_id = h5tools_get_new_fapl(H5P_DEFAULT)) < 0) { + error_msg("unable to create FAPL for file access\n"); + h5tools_setstatus(EXIT_FAILURE); + goto done; + } if (drivername) { h5tools_vfd_info_t vfd_info; @@ -1634,8 +1647,17 @@ main(int argc, char *argv[]) vfd_info.info = &hdfs_fa; #endif - if ((fapl_id = h5tools_get_fapl(H5P_DEFAULT, NULL, &vfd_info)) < 0) { - error_msg("Unable to create FAPL for file access\n"); + /* Set non-default virtual file driver, if requested */ + if (h5tools_set_fapl_vfd(fapl_id, &vfd_info) < 0) { + error_msg("unable to set VFD on fapl for file\n"); + h5tools_setstatus(EXIT_FAILURE); + goto done; + } + } + if (page_cache > 0) { + if (H5Pset_page_buffer_size(fapl_id, page_cache, 0, 0) < 0) { + error_msg("unable to set page buffer cache size for file access\n"); + h5tools_setstatus(EXIT_FAILURE); goto done; } } @@ -1649,7 +1671,7 @@ main(int argc, char *argv[]) printf("Filename: %s\n", fname); - fid = h5tools_fopen(fname, H5F_ACC_RDONLY, fapl_id, (fapl_id != H5P_DEFAULT), NULL, 0); + fid = h5tools_fopen(fname, H5F_ACC_RDONLY, fapl_id, (drivername != NULL), NULL, 0); if (fid < 0) { error_msg("unable to open file \"%s\"\n", fname); diff --git a/tools/src/misc/h5mkgrp.c b/tools/src/misc/h5mkgrp.c index 92e30423661..b96251991b5 100644 --- a/tools/src/misc/h5mkgrp.c +++ b/tools/src/misc/h5mkgrp.c @@ -30,13 +30,15 @@ static struct h5_long_options l_opts[] = { /* Command line parameter settings */ typedef struct mkgrp_opt_t { - char *fname; /* File name to operate on */ - bool latest; /* Whether file should use latest format versions */ - bool verbose; /* Whether output should be verbose */ - bool parents; /* Whether to create intermediate groups */ - size_t ngroups; /* Number of groups to create */ - char **groups; /* Pointer to array of group names */ - hid_t fapl_id; /* fapl to use when opening the file */ + char *fname; /* File name to operate on */ + bool latest; /* Whether file should use latest format versions */ + bool verbose; /* Whether output should be verbose */ + bool parents; /* Whether to create intermediate groups */ + size_t ngroups; /* Number of groups to create */ + char **groups; /* Pointer to array of group names */ + hid_t fapl_id; /* fapl to use when opening the file */ + bool custom_vol; /* Whether fapl uses custom VOL */ + bool custom_vfd; /* Whether fapl uses custom VFD */ } mkgrp_opt_t; static mkgrp_opt_t params_g; /* Command line parameter settings */ @@ -135,8 +137,6 @@ parse_command_line(int argc, const char *const *argv, mkgrp_opt_t *options) { int opt; /* Option from command line */ size_t curr_group; /* Current group name to copy */ - bool custom_vol = false; - bool custom_vfd = false; h5tools_vol_info_t vol_info; h5tools_vfd_info_t vfd_info; hid_t tmp_fapl_id = H5I_INVALID_HID; @@ -182,15 +182,15 @@ parse_command_line(int argc, const char *const *argv, mkgrp_opt_t *options) break; case '1': - vol_info.type = VOL_BY_VALUE; - vol_info.u.value = (H5VL_class_value_t)atoi(H5_optarg); - custom_vol = true; + vol_info.type = VOL_BY_VALUE; + vol_info.u.value = (H5VL_class_value_t)atoi(H5_optarg); + options->custom_vol = true; break; case '2': - vol_info.type = VOL_BY_NAME; - vol_info.u.name = H5_optarg; - custom_vol = true; + vol_info.type = VOL_BY_NAME; + vol_info.u.name = H5_optarg; + options->custom_vol = true; break; case '3': @@ -198,15 +198,15 @@ parse_command_line(int argc, const char *const *argv, mkgrp_opt_t *options) break; case '4': - vfd_info.type = VFD_BY_VALUE; - vfd_info.u.value = (H5FD_class_value_t)atoi(H5_optarg); - custom_vfd = true; + vfd_info.type = VFD_BY_VALUE; + vfd_info.u.value = (H5FD_class_value_t)atoi(H5_optarg); + options->custom_vfd = true; break; case '5': - vfd_info.type = VFD_BY_NAME; - vfd_info.u.name = H5_optarg; - custom_vfd = true; + vfd_info.type = VFD_BY_NAME; + vfd_info.u.name = H5_optarg; + options->custom_vfd = true; break; case '6': @@ -251,19 +251,25 @@ parse_command_line(int argc, const char *const *argv, mkgrp_opt_t *options) } /* Setup a custom fapl for file accesses */ - if (custom_vol || custom_vfd) { - if ((tmp_fapl_id = h5tools_get_fapl(options->fapl_id, custom_vol ? &vol_info : NULL, - custom_vfd ? &vfd_info : NULL)) < 0) { - error_msg("failed to setup file access property list (fapl) for file\n"); + if (options->custom_vol || options->custom_vfd) { + if ((tmp_fapl_id = h5tools_get_new_fapl(options->fapl_id)) < 0) { + error_msg("unable to create FAPL for file access\n"); leave(EXIT_FAILURE); } - - /* Close the old fapl */ - if (options->fapl_id != H5P_DEFAULT) - if (H5Pclose(options->fapl_id) < 0) { - error_msg("failed to close file access property list (fapl)\n"); + /* Set non-default VOL connector, if requested */ + if (options->custom_vol) { + if (h5tools_set_fapl_vol(tmp_fapl_id, &vol_info) < 0) { + error_msg("unable to set VOL on fapl for file\n"); leave(EXIT_FAILURE); } + } + /* Set non-default virtual file driver, if requested */ + if (options->custom_vfd) { + if (h5tools_set_fapl_vfd(tmp_fapl_id, &vfd_info) < 0) { + error_msg("unable to set VFD on fapl for file\n"); + leave(EXIT_FAILURE); + } + } options->fapl_id = tmp_fapl_id; } @@ -323,8 +329,8 @@ main(int argc, char *argv[]) } /* Attempt to open an existing HDF5 file first */ - fid = h5tools_fopen(params_g.fname, H5F_ACC_RDWR, params_g.fapl_id, (params_g.fapl_id != H5P_DEFAULT), - NULL, 0); + fid = h5tools_fopen(params_g.fname, H5F_ACC_RDWR, params_g.fapl_id, + (params_g.custom_vol || params_g.custom_vfd), 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/h5diff/expected/h5diff_10.txt b/tools/test/h5diff/expected/h5diff_10.txt index a30da23a8fe..30a62550fd9 100644 --- a/tools/test/h5diff/expected/h5diff_10.txt +++ b/tools/test/h5diff/expected/h5diff_10.txt @@ -25,6 +25,7 @@ usage: h5diff [OPTIONS] file1 file2 [obj1[ obj2]] 3 : All level 2 information plus file names. -q, --quiet Quiet mode. Do not produce output. + --page-buffer-size=N Set the page buffer cache size, N=non-negative integers --vol-value-1 Value (ID) of the VOL connector to use for opening the first HDF5 file specified --vol-name-1 Name of the VOL connector to use for opening the first diff --git a/tools/test/h5diff/expected/h5diff_600.txt b/tools/test/h5diff/expected/h5diff_600.txt index bdb7788af7d..5a081f96b3a 100644 --- a/tools/test/h5diff/expected/h5diff_600.txt +++ b/tools/test/h5diff/expected/h5diff_600.txt @@ -25,6 +25,7 @@ usage: h5diff [OPTIONS] file1 file2 [obj1[ obj2]] 3 : All level 2 information plus file names. -q, --quiet Quiet mode. Do not produce output. + --page-buffer-size=N Set the page buffer cache size, N=non-negative integers --vol-value-1 Value (ID) of the VOL connector to use for opening the first HDF5 file specified --vol-name-1 Name of the VOL connector to use for opening the first diff --git a/tools/test/h5diff/expected/h5diff_603.txt b/tools/test/h5diff/expected/h5diff_603.txt index ce1577c5f82..12e67ddb02b 100644 --- a/tools/test/h5diff/expected/h5diff_603.txt +++ b/tools/test/h5diff/expected/h5diff_603.txt @@ -26,6 +26,7 @@ usage: h5diff [OPTIONS] file1 file2 [obj1[ obj2]] 3 : All level 2 information plus file names. -q, --quiet Quiet mode. Do not produce output. + --page-buffer-size=N Set the page buffer cache size, N=non-negative integers --vol-value-1 Value (ID) of the VOL connector to use for opening the first HDF5 file specified --vol-name-1 Name of the VOL connector to use for opening the first diff --git a/tools/test/h5diff/expected/h5diff_606.txt b/tools/test/h5diff/expected/h5diff_606.txt index 9ee22448c5b..1d04cb92f53 100644 --- a/tools/test/h5diff/expected/h5diff_606.txt +++ b/tools/test/h5diff/expected/h5diff_606.txt @@ -26,6 +26,7 @@ usage: h5diff [OPTIONS] file1 file2 [obj1[ obj2]] 3 : All level 2 information plus file names. -q, --quiet Quiet mode. Do not produce output. + --page-buffer-size=N Set the page buffer cache size, N=non-negative integers --vol-value-1 Value (ID) of the VOL connector to use for opening the first HDF5 file specified --vol-name-1 Name of the VOL connector to use for opening the first diff --git a/tools/test/h5diff/expected/h5diff_612.txt b/tools/test/h5diff/expected/h5diff_612.txt index fee63aaed28..130970a1f45 100644 --- a/tools/test/h5diff/expected/h5diff_612.txt +++ b/tools/test/h5diff/expected/h5diff_612.txt @@ -26,6 +26,7 @@ usage: h5diff [OPTIONS] file1 file2 [obj1[ obj2]] 3 : All level 2 information plus file names. -q, --quiet Quiet mode. Do not produce output. + --page-buffer-size=N Set the page buffer cache size, N=non-negative integers --vol-value-1 Value (ID) of the VOL connector to use for opening the first HDF5 file specified --vol-name-1 Name of the VOL connector to use for opening the first diff --git a/tools/test/h5diff/expected/h5diff_615.txt b/tools/test/h5diff/expected/h5diff_615.txt index 562308aaa9a..9c086bf2360 100644 --- a/tools/test/h5diff/expected/h5diff_615.txt +++ b/tools/test/h5diff/expected/h5diff_615.txt @@ -26,6 +26,7 @@ usage: h5diff [OPTIONS] file1 file2 [obj1[ obj2]] 3 : All level 2 information plus file names. -q, --quiet Quiet mode. Do not produce output. + --page-buffer-size=N Set the page buffer cache size, N=non-negative integers --vol-value-1 Value (ID) of the VOL connector to use for opening the first HDF5 file specified --vol-name-1 Name of the VOL connector to use for opening the first diff --git a/tools/test/h5diff/expected/h5diff_621.txt b/tools/test/h5diff/expected/h5diff_621.txt index 03b69bba232..c76aae8b347 100644 --- a/tools/test/h5diff/expected/h5diff_621.txt +++ b/tools/test/h5diff/expected/h5diff_621.txt @@ -26,6 +26,7 @@ usage: h5diff [OPTIONS] file1 file2 [obj1[ obj2]] 3 : All level 2 information plus file names. -q, --quiet Quiet mode. Do not produce output. + --page-buffer-size=N Set the page buffer cache size, N=non-negative integers --vol-value-1 Value (ID) of the VOL connector to use for opening the first HDF5 file specified --vol-name-1 Name of the VOL connector to use for opening the first diff --git a/tools/test/h5diff/expected/h5diff_622.txt b/tools/test/h5diff/expected/h5diff_622.txt index 05e6b94c502..99f396aa40d 100644 --- a/tools/test/h5diff/expected/h5diff_622.txt +++ b/tools/test/h5diff/expected/h5diff_622.txt @@ -26,6 +26,7 @@ usage: h5diff [OPTIONS] file1 file2 [obj1[ obj2]] 3 : All level 2 information plus file names. -q, --quiet Quiet mode. Do not produce output. + --page-buffer-size=N Set the page buffer cache size, N=non-negative integers --vol-value-1 Value (ID) of the VOL connector to use for opening the first HDF5 file specified --vol-name-1 Name of the VOL connector to use for opening the first diff --git a/tools/test/h5diff/expected/h5diff_623.txt b/tools/test/h5diff/expected/h5diff_623.txt index d2e81fa8f47..3490630de93 100644 --- a/tools/test/h5diff/expected/h5diff_623.txt +++ b/tools/test/h5diff/expected/h5diff_623.txt @@ -26,6 +26,7 @@ usage: h5diff [OPTIONS] file1 file2 [obj1[ obj2]] 3 : All level 2 information plus file names. -q, --quiet Quiet mode. Do not produce output. + --page-buffer-size=N Set the page buffer cache size, N=non-negative integers --vol-value-1 Value (ID) of the VOL connector to use for opening the first HDF5 file specified --vol-name-1 Name of the VOL connector to use for opening the first diff --git a/tools/test/h5diff/expected/h5diff_624.txt b/tools/test/h5diff/expected/h5diff_624.txt index 94e6b4ef8af..f6ff568800e 100644 --- a/tools/test/h5diff/expected/h5diff_624.txt +++ b/tools/test/h5diff/expected/h5diff_624.txt @@ -26,6 +26,7 @@ usage: h5diff [OPTIONS] file1 file2 [obj1[ obj2]] 3 : All level 2 information plus file names. -q, --quiet Quiet mode. Do not produce output. + --page-buffer-size=N Set the page buffer cache size, N=non-negative integers --vol-value-1 Value (ID) of the VOL connector to use for opening the first HDF5 file specified --vol-name-1 Name of the VOL connector to use for opening the first diff --git a/tools/test/h5dump/CMakeTests.cmake b/tools/test/h5dump/CMakeTests.cmake index 546cfcbf011..05f3648eb57 100644 --- a/tools/test/h5dump/CMakeTests.cmake +++ b/tools/test/h5dump/CMakeTests.cmake @@ -23,6 +23,7 @@ charsets.ddl err_attr_dspace.ddl file_space.ddl + file_space_cache.ddl filter_fail.ddl non_existing.ddl infinite_loop.ddl @@ -1187,6 +1188,7 @@ ADD_H5_TEST (tboot2A 0 --enable-error-stack --boot-block tfcontents2.h5) ADD_H5_TEST (tboot2B 0 --enable-error-stack --superblock tfcontents2.h5) ADD_H5_TEST (file_space 0 --enable-error-stack -B file_space.h5) + ADD_H5_TEST (file_space_cache 0 --enable-error-stack=2 --page-buffer-size=16384 -B file_space.h5) # test -p with a non existing dataset ADD_H5ERR_MASK_TEST (tperror 1 "h5dump error: unable to get link info from \"bogus\"" --enable-error-stack -p -d bogus tfcontents1.h5) diff --git a/tools/test/h5dump/expected/file_space_cache.ddl b/tools/test/h5dump/expected/file_space_cache.ddl new file mode 100644 index 00000000000..6b8aa476a19 --- /dev/null +++ b/tools/test/h5dump/expected/file_space_cache.ddl @@ -0,0 +1,22 @@ +HDF5 "file_space.h5" { +SUPER_BLOCK { + SUPERBLOCK_VERSION 2 + FREELIST_VERSION 0 + SYMBOLTABLE_VERSION 0 + OBJECTHEADER_VERSION 0 + OFFSET_SIZE 8 + LENGTH_SIZE 8 + BTREE_RANK 16 + BTREE_LEAF 4 + ISTORE_K 32 + FILE_SPACE_STRATEGY H5F_FSPACE_STRATEGY_NONE + FREE_SPACE_PERSIST FALSE + FREE_SPACE_SECTION_THRESHOLD 1 + FILE_SPACE_PAGE_SIZE 8192 + USER_BLOCK { + USERBLOCK_SIZE 0 + } +} +GROUP "/" { +} +} diff --git a/tools/test/h5dump/expected/h5dump-help.txt b/tools/test/h5dump/expected/h5dump-help.txt index 45beb63d23b..a78d8d820ec 100644 --- a/tools/test/h5dump/expected/h5dump-help.txt +++ b/tools/test/h5dump/expected/h5dump-help.txt @@ -16,6 +16,7 @@ usage: h5dump [OPTIONS] files -b B, --binary=B Binary file output, of form B -O F, --ddl=F Output ddl text into file F Use blank(empty) filename F to suppress ddl display + --page-buffer-size=N Set the page buffer cache size, N=non-negative integers --s3-cred= Supply S3 authentication information to "ros3" vfd. :: "(,,)" If absent or -> "(,,)", no authentication. diff --git a/tools/test/h5dump/expected/pbits/tnofilename-with-packed-bits.ddl b/tools/test/h5dump/expected/pbits/tnofilename-with-packed-bits.ddl index 45beb63d23b..a78d8d820ec 100644 --- a/tools/test/h5dump/expected/pbits/tnofilename-with-packed-bits.ddl +++ b/tools/test/h5dump/expected/pbits/tnofilename-with-packed-bits.ddl @@ -16,6 +16,7 @@ usage: h5dump [OPTIONS] files -b B, --binary=B Binary file output, of form B -O F, --ddl=F Output ddl text into file F Use blank(empty) filename F to suppress ddl display + --page-buffer-size=N Set the page buffer cache size, N=non-negative integers --s3-cred= Supply S3 authentication information to "ros3" vfd. :: "(,,)" If absent or -> "(,,)", no authentication. diff --git a/tools/test/h5dump/expected/pbits/tpbitsIncomplete.ddl b/tools/test/h5dump/expected/pbits/tpbitsIncomplete.ddl index 45beb63d23b..a78d8d820ec 100644 --- a/tools/test/h5dump/expected/pbits/tpbitsIncomplete.ddl +++ b/tools/test/h5dump/expected/pbits/tpbitsIncomplete.ddl @@ -16,6 +16,7 @@ usage: h5dump [OPTIONS] files -b B, --binary=B Binary file output, of form B -O F, --ddl=F Output ddl text into file F Use blank(empty) filename F to suppress ddl display + --page-buffer-size=N Set the page buffer cache size, N=non-negative integers --s3-cred= Supply S3 authentication information to "ros3" vfd. :: "(,,)" If absent or -> "(,,)", no authentication. diff --git a/tools/test/h5dump/expected/pbits/tpbitsLengthExceeded.ddl b/tools/test/h5dump/expected/pbits/tpbitsLengthExceeded.ddl index 45beb63d23b..a78d8d820ec 100644 --- a/tools/test/h5dump/expected/pbits/tpbitsLengthExceeded.ddl +++ b/tools/test/h5dump/expected/pbits/tpbitsLengthExceeded.ddl @@ -16,6 +16,7 @@ usage: h5dump [OPTIONS] files -b B, --binary=B Binary file output, of form B -O F, --ddl=F Output ddl text into file F Use blank(empty) filename F to suppress ddl display + --page-buffer-size=N Set the page buffer cache size, N=non-negative integers --s3-cred= Supply S3 authentication information to "ros3" vfd. :: "(,,)" If absent or -> "(,,)", no authentication. diff --git a/tools/test/h5dump/expected/pbits/tpbitsLengthPositive.ddl b/tools/test/h5dump/expected/pbits/tpbitsLengthPositive.ddl index 45beb63d23b..a78d8d820ec 100644 --- a/tools/test/h5dump/expected/pbits/tpbitsLengthPositive.ddl +++ b/tools/test/h5dump/expected/pbits/tpbitsLengthPositive.ddl @@ -16,6 +16,7 @@ usage: h5dump [OPTIONS] files -b B, --binary=B Binary file output, of form B -O F, --ddl=F Output ddl text into file F Use blank(empty) filename F to suppress ddl display + --page-buffer-size=N Set the page buffer cache size, N=non-negative integers --s3-cred= Supply S3 authentication information to "ros3" vfd. :: "(,,)" If absent or -> "(,,)", no authentication. diff --git a/tools/test/h5dump/expected/pbits/tpbitsMaxExceeded.ddl b/tools/test/h5dump/expected/pbits/tpbitsMaxExceeded.ddl index 45beb63d23b..a78d8d820ec 100644 --- a/tools/test/h5dump/expected/pbits/tpbitsMaxExceeded.ddl +++ b/tools/test/h5dump/expected/pbits/tpbitsMaxExceeded.ddl @@ -16,6 +16,7 @@ usage: h5dump [OPTIONS] files -b B, --binary=B Binary file output, of form B -O F, --ddl=F Output ddl text into file F Use blank(empty) filename F to suppress ddl display + --page-buffer-size=N Set the page buffer cache size, N=non-negative integers --s3-cred= Supply S3 authentication information to "ros3" vfd. :: "(,,)" If absent or -> "(,,)", no authentication. diff --git a/tools/test/h5dump/expected/pbits/tpbitsOffsetExceeded.ddl b/tools/test/h5dump/expected/pbits/tpbitsOffsetExceeded.ddl index 45beb63d23b..a78d8d820ec 100644 --- a/tools/test/h5dump/expected/pbits/tpbitsOffsetExceeded.ddl +++ b/tools/test/h5dump/expected/pbits/tpbitsOffsetExceeded.ddl @@ -16,6 +16,7 @@ usage: h5dump [OPTIONS] files -b B, --binary=B Binary file output, of form B -O F, --ddl=F Output ddl text into file F Use blank(empty) filename F to suppress ddl display + --page-buffer-size=N Set the page buffer cache size, N=non-negative integers --s3-cred= Supply S3 authentication information to "ros3" vfd. :: "(,,)" If absent or -> "(,,)", no authentication. diff --git a/tools/test/h5dump/expected/pbits/tpbitsOffsetNegative.ddl b/tools/test/h5dump/expected/pbits/tpbitsOffsetNegative.ddl index 45beb63d23b..a78d8d820ec 100644 --- a/tools/test/h5dump/expected/pbits/tpbitsOffsetNegative.ddl +++ b/tools/test/h5dump/expected/pbits/tpbitsOffsetNegative.ddl @@ -16,6 +16,7 @@ usage: h5dump [OPTIONS] files -b B, --binary=B Binary file output, of form B -O F, --ddl=F Output ddl text into file F Use blank(empty) filename F to suppress ddl display + --page-buffer-size=N Set the page buffer cache size, N=non-negative integers --s3-cred= Supply S3 authentication information to "ros3" vfd. :: "(,,)" If absent or -> "(,,)", no authentication. diff --git a/tools/test/h5dump/testh5dump.sh.in b/tools/test/h5dump/testh5dump.sh.in index efada14934f..6a60785e959 100644 --- a/tools/test/h5dump/testh5dump.sh.in +++ b/tools/test/h5dump/testh5dump.sh.in @@ -198,6 +198,7 @@ $SRC_H5DUMP_TESTFILES/tst_onion_dset_1d.h5.onion LIST_OTHER_TEST_FILES=" $SRC_H5DUMP_OUTFILES/charsets.ddl $SRC_H5DUMP_OUTFILES/file_space.ddl +$SRC_H5DUMP_OUTFILES/file_space_cache.ddl $SRC_H5DUMP_OUTFILES/filter_fail.ddl $SRC_H5DUMP_OUTFILES/non_existing.ddl $SRC_H5DUMP_OUTFILES/infinite_loop.ddl @@ -1254,6 +1255,7 @@ TOOLTEST tboot2.ddl --enable-error-stack -B tfcontents2.h5 TOOLTEST tboot2A.ddl --enable-error-stack --boot-block tfcontents2.h5 TOOLTEST tboot2B.ddl --enable-error-stack --superblock tfcontents2.h5 TOOLTEST file_space.ddl --enable-error-stack -B file_space.h5 +TOOLTEST file_space_cache.ddl --enable-error-stack=2 --page-buffer-size=16384 -B file_space.h5 # test -p with a non existing dataset GREPTEST ERRTXT "h5dump error: unable to get link info from" tperror.ddl --enable-error-stack -p -d bogus tfcontents1.h5 diff --git a/tools/test/h5ls/CMakeTests.cmake b/tools/test/h5ls/CMakeTests.cmake index e47c254f465..f9a489f96f0 100644 --- a/tools/test/h5ls/CMakeTests.cmake +++ b/tools/test/h5ls/CMakeTests.cmake @@ -258,6 +258,9 @@ ADD_H5_TEST (tgroup 0 -w80 tgroup.h5) ADD_H5_TEST (tgroup-3 0 -w80 tgroup.h5/g1) + # test page buffer cache command + ADD_H5_TEST (tall-pbc 0 -w80 --page-buffer-size=8192 tall.h5) + # test for displaying groups # The following combination of arguments is expected to return an error message # and return value 1 diff --git a/tools/test/h5ls/expected/help-1.ls b/tools/test/h5ls/expected/help-1.ls index 1cf733bc3a3..668f34aabe6 100644 --- a/tools/test/h5ls/expected/help-1.ls +++ b/tools/test/h5ls/expected/help-1.ls @@ -35,6 +35,7 @@ usage: h5ls [OPTIONS] file[/OBJECT] [file[/[OBJECT]...] -wN, --width=N Set the number of columns of output -v, --verbose Generate more verbose output -V, --version Print version number and exit + --page-buffer-size=N Set the page buffer cache size, N=non-negative integers --vfd=DRIVER Use the specified virtual file driver -x, --hexdump Show raw data in hexadecimal format --s3-cred=C Supply S3 authentication information to "ros3" vfd. diff --git a/tools/test/h5ls/expected/help-2.ls b/tools/test/h5ls/expected/help-2.ls index 1cf733bc3a3..668f34aabe6 100644 --- a/tools/test/h5ls/expected/help-2.ls +++ b/tools/test/h5ls/expected/help-2.ls @@ -35,6 +35,7 @@ usage: h5ls [OPTIONS] file[/OBJECT] [file[/[OBJECT]...] -wN, --width=N Set the number of columns of output -v, --verbose Generate more verbose output -V, --version Print version number and exit + --page-buffer-size=N Set the page buffer cache size, N=non-negative integers --vfd=DRIVER Use the specified virtual file driver -x, --hexdump Show raw data in hexadecimal format --s3-cred=C Supply S3 authentication information to "ros3" vfd. diff --git a/tools/test/h5ls/expected/help-3.ls b/tools/test/h5ls/expected/help-3.ls index 1cf733bc3a3..668f34aabe6 100644 --- a/tools/test/h5ls/expected/help-3.ls +++ b/tools/test/h5ls/expected/help-3.ls @@ -35,6 +35,7 @@ usage: h5ls [OPTIONS] file[/OBJECT] [file[/[OBJECT]...] -wN, --width=N Set the number of columns of output -v, --verbose Generate more verbose output -V, --version Print version number and exit + --page-buffer-size=N Set the page buffer cache size, N=non-negative integers --vfd=DRIVER Use the specified virtual file driver -x, --hexdump Show raw data in hexadecimal format --s3-cred=C Supply S3 authentication information to "ros3" vfd. diff --git a/tools/test/h5ls/expected/textlinksrc-nodangle-1.ls b/tools/test/h5ls/expected/textlinksrc-nodangle-1.ls index 1cf733bc3a3..668f34aabe6 100644 --- a/tools/test/h5ls/expected/textlinksrc-nodangle-1.ls +++ b/tools/test/h5ls/expected/textlinksrc-nodangle-1.ls @@ -35,6 +35,7 @@ usage: h5ls [OPTIONS] file[/OBJECT] [file[/[OBJECT]...] -wN, --width=N Set the number of columns of output -v, --verbose Generate more verbose output -V, --version Print version number and exit + --page-buffer-size=N Set the page buffer cache size, N=non-negative integers --vfd=DRIVER Use the specified virtual file driver -x, --hexdump Show raw data in hexadecimal format --s3-cred=C Supply S3 authentication information to "ros3" vfd. diff --git a/tools/test/h5ls/expected/tgroup-1.ls b/tools/test/h5ls/expected/tgroup-1.ls index 1cf733bc3a3..668f34aabe6 100644 --- a/tools/test/h5ls/expected/tgroup-1.ls +++ b/tools/test/h5ls/expected/tgroup-1.ls @@ -35,6 +35,7 @@ usage: h5ls [OPTIONS] file[/OBJECT] [file[/[OBJECT]...] -wN, --width=N Set the number of columns of output -v, --verbose Generate more verbose output -V, --version Print version number and exit + --page-buffer-size=N Set the page buffer cache size, N=non-negative integers --vfd=DRIVER Use the specified virtual file driver -x, --hexdump Show raw data in hexadecimal format --s3-cred=C Supply S3 authentication information to "ros3" vfd. diff --git a/tools/test/h5repack/expected/h5repack-help.txt b/tools/test/h5repack/expected/h5repack-help.txt index bff70afdb08..ae655feccd0 100644 --- a/tools/test/h5repack/expected/h5repack-help.txt +++ b/tools/test/h5repack/expected/h5repack-help.txt @@ -10,6 +10,7 @@ usage: h5repack [OPTIONS] file1 file2 N - is an integer greater than 1, 2 displays read/write timing -V, --version Print version number and exit -n, --native Use a native HDF5 type when repacking + --page-buffer-size=N Set the page buffer cache size, N=non-negative integers --src-vol-value Value (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 diff --git a/tools/test/h5repack/h5repacktst.c b/tools/test/h5repack/h5repacktst.c index f3b84c4d1fd..62d3a948c92 100644 --- a/tools/test/h5repack/h5repacktst.c +++ b/tools/test/h5repack/h5repacktst.c @@ -384,7 +384,7 @@ main(void) GOERROR; if (h5repack_verify(FNAME0, FNAME0OUT, &pack_options) <= 0) GOERROR; - if (h5repack_cmp_pl(FNAME0, pack_options.fin_fapl, FNAME0OUT, pack_options.fout_fapl) <= 0) + if (h5repack_cmp_pl(FNAME0, FNAME0OUT, &pack_options) <= 0) GOERROR; if (h5repack_end(&pack_options) < 0) GOERROR; @@ -404,7 +404,7 @@ main(void) GOERROR; if (h5repack_verify(FNAME1, FNAME1OUT, &pack_options) <= 0) GOERROR; - if (h5repack_cmp_pl(FNAME1, pack_options.fin_fapl, FNAME1OUT, pack_options.fout_fapl) <= 0) + if (h5repack_cmp_pl(FNAME1, FNAME1OUT, &pack_options) <= 0) GOERROR; if (h5repack_end(&pack_options) < 0) GOERROR; @@ -424,7 +424,7 @@ main(void) GOERROR; if (h5repack_verify(FNAME2, FNAME2OUT, &pack_options) <= 0) GOERROR; - if (h5repack_cmp_pl(FNAME2, pack_options.fin_fapl, FNAME2OUT, pack_options.fout_fapl) <= 0) + if (h5repack_cmp_pl(FNAME2, FNAME2OUT, &pack_options) <= 0) GOERROR; if (h5repack_end(&pack_options) < 0) GOERROR; @@ -443,7 +443,7 @@ main(void) GOERROR; if (h5repack_verify(FNAME3, FNAME3OUT, &pack_options) <= 0) GOERROR; - if (h5repack_cmp_pl(FNAME3, pack_options.fin_fapl, FNAME3OUT, pack_options.fout_fapl) <= 0) + if (h5repack_cmp_pl(FNAME3, FNAME3OUT, &pack_options) <= 0) GOERROR; if (h5repack_end(&pack_options) < 0) GOERROR; @@ -1127,7 +1127,7 @@ main(void) GOERROR; if (h5repack_verify(FNAME7, FNAME7OUT, &pack_options) <= 0) GOERROR; - if (h5repack_cmp_pl(FNAME7, pack_options.fin_fapl, FNAME7OUT, pack_options.fout_fapl) <= 0) + if (h5repack_cmp_pl(FNAME7, FNAME7OUT, &pack_options) <= 0) GOERROR; if (h5repack_end(&pack_options) < 0) GOERROR; diff --git a/tools/test/h5stat/CMakeTests.cmake b/tools/test/h5stat/CMakeTests.cmake index f6287406ee8..943551b4bec 100644 --- a/tools/test/h5stat/CMakeTests.cmake +++ b/tools/test/h5stat/CMakeTests.cmake @@ -28,6 +28,7 @@ h5stat_notexist h5stat_nofile h5stat_filters + h5stat_filters-cache h5stat_filters-file h5stat_filters-F h5stat_filters-d @@ -192,6 +193,8 @@ ADD_H5_TEST (h5stat_filters-dT 0 -dT h5stat_filters.h5) ADD_H5_TEST (h5stat_filters-UD 0 -D h5stat_filters.h5) ADD_H5_TEST (h5stat_filters-UT 0 -T h5stat_filters.h5) +# Test for page buffer cache size option + ADD_H5_TEST (h5stat_filters-cache 0 --enable-error-stack=2 --page-buffer-size=8192 h5stat_filters.h5) # h5stat_tsohm.h5 is a copy of ../../../test/tsohm.h5 generated by tsohm.c # as of release 1.8.7-snap0 (on a 64-bit machine) ADD_H5_TEST (h5stat_tsohm 0 h5stat_tsohm.h5) diff --git a/tools/test/h5stat/expected/h5stat_filters-cache.ddl b/tools/test/h5stat/expected/h5stat_filters-cache.ddl new file mode 100644 index 00000000000..7383f0b31ff --- /dev/null +++ b/tools/test/h5stat/expected/h5stat_filters-cache.ddl @@ -0,0 +1,99 @@ +Filename: h5stat_filters.h5 +File information + # of unique groups: 1 + # of unique datasets: 15 + # of unique named datatypes: 1 + # of unique links: 0 + # of unique other: 0 + Max. # of links to object: 1 + Max. # of objects in group: 16 +File space information for file metadata (in bytes): + Superblock: 96 + Superblock extension: 0 + User block: 0 + Object headers: (total/unused) + Groups: 40/0 + Datasets(exclude compact data): 4128/1088 + Datatypes: 80/0 + Groups: + B-tree/List: 1200 + Heap: 384 + Attributes: + B-tree/List: 0 + Heap: 0 + Chunked datasets: + Index: 31392 + Datasets: + Heap: 72 + Shared Messages: + Header: 0 + B-tree/List: 0 + Heap: 0 + Free-space managers: + Header: 0 + Amount of free space: 0 +Small groups (with 0 to 9 links): + Total # of small groups: 0 +Group bins: + # of groups with 10 - 99 links: 1 + Total # of groups: 1 +Dataset dimension information: + Max. rank of datasets: 2 + Dataset ranks: + # of dataset with rank 1: 1 + # of dataset with rank 2: 14 +1-D Dataset information: + Max. dimension size of 1-D datasets: 100 + Small 1-D datasets (with dimension sizes 0 to 9): + Total # of small datasets: 0 + 1-D Dataset dimension bins: + # of datasets with dimension size 100 - 999: 1 + Total # of datasets: 1 +Dataset storage information: + Total raw data size: 9046 + Total external raw data size: 400 +Dataset layout information: + Dataset layout counts[COMPACT]: 1 + Dataset layout counts[CONTIG]: 2 + Dataset layout counts[CHUNKED]: 12 + Dataset layout counts[VIRTUAL]: 0 + Number of external files : 2 +Dataset filters information: + Number of datasets with: + NO filter: 7 + GZIP filter: 2 + SHUFFLE filter: 2 + FLETCHER32 filter: 2 + SZIP filter: 2 + NBIT filter: 2 + SCALEOFFSET filter: 1 + USER-DEFINED filter: 1 +Dataset datatype information: + # of unique datatypes used by datasets: 2 + Dataset datatype #0: + Count (total/named) = (14/0) + Size (desc./elmt) = (14/4) + Dataset datatype #1: + Count (total/named) = (1/0) + Size (desc./elmt) = (14/4) + Total dataset datatype count: 15 +Small # of attributes (objects with 1 to 10 attributes): + Total # of objects with small # of attributes: 0 +Attribute bins: + Total # of objects with attributes: 0 + Max. # of attributes to objects: 0 +Free-space persist: FALSE +Free-space section threshold: 1 bytes +Small size free-space sections (< 10 bytes): + Total # of small size sections: 0 +Free-space section bins: + Total # of sections: 0 +File space management strategy: H5F_FSPACE_STRATEGY_FSM_AGGR +File space page size: 4096 bytes +Summary of file space information: + File metadata: 37392 bytes + Raw data: 9046 bytes + Amount/Percent of tracked free space: 0 bytes/0.0% + Unaccounted space: 258 bytes +Total space: 46696 bytes +External raw data: 400 bytes diff --git a/tools/test/h5stat/expected/h5stat_help1.ddl b/tools/test/h5stat/expected/h5stat_help1.ddl index 54d6a318eda..82f1cfff3ee 100644 --- a/tools/test/h5stat/expected/h5stat_help1.ddl +++ b/tools/test/h5stat/expected/h5stat_help1.ddl @@ -25,6 +25,7 @@ usage: h5stat [OPTIONS] file than 0. The default threshold is 10. -s, --freespace Print free space information -S, --summary Print summary of file space information + --page-buffer-size=N Set the page buffer cache size, N=non-negative integers --s3-cred= Access file on S3, using provided credential :: (region,id,key) If == "(,,)", no authentication is used. diff --git a/tools/test/h5stat/expected/h5stat_help2.ddl b/tools/test/h5stat/expected/h5stat_help2.ddl index 54d6a318eda..82f1cfff3ee 100644 --- a/tools/test/h5stat/expected/h5stat_help2.ddl +++ b/tools/test/h5stat/expected/h5stat_help2.ddl @@ -25,6 +25,7 @@ usage: h5stat [OPTIONS] file than 0. The default threshold is 10. -s, --freespace Print free space information -S, --summary Print summary of file space information + --page-buffer-size=N Set the page buffer cache size, N=non-negative integers --s3-cred= Access file on S3, using provided credential :: (region,id,key) If == "(,,)", no authentication is used. diff --git a/tools/test/h5stat/expected/h5stat_nofile.ddl b/tools/test/h5stat/expected/h5stat_nofile.ddl index 54d6a318eda..82f1cfff3ee 100644 --- a/tools/test/h5stat/expected/h5stat_nofile.ddl +++ b/tools/test/h5stat/expected/h5stat_nofile.ddl @@ -25,6 +25,7 @@ usage: h5stat [OPTIONS] file than 0. The default threshold is 10. -s, --freespace Print free space information -S, --summary Print summary of file space information + --page-buffer-size=N Set the page buffer cache size, N=non-negative integers --s3-cred= Access file on S3, using provided credential :: (region,id,key) If == "(,,)", no authentication is used. diff --git a/tools/test/h5stat/testh5stat.sh.in b/tools/test/h5stat/testh5stat.sh.in index bc48494f59b..b44c43921de 100644 --- a/tools/test/h5stat/testh5stat.sh.in +++ b/tools/test/h5stat/testh5stat.sh.in @@ -84,6 +84,7 @@ $SRC_H5STAT_OUTFILES/h5stat_help2.ddl $SRC_H5STAT_OUTFILES/h5stat_notexist.ddl $SRC_H5STAT_OUTFILES/h5stat_nofile.ddl $SRC_H5STAT_OUTFILES/h5stat_filters.ddl +$SRC_H5STAT_OUTFILES/h5stat_filters-cache.ddl $SRC_H5STAT_OUTFILES/h5stat_filters-file.ddl $SRC_H5STAT_OUTFILES/h5stat_filters-F.ddl $SRC_H5STAT_OUTFILES/h5stat_filters-d.ddl @@ -290,6 +291,8 @@ TOOLTEST h5stat_filters-g.ddl -g h5stat_filters.h5 TOOLTEST h5stat_filters-dT.ddl -dT h5stat_filters.h5 TOOLTEST h5stat_filters-UD.ddl -D h5stat_filters.h5 TOOLTEST h5stat_filters-UT.ddl -T h5stat_filters.h5 +# Test for page buffer cache size option +TOOLTEST h5stat_filters-cache.ddl --page-buffer-size=8192 h5stat_filters.h5 # # h5stat_tsohm.h5 is a copy of ../../../test/tsohm.h5 generated by tsohm.c # as of release 1.8.7-snap0 (on a 64-bit machine) From 0443a946d3448f8dd0a55943741f34d20ac73ecc Mon Sep 17 00:00:00 2001 From: mattjala <124107509+mattjala@users.noreply.github.com> Date: Wed, 19 Jun 2024 07:48:11 -0500 Subject: [PATCH 22/45] Clarify documentation for H5CX_get_data_transform (#4580) * Correct comment for H5CX_get_data_transform * Document why data transform ctx field doesnt use macro --- src/H5CX.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/H5CX.c b/src/H5CX.c index d3d1ab3bed3..2b25288f41c 100644 --- a/src/H5CX.c +++ b/src/H5CX.c @@ -2351,7 +2351,7 @@ H5CX_get_filter_cb(H5Z_cb_t *filter_cb) /*------------------------------------------------------------------------- * Function: H5CX_get_data_transform * - * Purpose: Retrieves the I/O filter callback function for the current API call context. + * Purpose: Retrieves the data transformation expression for the current API call context. * * Return: Non-negative on success / Negative on failure * @@ -2371,6 +2371,9 @@ H5CX_get_data_transform(H5Z_data_xform_t **data_transform) assert(head && *head); assert(H5P_DEFAULT != (*head)->ctx.dxpl_id); + /* This getter does not use H5CX_RETRIEVE_PROP_VALID in order to use H5P_peek instead of H5P_get. + This prevents invocation of the data transform property's library-defined copy callback */ + /* Check if the value has been retrieved already */ if (!(*head)->ctx.data_transform_valid) { /* Check for default DXPL */ From 8f3520e20bd9b7b9c3fb1fd5a3fda5612bd8a4a1 Mon Sep 17 00:00:00 2001 From: Dana Robinson <43805+derobins@users.noreply.github.com> Date: Wed, 19 Jun 2024 05:49:07 -0700 Subject: [PATCH 23/45] Remove public API call from ros3 VFD (#4583) --- src/H5FDros3.c | 76 +++++++++++++++++++++++--------------------------- src/H5Pfapl.c | 21 +++++++------- 2 files changed, 45 insertions(+), 52 deletions(-) diff --git a/src/H5FDros3.c b/src/H5FDros3.c index 6222fef8bf3..eebf9edca3c 100644 --- a/src/H5FDros3.c +++ b/src/H5FDros3.c @@ -352,17 +352,13 @@ H5Pget_fapl_ros3(hid_t fapl_id, H5FD_ros3_fapl_t *fa_dst /*out*/) if (fa_dst == NULL) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "fa_dst is NULL"); - - plist = H5P_object_verify(fapl_id, H5P_FILE_ACCESS); - if (plist == NULL) + if (NULL == (plist = H5P_object_verify(fapl_id, H5P_FILE_ACCESS))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access list"); - if (H5FD_ROS3 != H5P_peek_driver(plist)) - HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "incorrect VFL driver"); + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "fapl not set to use the ros3 VFD"); - fa_src = (const H5FD_ros3_fapl_t *)H5P_peek_driver_info(plist); - if (fa_src == NULL) - HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "bad VFL driver info"); + if (NULL == (fa_src = (const H5FD_ros3_fapl_t *)H5P_peek_driver_info(plist))) + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "bad VFL driver info"); /* Copy the ros3 fapl data out */ H5MM_memcpy(fa_dst, fa_src, sizeof(H5FD_ros3_fapl_t)); @@ -694,22 +690,19 @@ H5Pset_fapl_ros3_token(hid_t fapl_id, const char *token) static H5FD_t * H5FD__ros3_open(const char *url, unsigned flags, hid_t fapl_id, haddr_t maxaddr) { - H5FD_ros3_t *file = NULL; - struct tm *now = NULL; - char iso8601now[ISO8601_SIZE]; - unsigned char signing_key[SHA256_DIGEST_LENGTH]; - s3r_t *handle = NULL; - H5FD_ros3_fapl_t fa; - H5P_genplist_t *plist = NULL; - htri_t token_exists; - char *token; - H5FD_t *ret_value = NULL; + H5FD_ros3_t *file = NULL; + struct tm *now = NULL; + char iso8601now[ISO8601_SIZE]; + unsigned char signing_key[SHA256_DIGEST_LENGTH]; + s3r_t *handle = NULL; + const H5FD_ros3_fapl_t *fa = NULL; + H5P_genplist_t *plist = NULL; + htri_t token_exists; + char *token; + H5FD_t *ret_value = NULL; FUNC_ENTER_PACKAGE - /* Sanity check on file offsets */ - HDcompile_assert(sizeof(HDoff_t) >= sizeof(size_t)); - /* Check arguments */ if (!url || !*url) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "invalid file name"); @@ -719,27 +712,29 @@ H5FD__ros3_open(const char *url, unsigned flags, hid_t fapl_id, haddr_t maxaddr) HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, NULL, "bogus maxaddr"); if (flags != H5F_ACC_RDONLY) HGOTO_ERROR(H5E_ARGS, H5E_UNSUPPORTED, NULL, "only Read-Only access allowed"); + if (NULL == (plist = H5P_object_verify(fapl_id, H5P_FILE_ACCESS))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file access property list"); - if (FAIL == H5Pget_fapl_ros3(fapl_id, &fa)) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "can't get property list"); - + /* Init curl */ if (CURLE_OK != curl_global_init(CURL_GLOBAL_DEFAULT)) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "unable to initialize curl global (placeholder flags)"); + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, NULL, "unable to initialize curl global (placeholder flags)"); + + /* Get ros3 driver info */ + if (NULL == (fa = (const H5FD_ros3_fapl_t *)H5P_peek_driver_info(plist))) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, NULL, "could not get ros3 VFL driver info"); /* Session/security token */ - if (NULL == (plist = H5P_object_verify(fapl_id, H5P_FILE_ACCESS))) - HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, NULL, "not a file access property list"); if ((token_exists = H5P_exist_plist(plist, ROS3_TOKEN_PROP_NAME)) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "failed to check if property token exists in plist"); + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, NULL, "failed check for property token in plist"); if (token_exists) { if (H5P_get(plist, ROS3_TOKEN_PROP_NAME, &token) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "unable to get token value"); + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, NULL, "unable to get token value"); } /* Open file; procedure depends on whether or not the fapl instructs to * authenticate requests or not. */ - if (fa.authenticate == true) { + if (fa->authenticate == true) { /* Compute signing key (part of AWS/S3 REST API). Can be re-used by * user/key for 7 days after creation. * @@ -749,15 +744,15 @@ H5FD__ros3_open(const char *url, unsigned flags, hid_t fapl_id, haddr_t maxaddr) assert(now != NULL); if (ISO8601NOW(iso8601now, now) != (ISO8601_SIZE - 1)) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "problem while writing iso8601 timestamp"); - if (FAIL == H5FD_s3comms_signing_key(signing_key, (const char *)fa.secret_key, - (const char *)fa.aws_region, (const char *)iso8601now)) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "problem while computing signing key"); + if (FAIL == H5FD_s3comms_signing_key(signing_key, (const char *)fa->secret_key, + (const char *)fa->aws_region, (const char *)iso8601now)) + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, NULL, "problem while computing signing key"); if (token_exists) - handle = H5FD_s3comms_s3r_open(url, (const char *)fa.aws_region, (const char *)fa.secret_id, + handle = H5FD_s3comms_s3r_open(url, (const char *)fa->aws_region, (const char *)fa->secret_id, (const unsigned char *)signing_key, (const char *)token); else - handle = H5FD_s3comms_s3r_open(url, (const char *)fa.aws_region, (const char *)fa.secret_id, + handle = H5FD_s3comms_s3r_open(url, (const char *)fa->aws_region, (const char *)fa->secret_id, (const unsigned char *)signing_key, ""); } else @@ -771,16 +766,15 @@ H5FD__ros3_open(const char *url, unsigned flags, hid_t fapl_id, haddr_t maxaddr) HGOTO_ERROR(H5E_VFL, H5E_CANTOPENFILE, NULL, "could not open"); /* Create new file struct */ - file = H5FL_CALLOC(H5FD_ros3_t); - if (file == NULL) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "unable to allocate file struct"); + if (NULL == (file = H5FL_CALLOC(H5FD_ros3_t))) + HGOTO_ERROR(H5E_VFL, H5E_NOSPACE, NULL, "unable to allocate file struct"); file->s3r_handle = handle; - H5MM_memcpy(&(file->fa), &fa, sizeof(H5FD_ros3_fapl_t)); + H5MM_memcpy(&(file->fa), fa, sizeof(H5FD_ros3_fapl_t)); #ifdef ROS3_STATS if (FAIL == H5FD__ros3_reset_stats(file)) - HGOTO_ERROR(H5E_INTERNAL, H5E_UNINITIALIZED, NULL, "unable to reset file statistics"); + HGOTO_ERROR(H5E_VFL, H5E_UNINITIALIZED, NULL, "unable to reset file statistics"); #endif /* Cache the initial bytes of the file */ @@ -791,7 +785,7 @@ H5FD__ros3_open(const char *url, unsigned flags, hid_t fapl_id, haddr_t maxaddr) if (NULL == (file->cache = (uint8_t *)H5MM_calloc(file->cache_size))) HGOTO_ERROR(H5E_VFL, H5E_NOSPACE, NULL, "unable to allocate cache memory"); - if (H5FD_s3comms_s3r_read(file->s3r_handle, 0, file->cache_size, file->cache) == FAIL) + if (H5FD_s3comms_s3r_read(file->s3r_handle, 0, file->cache_size, file->cache) < 0) HGOTO_ERROR(H5E_VFL, H5E_READERROR, NULL, "unable to execute read"); } diff --git a/src/H5Pfapl.c b/src/H5Pfapl.c index 3d4ca8b69eb..03a65fb7870 100644 --- a/src/H5Pfapl.c +++ b/src/H5Pfapl.c @@ -1477,23 +1477,22 @@ H5Pget_driver(hid_t plist_id) /*------------------------------------------------------------------------- * Function: H5P_peek_driver_info * - * Purpose: Returns a pointer directly to the file driver-specific - * information of a file access. + * Purpose: Returns a pointer directly to the file driver-specific + * information of a file access. * - * Return: Success: Ptr to *uncopied* driver specific data - * structure if any. - * - * Failure: NULL. Null is also returned if the driver has - * not registered any driver-specific properties - * although no error is pushed on the stack in - * this case. + * Return: Success: Pointer to *uncopied* driver-specific data + * structure, if any. * + * Failure: NULL. NULL is also returned if the driver has + * not registered any driver-specific properties + * although no error is pushed on the stack in + * this case. *------------------------------------------------------------------------- */ const void * H5P_peek_driver_info(H5P_genplist_t *plist) { - const void *ret_value = NULL; /* Return value */ + const void *ret_value = NULL; FUNC_ENTER_NOAPI(NULL) @@ -1504,7 +1503,7 @@ H5P_peek_driver_info(H5P_genplist_t *plist) if (H5P_peek(plist, H5F_ACS_FILE_DRV_NAME, &driver_prop) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get driver info"); ret_value = driver_prop.driver_info; - } /* end if */ + } else HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, NULL, "not a file access property list"); From 07bc505fdd64c54a2372d2a46bf96ec75d5977df Mon Sep 17 00:00:00 2001 From: Dana Robinson <43805+derobins@users.noreply.github.com> Date: Wed, 19 Jun 2024 05:51:50 -0700 Subject: [PATCH 24/45] Remove printf debugging from H5FDs3comms.c (#4584) --- src/H5FDs3comms.c | 219 +--------------------------------------------- 1 file changed, 1 insertion(+), 218 deletions(-) diff --git a/src/H5FDs3comms.c b/src/H5FDs3comms.c index bcda801a8dd..9b0d786dfe7 100644 --- a/src/H5FDs3comms.c +++ b/src/H5FDs3comms.c @@ -47,17 +47,7 @@ #ifdef H5_HAVE_ROS3_VFD -/* toggle debugging: pick a level - */ -#define S3COMMS_DEBUG_NONE 0 -#define S3COMMS_DEBUG_REQUESTS 1 -#define S3COMMS_DEBUG_TRACE_API 2 -#define S3COMMS_DEBUG_TRACE_INTERNAL 3 -#define S3COMMS_DEBUG_HEADERS 4 -#define S3COMMS_DEBUG 0 - /* manipulate verbosity of CURL output - * operates separately from S3COMMS_DEBUG * * 0 -> no explicit curl output * 1 -> on error, print failure info to stderr @@ -218,18 +208,6 @@ H5FD_s3comms_hrb_node_set(hrb_node_t **L, const char *name, const char *value) FUNC_ENTER_NOAPI_NOINIT -#if S3COMMS_DEBUG >= S3COMMS_DEBUG_HEADERS - fprintf(stdout, "called H5FD_s3comms_hrb_node_set."); - printf("NAME: %s\n", name); - printf("VALUE: %s\n", value); - printf("LIST:\n->"); - for (node_ptr = (*L); node_ptr != NULL; node_ptr = node_ptr->next) - fprintf(stdout, "{%s}\n->", node_ptr->cat); - printf("(null)\n"); - fflush(stdout); - node_ptr = NULL; -#endif - if (name == NULL) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to operate on null name"); namelen = strlen(name); @@ -297,10 +275,6 @@ H5FD_s3comms_hrb_node_set(hrb_node_t **L, const char *name, const char *value) if (value == NULL) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "trying to remove node from empty list"); else { -#if S3COMMS_DEBUG >= S3COMMS_DEBUG_HEADERS - printf("CREATE NEW\n"); - fflush(stdout); -#endif /******************* * CREATE NEW LIST * *******************/ @@ -328,60 +302,24 @@ H5FD_s3comms_hrb_node_set(hrb_node_t **L, const char *name, const char *value) is_looking = false; if (value == NULL) { -#if S3COMMS_DEBUG >= S3COMMS_DEBUG_HEADERS - printf("REMOVE HEAD\n"); - fflush(stdout); -#endif /*************** * REMOVE HEAD * ***************/ *L = node_ptr->next; -#if S3COMMS_DEBUG >= S3COMMS_DEBUG_HEADERS - printf("FREEING CAT (node)\n"); - fflush(stdout); -#endif H5MM_xfree(node_ptr->cat); -#if S3COMMS_DEBUG >= S3COMMS_DEBUG_HEADERS - printf("FREEING LOWERNAME (node)\n"); - fflush(stdout); -#endif H5MM_xfree(node_ptr->lowername); -#if S3COMMS_DEBUG >= S3COMMS_DEBUG_HEADERS - printf("FREEING NAME (node)\n"); - fflush(stdout); -#endif H5MM_xfree(node_ptr->name); -#if S3COMMS_DEBUG >= S3COMMS_DEBUG_HEADERS - printf("FREEING VALUE (node)\n"); - fflush(stdout); -#endif H5MM_xfree(node_ptr->value); -#if S3COMMS_DEBUG >= S3COMMS_DEBUG_HEADERS - printf("MAGIC OK? %s\n", (node_ptr->magic == S3COMMS_HRB_NODE_MAGIC) ? "YES" : "NO"); - fflush(stdout); -#endif assert(node_ptr->magic == S3COMMS_HRB_NODE_MAGIC); node_ptr->magic += 1ul; -#if S3COMMS_DEBUG >= S3COMMS_DEBUG_HEADERS - printf("FREEING POINTER\n"); - fflush(stdout); -#endif H5MM_xfree(node_ptr); -#if S3COMMS_DEBUG >= S3COMMS_DEBUG_HEADERS - printf("FREEING WORKING LOWERNAME\n"); - fflush(stdout); -#endif H5MM_xfree(lowername); lowername = NULL; } else { -#if S3COMMS_DEBUG >= S3COMMS_DEBUG_HEADERS - printf("MODIFY HEAD\n"); - fflush(stdout); -#endif /*************** * MODIFY HEAD * ***************/ @@ -408,10 +346,6 @@ H5FD_s3comms_hrb_node_set(hrb_node_t **L, const char *name, const char *value) if (value == NULL) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "trying to remove a node 'before' head"); else { -#if S3COMMS_DEBUG >= S3COMMS_DEBUG_HEADERS - printf("PREPEND NEW HEAD\n"); - fflush(stdout); -#endif /******************* * INSERT NEW HEAD * *******************/ @@ -437,10 +371,6 @@ H5FD_s3comms_hrb_node_set(hrb_node_t **L, const char *name, const char *value) if (value == NULL) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "trying to remove absent node"); else { -#if S3COMMS_DEBUG >= S3COMMS_DEBUG_HEADERS - printf("APPEND A NODE\n"); - fflush(stdout); -#endif /******************* * APPEND NEW NODE * *******************/ @@ -460,10 +390,6 @@ H5FD_s3comms_hrb_node_set(hrb_node_t **L, const char *name, const char *value) if (value == NULL) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "trying to remove absent node"); else { -#if S3COMMS_DEBUG >= S3COMMS_DEBUG_HEADERS - printf("INSERT A NODE\n"); - fflush(stdout); -#endif /******************* * INSERT NEW NODE * *******************/ @@ -489,10 +415,6 @@ H5FD_s3comms_hrb_node_set(hrb_node_t **L, const char *name, const char *value) hrb_node_t *tmp = node_ptr->next; node_ptr->next = tmp->next; -#if S3COMMS_DEBUG >= S3COMMS_DEBUG_HEADERS - printf("REMOVE A NODE\n"); - fflush(stdout); -#endif H5MM_xfree(tmp->cat); H5MM_xfree(tmp->lowername); H5MM_xfree(tmp->name); @@ -506,10 +428,6 @@ H5FD_s3comms_hrb_node_set(hrb_node_t **L, const char *name, const char *value) lowername = NULL; } else { -#if S3COMMS_DEBUG >= S3COMMS_DEBUG_HEADERS - printf("MODIFY A NODE\n"); - fflush(stdout); -#endif /***************** * MODIFY A NODE * *****************/ @@ -602,10 +520,6 @@ H5FD_s3comms_hrb_destroy(hrb_t **_buf) FUNC_ENTER_NOAPI_NOINIT -#if S3COMMS_DEBUG >= S3COMMS_DEBUG_HEADERS - fprintf(stdout, "called H5FD_s3comms_hrb_destroy.\n"); -#endif - if (_buf != NULL && *_buf != NULL) { buf = *_buf; if (buf->magic != S3COMMS_HRB_MAGIC) @@ -663,10 +577,6 @@ H5FD_s3comms_hrb_init_request(const char *_verb, const char *_resource, const ch FUNC_ENTER_NOAPI_NOINIT -#if S3COMMS_DEBUG >= S3COMMS_DEBUG_TRACE_INTERNAL - fprintf(stdout, "called H5FD_s3comms_hrb_init_request.\n"); -#endif - if (_resource == NULL) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "resource string cannot be null."); @@ -767,10 +677,6 @@ H5FD_s3comms_s3r_close(s3r_t *handle) FUNC_ENTER_NOAPI_NOINIT -#if S3COMMS_DEBUG > S3COMMS_DEBUG_TRACE_API - fprintf(stdout, "called H5FD_s3comms_s3r_close.\n"); -#endif - if (handle == NULL) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "handle cannot be null."); if (handle->magic != S3COMMS_S3R_MAGIC) @@ -868,10 +774,6 @@ H5FD_s3comms_s3r_getsize(s3r_t *handle) FUNC_ENTER_NOAPI_NOINIT -#if S3COMMS_DEBUG >= S3COMMS_DEBUG_TRACE_INTERNAL - fprintf(stdout, "called H5FD_s3comms_s3r_getsize.\n"); -#endif - if (handle == NULL) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "handle cannot be null."); if (handle->magic != S3COMMS_S3R_MAGIC) @@ -916,10 +818,6 @@ H5FD_s3comms_s3r_getsize(s3r_t *handle) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "HTTP metadata buffer overrun"); else if (sds.size == 0) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "No HTTP metadata"); -#if S3COMMS_DEBUG >= S3COMMS_DEBUG_TRACE_INTERNAL - else - fprintf(stdout, "GETSIZE: OK\n"); -#endif /****************** * PARSE RESPONSE * @@ -950,10 +848,6 @@ H5FD_s3comms_s3r_getsize(s3r_t *handle) handle->filesize = (size_t)content_length; -#if S3COMMS_DEBUG >= S3COMMS_DEBUG_REQUESTS - fprintf(stdout, " -- size: %ju\n", content_length); -#endif - /********************** * UNDO HEAD SETTINGS * **********************/ @@ -1019,10 +913,6 @@ H5FD_s3comms_s3r_open(const char *url, const char *region, const char *id, const FUNC_ENTER_NOAPI_NOINIT -#if S3COMMS_DEBUG >= S3COMMS_DEBUG_TRACE_API - fprintf(stdout, "called H5FD_s3comms_s3r_open.\n"); -#endif - if (url == NULL || url[0] == '\0') HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "url cannot be null."); @@ -1217,10 +1107,6 @@ H5FD_s3comms_s3r_read(s3r_t *handle, haddr_t offset, size_t len, void *dest) FUNC_ENTER_NOAPI_NOINIT -#if S3COMMS_DEBUG >= S3COMMS_DEBUG_TRACE_API - fprintf(stdout, "called H5FD_s3comms_s3r_read.\n"); -#endif - /************************************** * ABSOLUTELY NECESSARY SANITY-CHECKS * **************************************/ @@ -1278,11 +1164,6 @@ H5FD_s3comms_s3r_read(s3r_t *handle, haddr_t offset, size_t len, void *dest) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to format HTTP Range value"); } -#if S3COMMS_DEBUG >= S3COMMS_DEBUG_HEADERS - fprintf(stdout, "%s: Bytes %" PRIuHADDR " - %" PRIuHADDR ", Request Size: %zu\n", handle->httpverb, - offset, offset + len - 1, len); -#endif - /******************* * COMPILE REQUEST * *******************/ @@ -1391,10 +1272,6 @@ H5FD_s3comms_s3r_read(s3r_t *handle, haddr_t offset, size_t len, void *dest) } if (rangebytesstr != NULL) { -#if S3COMMS_DEBUG >= S3COMMS_DEBUG_REQUESTS - fprintf(stdout, " -- request: %lu %zu\n", (size_t)offset, len); - -#endif if (FAIL == H5FD_s3comms_hrb_node_set(&headers, "Range", rangebytesstr)) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to set range header"); if (headers == NULL) @@ -1504,23 +1381,6 @@ H5FD_s3comms_s3r_read(s3r_t *handle, haddr_t offset, size_t len, void *dest) HGOTO_ERROR(H5E_VFL, H5E_CANTOPENFILE, FAIL, "curl cannot perform request"); #endif -#if S3COMMS_DEBUG >= S3COMMS_DEBUG_TRACE_INTERNAL - if (dest != NULL) { - fprintf(stdout, "len: %d\n", (int)len); - fprintf(stdout, "CHECKING FOR BUFFER OVERFLOW\n"); - if (sds == NULL) - fprintf(stdout, "sds is NULL!\n"); - else { - fprintf(stdout, "sds: 0x%llx\n", (long long)sds); - fprintf(stdout, "sds->size: %d\n", (int)sds->size); - if (len > sds->size) - fprintf(stdout, "buffer overwrite\n"); - } - } - else - fprintf(stdout, "performed on entire file\n"); -#endif - done: /* clean any malloc'd resources */ @@ -1668,10 +1528,6 @@ H5FD_s3comms_aws_canonical_request(char *canonical_request_dest, int _cr_size, c FUNC_ENTER_NOAPI_NOINIT -#if S3COMMS_DEBUG >= S3COMMS_DEBUG_TRACE_INTERNAL - fprintf(stdout, "called H5FD_s3comms_aws_canonical_request.\n"); -#endif - if (http_request == NULL) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "hrb object cannot be null."); assert(http_request->magic == S3COMMS_HRB_MAGIC); @@ -1774,10 +1630,6 @@ H5FD_s3comms_bytes_to_hex(char *dest, const unsigned char *msg, size_t msg_len, FUNC_ENTER_NOAPI_NOINIT -#if S3COMMS_DEBUG >= S3COMMS_DEBUG_TRACE_INTERNAL - fprintf(stdout, "called H5FD_s3comms_bytes_to_hex.\n"); -#endif - if (dest == NULL) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "hex destination cannot be null."); if (msg == NULL) @@ -1815,10 +1667,6 @@ H5FD_s3comms_free_purl(parsed_url_t *purl) { FUNC_ENTER_NOAPI_NOINIT_NOERR -#if S3COMMS_DEBUG >= S3COMMS_DEBUG_TRACE_INTERNAL - printf("called H5FD_s3comms_free_purl.\n"); -#endif - if (purl != NULL) { assert(purl->magic == S3COMMS_PARSED_URL_MAGIC); if (purl->scheme != NULL) @@ -1875,10 +1723,6 @@ H5FD_s3comms_HMAC_SHA256(const unsigned char *key, size_t key_len, const char *m FUNC_ENTER_NOAPI_NOINIT -#if S3COMMS_DEBUG >= S3COMMS_DEBUG_TRACE_INTERNAL - fprintf(stdout, "called H5FD_s3comms_HMAC_SHA256.\n"); -#endif - if (dest == NULL) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "destination cannot be null."); @@ -1962,10 +1806,6 @@ H5FD__s3comms_load_aws_creds_from_file(FILE *file, const char *profile_name, cha FUNC_ENTER_PACKAGE -#if S3COMMS_DEBUG >= S3COMMS_DEBUG_TRACE_INTERNAL - fprintf(stdout, "called load_aws_creds_from_file.\n"); -#endif - /* format target line for start of profile */ if (32 < snprintf(profile_line, 32, "[%s]", profile_name)) HGOTO_ERROR(H5E_ARGS, H5E_CANTCOPY, FAIL, "unable to format profile label"); @@ -2079,10 +1919,6 @@ H5FD_s3comms_load_aws_profile(const char *profile_name, char *key_id_out, char * FUNC_ENTER_NOAPI_NOINIT -#if S3COMMS_DEBUG >= S3COMMS_DEBUG_TRACE_INTERNAL - fprintf(stdout, "called H5FD_s3comms_load_aws_profile.\n"); -#endif - #ifdef H5_HAVE_WIN32_API ret = snprintf(awspath, 117, "%s/.aws/", getenv("USERPROFILE")); #else @@ -2161,10 +1997,6 @@ H5FD_s3comms_nlowercase(char *dest, const char *s, size_t len) FUNC_ENTER_NOAPI_NOINIT -#if S3COMMS_DEBUG >= S3COMMS_DEBUG_TRACE_INTERNAL - fprintf(stdout, "called H5FD_s3comms_nlowercase.\n"); -#endif - if (dest == NULL) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "destination cannot be null."); @@ -2221,10 +2053,6 @@ H5FD_s3comms_parse_url(const char *str, parsed_url_t **_purl) FUNC_ENTER_NOAPI_NOINIT -#if S3COMMS_DEBUG >= S3COMMS_DEBUG_TRACE_INTERNAL - printf("called H5FD_s3comms_parse_url.\n"); -#endif - if (str == NULL || *str == '\0') HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid url string"); @@ -2428,33 +2256,16 @@ H5FD_s3comms_percent_encode_char(char *repr, const unsigned char c, size_t *repr unsigned int i = 0; int chars_written = 0; herr_t ret_value = SUCCEED; -#if S3COMMS_DEBUG >= S3COMMS_DEBUG_TRACE_INTERNAL - unsigned char s[2] = {c, 0}; - unsigned char hex[3] = {0, 0, 0}; -#endif FUNC_ENTER_NOAPI_NOINIT -#if S3COMMS_DEBUG >= S3COMMS_DEBUG_TRACE_INTERNAL - fprintf(stdout, "called H5FD_s3comms_percent_encode_char.\n"); -#endif - if (repr == NULL) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no destination `repr`."); -#if S3COMMS_DEBUG >= S3COMMS_DEBUG_TRACE_INTERNAL - H5FD_s3comms_bytes_to_hex((char *)hex, s, 1, false); - fprintf(stdout, " CHAR: \'%s\'\n", s); - fprintf(stdout, " CHAR-HEX: \"%s\"\n", hex); -#endif - if (c <= (unsigned char)0x7f) { /* character represented in a single "byte" * and single percent-code */ -#if S3COMMS_DEBUG >= S3COMMS_DEBUG_TRACE_INTERNAL - fprintf(stdout, " SINGLE-BYTE\n"); -#endif *repr_len = 3; chars_written = snprintf(repr, 4, "%%%02X", c); if (chars_written < 0) @@ -2467,9 +2278,7 @@ H5FD_s3comms_percent_encode_char(char *repr, const unsigned char c, size_t *repr unsigned int k = 0; /* uint character representation */ unsigned int stack_size = 0; unsigned char stack[4] = {0, 0, 0, 0}; -#if S3COMMS_DEBUG >= S3COMMS_DEBUG_TRACE_INTERNAL - fprintf(stdout, " MULTI-BYTE\n"); -#endif + stack_size = 0; k = (unsigned int)c; *repr_len = 0; @@ -2487,16 +2296,6 @@ H5FD_s3comms_percent_encode_char(char *repr, const unsigned char c, size_t *repr * UTF-8 byte fields. */ -#if S3COMMS_DEBUG >= S3COMMS_DEBUG_TRACE_INTERNAL - fprintf(stdout, " STACK:\n {\n"); - for (i = 0; i < stack_size; i++) { - H5FD_s3comms_bytes_to_hex((char *)hex, (&stack[i]), 1, false); - hex[2] = 0; - fprintf(stdout, " %s,\n", hex); - } - fprintf(stdout, " }\n"); -#endif - /**************** * leading byte * ****************/ @@ -2580,10 +2379,6 @@ H5FD_s3comms_signing_key(unsigned char *md, const char *secret, const char *regi FUNC_ENTER_NOAPI_NOINIT -#if S3COMMS_DEBUG >= S3COMMS_DEBUG_TRACE_INTERNAL - fprintf(stdout, "called H5FD_s3comms_signing_key.\n"); -#endif - if (md == NULL) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "Destination `md` cannot be NULL."); if (secret == NULL) @@ -2669,10 +2464,6 @@ H5FD_s3comms_tostringtosign(char *dest, const char *req, const char *now, const FUNC_ENTER_NOAPI_NOINIT -#if S3COMMS_DEBUG >= S3COMMS_DEBUG_TRACE_INTERNAL - fprintf(stdout, "called H5FD_s3comms_tostringtosign.\n"); -#endif - if (dest == NULL) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "destination buffer cannot be null."); if (req == NULL) @@ -2753,10 +2544,6 @@ H5FD_s3comms_trim(char *dest, char *s, size_t s_len, size_t *n_written) FUNC_ENTER_NOAPI_NOINIT -#if S3COMMS_DEBUG >= S3COMMS_DEBUG_TRACE_INTERNAL - fprintf(stdout, "called H5FD_s3comms_trim.\n"); -#endif - if (dest == NULL) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "destination cannot be null."); if (s == NULL) @@ -2840,10 +2627,6 @@ H5FD_s3comms_uriencode(char *dest, const char *s, size_t s_len, bool encode_slas FUNC_ENTER_NOAPI_NOINIT -#if S3COMMS_DEBUG >= S3COMMS_DEBUG_TRACE_INTERNAL - fprintf(stdout, "H5FD_s3comms_uriencode called.\n"); -#endif - if (s == NULL) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "source string cannot be NULL"); if (dest == NULL) From 98b9c07c0ae37afe97124aba39eb4c960184a746 Mon Sep 17 00:00:00 2001 From: Dana Robinson <43805+derobins@users.noreply.github.com> Date: Wed, 19 Jun 2024 06:36:45 -0700 Subject: [PATCH 25/45] Cleanup of ros3 test (#4587) * Removed JS* macro scheme (replaced w/ h5test.h macros) * Moved curl setup/teardown to main() * A lot of cleanup and simplification --- test/ros3.c | 1575 +++++++++++++++------------------------------------ 1 file changed, 465 insertions(+), 1110 deletions(-) diff --git a/test/ros3.c b/test/ros3.c index cc058fbc9b0..b88c8c61de8 100644 --- a/test/ros3.c +++ b/test/ros3.c @@ -29,315 +29,6 @@ #ifdef H5_HAVE_ROS3_VFD -/* only include the testing macros if needed */ - -/***************************************************************************** - * - * FILE-LOCAL TESTING MACROS - * - * Purpose: - * - * 1) Upon test failure, goto-jump to single-location teardown in test - * function. E.g., `error:` (consistency with HDF corpus) or - * `failed:` (reflects purpose). - * >>> using "error", in part because `H5E_BEGIN_TRY` expects it. - * 2) Increase clarity and reduce overhead found with `TEST_ERROR`. - * e.g., "if(somefunction(arg, arg2) < 0) TEST_ERROR:" - * requires reading of entire line to know whether this if/call is - * part of the test setup, test operation, or a test unto itself. - * 3) Provide testing macros with optional user-supplied failure message; - * if not supplied (NULL), generate comparison output in the spirit of - * test-driven development. E.g., "expected 5 but was -3" - * User messages clarify test's purpose in code, encouraging description - * without relying on comments. - * 4) Configurable expected-actual order in generated comparison strings. - * Some prefer `VERIFY(expected, actual)`, others - * `VERIFY(actual, expected)`. Provide preprocessor ifdef switch - * to satisfy both parties, assuming one paradigm per test file. - * (One could #undef and redefine the flag through the file as desired, - * but _why_.) - * - * Provided as courtesy, per consideration for inclusion in the library - * proper. - * - * Macros: - * - * JSVERIFY_EXP_ACT - ifdef flag, configures comparison order - * FAIL_IF() - check condition - * FAIL_UNLESS() - check _not_ condition - * JSVERIFY() - long-int equality check; prints reason/comparison - * JSVERIFY_NOT() - long-int inequality check; prints - * JSVERIFY_STR() - string equality check; prints - * - *****************************************************************************/ - -/*---------------------------------------------------------------------------- - * - * ifdef flag: JSVERIFY_EXP_ACT - * - * JSVERIFY macros accept arguments as (EXPECTED, ACTUAL[, reason]) - * default, if this is undefined, is (ACTUAL, EXPECTED[, reason]) - * - *---------------------------------------------------------------------------- - */ -#define JSVERIFY_EXP_ACT 1L - -/*---------------------------------------------------------------------------- - * - * Macro: JSFAILED_AT() - * - * Purpose: - * - * Preface a test failure by printing "*FAILED*" and location to stdout - * Similar to `H5_FAILED(); AT();` from h5test.h - * - * *FAILED* at somefile.c:12 in function_name()... - * - *---------------------------------------------------------------------------- - */ -#define JSFAILED_AT() \ - { \ - printf("*FAILED* at %s:%d in %s()...\n", __FILE__, __LINE__, __func__); \ - } - -/*---------------------------------------------------------------------------- - * - * Macro: FAIL_IF() - * - * Purpose: - * - * Make tests more accessible and less cluttered than - * `if (thing == otherthing()) TEST_ERROR` - * paradigm. - * - * The following lines are roughly equivalent: - * - * `if (myfunc() < 0) TEST_ERROR;` (as seen elsewhere in HDF tests) - * `FAIL_IF(myfunc() < 0)` - * - * Prints a generic "FAILED AT" line to stdout and jumps to `error`, - * similar to `TEST_ERROR` in h5test.h - * - *---------------------------------------------------------------------------- - */ -#define FAIL_IF(condition) \ - if (condition) { \ - JSFAILED_AT() \ - goto error; \ - } - -/*---------------------------------------------------------------------------- - * - * Macro: FAIL_UNLESS() - * - * Purpose: - * - * TEST_ERROR wrapper to reduce cognitive overhead from "negative tests", - * e.g., "a != b". - * - * Opposite of FAIL_IF; fails if the given condition is _not_ true. - * - * `FAIL_IF( 5 != my_op() )` - * is equivalent to - * `FAIL_UNLESS( 5 == my_op() )` - * However, `JSVERIFY(5, my_op(), "bad return")` may be even clearer. - * (see JSVERIFY) - * - *---------------------------------------------------------------------------- - */ -#if 0 /* UNUSED */ -#define FAIL_UNLESS(condition) \ - if (!(condition)) { \ - JSFAILED_AT() \ - goto error; \ - } -#endif - -/*---------------------------------------------------------------------------- - * - * Macro: JSERR_LONG() - * - * Purpose: - * - * Print an failure message for long-int arguments. - * ERROR-AT printed first. - * If `reason` is given, it is printed on own line and newlined after - * else, prints "expected/actual" aligned on own lines. - * - * *FAILED* at myfile.c:488 in somefunc()... - * forest must be made of trees. - * - * or - * - * *FAILED* at myfile.c:488 in somefunc()... - * ! Expected 425 - * ! Actual 3 - * - *---------------------------------------------------------------------------- - */ -static inline void -jserr_long(long expected, long actual, const char *reason) -{ - if (reason != NULL) { - printf("%s\n", reason); - } - else { - printf(" ! Expected %ld\n ! Actual %ld\n", expected, actual); - } -} - -#define JSERR_LONG(expected, actual, reason) \ - { \ - JSFAILED_AT() \ - jserr_long((long)(expected), (long)(actual), (reason)); \ - } - -/*---------------------------------------------------------------------------- - * - * Macro: JSERR_STR() - * - * Purpose: - * - * Print an failure message for string arguments. - * ERROR-AT printed first. - * If `reason` is given, it is printed on own line and newlined after - * else, prints "expected/actual" aligned on own lines. - * - * *FAILED* at myfile.c:421 in myfunc()... - * Blue and Red strings don't match! - * - * or - * - * *FAILED* at myfile.c:421 in myfunc()... - * !!! Expected: - * this is my expected - * string - * !!! Actual: - * not what I expected at all - * - *---------------------------------------------------------------------------- - */ -static inline void -jserr_str(const char *expected, const char *actual, const char *reason) -{ - if (reason != NULL) { - printf("%s\n", reason); - } - else { - printf("!!! Expected:\n%s\n!!!Actual:\n%s\n", expected, actual); - } -} - -#define JSERR_STR(expected, actual, reason) \ - { \ - JSFAILED_AT() \ - jserr_str((expected), (actual), (reason)); \ - } - -#ifdef JSVERIFY_EXP_ACT - -/*---------------------------------------------------------------------------- - * - * Macro: JSVERIFY() - * - * Purpose: - * - * Verify that two long integers are equal. - * If unequal, print failure message - * (with `reason`, if not NULL; expected/actual if NULL) - * and jump to `error` at end of function - * - *---------------------------------------------------------------------------- - */ -#define JSVERIFY(expected, actual, reason) \ - if ((long)(actual) != (long)(expected)) { \ - JSERR_LONG((expected), (actual), (reason)) \ - goto error; \ - } /* JSVERIFY */ - -/*---------------------------------------------------------------------------- - * - * Macro: JSVERIFY_NOT() - * - * Purpose: - * - * Verify that two long integers are _not_ equal. - * If equal, print failure message - * (with `reason`, if not NULL; expected/actual if NULL) - * and jump to `error` at end of function - * - *---------------------------------------------------------------------------- - */ -#define JSVERIFY_NOT(expected, actual, reason) \ - if ((long)(actual) == (long)(expected)) { \ - JSERR_LONG((expected), (actual), (reason)) \ - goto error; \ - } /* JSVERIFY_NOT */ - -/*---------------------------------------------------------------------------- - * - * Macro: JSVERIFY_STR() - * - * Purpose: - * - * Verify that two strings are equal. - * If unequal, print failure message - * (with `reason`, if not NULL; expected/actual if NULL) - * and jump to `error` at end of function - * - *---------------------------------------------------------------------------- - */ -#define JSVERIFY_STR(expected, actual, reason) \ - if (strcmp((actual), (expected)) != 0) { \ - JSERR_STR((expected), (actual), (reason)); \ - goto error; \ - } /* JSVERIFY_STR */ - -#else -/* JSVERIFY_EXP_ACT not defined - * - * Repeats macros above, but with actual/expected parameters reversed. - */ - -/*---------------------------------------------------------------------------- - * Macro: JSVERIFY() - * See: JSVERIFY documentation above. - *---------------------------------------------------------------------------- - */ -#define JSVERIFY(actual, expected, reason) \ - if ((long)(actual) != (long)(expected)) { \ - JSERR_LONG((expected), (actual), (reason)); \ - goto error; \ - } /* JSVERIFY */ - -/*---------------------------------------------------------------------------- - * Macro: JSVERIFY_NOT() - * See: JSVERIFY_NOT documentation above. - *---------------------------------------------------------------------------- - */ -#define JSVERIFY_NOT(actual, expected, reason) \ - if ((long)(actual) == (long)(expected)) { \ - JSERR_LONG((expected), (actual), (reason)) \ - goto error; \ - } /* JSVERIFY_NOT */ - -/*---------------------------------------------------------------------------- - * Macro: JSVERIFY_STR() - * See: JSVERIFY_STR documentation above. - *---------------------------------------------------------------------------- - */ -#define JSVERIFY_STR(actual, expected, reason) \ - if (strcmp((actual), (expected)) != 0) { \ - JSERR_STR((expected), (actual), (reason)); \ - goto error; \ - } /* JSVERIFY_STR */ - -#endif /* ifdef/else JSVERIFY_EXP_ACT */ - -/******************************** - * OTHER MACROS AND DEFINITIONS * - ********************************/ - #define MAXADDR (((haddr_t)1 << (8 * sizeof(HDoff_t) - 1)) - 1) #define S3_TEST_PROFILE_NAME "ros3_vfd_test" @@ -375,52 +66,25 @@ H5FD_ros3_fapl_t restricted_access_fa = {H5FD_CURR_ROS3_FAPL_T_VERSION, /* fapl H5FD_ros3_fapl_t anonymous_fa = {H5FD_CURR_ROS3_FAPL_T_VERSION, false, "", "", ""}; /*--------------------------------------------------------------------------- + * Function: test_fapl_config_validation * - * Function: test_fapl_config_validation() - * - * Purpose: - * - * Test data consistency of fapl configuration. - * Tests `H5FD_ros3_validate_config` indirectly through `H5Pset_fapl_ros3`. - * - * Return: - * - * PASSED : 0 - * FAILED : 1 + * Purpose: Test ros3 fapl configurations and H5Pset/get_fapl_ros3() * + * Return: PASS : 0 + * FAIL : 1 *--------------------------------------------------------------------------- */ static int test_fapl_config_validation(void) { - - /********************* - * test-local macros * - *********************/ - - /************************* - * test-local structures * - *************************/ - struct testcase { const char *msg; herr_t expected; H5FD_ros3_fapl_t config; }; - /************************ - * test-local variables * - ************************/ - - hid_t fapl_id = H5I_INVALID_HID; /* file access property list ID */ - H5FD_ros3_fapl_t config; - H5FD_ros3_fapl_t fa_fetch; - herr_t success = SUCCEED; - unsigned int i = 0; - unsigned int ncases = 8; /* should equal number of cases */ - struct testcase *case_ptr = NULL; /* dumb work-around for possible */ - /* dynamic cases creation because */ - /* of compiler warnings Wlarger-than */ + hid_t fapl_id = H5I_INVALID_HID; + const int NCASES = 8; /* Should equal number of cases */ struct testcase cases_arr[] = { { "non-authenticating config allows empties.\n", @@ -513,11 +177,7 @@ test_fapl_config_validation(void) }, }; - TESTING("ROS3 fapl configuration validation"); - - /********* - * TESTS * - *********/ + TESTING("ros3 fapl configuration validation"); if (false == s3_test_bucket_defined) { SKIPPED(); @@ -526,78 +186,67 @@ test_fapl_config_validation(void) return 0; } - for (i = 0; i < ncases; i++) { + for (int i = 0; i < NCASES; i++) { + + struct testcase *case_ptr = &cases_arr[i]; /* Alias */ + herr_t ret; + + if ((fapl_id = H5Pcreate(H5P_FILE_ACCESS)) < 0) + TEST_ERROR; - /*--------------- - * per-test setup - *--------------- - */ - case_ptr = &cases_arr[i]; - fapl_id = H5Pcreate(H5P_FILE_ACCESS); - FAIL_IF(fapl_id < 0) /* sanity-check */ - - /*----------------------------------- - * Actually test. - * Mute stack trace in failure cases. - *----------------------------------- - */ H5E_BEGIN_TRY { - /* `H5FD_ros3_validate_config(...)` is static/private - * to src/ros3.c and cannot (and should not?) be tested directly? - * Instead, validate config through public api. - */ - success = H5Pset_fapl_ros3(fapl_id, &case_ptr->config); + ret = H5Pset_fapl_ros3(fapl_id, &case_ptr->config); } H5E_END_TRY - JSVERIFY(case_ptr->expected, success, case_ptr->msg) + if (ret != case_ptr->expected) + FAIL_PUTS_ERROR(case_ptr->msg); - /* Make sure we can get back what we put in. - * Only valid if the fapl configuration does not result in error. + /* If H5Pset_fapl_ros3() succeeded, make sure H5Pget_fapl_ros3() + * returns what we put in. */ - if (success == SUCCEED) { - config = case_ptr->config; - JSVERIFY(SUCCEED, H5Pget_fapl_ros3(fapl_id, &fa_fetch), "unable to get fapl") - - JSVERIFY(H5FD_CURR_ROS3_FAPL_T_VERSION, fa_fetch.version, "invalid version number") - JSVERIFY(config.version, fa_fetch.version, "version number mismatch") - JSVERIFY(config.authenticate, fa_fetch.authenticate, "authentication flag mismatch") - JSVERIFY_STR(config.aws_region, fa_fetch.aws_region, NULL) - JSVERIFY_STR(config.secret_id, fa_fetch.secret_id, NULL) - JSVERIFY_STR(config.secret_key, fa_fetch.secret_key, NULL) + if (ret == SUCCEED) { + H5FD_ros3_fapl_t config = case_ptr->config; /* Alias for this config */ + H5FD_ros3_fapl_t conf_out; /* Config from fapl */ + + /* Get the config from the fapl */ + if (H5Pget_fapl_ros3(fapl_id, &conf_out) < 0) + TEST_ERROR; + + /* Make sure all fields match */ + if (H5FD_CURR_ROS3_FAPL_T_VERSION != conf_out.version) + FAIL_PUTS_ERROR("invalid version number"); + if (config.version != conf_out.version) + FAIL_PUTS_ERROR("version number mismatch"); + if (config.authenticate != conf_out.authenticate) + FAIL_PUTS_ERROR("authentication flag mismatch"); + if (strncmp(config.aws_region, conf_out.aws_region, H5FD_ROS3_MAX_REGION_LEN + 1)) + FAIL_PUTS_ERROR("AWS region mismatch"); + if (strncmp(config.secret_id, conf_out.secret_id, H5FD_ROS3_MAX_SECRET_ID_LEN + 1)) + FAIL_PUTS_ERROR("secret ID mismatch"); + if (strncmp(config.secret_key, conf_out.secret_key, H5FD_ROS3_MAX_SECRET_KEY_LEN + 1)) + FAIL_PUTS_ERROR("secret key mismatch"); } - /*----------------------------- - * per-test sanitation/teardown - *----------------------------- - */ - FAIL_IF(FAIL == H5Pclose(fapl_id)) - fapl_id = -1; - - } /* for each test case */ + if (H5Pclose(fapl_id) < 0) + TEST_ERROR; + } PASSED(); return 0; error: - /*********** - * CLEANUP * - ***********/ - - if (fapl_id < 0) { - H5E_BEGIN_TRY - { - (void)H5Pclose(fapl_id); - } - H5E_END_TRY + H5E_BEGIN_TRY + { + H5Pclose(fapl_id); } + H5E_END_TRY return 1; -} /* test_fapl_config_validation */ +} /* end test_fapl_config_validation() */ /*------------------------------------------------------------------------- - * - * Function: test_ros3_fapl() + * Function: test_ros3_fapl * * Purpose: Tests the file handle interface for the ROS3 driver * @@ -608,18 +257,13 @@ test_fapl_config_validation(void) * For now, test only fapl & flags. Extend as the * work on the VFD continues. * - * Return: Success: 0 - * Failure: 1 - * + * Return: PASS : 0 + * FAIL : 1 *------------------------------------------------------------------------- */ static int -test_ros3_fapl(void) +test_ros3_fapl_driver_flags(void) { - /************************ - * test-local variables * - ************************/ - hid_t fapl_id = H5I_INVALID_HID; /* file access property list ID */ hid_t driver_id = H5I_INVALID_HID; /* ID for this VFD */ unsigned long driver_flags = 0; /* VFD feature flags */ @@ -631,30 +275,24 @@ test_ros3_fapl(void) "plugh", /* secret_key */ }; - TESTING("ROS3 fapl "); - - /* Set property list and file name for ROS3 driver. - */ - fapl_id = H5Pcreate(H5P_FILE_ACCESS); - FAIL_IF(fapl_id < 0) + TESTING("ros3 driver flags"); - FAIL_IF(FAIL == H5Pset_fapl_ros3(fapl_id, &ros3_fa_0)) + if ((fapl_id = H5Pcreate(H5P_FILE_ACCESS)) < 0) + TEST_ERROR; + if (H5Pset_fapl_ros3(fapl_id, &ros3_fa_0) < 0) + TEST_ERROR; + if ((driver_id = H5Pget_driver(fapl_id)) < 0) + TEST_ERROR; - driver_id = H5Pget_driver(fapl_id); - FAIL_IF(driver_id < 0) + /* Get VFD flags */ + if (H5FDdriver_query(driver_id, &driver_flags) < 0) + TEST_ERROR; - /**************** - * Check that the VFD feature flags are correct - * SPEC MAY CHANGE - ******************/ - - FAIL_IF(H5FDdriver_query(driver_id, &driver_flags) < 0) - - JSVERIFY_NOT(0, (driver_flags & H5FD_FEAT_DATA_SIEVE), - "bit(s) in `driver_flags` must align with " - "H5FD_FEAT_DATA_SIEVE") - - JSVERIFY(H5FD_FEAT_DATA_SIEVE, driver_flags, "H5FD_FEAT_DATA_SIEVE should be the only supported flag") + /* Validate flags */ + if (0 == (driver_flags & H5FD_FEAT_DATA_SIEVE)) + FAIL_PUTS_ERROR("ros3 VFD should support H5FD_FEAT_DATA_SIEVE"); + if (H5FD_FEAT_DATA_SIEVE != driver_flags) + FAIL_PUTS_ERROR("H5FD_FEAT_DATA_SIEVE should be the only supported flag"); PASSED(); return 0; @@ -662,275 +300,189 @@ test_ros3_fapl(void) error: H5E_BEGIN_TRY { - (void)H5Pclose(fapl_id); + H5Pclose(fapl_id); } H5E_END_TRY return 1; -} /* test_ros3_fapl() */ +} /* end test_ros3_fapl() */ /*--------------------------------------------------------------------------- + * Function: test_vfl_open * - * Function: test_vfd_open() - * - * Purpose: - * - * Demonstrate/specify VFD-level "Open" failure cases - * - * Return: - * - * PASSED : 0 - * FAILED : 1 + * Purpose: Test the VFL "open" callback * + * Return: PASS : 0 + * FAIL : 1 *--------------------------------------------------------------------------- */ static int -test_vfd_open(void) +test_vfl_open(void) { - - /********************* - * test-local macros * - *********************/ - -#define FAPL_H5P_DEFAULT -2 -#define FAPL_FILE_ACCESS -3 -#define FAPL_ROS3_ANON -4 - - /************************* - * test-local structures * - *************************/ - struct test_condition { const char *message; const char *url; unsigned flags; - int which_fapl; + hid_t fapl; haddr_t maxaddr; }; - /************************ - * test-local variables * - ************************/ + /* struct test_condition tests[] defined after fapl initialization */ + H5FD_t *fd = NULL; + hid_t ros3_fapl_id = H5I_INVALID_HID; + hid_t default_fapl_id = H5I_INVALID_HID; + const int TESTS_COUNT = 10; + + TESTING("ros3 VFD-level open"); + + if (false == s3_test_bucket_defined) { + SKIPPED(); + puts(" environment variable HDF5_ROS3_TEST_BUCKET_URL not defined"); + fflush(stdout); + return 0; + } + + /* Set up fapls */ + if ((default_fapl_id = H5Pcreate(H5P_FILE_ACCESS)) < 0) + TEST_ERROR; + if ((ros3_fapl_id = H5Pcreate(H5P_FILE_ACCESS)) < 0) + TEST_ERROR; + if (H5Pset_fapl_ros3(ros3_fapl_id, &anonymous_fa) < 0) + TEST_ERROR; + + /* Set up test cases */ struct test_condition tests[] = { { "default property list (H5P_DEFAULT) is invalid", url_text_public, H5F_ACC_RDONLY, - FAPL_H5P_DEFAULT, + H5P_DEFAULT, MAXADDR, }, { "generic file access property list is invalid", url_text_public, H5F_ACC_RDONLY, - FAPL_FILE_ACCESS, + default_fapl_id, MAXADDR, }, { "filename cannot be null", NULL, H5F_ACC_RDONLY, - FAPL_ROS3_ANON, + ros3_fapl_id, MAXADDR, }, { "filename cannot be empty", "", H5F_ACC_RDONLY, - FAPL_ROS3_ANON, + ros3_fapl_id, MAXADDR, }, { "filename must exist", url_missing, H5F_ACC_RDONLY, - FAPL_ROS3_ANON, + ros3_fapl_id, MAXADDR, }, { "read-write flag not supported", url_text_public, H5F_ACC_RDWR, - FAPL_ROS3_ANON, + ros3_fapl_id, MAXADDR, }, { "truncate flag not supported", url_text_public, H5F_ACC_TRUNC, - FAPL_ROS3_ANON, + ros3_fapl_id, MAXADDR, }, { "create flag not supported", url_text_public, H5F_ACC_CREAT, - FAPL_ROS3_ANON, + ros3_fapl_id, MAXADDR, }, { "EXCL flag not supported", url_text_public, H5F_ACC_EXCL, - FAPL_ROS3_ANON, + ros3_fapl_id, MAXADDR, }, { "maxaddr cannot be 0 (caught in `H5FD_open()`)", url_text_public, H5F_ACC_RDONLY, - FAPL_ROS3_ANON, + ros3_fapl_id, 0, }, }; - H5FD_t *fd = NULL; - bool curl_ready = false; - hid_t fapl_id = H5I_INVALID_HID; - hid_t fapl_file_access = H5I_INVALID_HID; - unsigned i = 0; - unsigned tests_count = 10; - - TESTING("ROS3 VFD-level open"); - - if (false == s3_test_bucket_defined) { - SKIPPED(); - puts(" environment variable HDF5_ROS3_TEST_BUCKET_URL not defined"); - fflush(stdout); - return 0; - } - - FAIL_IF(CURLE_OK != curl_global_init(CURL_GLOBAL_DEFAULT)) - curl_ready = true; - - fapl_file_access = H5Pcreate(H5P_FILE_ACCESS); - FAIL_IF(fapl_file_access < 0) - - fapl_id = H5Pcreate(H5P_FILE_ACCESS); - FAIL_IF(fapl_id < 0) - FAIL_IF(FAIL == H5Pset_fapl_ros3(fapl_id, &anonymous_fa)) - - /********* - * TESTS * - *********/ - /* all the test cases that will _not_ open - */ - for (i = 0; i < tests_count; i++) { - struct test_condition T = tests[i]; - hid_t _fapl_id = H5P_DEFAULT; - - fd = NULL; - - if (T.which_fapl == FAPL_FILE_ACCESS) - _fapl_id = fapl_file_access; - else if (T.which_fapl == FAPL_ROS3_ANON) - _fapl_id = fapl_id; + /* Test a variety of cases that are expected to fail */ + for (int i = 0; i < TESTS_COUNT; i++) { H5E_BEGIN_TRY { - fd = H5FDopen(T.url, T.flags, _fapl_id, T.maxaddr); + fd = H5FDopen(tests[i].url, tests[i].flags, tests[i].fapl, tests[i].maxaddr); } H5E_END_TRY + if (NULL != fd) - JSVERIFY(1, 0, T.message); /* wrapper to print message and fail */ + FAIL_PUTS_ERROR(tests[i].message); } - FAIL_IF(NULL != fd) - - /* finally, show that a file can be opened - */ - fd = H5FDopen(url_text_public, H5F_ACC_RDONLY, fapl_id, MAXADDR); - FAIL_IF(NULL == fd) - - /************ - * TEARDOWN * - ************/ - - FAIL_IF(FAIL == H5FDclose(fd)) - fd = NULL; - - FAIL_IF(FAIL == H5Pclose(fapl_id)) - fapl_id = -1; + /* Finally, show that a file can be opened */ + if (NULL == (fd = H5FDopen(url_text_public, H5F_ACC_RDONLY, ros3_fapl_id, MAXADDR))) + TEST_ERROR; + if (H5FDclose(fd) < 0) + TEST_ERROR; - FAIL_IF(FAIL == H5Pclose(fapl_file_access)) - fapl_file_access = -1; - - curl_global_cleanup(); - curl_ready = false; + if (H5Pclose(default_fapl_id) < 0) + TEST_ERROR; + if (H5Pclose(ros3_fapl_id) < 0) + TEST_ERROR; PASSED(); return 0; error: - /*********** - * CLEANUP * - ***********/ - - if (fd) { - (void)H5FDclose(fd); - } - if (fapl_id >= 0) { - H5E_BEGIN_TRY - { - (void)H5Pclose(fapl_id); - } - H5E_END_TRY - } - if (fapl_file_access >= 0) { - H5E_BEGIN_TRY - { - (void)H5Pclose(fapl_file_access); - } - H5E_END_TRY - } - if (curl_ready == true) { - curl_global_cleanup(); + H5E_BEGIN_TRY + { + H5FDclose(fd); + H5Pclose(default_fapl_id); + H5Pclose(ros3_fapl_id); } + H5E_END_TRY return 1; -#undef FAPL_FILE_ACCESS -#undef FAPL_H5P_DEFAULT -#undef FAPL_ROS3_ANON - -} /* test_vfd_open */ +} /* end test_vfd_open() */ /*--------------------------------------------------------------------------- + * Function: test_eof_eoa * - * Function: test_eof_eoa() - * - * Purpose: - * - * Demonstrate behavior of get_eof, get_eoa, and set_eoa. - * - * Return: - * - * PASSED : 0 - * FAILED : 1 + * Purpose: Demonstrate behavior of get_eof, get_eoa, and set_eoa * + * Return: PASS : 0 + * FAIL : 1 *--------------------------------------------------------------------------- */ static int test_eof_eoa(void) { - - /********************* - * test-local macros * - *********************/ - - /************************* - * test-local structures * - *************************/ - - /************************ - * test-local variables * - ************************/ - - H5FD_t *fd_shakespeare = NULL; - bool curl_ready = false; - hid_t fapl_id = H5I_INVALID_HID; + const haddr_t INITIAL_ADDR = 5458199; /* Fragile! */ + const haddr_t LOWER_ADDR = INITIAL_ADDR - (1024 * 1024); + const haddr_t HIGHER_ADDR = INITIAL_ADDR + (1024 * 1024); + H5FD_t *fd = NULL; + hid_t fapl_id = H5I_INVALID_HID; TESTING("ROS3 eof/eoa gets and sets"); @@ -948,198 +500,69 @@ test_eof_eoa(void) return 0; } - /********* - * SETUP * - *********/ - - FAIL_IF(CURLE_OK != curl_global_init(CURL_GLOBAL_DEFAULT)) - curl_ready = true; - - fapl_id = H5Pcreate(H5P_FILE_ACCESS); - FAIL_IF(0 > fapl_id) - FAIL_IF(FAIL == H5Pset_fapl_ros3(fapl_id, &restricted_access_fa)) - - fd_shakespeare = H5FDopen(url_text_restricted, H5F_ACC_RDONLY, fapl_id, HADDR_UNDEF); - FAIL_IF(NULL == fd_shakespeare) - - /********* - * TESTS * - *********/ - - /* verify as found - */ - JSVERIFY(5458199, H5FDget_eof(fd_shakespeare, H5FD_MEM_DEFAULT), NULL) - JSVERIFY(H5FDget_eof(fd_shakespeare, H5FD_MEM_DEFAULT), H5FDget_eof(fd_shakespeare, H5FD_MEM_DRAW), - "mismatch between DEFAULT and RAW memory types") - JSVERIFY(0, H5FDget_eoa(fd_shakespeare, H5FD_MEM_DEFAULT), "EoA should be unset by H5FDopen") - - /* set EoA below EoF - */ - JSVERIFY(SUCCEED, H5FDset_eoa(fd_shakespeare, H5FD_MEM_DEFAULT, 44442202), "unable to set EoA (lower)") - JSVERIFY(5458199, H5FDget_eof(fd_shakespeare, H5FD_MEM_DEFAULT), "EoF changed") - JSVERIFY(44442202, H5FDget_eoa(fd_shakespeare, H5FD_MEM_DEFAULT), "EoA unchanged") - - /* set EoA above EoF - */ - JSVERIFY(SUCCEED, H5FDset_eoa(fd_shakespeare, H5FD_MEM_DEFAULT, 6789012), "unable to set EoA (higher)") - JSVERIFY(5458199, H5FDget_eof(fd_shakespeare, H5FD_MEM_DEFAULT), "EoF changed") - JSVERIFY(6789012, H5FDget_eoa(fd_shakespeare, H5FD_MEM_DEFAULT), "EoA unchanged") - - /************ - * TEARDOWN * - ************/ - - FAIL_IF(FAIL == H5FDclose(fd_shakespeare)) - - FAIL_IF(FAIL == H5Pclose(fapl_id)) - fapl_id = -1; - - curl_global_cleanup(); - curl_ready = false; + if ((fapl_id = H5Pcreate(H5P_FILE_ACCESS)) < 0) + TEST_ERROR; + if (H5Pset_fapl_ros3(fapl_id, &restricted_access_fa) < 0) + TEST_ERROR; + + /* Open and verify EOA and EOF in a sample file */ + if (NULL == (fd = H5FDopen(url_text_restricted, H5F_ACC_RDONLY, fapl_id, HADDR_UNDEF))) + TEST_ERROR; + if (INITIAL_ADDR != H5FDget_eof(fd, H5FD_MEM_DEFAULT)) + FAIL_PUTS_ERROR("incorrect EOF (fragile - make sure the file size didn't change)"); + if (H5FDget_eof(fd, H5FD_MEM_DEFAULT) != H5FDget_eof(fd, H5FD_MEM_DRAW)) + FAIL_PUTS_ERROR("mismatch between DEFAULT and RAW memory types"); + if (0 != H5FDget_eoa(fd, H5FD_MEM_DEFAULT)) + FAIL_PUTS_ERROR("EOA should be unset by H5FDopen"); + + /* Set EOA below EOF - should succeed w/ EOF changed and EOA unchanged */ + if (H5FDset_eoa(fd, H5FD_MEM_DEFAULT, LOWER_ADDR) < 0) + TEST_ERROR; + if (INITIAL_ADDR != H5FDget_eof(fd, H5FD_MEM_DEFAULT)) + FAIL_PUTS_ERROR("EOF changed when setting (lower) EOA"); + if (LOWER_ADDR != H5FDget_eoa(fd, H5FD_MEM_DEFAULT)) + FAIL_PUTS_ERROR("EOA unchanged when setting (lower) EOA"); + + /* Set EOA above EOF - should succeed w/ EOF changed and EOA unchanged */ + if (H5FDset_eoa(fd, H5FD_MEM_DEFAULT, HIGHER_ADDR) < 0) + TEST_ERROR; + if (INITIAL_ADDR != H5FDget_eof(fd, H5FD_MEM_DEFAULT)) + FAIL_PUTS_ERROR("EOF changed when setting (higher) EOA"); + if (HIGHER_ADDR != H5FDget_eoa(fd, H5FD_MEM_DEFAULT)) + FAIL_PUTS_ERROR("EOA unchanged when setting (higher) EOA"); + + if (H5FDclose(fd) < 0) + TEST_ERROR; + if (H5Pclose(fapl_id) < 0) + TEST_ERROR; PASSED(); return 0; error: - /*********** - * CLEANUP * - ***********/ - - if (fd_shakespeare) - (void)H5FDclose(fd_shakespeare); - if (true == curl_ready) - curl_global_cleanup(); - if (fapl_id >= 0) { - H5E_BEGIN_TRY - { - (void)H5Pclose(fapl_id); - } - H5E_END_TRY - } - - return 1; - -} /* test_eof_eoa */ - -/*----------------------------------------------------------------------------- - * - * Function: test_H5FDread_without_eoa_set_fails() - * - * Purpose: - * - * Demonstrate a not-obvious constraint by the library, preventing - * file read before EoA is set - * - *----------------------------------------------------------------------------- - */ -static int -test_H5FDread_without_eoa_set_fails(void) -{ - char buffer[256]; - unsigned int i = 0; - H5FD_t *file_shakespeare = NULL; - hid_t fapl_id = H5I_INVALID_HID; - - TESTING("ROS3 VFD read-eoa temporal coupling library limitation "); - - if (s3_test_credentials_loaded == 0) { - SKIPPED(); - puts(" s3 credentials are not loaded"); - fflush(stdout); - return 0; - } - - if (false == s3_test_bucket_defined) { - SKIPPED(); - puts(" environment variable HDF5_ROS3_TEST_BUCKET_URL not defined"); - fflush(stdout); - return 0; - } - - /********* - * SETUP * - *********/ - - /* create ROS3 fapl - */ - fapl_id = H5Pcreate(H5P_FILE_ACCESS); - FAIL_IF(fapl_id < 0) - FAIL_IF(FAIL == H5Pset_fapl_ros3(fapl_id, &restricted_access_fa)) - - file_shakespeare = H5FDopen(url_text_restricted, H5F_ACC_RDONLY, fapl_id, MAXADDR); - FAIL_IF(NULL == file_shakespeare) - - JSVERIFY(0, H5FDget_eoa(file_shakespeare, H5FD_MEM_DEFAULT), "EoA should remain unset by H5FDopen") - - for (i = 0; i < 256; i++) - buffer[i] = 0; /* zero buffer contents */ - - /******** - * TEST * - ********/ - - H5E_BEGIN_TRY{/* mute stack trace on expected failure */ - JSVERIFY(FAIL, H5FDread(file_shakespeare, H5FD_MEM_DRAW, H5P_DEFAULT, 1200699, 102, buffer), - "cannot read before eoa is set")} H5E_END_TRY - JSVERIFY_STR("", buffer, "buffer should remain untouched") - - /************ - * TEARDOWN * - ************/ - - FAIL_IF(FAIL == H5FDclose(file_shakespeare)) - file_shakespeare = NULL; - - FAIL_IF(FAIL == H5Pclose(fapl_id)) - fapl_id = -1; - - PASSED(); - return 0; - -error: - /*********** - * CLEANUP * - ***********/ - - if (file_shakespeare) { - (void)H5FDclose(file_shakespeare); - } - if (fapl_id >= 0) { - H5E_BEGIN_TRY - { - (void)H5Pclose(fapl_id); - } - H5E_END_TRY + H5E_BEGIN_TRY + { + H5FDclose(fd); + H5Pclose(fapl_id); } + H5E_END_TRY return 1; -} /* test_H5FDread_without_eoa_set_fails */ +} /* end test_eof_eoa() */ /*--------------------------------------------------------------------------- + * Function: test_vfl_read * - * Function: test_read() - * - * Purpose: - * - * Return: - * - * PASSED : 0 - * FAILED : 1 + * Purpose: Test reading via the VFL API * + * Return: PASS : 0 + * FAIL : 1 *--------------------------------------------------------------------------- */ static int -test_read(void) +test_vfl_read(void) { - - /********************* - * test-local macros * - *********************/ - - /************************* - * test-local structures * - *************************/ struct testcase { const char *message; /* purpose of test case */ haddr_t eoa_set; /* set file EOA to this prior to read */ @@ -1149,10 +572,7 @@ test_read(void) const char *expected; /* expected contents of buffer; failure ignores */ }; - /************************ - * test-local variables * - ************************/ - struct testcase cases[] = { + struct testcase tests[] = { { "successful range-get", 6464, @@ -1202,16 +622,12 @@ test_read(void) NULL, }, }; - unsigned testcase_count = 6; - unsigned test_i = 0; - struct testcase test; - herr_t open_return = FAIL; - char buffer[S3_TEST_MAX_URL_SIZE]; - unsigned int i = 0; - H5FD_t *file_raven = NULL; - hid_t fapl_id = H5I_INVALID_HID; + const int TESTCASE_COUNT = 6; + char buffer[S3_TEST_MAX_URL_SIZE]; + H5FD_t *fd = NULL; + hid_t fapl_id = H5I_INVALID_HID; - TESTING("ROS3 VFD read/range-gets"); + TESTING("ros3 VFD read/range-gets"); if (s3_test_credentials_loaded == 0) { SKIPPED(); @@ -1227,132 +643,89 @@ test_read(void) return 0; } - /********* - * SETUP * - *********/ + if ((fapl_id = H5Pcreate(H5P_FILE_ACCESS)) < 0) + TEST_ERROR; + if (H5Pset_fapl_ros3(fapl_id, &restricted_access_fa) < 0) + TEST_ERROR; - /* create ROS3 fapl - */ - fapl_id = H5Pcreate(H5P_FILE_ACCESS); - FAIL_IF(fapl_id < 0) - FAIL_IF(FAIL == H5Pset_fapl_ros3(fapl_id, &restricted_access_fa)) + if (NULL == (fd = H5FDopen(url_text_public, H5F_ACC_RDONLY, fapl_id, HADDR_UNDEF))) + TEST_ERROR; + if (6464 != H5FDget_eof(fd, H5FD_MEM_DEFAULT)) + FAIL_PUTS_ERROR("incorrect EOF (fragile - make sure the file size didn't change)"); - /* open file - */ - file_raven = - H5FDopen( /* will open with "authenticating" fapl */ - url_text_public, /* TODO: check return state: anon access of restricted says OK? (not NULL) - */ - H5F_ACC_RDONLY, fapl_id, HADDR_UNDEF); /* Demonstrate success with "automatic" value */ - FAIL_IF(NULL == file_raven) + for (int i = 0; i < TESTCASE_COUNT; i++) { - JSVERIFY(6464, H5FDget_eof(file_raven, H5FD_MEM_DEFAULT), NULL) + herr_t ret = FAIL; - /********* - * TESTS * - *********/ + /* Per-test setup */ - for (test_i = 0; test_i < testcase_count; test_i++) { + if (S3_TEST_MAX_URL_SIZE < tests[i].len) + FAIL_PUTS_ERROR("buffer too small!"); + if (H5FD_set_eoa(fd, H5FD_MEM_DEFAULT, tests[i].eoa_set) < 0) + TEST_ERROR; + memset(buffer, 0, S3_TEST_MAX_URL_SIZE); - /* -------------- * - * per-test setup * - * -------------- */ - - test = cases[test_i]; - open_return = FAIL; - - FAIL_IF(S3_TEST_MAX_URL_SIZE < test.len) /* buffer too small! */ - - FAIL_IF(FAIL == H5FD_set_eoa(file_raven, H5FD_MEM_DEFAULT, test.eoa_set)) - - for (i = 0; i < S3_TEST_MAX_URL_SIZE; i++) /* zero buffer contents */ - buffer[i] = 0; - - /* ------------ * - * conduct test * - * ------------ */ + /* Check test config */ H5E_BEGIN_TRY { - open_return = H5FDread(file_raven, H5FD_MEM_DRAW, H5P_DEFAULT, test.addr, test.len, buffer); + ret = H5FDread(fd, H5FD_MEM_DRAW, H5P_DEFAULT, tests[i].addr, tests[i].len, buffer); } H5E_END_TRY - JSVERIFY(test.success, open_return, test.message) - if (open_return == SUCCEED) - JSVERIFY_STR(test.expected, buffer, NULL) - - } /* for each testcase */ - - /************ - * TEARDOWN * - ************/ - - FAIL_IF(FAIL == H5FDclose(file_raven)) - file_raven = NULL; + if (tests[i].success != ret) + FAIL_PUTS_ERROR(tests[i].message); + if (ret == SUCCEED) + if (strncmp(tests[i].expected, buffer, S3_TEST_MAX_URL_SIZE)) + FAIL_PUTS_ERROR("expected output is not the same"); + } - FAIL_IF(FAIL == H5Pclose(fapl_id)) - fapl_id = -1; + if (H5FDclose(fd) < 0) + TEST_ERROR; + if (H5Pclose(fapl_id) < 0) + TEST_ERROR; PASSED(); return 0; error: - /*********** - * CLEANUP * - ***********/ - - if (file_raven) - (void)H5FDclose(file_raven); - if (fapl_id >= 0) { - H5E_BEGIN_TRY - { - (void)H5Pclose(fapl_id); - } - H5E_END_TRY + H5E_BEGIN_TRY + { + H5FDclose(fd); + H5Pclose(fapl_id); } + H5E_END_TRY return 1; -} /* test_read */ +} /* end test_vfl_read() */ -/*--------------------------------------------------------------------------- - * - * Function: test_noops_and_autofails() - * - * Purpose: - * - * Demonstrate the unavailable and do-nothing routines unique to - * Read-Only VFD. - * - * Return: +/*----------------------------------------------------------------------------- + * Function: test_vfl_read_without_eoa_set_fails * - * PASSED : 0 - * FAILED : 1 + * Purpose: Demonstrate a not-obvious constraint by the library, preventing + * file read before EOA is set * - *--------------------------------------------------------------------------- + * Return: PASS : 0 + * FAIL : 1 + *----------------------------------------------------------------------------- */ static int -test_noops_and_autofails(void) +test_vfl_read_without_eoa_set_fails(void) { - /********************* - * test-local macros * - *********************/ - - /************************* - * test-local structures * - *************************/ + char buffer[256]; + H5FD_t *fd = NULL; + hid_t fapl_id = H5I_INVALID_HID; + herr_t ret; - /************************ - * test-local variables * - ************************/ + TESTING("ros3 VFD read-eoa temporal coupling library limitation"); - bool curl_ready = false; - hid_t fapl_id = H5I_INVALID_HID; - H5FD_t *file = NULL; - const char data[36] = "The Force shall be with you, always"; - - TESTING("ROS3 VFD always-fail and no-op routines"); + if (s3_test_credentials_loaded == 0) { + SKIPPED(); + puts(" s3 credentials are not loaded"); + fflush(stdout); + return 0; + } if (false == s3_test_bucket_defined) { SKIPPED(); @@ -1361,115 +734,149 @@ test_noops_and_autofails(void) return 0; } - /********* - * SETUP * - *********/ + /* Set up fapl */ + if ((fapl_id = H5Pcreate(H5P_FILE_ACCESS)) < 0) + TEST_ERROR; + if (H5Pset_fapl_ros3(fapl_id, &restricted_access_fa) < 0) + TEST_ERROR; - FAIL_IF(CURLE_OK != curl_global_init(CURL_GLOBAL_DEFAULT)) - curl_ready = true; + /* Open w/ VFL call */ + if (NULL == (fd = H5FDopen(url_text_restricted, H5F_ACC_RDONLY, fapl_id, MAXADDR))) + TEST_ERROR; + if (0 != H5FDget_eoa(fd, H5FD_MEM_DEFAULT)) + FAIL_PUTS_ERROR("EOA should remain unset by H5FDopen"); - /* create ROS3 fapl - */ - fapl_id = H5Pcreate(H5P_FILE_ACCESS); - FAIL_IF(fapl_id < 0) - JSVERIFY(SUCCEED, H5Pset_fapl_ros3(fapl_id, &anonymous_fa), NULL) + /* Try reading without EOA set (should fail) */ + memset(buffer, 0, 256); + H5E_BEGIN_TRY + { + ret = H5FDread(fd, H5FD_MEM_DRAW, H5P_DEFAULT, 1200699, 102, buffer); + } + H5E_END_TRY + if (ret != FAIL) + FAIL_PUTS_ERROR("should not be able to read before eoa is set"); + for (int i = 0; i < 256; i++) { + if (buffer[i] != 0) + FAIL_PUTS_ERROR("buffer should remain untouched"); + } - /* open file - */ - file = H5FDopen(url_text_public, H5F_ACC_RDONLY, fapl_id, HADDR_UNDEF); - FAIL_IF(NULL == file) + if (H5FDclose(fd) < 0) + TEST_ERROR; + if (H5Pclose(fapl_id) < 0) + TEST_ERROR; - /********* - * TESTS * - *********/ + PASSED(); + return 0; - /* auto-fail calls to write and truncate - */ - H5E_BEGIN_TRY{JSVERIFY(FAIL, H5FDwrite(file, H5FD_MEM_DRAW, H5P_DEFAULT, 1000, 35, data), - "write must fail")} H5E_END_TRY +error: + H5E_BEGIN_TRY + { + H5FDclose(fd); + H5Pclose(fapl_id); + } + H5E_END_TRY - H5E_BEGIN_TRY{JSVERIFY(FAIL, H5FDtruncate(file, H5P_DEFAULT, false), "truncate must fail")} H5E_END_TRY + return 1; - H5E_BEGIN_TRY{ - JSVERIFY(FAIL, H5FDtruncate(file, H5P_DEFAULT, true), "truncate must fail (closing)")} H5E_END_TRY +} /* end test_vfl_read_without_eoa_set_fails() */ - /************ - * TEARDOWN * - ************/ +/*--------------------------------------------------------------------------- + * Function: test_noops_and_autofails + * + * Purpose: Demonstrate the unavailable and do-nothing routines unique to + * Read-Only VFD + * + * Return: PASS : 0 + * FAIL : 1 + *--------------------------------------------------------------------------- + */ +static int +test_noops_and_autofails(void) +{ + hid_t fapl_id = H5I_INVALID_HID; + H5FD_t *fd = NULL; + const char data[36] = "The Force shall be with you, always"; + herr_t ret; - FAIL_IF(FAIL == H5FDclose(file)) - file = NULL; + TESTING("ros3 VFD always-fail and no-op routines"); - FAIL_IF(FAIL == H5Pclose(fapl_id)) - fapl_id = -1; + if (false == s3_test_bucket_defined) { + SKIPPED(); + puts(" environment variable HDF5_ROS3_TEST_BUCKET_URL not defined"); + fflush(stdout); + return 0; + } - curl_global_cleanup(); - curl_ready = false; + if ((fapl_id = H5Pcreate(H5P_FILE_ACCESS)) < 0) + TEST_ERROR; + if (H5Pset_fapl_ros3(fapl_id, &anonymous_fa) < 0) + TEST_ERROR; + if (NULL == (fd = H5FDopen(url_text_public, H5F_ACC_RDONLY, fapl_id, HADDR_UNDEF))) + TEST_ERROR; + + /* Calls to write and truncate must fail */ + H5E_BEGIN_TRY + { + ret = H5FDwrite(fd, H5FD_MEM_DRAW, H5P_DEFAULT, 1000, 35, data); + } + H5E_END_TRY + if (ret == SUCCEED) + FAIL_PUTS_ERROR("write calls must fail"); + + H5E_BEGIN_TRY + { + ret = H5FDtruncate(fd, H5P_DEFAULT, false); + } + H5E_END_TRY + if (ret == SUCCEED) + FAIL_PUTS_ERROR("truncate calls must fail"); + + H5E_BEGIN_TRY + { + ret = H5FDtruncate(fd, H5P_DEFAULT, true); + } + H5E_END_TRY + if (ret == SUCCEED) + FAIL_PUTS_ERROR("truncate calls must fail (closing flag set)"); + + if (H5FDclose(fd) < 0) + TEST_ERROR; + if (H5Pclose(fapl_id) < 0) + TEST_ERROR; PASSED(); return 0; error: - /*********** - * CLEANUP * - ***********/ - - if (fapl_id >= 0) { - H5E_BEGIN_TRY - { - (void)H5Pclose(fapl_id); - } - H5E_END_TRY - } - if (file) { - (void)H5FDclose(file); - } - if (curl_ready == true) { - curl_global_cleanup(); + H5E_BEGIN_TRY + { + H5FDclose(fd); + H5Pclose(fapl_id); } + H5E_END_TRY return 1; -} /* test_noops_and_autofails*/ +} /* end test_noops_and_autofails() */ /*--------------------------------------------------------------------------- + * Function: test_cmp * - * Function: test_cmp() - * - * Purpose: - * - * Verify "file comparison" behavior. - * - * Return: - * - * PASSED : 0 - * FAILED : 1 + * Purpose: Verify file comparison behavior * + * Return: PASS : 0 + * FAIL : 1 *--------------------------------------------------------------------------- */ static int test_cmp(void) { - - /********************* - * test-local macros * - *********************/ - - /************************* - * test-local structures * - *************************/ - - /************************ - * test-local variables * - ************************/ - H5FD_t *fd_raven = NULL; H5FD_t *fd_shakes = NULL; H5FD_t *fd_raven_2 = NULL; - bool curl_ready = false; hid_t fapl_id = H5I_INVALID_HID; - TESTING("ROS3 cmp (comparison)"); + TESTING("ros3 cmp (comparison)"); if (s3_test_credentials_loaded == 0) { SKIPPED(); @@ -1485,112 +892,69 @@ test_cmp(void) return 0; } - /********* - * SETUP * - *********/ - - FAIL_IF(CURLE_OK != curl_global_init(CURL_GLOBAL_DEFAULT)) - curl_ready = true; - - fapl_id = H5Pcreate(H5P_FILE_ACCESS); - FAIL_IF(0 > fapl_id) - JSVERIFY(SUCCEED, H5Pset_fapl_ros3(fapl_id, &restricted_access_fa), NULL) - - fd_raven = H5FDopen(url_text_public, H5F_ACC_RDONLY, fapl_id, HADDR_UNDEF); - FAIL_IF(NULL == fd_raven) - - fd_shakes = H5FDopen(url_text_restricted, H5F_ACC_RDONLY, fapl_id, HADDR_UNDEF); - FAIL_IF(NULL == fd_shakes) - - fd_raven_2 = H5FDopen(url_text_public, H5F_ACC_RDONLY, fapl_id, HADDR_UNDEF); - FAIL_IF(NULL == fd_raven_2) - - /********* - * TESTS * - *********/ - - JSVERIFY(0, H5FDcmp(fd_raven, fd_raven_2), NULL) - JSVERIFY(-1, H5FDcmp(fd_raven, fd_shakes), NULL) - JSVERIFY(-1, H5FDcmp(fd_shakes, fd_raven_2), NULL) - - /************ - * TEARDOWN * - ************/ - - FAIL_IF(FAIL == H5FDclose(fd_raven)) - fd_raven = NULL; - FAIL_IF(FAIL == H5FDclose(fd_shakes)) - fd_shakes = NULL; - FAIL_IF(FAIL == H5FDclose(fd_raven_2)) - fd_raven_2 = NULL; - FAIL_IF(FAIL == H5Pclose(fapl_id)) - fapl_id = -1; - - curl_global_cleanup(); - curl_ready = false; + if ((fapl_id = H5Pcreate(H5P_FILE_ACCESS)) < 0) + TEST_ERROR; + if (H5Pset_fapl_ros3(fapl_id, &restricted_access_fa) < 0) + TEST_ERROR; + + /* Open files */ + if (NULL == (fd_raven = H5FDopen(url_text_public, H5F_ACC_RDONLY, fapl_id, HADDR_UNDEF))) + TEST_ERROR; + if (NULL == (fd_shakes = H5FDopen(url_text_restricted, H5F_ACC_RDONLY, fapl_id, HADDR_UNDEF))) + TEST_ERROR; + if (NULL == (fd_raven_2 = H5FDopen(url_text_public, H5F_ACC_RDONLY, fapl_id, HADDR_UNDEF))) + TEST_ERROR; + + /* Compare files */ + if (0 != H5FDcmp(fd_raven, fd_raven_2)) + FAIL_PUTS_ERROR("bad comparison (case 1)"); + if (-1 != H5FDcmp(fd_raven, fd_shakes)) + FAIL_PUTS_ERROR("bad comparison (case 2)"); + if (-1 != H5FDcmp(fd_shakes, fd_raven_2)) + FAIL_PUTS_ERROR("bad comparison (case 3)"); + + if (H5FDclose(fd_raven) < 0) + TEST_ERROR; + if (H5FDclose(fd_shakes) < 0) + TEST_ERROR; + if (H5FDclose(fd_raven_2) < 0) + TEST_ERROR; + if (H5Pclose(fapl_id) < 0) + TEST_ERROR; PASSED(); return 0; error: - /*********** - * CLEANUP * - ***********/ - - if (fd_raven != NULL) - (void)H5FDclose(fd_raven); - if (fd_raven_2 != NULL) - (void)H5FDclose(fd_raven_2); - if (fd_shakes != NULL) - (void)H5FDclose(fd_shakes); - if (true == curl_ready) - curl_global_cleanup(); - if (fapl_id >= 0) { - H5E_BEGIN_TRY - { - (void)H5Pclose(fapl_id); - } - H5E_END_TRY + H5E_BEGIN_TRY + { + H5FDclose(fd_raven); + H5FDclose(fd_shakes); + H5FDclose(fd_raven_2); + H5Pclose(fapl_id); } + H5E_END_TRY return 1; -} /* test_cmp */ +} /* end test_cmp() */ /*--------------------------------------------------------------------------- + * Function: test_ros3_access_modes * - * Function: test_H5F_integration() - * - * Purpose: - * - * Demonstrate S3 file-open through H5F API. - * - * Return: - * - * PASSED : 0 - * FAILED : 1 + * Purpose: Make sure ros3 files can only be opened read-only * + * Return: PASS : 0 + * FAIL : 1 *--------------------------------------------------------------------------- */ static int -test_H5F_integration(void) +test_ros3_access_modes(void) { - /********************* - * test-local macros * - *********************/ - - /************************* - * test-local structures * - *************************/ - - /************************ - * test-local variables * - ************************/ - - hid_t file = H5I_INVALID_HID; + hid_t fid = H5I_INVALID_HID; hid_t fapl_id = H5I_INVALID_HID; - TESTING("S3 file access through HD5F library (H5F API)"); + TESTING("ros3 access modes"); if (s3_test_credentials_loaded == 0) { SKIPPED(); @@ -1606,76 +970,61 @@ test_H5F_integration(void) return 0; } - /********* - * SETUP * - *********/ - - fapl_id = H5Pcreate(H5P_FILE_ACCESS); - FAIL_IF(0 > fapl_id) - FAIL_IF(FAIL == H5Pset_fapl_ros3(fapl_id, &restricted_access_fa)) - - /********* - * TESTS * - *********/ - - /* Read-Write Open access is not allowed with this file driver. - */ - H5E_BEGIN_TRY{FAIL_IF(0 <= H5Fopen(url_h5_public, H5F_ACC_RDWR, fapl_id))} H5E_END_TRY - - /* H5Fcreate() is not allowed with this file driver. - */ - H5E_BEGIN_TRY{FAIL_IF(0 <= H5Fcreate(url_missing, H5F_ACC_RDONLY, H5P_DEFAULT, fapl_id))} H5E_END_TRY + if ((fapl_id = H5Pcreate(H5P_FILE_ACCESS)) < 0) + TEST_ERROR; + if (H5Pset_fapl_ros3(fapl_id, &restricted_access_fa) < 0) + TEST_ERROR; - /* Successful open. - */ - file = H5Fopen(url_h5_public, H5F_ACC_RDONLY, fapl_id); - FAIL_IF(file < 0) + /* Read-Write Open access is not allowed with this file driver */ + H5E_BEGIN_TRY + { + fid = H5Fopen(url_h5_public, H5F_ACC_RDWR, fapl_id); + } + H5E_END_TRY + if (fid != H5I_INVALID_HID) + FAIL_PUTS_ERROR("should not be allowed to open a file read-write with the ros3 VFD"); - /************ - * TEARDOWN * - ************/ + /* H5Fcreate() is not allowed with this file driver */ + H5E_BEGIN_TRY + { + fid = H5Fcreate(url_missing, H5F_ACC_RDONLY, H5P_DEFAULT, fapl_id); + } + H5E_END_TRY + if (fid != H5I_INVALID_HID) + FAIL_PUTS_ERROR("should not be allowed to create a file with the ros3 VFD"); - FAIL_IF(FAIL == H5Fclose(file)) - file = -1; + /* Read-only access should succeed */ + if ((fid = H5Fopen(url_h5_public, H5F_ACC_RDONLY, fapl_id)) < 0) + TEST_ERROR; - FAIL_IF(FAIL == H5Pclose(fapl_id)) - fapl_id = -1; + if (H5Fclose(fid) < 0) + TEST_ERROR; + if (H5Pclose(fapl_id) < 0) + TEST_ERROR; PASSED(); return 0; error: - /*********** - * CLEANUP * - ***********/ - printf("\nerror!"); - fflush(stdout); - - if (fapl_id >= 0) { - H5E_BEGIN_TRY - { - (void)H5Pclose(fapl_id); - } - H5E_END_TRY + H5E_BEGIN_TRY + { + H5Fclose(fid); + H5Pclose(fapl_id); } - if (file > 0) - (void)H5Fclose(file); + H5E_END_TRY return 1; -} /* test_H5F_integration */ - +} /* end test_ros3_access_modes() */ #endif /* H5_HAVE_ROS3_VFD */ /*------------------------------------------------------------------------- - * * Function: main * - * Purpose: Tests the basic features of Virtual File Drivers - * - * Return: Success: 0 - * Failure: 1 + * Purpose: Tests the basic functionality of the ros3 VFD * + * Return: Success: EXIT_SUCCESS + * Failure: EXIT_FAILURE *------------------------------------------------------------------------- */ int @@ -1692,7 +1041,7 @@ main(void) #ifdef H5_HAVE_ROS3_VFD /************************ - * initialize test urls * + * Initialize test urls * ************************/ bucket_url_env = getenv("HDF5_ROS3_TEST_BUCKET_URL"); @@ -1709,39 +1058,37 @@ main(void) (const char *)s3_test_bucket_url, (const char *)S3_TEST_RESOURCE_TEXT_RESTRICTED)) { printf("* ros3 setup failed (text_restricted) ! *\n"); - return 1; + return EXIT_FAILURE; } if (S3_TEST_MAX_URL_SIZE < snprintf(url_text_public, (size_t)S3_TEST_MAX_URL_SIZE, "%s/%s", (const char *)s3_test_bucket_url, (const char *)S3_TEST_RESOURCE_TEXT_PUBLIC)) { printf("* ros3 setup failed (text_public) ! *\n"); - return 1; + return EXIT_FAILURE; } if (S3_TEST_MAX_URL_SIZE < snprintf(url_h5_public, (size_t)S3_TEST_MAX_URL_SIZE, "%s/%s", (const char *)s3_test_bucket_url, (const char *)S3_TEST_RESOURCE_H5_PUBLIC)) { printf("* ros3 setup failed (h5_public) ! *\n"); - return 1; + return EXIT_FAILURE; } if (S3_TEST_MAX_URL_SIZE < snprintf(url_missing, S3_TEST_MAX_URL_SIZE, "%s/%s", (const char *)s3_test_bucket_url, (const char *)S3_TEST_RESOURCE_MISSING)) { printf("* ros3 setup failed (missing) ! *\n"); - return 1; + return EXIT_FAILURE; } /************************************** - * load credentials and prepare fapls * + * Load credentials and prepare fapls * **************************************/ - /* "clear" profile data strings */ + /* Clear profile data strings */ s3_test_aws_access_key_id[0] = '\0'; s3_test_aws_secret_access_key[0] = '\0'; s3_test_aws_region[0] = '\0'; - /* attempt to load test credentials - * if unable, certain tests will be skipped - */ + /* Attempt to load test credentials - if unable, certain tests will be skipped */ if (SUCCEED == H5FD_s3comms_load_aws_profile(S3_TEST_PROFILE_NAME, s3_test_aws_access_key_id, s3_test_aws_secret_access_key, s3_test_aws_region)) { s3_test_credentials_loaded = 1; @@ -1753,29 +1100,37 @@ main(void) } /****************** - * commence tests * + * Commence tests * ******************/ h5_reset(); - nerrors += test_fapl_config_validation(); - nerrors += test_ros3_fapl(); - nerrors += test_vfd_open(); - nerrors += test_eof_eoa(); - nerrors += test_H5FDread_without_eoa_set_fails(); - nerrors += test_read(); - nerrors += test_noops_and_autofails(); - nerrors += test_cmp(); - nerrors += test_H5F_integration(); + if (CURLE_OK != curl_global_init(CURL_GLOBAL_DEFAULT)) { + printf("Unable to set up curl, can't run ros3 tests\n"); + nerrors++; + } + + if (nerrors == 0) { + nerrors += test_fapl_config_validation(); + nerrors += test_ros3_fapl_driver_flags(); + nerrors += test_vfl_open(); + nerrors += test_eof_eoa(); + nerrors += test_vfl_read(); + nerrors += test_vfl_read_without_eoa_set_fails(); + nerrors += test_noops_and_autofails(); + nerrors += test_cmp(); + nerrors += test_ros3_access_modes(); + } + + curl_global_cleanup(); if (nerrors > 0) { printf("***** %d ros3 TEST%s FAILED! *****\n", nerrors, nerrors > 1 ? "S" : ""); - nerrors = 1; + return EXIT_FAILURE; } - else { - printf("All ros3 tests passed.\n"); - } - return nerrors; /* 0 if no errors, 1 if any errors */ + + printf("All ros3 tests passed.\n"); + return EXIT_SUCCESS; #else @@ -1784,4 +1139,4 @@ main(void) #endif /* H5_HAVE_ROS3_VFD */ -} /* main() */ +} /* end main() */ From a7ff043b59ef89b89b7fa86af9992024aa806bb0 Mon Sep 17 00:00:00 2001 From: Dana Robinson <43805+derobins@users.noreply.github.com> Date: Wed, 19 Jun 2024 12:24:13 -0700 Subject: [PATCH 26/45] Removed unused code from H5FDs3comms.c (#4588) * H5FD_s3comms_nlowercase() * H5FD_s3comms_trim() * H5FD_s3comms_uriencode() --- src/H5FDs3comms.c | 199 ------------------------------- src/H5FDs3comms.h | 8 -- test/s3comms.c | 297 ---------------------------------------------- 3 files changed, 504 deletions(-) diff --git a/src/H5FDs3comms.c b/src/H5FDs3comms.c index 9b0d786dfe7..26691318e60 100644 --- a/src/H5FDs3comms.c +++ b/src/H5FDs3comms.c @@ -1967,51 +1967,6 @@ H5FD_s3comms_load_aws_profile(const char *profile_name, char *key_id_out, char * FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD_s3comms_load_aws_profile() */ -/*---------------------------------------------------------------------------- - * - * Function: H5FD_s3comms_nlowercase() - * - * Purpose: - * - * From string starting at `s`, write `len` characters to `dest`, - * converting all to lowercase. - * - * Behavior is undefined if `s` is NULL or `len` overruns the allocated - * space of either `s` or `dest`. - * - * Provided as convenience. - * - * Return: - * - * - SUCCESS: `SUCCEED` - * - upon completion, `dest` is populated - * - FAILURE: `FAIL` - * - `dest == NULL` - * - *---------------------------------------------------------------------------- - */ -herr_t -H5FD_s3comms_nlowercase(char *dest, const char *s, size_t len) -{ - herr_t ret_value = SUCCEED; - - FUNC_ENTER_NOAPI_NOINIT - - if (dest == NULL) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "destination cannot be null."); - - if (len > 0) { - H5MM_memcpy(dest, s, len); - do { - len--; - dest[len] = (char)tolower((int)dest[len]); - } while (len > 0); - } - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5FD_s3comms_nlowercase() */ - /*---------------------------------------------------------------------------- * * Function: H5FD_s3comms_parse_url() @@ -2511,158 +2466,4 @@ H5FD_s3comms_tostringtosign(char *dest, const char *req, const char *now, const FUNC_LEAVE_NOAPI(ret_value) } /* end H5ros3_tostringtosign() */ -/*---------------------------------------------------------------------------- - * - * Function: H5FD_s3comms_trim() - * - * Purpose: - * - * Remove all whitespace characters from start and end of a string `s` - * of length `s_len`, writing trimmed string copy to `dest`. - * Stores number of characters remaining at `n_written`. - * - * Destination for trimmed copy `dest` cannot be null. - * `dest` must have adequate space allocated for trimmed copy. - * If inadequate space, behavior is undefined, possibly resulting - * in segfault or overwrite of other data. - * - * If `s` is NULL or all whitespace, `dest` is untouched and `n_written` - * is set to 0. - * - * Return: - * - * - SUCCESS: `SUCCEED` - * - FAILURE: `FAIL` - * - `dest == NULL` - * - *---------------------------------------------------------------------------- - */ -herr_t -H5FD_s3comms_trim(char *dest, char *s, size_t s_len, size_t *n_written) -{ - herr_t ret_value = SUCCEED; - - FUNC_ENTER_NOAPI_NOINIT - - if (dest == NULL) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "destination cannot be null."); - if (s == NULL) - s_len = 0; - - if (s_len > 0) { - /* Find first non-whitespace character from start; - * reduce total length per character. - */ - while (s_len > 0 && isspace((unsigned char)s[0])) { - s++; - s_len--; - } - - /* Find first non-whitespace character from tail; - * reduce length per-character. - * If length is 0 already, there is no non-whitespace character. - */ - if (s_len > 0) { - do { - s_len--; - } while (isspace((unsigned char)s[s_len])); - s_len++; - - /* write output into dest */ - H5MM_memcpy(dest, s, s_len); - } - } - - *n_written = s_len; - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5FD_s3comms_trim() */ - -/*---------------------------------------------------------------------------- - * - * Function: H5FD_s3comms_uriencode() - * - * Purpose: - * - * URIencode (percent-encode) every byte except "[a-zA-Z0-9]-._~". - * - * For each character in source string `_s` from `s[0]` to `s[s_len-1]`, - * writes to `dest` either the raw character or its percent-encoded - * equivalent. - * - * See `H5FD_s3comms_bytes_to_hex` for information on percent-encoding. - * - * Space (' ') character encoded as "%20" (not "+") - * - * Forward-slash ('/') encoded as "%2F" only when `encode_slash == true`. - * - * Records number of characters written at `n_written`. - * - * Assumes that `dest` has been allocated with enough space. - * - * Neither `dest` nor `s` can be NULL. - * - * `s_len == 0` will have no effect. - * - * Return: - * - * - SUCCESS: `SUCCEED` - * - FAILURE: `FAIL` - * - source strings `s` or destination `dest` are NULL - * - error while attempting to percent-encode a character - * - *---------------------------------------------------------------------------- - */ -herr_t -H5FD_s3comms_uriencode(char *dest, const char *s, size_t s_len, bool encode_slash, size_t *n_written) -{ - char c = 0; - size_t dest_off = 0; - char hex_buffer[13]; - size_t hex_off = 0; - size_t hex_len = 0; - herr_t ret_value = SUCCEED; - size_t s_off = 0; - - FUNC_ENTER_NOAPI_NOINIT - - if (s == NULL) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "source string cannot be NULL"); - if (dest == NULL) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "destination cannot be NULL"); - - /* Write characters to destination, converting to percent-encoded - * "hex-utf-8" strings if necessary. - * e.g., '$' -> "%24" - */ - for (s_off = 0; s_off < s_len; s_off++) { - c = s[s_off]; - if (isalnum(c) || c == '.' || c == '-' || c == '_' || c == '~' || (c == '/' && encode_slash == false)) - dest[dest_off++] = c; - else { - hex_off = 0; - if (H5FD_s3comms_percent_encode_char(hex_buffer, (const unsigned char)c, &hex_len) == FAIL) { - hex_buffer[0] = c; - hex_buffer[1] = 0; - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, - "unable to percent-encode character \'%s\' " - "at %d in \"%s\"", - hex_buffer, (int)s_off, s); - } - - for (hex_off = 0; hex_off < hex_len; hex_off++) - dest[dest_off++] = hex_buffer[hex_off]; - } /* end else (not a regular character) */ - } /* end for each character */ - - if (dest_off < s_len) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "buffer overflow"); - - *n_written = dest_off; - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* H5FD_s3comms_uriencode */ - #endif /* H5_HAVE_ROS3_VFD */ diff --git a/src/H5FDs3comms.h b/src/H5FDs3comms.h index 120a71a9c85..d523928efc6 100644 --- a/src/H5FDs3comms.h +++ b/src/H5FDs3comms.h @@ -533,8 +533,6 @@ H5_DLL herr_t H5FD_s3comms_HMAC_SHA256(const unsigned char *key, size_t key_len, H5_DLL herr_t H5FD_s3comms_load_aws_profile(const char *name, char *key_id_out, char *secret_access_key_out, char *aws_region_out); -H5_DLL herr_t H5FD_s3comms_nlowercase(char *dest, const char *s, size_t len); - H5_DLL herr_t H5FD_s3comms_parse_url(const char *str, parsed_url_t **purl); H5_DLL herr_t H5FD_s3comms_percent_encode_char(char *repr, const unsigned char c, size_t *repr_len); @@ -544,12 +542,6 @@ H5_DLL herr_t H5FD_s3comms_signing_key(unsigned char *md, const char *secret, co H5_DLL herr_t H5FD_s3comms_tostringtosign(char *dest, const char *req_str, const char *now, const char *region); - -H5_DLL herr_t H5FD_s3comms_trim(char *dest, char *s, size_t s_len, size_t *n_written); - -H5_DLL herr_t H5FD_s3comms_uriencode(char *dest, const char *s, size_t s_len, bool encode_slash, - size_t *n_written); - #ifdef __cplusplus } #endif diff --git a/test/s3comms.c b/test/s3comms.c index 40f163e8ef2..e08da8e99b1 100644 --- a/test/s3comms.c +++ b/test/s3comms.c @@ -1255,80 +1255,6 @@ test_HMAC_SHA256(void) } /* end test_HMAC_SHA256() */ -/*---------------------------------------------------------------------------- - * - * Function: test_nlowercase() - * - * Purpose: - * - * Define and verify behavior of `H5FD_s3comms_nlowercase()` - * - *---------------------------------------------------------------------------- - */ -static herr_t -test_nlowercase(void) -{ - /************************* - * test-local structures * - *************************/ - - struct testcase { - const char *in; - size_t len; - const char *exp; - }; - - /************************ - * test-local variables * - ************************/ - - /* any character after in exp on or after exp[len] is undefined. - * in this test, kept as the null character for simplicity. - */ - struct testcase cases[] = { - { - "HALlEluJAh", - 6, - "hallel", - }, - { - "all\0 lower", - 10, - "all\0 lower", - }, - { - "to meeeeeee", - 0, - "", - }, - }; - char *dest = NULL; - int i = 0; - int n_cases = 3; - - TESTING("nlowercase"); - - for (i = 0; i < n_cases; i++) { - dest = (char *)malloc(sizeof(char) * 16); - - JSVERIFY(SUCCEED, H5FD_s3comms_nlowercase(dest, cases[i].in, cases[i].len), cases[i].in) - if (cases[i].len > 0) { - JSVERIFY(0, strncmp(dest, cases[i].exp, cases[i].len), NULL) - } - free(dest); - } /* end for each testcase */ - - JSVERIFY(FAIL, H5FD_s3comms_nlowercase(NULL, cases[0].in, cases[0].len), "null destination should fail") - - PASSED(); - return 0; - -error: - free(dest); - return -1; - -} /* end test_nlowercase() */ - /*--------------------------------------------------------------------------- * * Function: test_parse_url() @@ -2252,226 +2178,6 @@ test_tostringtosign(void) } /* end test_tostringtosign() */ -/*---------------------------------------------------------------------------- - * - * Function: test_trim() - * - * Purpose: - * - * Define and verify behavior of `H5FD_s3comms_trim()`. - * - *---------------------------------------------------------------------------- - */ -static herr_t -test_trim(void) -{ - /************************* - * test-local structures * - *************************/ - - struct testcase { - const char *in; - size_t in_len; - const char *exp; - size_t exp_len; - }; - - /************************ - * test-local variables * - ************************/ - - struct testcase cases[] = { - { - "block string", - 12, - "block string", - 12, - }, - { - " \n\r \t", - 6, - "", - 0, - }, - { - " \twhite b4", - 10, - "white b4", - 8, - }, - { - "white after\r\n ", - 15, - "white after", - 11, - }, - { - " on\nends\t", - 9, - "on\nends", - 7, - }, - }; - char dest[32]; - size_t dest_len = 0; - int i = 0; - int n_cases = 5; - char *str = NULL; - - TESTING("s3comms trim"); - - for (i = 0; i < n_cases; i++) { - assert(str == NULL); - str = (char *)malloc(sizeof(char) * cases[i].in_len); - assert(str != NULL); - strncpy(str, cases[i].in, cases[i].in_len); - - JSVERIFY(SUCCEED, H5FD_s3comms_trim(dest, str, cases[i].in_len, &dest_len), NULL) - JSVERIFY(cases[i].exp_len, dest_len, cases[i].in) - if (dest_len > 0) { - JSVERIFY(0, strncmp(cases[i].exp, dest, dest_len), cases[i].exp) - } - free(str); - str = NULL; - } /* end for each testcase */ - - JSVERIFY(SUCCEED, H5FD_s3comms_trim(dest, NULL, 3, &dest_len), - "should not fail when trimming a null string"); - JSVERIFY(0, dest_len, "trimming NULL string writes 0 characters") - - assert(str == NULL); - str = (char *)malloc(sizeof(char *) * 11); - assert(str != NULL); - memcpy(str, "some text ", 11); /* string with null terminator */ - JSVERIFY(FAIL, H5FD_s3comms_trim(NULL, str, 10, &dest_len), "destination for trim cannot be NULL"); - free(str); - str = NULL; - - PASSED(); - return 0; - -error: - if (str != NULL) { - free(str); - } - return -1; - -} /* end test_trim() */ - -/*---------------------------------------------------------------------------- - * - * Function: test_uriencode() - * - * Purpose: - * - * Define and verify behavior of `H5FD_s3comms_uriencode()`. - * - *---------------------------------------------------------------------------- - */ -static herr_t -test_uriencode(void) -{ - /************************* - * test-local structures * - *************************/ - - struct testcase { - const char *str; - size_t s_len; - bool encode_slash; - const char *expected; - }; - - /************************ - * test-local variables * - ************************/ - - struct testcase cases[] = {{ - "/path/to/resource.jpg", - 21, - false, - "/path/to/resource.jpg", - }, - { - "/path/to/resource.jpg", - 21, - true, - "%2Fpath%2Fto%2Fresource.jpg", - }, - { - "string got_spaa ces", - 20, - true, - "string%20got_spaa%20%20ces", - }, - { - "sp ac~es/and-sl ash.encoded", - 27, - true, - "sp%20ac~es%2Fand-sl%20ash.encoded", - }, - { - "sp ac~es/and-sl ash.unencoded", - 29, - false, - "sp%20ac~es/and-sl%20ash.unencoded", - }, - { - "/path/to/resource.txt", - 0, - false, - "", - - }}; - char *dest = NULL; - size_t dest_written = 0; - int i = 0; - int ncases = 6; - size_t str_len = 0; - - TESTING("s3comms uriencode"); - - for (i = 0; i < ncases; i++) { - str_len = cases[i].s_len; - dest = (char *)malloc(sizeof(char) * str_len * 3 + 1); - FAIL_IF(dest == NULL) - - JSVERIFY(SUCCEED, - H5FD_s3comms_uriencode(dest, cases[i].str, str_len, cases[i].encode_slash, &dest_written), - NULL); - JSVERIFY(strlen(cases[i].expected), dest_written, NULL) - JSVERIFY(0, strncmp(dest, cases[i].expected, dest_written), cases[i].expected); - - free(dest); - dest = NULL; - } /* end for each testcase */ - - /*************** - * ERROR CASES * - ***************/ - - dest = (char *)malloc(sizeof(char) * 15); - assert(dest != NULL); - - JSVERIFY(FAIL, H5FD_s3comms_uriencode(NULL, "word$", 5, false, &dest_written), - "destination cannot be NULL"); - JSVERIFY(FAIL, H5FD_s3comms_uriencode(dest, NULL, 5, false, &dest_written), - "source string cannot be NULL"); - - free(dest); - dest = NULL; - - PASSED(); - return 0; - -error: - if (dest != NULL) { - free(dest); - } - return -1; - -} /* end test_uriencode() */ - #endif /* H5_HAVE_ROS3_VFD */ /*------------------------------------------------------------------------- @@ -2532,9 +2238,6 @@ main(void) /* tests ordered roughly by dependence */ nerrors += test_macro_format_credential() < 0 ? 1 : 0; - nerrors += test_trim() < 0 ? 1 : 0; - nerrors += test_nlowercase() < 0 ? 1 : 0; - nerrors += test_uriencode() < 0 ? 1 : 0; nerrors += test_percent_encode_char() < 0 ? 1 : 0; nerrors += test_bytes_to_hex() < 0 ? 1 : 0; nerrors += test_HMAC_SHA256() < 0 ? 1 : 0; From 9319f8daaf253faeda510b3fd0b7a2067a47e45d Mon Sep 17 00:00:00 2001 From: Dana Robinson <43805+derobins@users.noreply.github.com> Date: Wed, 19 Jun 2024 13:03:10 -0700 Subject: [PATCH 27/45] Remove magic fields from s3comms structs (#4589) --- src/H5FDs3comms.c | 76 ++++++----------------------------------------- src/H5FDs3comms.h | 57 +++++++---------------------------- test/s3comms.c | 1 - 3 files changed, 20 insertions(+), 114 deletions(-) diff --git a/src/H5FDs3comms.c b/src/H5FDs3comms.c index 26691318e60..d0577fa5e78 100644 --- a/src/H5FDs3comms.c +++ b/src/H5FDs3comms.c @@ -73,11 +73,9 @@ * pointer to data region and record of bytes written (offset) */ struct s3r_datastruct { - unsigned long magic; - char *data; - size_t size; + char *data; + size_t size; }; -#define S3COMMS_CALLBACK_DATASTRUCT_MAGIC 0x28c2b2ul /********************/ /* Local Prototypes */ @@ -130,9 +128,6 @@ curlwritecallback(char *ptr, size_t size, size_t nmemb, void *userdata) size_t product = (size * nmemb); size_t written = 0; - if (sds->magic != S3COMMS_CALLBACK_DATASTRUCT_MAGIC) - return written; - if (size > 0) { H5MM_memcpy(&(sds->data[sds->size]), ptr, product); sds->size += product; @@ -259,7 +254,6 @@ H5FD_s3comms_hrb_node_set(hrb_node_t **L, const char *name, const char *value) if (new_node == NULL) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "cannot make space for new set."); - new_node->magic = S3COMMS_HRB_NODE_MAGIC; new_node->name = NULL; new_node->value = NULL; new_node->cat = NULL; @@ -292,7 +286,6 @@ H5FD_s3comms_hrb_node_set(hrb_node_t **L, const char *name, const char *value) /* sanity-check pointer passed in */ assert((*L) != NULL); - assert((*L)->magic == S3COMMS_HRB_NODE_MAGIC); node_ptr = (*L); /* Check whether to modify/remove first node in list @@ -312,8 +305,6 @@ H5FD_s3comms_hrb_node_set(hrb_node_t **L, const char *name, const char *value) H5MM_xfree(node_ptr->lowername); H5MM_xfree(node_ptr->name); H5MM_xfree(node_ptr->value); - assert(node_ptr->magic == S3COMMS_HRB_NODE_MAGIC); - node_ptr->magic += 1ul; H5MM_xfree(node_ptr); H5MM_xfree(lowername); @@ -334,7 +325,6 @@ H5FD_s3comms_hrb_node_set(hrb_node_t **L, const char *name, const char *value) H5MM_xfree(lowername); lowername = NULL; - new_node->magic += 1ul; H5MM_xfree(new_node); new_node = NULL; } @@ -420,8 +410,6 @@ H5FD_s3comms_hrb_node_set(hrb_node_t **L, const char *name, const char *value) H5MM_xfree(tmp->name); H5MM_xfree(tmp->value); - assert(tmp->magic == S3COMMS_HRB_NODE_MAGIC); - tmp->magic += 1ul; H5MM_xfree(tmp); H5MM_xfree(lowername); @@ -437,8 +425,6 @@ H5FD_s3comms_hrb_node_set(hrb_node_t **L, const char *name, const char *value) H5MM_xfree(node_ptr->value); H5MM_xfree(node_ptr->cat); - assert(new_node->magic == S3COMMS_HRB_NODE_MAGIC); - new_node->magic += 1ul; H5MM_xfree(new_node); H5MM_xfree(lowername); new_node = NULL; @@ -470,8 +456,6 @@ H5FD_s3comms_hrb_node_set(hrb_node_t **L, const char *name, const char *value) if (valuecpy != NULL) H5MM_xfree(valuecpy); if (new_node != NULL) { - assert(new_node->magic == S3COMMS_HRB_NODE_MAGIC); - new_node->magic += 1ul; H5MM_xfree(new_node); } } @@ -502,14 +486,7 @@ H5FD_s3comms_hrb_node_set(hrb_node_t **L, const char *name, const char *value) * - Destroy node/list separately as appropriate * - Failure to account for this will result in a memory leak. * - * Return: - * - * - SUCCESS: `SUCCEED` - * - successfully released buffer resources - * - if `buf` is NULL or `*buf` is NULL, no effect - * - FAILURE: `FAIL` - * - `buf->magic != S3COMMS_HRB_MAGIC` - * + * Return: SUCCEED (can't fail) *---------------------------------------------------------------------------- */ herr_t @@ -518,22 +495,18 @@ H5FD_s3comms_hrb_destroy(hrb_t **_buf) hrb_t *buf = NULL; herr_t ret_value = SUCCEED; - FUNC_ENTER_NOAPI_NOINIT + FUNC_ENTER_NOAPI_NOINIT_NOERR if (_buf != NULL && *_buf != NULL) { buf = *_buf; - if (buf->magic != S3COMMS_HRB_MAGIC) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "pointer's magic does not match."); H5MM_xfree(buf->verb); H5MM_xfree(buf->version); H5MM_xfree(buf->resource); - buf->magic += 1ul; H5MM_xfree(buf); *_buf = NULL; - } /* end if `_buf` has some value */ + } -done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD_s3comms_hrb_destroy() */ @@ -590,7 +563,6 @@ H5FD_s3comms_hrb_init_request(const char *_verb, const char *_resource, const ch request = (hrb_t *)H5MM_malloc(sizeof(hrb_t)); if (request == NULL) HGOTO_ERROR(H5E_ARGS, H5E_CANTALLOC, NULL, "no space for request structure"); - request->magic = S3COMMS_HRB_MAGIC; request->body = NULL; request->body_len = 0; request->first_header = NULL; @@ -661,13 +633,7 @@ H5FD_s3comms_hrb_init_request(const char *_verb, const char *_resource, const ch * Close communications through given S3 Request Handle (`s3r_t`) * and clean up associated resources. * - * Return: - * - * - SUCCESS: `SUCCEED` - * - FAILURE: `FAIL` - * - fails if handle is null or has invalid magic number - * - * + * Return: SUCCEED/FAIL *---------------------------------------------------------------------------- */ herr_t @@ -679,8 +645,6 @@ H5FD_s3comms_s3r_close(s3r_t *handle) if (handle == NULL) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "handle cannot be null."); - if (handle->magic != S3COMMS_S3R_MAGIC) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "handle has invalid magic."); curl_easy_cleanup(handle->curlhandle); @@ -768,7 +732,7 @@ H5FD_s3comms_s3r_getsize(s3r_t *handle) CURL *curlh = NULL; char *end = NULL; char *headerresponse = NULL; - struct s3r_datastruct sds = {S3COMMS_CALLBACK_DATASTRUCT_MAGIC, NULL, 0}; + struct s3r_datastruct sds = {NULL, 0}; char *start = NULL; herr_t ret_value = SUCCEED; @@ -776,8 +740,6 @@ H5FD_s3comms_s3r_getsize(s3r_t *handle) if (handle == NULL) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "handle cannot be null."); - if (handle->magic != S3COMMS_S3R_MAGIC) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "handle has invalid magic."); if (handle->curlhandle == NULL) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "handle has bad (null) curlhandle."); @@ -860,7 +822,6 @@ H5FD_s3comms_s3r_getsize(s3r_t *handle) done: H5MM_xfree(headerresponse); - sds.magic += 1; /* set to bad magic */ FUNC_LEAVE_NOAPI(ret_value) } /* H5FD_s3comms_s3r_getsize */ @@ -921,13 +882,11 @@ H5FD_s3comms_s3r_open(const char *url, const char *region, const char *id, const HGOTO_ERROR(H5E_ARGS, H5E_CANTCREATE, NULL, "unable to create parsed url structure"); assert(purl != NULL); /* if above passes, this must be true */ - assert(purl->magic == S3COMMS_PARSED_URL_MAGIC); handle = (s3r_t *)H5MM_malloc(sizeof(s3r_t)); if (handle == NULL) HGOTO_ERROR(H5E_ARGS, H5E_CANTALLOC, NULL, "could not malloc space for handle."); - handle->magic = S3COMMS_S3R_MAGIC; handle->purl = purl; handle->filesize = 0; handle->region = NULL; @@ -1113,13 +1072,10 @@ H5FD_s3comms_s3r_read(s3r_t *handle, haddr_t offset, size_t len, void *dest) if (handle == NULL) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "handle cannot be null."); - if (handle->magic != S3COMMS_S3R_MAGIC) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "handle has invalid magic."); if (handle->curlhandle == NULL) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "handle has bad (null) curlhandle."); if (handle->purl == NULL) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "handle has bad (null) url."); - assert(handle->purl->magic == S3COMMS_PARSED_URL_MAGIC); if (offset > handle->filesize || (len + offset) > handle->filesize) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to read past EoF"); @@ -1134,9 +1090,8 @@ H5FD_s3comms_s3r_read(s3r_t *handle, haddr_t offset, size_t len, void *dest) if (sds == NULL) HGOTO_ERROR(H5E_ARGS, H5E_CANTALLOC, FAIL, "could not malloc destination datastructure."); - sds->magic = S3COMMS_CALLBACK_DATASTRUCT_MAGIC; - sds->data = (char *)dest; - sds->size = 0; + sds->data = (char *)dest; + sds->size = 0; if (CURLE_OK != curl_easy_setopt(curlh, CURLOPT_WRITEDATA, sds)) HGOTO_ERROR(H5E_ARGS, H5E_UNINITIALIZED, FAIL, "error while setting CURL option (CURLOPT_WRITEDATA)."); @@ -1244,7 +1199,6 @@ H5FD_s3comms_s3r_read(s3r_t *handle, haddr_t offset, size_t len, void *dest) (const char *)handle->purl->path, "HTTP/1.1"); if (request == NULL) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "could not allocate hrb_t request."); - assert(request->magic == S3COMMS_HRB_MAGIC); now = gmnow(); if (ISO8601NOW(iso8601now, now) != (ISO8601_SIZE - 1)) @@ -1254,13 +1208,11 @@ H5FD_s3comms_s3r_read(s3r_t *handle, haddr_t offset, size_t len, void *dest) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to set x-amz-date header"); if (headers == NULL) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "problem building headers list."); - assert(headers->magic == S3COMMS_HRB_NODE_MAGIC); if (FAIL == H5FD_s3comms_hrb_node_set(&headers, "x-amz-content-sha256", (const char *)EMPTY_SHA256)) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to set x-amz-content-sha256 header"); if (headers == NULL) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "problem building headers list."); - assert(headers->magic == S3COMMS_HRB_NODE_MAGIC); if (strlen((const char *)handle->token) > 0) { if (FAIL == @@ -1268,7 +1220,6 @@ H5FD_s3comms_s3r_read(s3r_t *handle, haddr_t offset, size_t len, void *dest) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to set x-amz-security-token header"); if (headers == NULL) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "problem building headers list."); - assert(headers->magic == S3COMMS_HRB_NODE_MAGIC); } if (rangebytesstr != NULL) { @@ -1276,14 +1227,12 @@ H5FD_s3comms_s3r_read(s3r_t *handle, haddr_t offset, size_t len, void *dest) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to set range header"); if (headers == NULL) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "problem building headers list."); - assert(headers->magic == S3COMMS_HRB_NODE_MAGIC); } if (FAIL == H5FD_s3comms_hrb_node_set(&headers, "Host", handle->purl->host)) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to set host header"); if (headers == NULL) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "problem building headers list."); - assert(headers->magic == S3COMMS_HRB_NODE_MAGIC); request->first_header = headers; @@ -1327,7 +1276,6 @@ H5FD_s3comms_s3r_read(s3r_t *handle, haddr_t offset, size_t len, void *dest) node = request->first_header; while (node != NULL) { - assert(node->magic == S3COMMS_HRB_NODE_MAGIC); curlheaders = curl_slist_append(curlheaders, (const char *)node->cat); if (curlheaders == NULL) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "could not append header to curl slist."); @@ -1530,7 +1478,6 @@ H5FD_s3comms_aws_canonical_request(char *canonical_request_dest, int _cr_size, c if (http_request == NULL) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "hrb object cannot be null."); - assert(http_request->magic == S3COMMS_HRB_MAGIC); if (canonical_request_dest == NULL) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "canonical request destination cannot be null."); @@ -1554,8 +1501,6 @@ H5FD_s3comms_aws_canonical_request(char *canonical_request_dest, int _cr_size, c node = http_request->first_header; /* assumed sorted */ while (node != NULL) { - assert(node->magic == S3COMMS_HRB_NODE_MAGIC); - ret = snprintf(tmpstr, sizeof(tmpstr), "%s:%s\n", node->lowername, node->value); if (ret < 0 || ret >= (int)sizeof(tmpstr)) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to concatenate HTTP header %s:%s", @@ -1668,7 +1613,6 @@ H5FD_s3comms_free_purl(parsed_url_t *purl) FUNC_ENTER_NOAPI_NOINIT_NOERR if (purl != NULL) { - assert(purl->magic == S3COMMS_PARSED_URL_MAGIC); if (purl->scheme != NULL) H5MM_xfree(purl->scheme); if (purl->host != NULL) @@ -1679,7 +1623,6 @@ H5FD_s3comms_free_purl(parsed_url_t *purl) H5MM_xfree(purl->path); if (purl->query != NULL) H5MM_xfree(purl->query); - purl->magic += 1ul; H5MM_xfree(purl); } @@ -2016,7 +1959,6 @@ H5FD_s3comms_parse_url(const char *str, parsed_url_t **_purl) purl = (parsed_url_t *)H5MM_malloc(sizeof(parsed_url_t)); if (purl == NULL) HGOTO_ERROR(H5E_ARGS, H5E_CANTALLOC, FAIL, "can't allocate space for parsed_url_t"); - purl->magic = S3COMMS_PARSED_URL_MAGIC; purl->scheme = NULL; purl->host = NULL; purl->port = NULL; diff --git a/src/H5FDs3comms.h b/src/H5FDs3comms.h index d523928efc6..a0c72c7129a 100644 --- a/src/H5FDs3comms.h +++ b/src/H5FDs3comms.h @@ -207,12 +207,6 @@ * All data (`name`, `value`, `lowername`, and `cat`) are null-terminated * strings allocated specifically for their node. * - * - * - * `magic` (unsigned long) - * - * "unique" identifier number for the structure type - * * `name` (char *) * * Case-meaningful name of the HTTP field. @@ -243,14 +237,12 @@ *---------------------------------------------------------------------------- */ typedef struct hrb_node_t { - unsigned long magic; char *name; char *value; char *cat; char *lowername; struct hrb_node_t *next; } hrb_node_t; -#define S3COMMS_HRB_NODE_MAGIC 0x7F5757UL /*---------------------------------------------------------------------------- * @@ -280,14 +272,6 @@ typedef struct hrb_node_t { * included in the request by a pointer to the head of the list. * * - * - * `magic` (unsigned long) - * - * "Magic" number confirming that this is an hrb_t structure and - * what operations are valid for it. - * - * Must be S3COMMS_HRB_MAGIC to be valid. - * * `body` (char *) : * * Pointer to start of HTTP body. @@ -319,15 +303,13 @@ typedef struct hrb_node_t { *---------------------------------------------------------------------------- */ typedef struct { - unsigned long magic; - char *body; - size_t body_len; - hrb_node_t *first_header; - char *resource; - char *verb; - char *version; + char *body; + size_t body_len; + hrb_node_t *first_header; + char *resource; + char *verb; + char *version; } hrb_t; -#define S3COMMS_HRB_MAGIC 0x6DCC84UL /*---------------------------------------------------------------------------- * @@ -345,12 +327,6 @@ typedef struct { * Scheme Host Port Resource Query/-ies * * - * - * `magic` (unsigned long) - * - * Structure identification and validation identifier. - * Identifies as `parsed_url_t` type. - * * `scheme` (char *) * * String representing which protocol is to be expected. @@ -382,14 +358,12 @@ typedef struct { *---------------------------------------------------------------------------- */ typedef struct { - unsigned long magic; - char *scheme; /* required */ - char *host; /* required */ - char *port; - char *path; - char *query; + char *scheme; /* required */ + char *host; /* required */ + char *port; + char *path; + char *query; } parsed_url_t; -#define S3COMMS_PARSED_URL_MAGIC 0x21D0DFUL /*---------------------------------------------------------------------------- * @@ -411,12 +385,6 @@ typedef struct { * undefined behavior if called to perform in multiple threads. * * - * - * `magic` (unsigned long) - * - * "magic" number identifying this structure as unique type. - * MUST equal `S3R_MAGIC` to be valid. - * * `curlhandle` (CURL) * * Pointer to the curl_easy handle generated for the request. @@ -470,7 +438,6 @@ typedef struct { *---------------------------------------------------------------------------- */ typedef struct { - unsigned long magic; CURL *curlhandle; size_t filesize; char *httpverb; @@ -481,8 +448,6 @@ typedef struct { char *token; } s3r_t; -#define S3COMMS_S3R_MAGIC 0x44d8d79 - #ifdef __cplusplus extern "C" { #endif diff --git a/test/s3comms.c b/test/s3comms.c index e08da8e99b1..0dcff97cc65 100644 --- a/test/s3comms.c +++ b/test/s3comms.c @@ -730,7 +730,6 @@ test_hrb_init_request(void) } else { FAIL_IF(req == NULL); - JSVERIFY(S3COMMS_HRB_MAGIC, req->magic, NULL) if (C->verb == NULL) { JSVERIFY_STR("GET", req->verb, NULL) } From 8a3063b49e7780122ec173f2104e2be95ba312e8 Mon Sep 17 00:00:00 2001 From: Dana Robinson <43805+derobins@users.noreply.github.com> Date: Wed, 19 Jun 2024 14:22:21 -0700 Subject: [PATCH 28/45] Remove dead H5FD_s3comms_percent_encode_char() (#4591) --- src/H5FDs3comms.c | 118 ---------------------------------------------- src/H5FDs3comms.h | 2 - test/s3comms.c | 72 ---------------------------- 3 files changed, 192 deletions(-) diff --git a/src/H5FDs3comms.c b/src/H5FDs3comms.c index d0577fa5e78..4246263a551 100644 --- a/src/H5FDs3comms.c +++ b/src/H5FDs3comms.c @@ -2110,124 +2110,6 @@ H5FD_s3comms_parse_url(const char *str, parsed_url_t **_purl) FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD_s3comms_parse_url() */ -/*---------------------------------------------------------------------------- - * - * Function: H5FD_s3comms_percent_encode_char() - * - * Purpose: - * - * "Percent-encode" utf-8 character `c`, e.g., - * '$' -> "%24" - * '¢' -> "%C2%A2" - * - * `c` cannot be null. - * - * Does not (currently) accept multi-byte characters... - * limit to (?) u+00ff, well below upper bound for two-byte utf-8 encoding - * (u+0080..u+07ff). - * - * Writes output to `repr`. - * `repr` cannot be null. - * Assumes adequate space i `repr`... - * >>> char[4] or [7] for most characters, - * >>> [13] as theoretical maximum. - * - * Representation `repr` is null-terminated. - * - * Stores length of representation (without null terminator) at pointer - * `repr_len`. - * - * Return : SUCCEED/FAIL - * - * - SUCCESS: `SUCCEED` - * - percent-encoded representation written to `repr` - * - 'repr' is null-terminated - * - FAILURE: `FAIL` - * - `c` or `repr` was NULL - * - *---------------------------------------------------------------------------- - */ -herr_t -H5FD_s3comms_percent_encode_char(char *repr, const unsigned char c, size_t *repr_len) -{ - unsigned int i = 0; - int chars_written = 0; - herr_t ret_value = SUCCEED; - - FUNC_ENTER_NOAPI_NOINIT - - if (repr == NULL) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no destination `repr`."); - - if (c <= (unsigned char)0x7f) { - /* character represented in a single "byte" - * and single percent-code - */ - *repr_len = 3; - chars_written = snprintf(repr, 4, "%%%02X", c); - if (chars_written < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "cannot write char %c", c); - } /* end if single-byte unicode char */ - else { - /* multi-byte, multi-percent representation - */ - unsigned int acc = 0; /* byte accumulator */ - unsigned int k = 0; /* uint character representation */ - unsigned int stack_size = 0; - unsigned char stack[4] = {0, 0, 0, 0}; - - stack_size = 0; - k = (unsigned int)c; - *repr_len = 0; - do { - /* push number onto stack in six-bit slices - */ - acc = k; - acc >>= 6; /* cull least */ - acc <<= 6; /* six bits */ - stack[stack_size++] = (unsigned char)(k - acc); - k = acc >> 6; - } while (k > 0); - - /* `stack` now has two to four six-bit 'numbers' to be put into - * UTF-8 byte fields. - */ - - /**************** - * leading byte * - ****************/ - - /* prepend 11[1[1]]0 to first byte */ - /* 110xxxxx, 1110xxxx, or 11110xxx */ - acc = 0xC0; /* 0x11000000 */ - acc += (stack_size > 2) ? 0x20 : 0; /* 0x00100000 */ - acc += (stack_size > 3) ? 0x10 : 0; /* 0x00010000 */ - stack_size--; - chars_written = snprintf(repr, 4, "%%%02X", (unsigned char)(acc + stack[stack_size])); - if (chars_written < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "cannot write char %c", c); - *repr_len += 3; - - /************************ - * continuation byte(s) * - ************************/ - - /* 10xxxxxx */ - for (i = 0; i < stack_size; i++) { - chars_written = - snprintf(&repr[i * 3 + 3], 4, "%%%02X", (unsigned char)(0x80 + stack[stack_size - 1 - i])); - if (chars_written < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "cannot write char %c", c); - *repr_len += 3; - } /* end for each continuation byte */ - } /* end else (multi-byte) */ - - *(repr + *repr_len) = '\0'; - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* H5FD_s3comms_percent_encode_char */ - /*---------------------------------------------------------------------------- * * Function: H5FD_s3comms_signing_key() diff --git a/src/H5FDs3comms.h b/src/H5FDs3comms.h index a0c72c7129a..62855e3d952 100644 --- a/src/H5FDs3comms.h +++ b/src/H5FDs3comms.h @@ -500,8 +500,6 @@ H5_DLL herr_t H5FD_s3comms_load_aws_profile(const char *name, char *key_id_out, H5_DLL herr_t H5FD_s3comms_parse_url(const char *str, parsed_url_t **purl); -H5_DLL herr_t H5FD_s3comms_percent_encode_char(char *repr, const unsigned char c, size_t *repr_len); - H5_DLL herr_t H5FD_s3comms_signing_key(unsigned char *md, const char *secret, const char *region, const char *iso8601now); diff --git a/test/s3comms.c b/test/s3comms.c index 0dcff97cc65..ab447f869d9 100644 --- a/test/s3comms.c +++ b/test/s3comms.c @@ -1546,77 +1546,6 @@ test_parse_url(void) } /* end test_parse_url() */ -/*--------------------------------------------------------------------------- - * - * Function: test_percent_encode_char() - * - * Purpose: - * - * Define and verify behavior of `H5FD_s3comms_percent_encode_char()` - * - * Return: - * - * Success: 0 - * Failure: -1 - * - *--------------------------------------------------------------------------- - */ -static herr_t -test_percent_encode_char(void) -{ - /************************* - * test-local structures * - *************************/ - - struct testcase { - const char c; - const char *exp; - size_t exp_len; - }; - - /************************ - * test-local variables * - ************************/ - - struct testcase cases[] = { - {'$', "%24", 3}, /* u+0024 dollar sign */ - {' ', "%20", 3}, /* u+0020 space */ - {'^', "%5E", 3}, /* u+0094 carat */ - {'/', "%2F", 3}, /* u+002f solidus (forward slash) */ - /* {??, "%C5%8C", 6},*/ /* u+014c Latin Capital Letter O with Macron */ - /* Not included because it is multibyte "wide" character that poses */ - /* issues both in the underlying function and in being written in */ - /* this file. */ - /* {'¢', "%C2%A2", 6}, */ /* u+00a2 cent sign */ - /* above works, but complains about wide character overflow */ - /* Elide for now, until it is determined (a) unnecessary or */ - /* (b) requiring signature change to accommodate wide characters */ - {'\0', "%00", 3}, /* u+0000 null */ - }; - char dest[13]; - size_t dest_len = 0; - int i = 0; - int n_cases = 5; - - TESTING("percent encode characters"); - - for (i = 0; i < n_cases; i++) { - JSVERIFY(SUCCEED, H5FD_s3comms_percent_encode_char(dest, (const unsigned char)cases[i].c, &dest_len), - NULL) - JSVERIFY(cases[i].exp_len, dest_len, NULL) - JSVERIFY(0, strncmp(dest, cases[i].exp, dest_len), NULL) - JSVERIFY_STR(cases[i].exp, dest, NULL) - } - - JSVERIFY(FAIL, H5FD_s3comms_percent_encode_char(NULL, (const unsigned char)'^', &dest_len), NULL) - - PASSED(); - return 0; - -error: - return -1; -} /* end test_percent_encode_char() */ - /*--------------------------------------------------------------------------- * Function: test_s3r_get_filesize() *--------------------------------------------------------------------------- @@ -2237,7 +2166,6 @@ main(void) /* tests ordered roughly by dependence */ nerrors += test_macro_format_credential() < 0 ? 1 : 0; - nerrors += test_percent_encode_char() < 0 ? 1 : 0; nerrors += test_bytes_to_hex() < 0 ? 1 : 0; nerrors += test_HMAC_SHA256() < 0 ? 1 : 0; nerrors += test_signing_key() < 0 ? 1 : 0; From e6f8118bfc0e93726a1d656d8a7e0722d3eef164 Mon Sep 17 00:00:00 2001 From: Allen Byrne <50328838+byrnHDF@users.noreply.github.com> Date: Thu, 20 Jun 2024 16:01:43 -0500 Subject: [PATCH 29/45] Rework the TestExpress usage and refactor dead code (#4590) --- .github/workflows/abi-report.yml | 2 +- .github/workflows/cmake-bintest.yml | 12 ++-- .github/workflows/testxpr-cmake.yml | 2 + c++/test/dsets.cpp | 1 - c++/test/tlinks.cpp | 3 +- config/cmake/LIBAEC/CMakeLists.txt | 8 +-- config/cmake/LIBAEC/CPack.Info.plist.in | 2 +- config/cmake/ZLIB/CMakeLists.txt | 2 +- java/src/hdf/overview.html | 2 +- test/accum.c | 2 +- test/accum_swmr_reader.c | 2 +- test/app_ref.c | 6 +- test/big.c | 9 ++- test/btree2.c | 16 +++--- test/cache_logging.c | 5 +- test/chunk_info.c | 2 +- test/cmpd_dset.c | 2 +- test/cross_read.c | 2 +- test/del_many_dense_attrs.c | 2 +- test/dsets.c | 2 +- test/dt_arith.c | 34 ++++++------ test/dtypes.c | 38 ++++++------- test/earray.c | 23 ++++---- test/efc.c | 3 +- test/enum.c | 2 +- test/err_compat.c | 3 +- test/error_test.c | 3 +- test/event_set.c | 2 +- test/evict_on_close.c | 2 +- test/extend.c | 2 +- test/external.c | 2 +- test/external_env.c | 2 +- test/farray.c | 23 ++++---- test/fheap.c | 18 +++--- test/file_image.c | 22 +++++--- test/filenotclosed.c | 2 +- test/fillval.c | 2 +- test/filter_fail.c | 2 +- test/filter_plugin.c | 12 ++-- test/flush1.c | 2 +- test/flush2.c | 2 +- test/freespace.c | 2 +- test/getname.c | 2 +- test/gheap.c | 2 +- test/h5test.c | 73 ++----------------------- test/h5test.h | 33 ++++++++--- test/hdfs.c | 2 +- test/istore.c | 2 +- test/lheap.c | 2 +- test/links.c | 2 +- test/links_env.c | 2 +- test/mdset.c | 2 +- test/mf.c | 2 +- test/mirror_vfd.c | 2 +- test/mount.c | 2 +- test/mtime.c | 2 +- test/ntypes.c | 2 +- test/objcopy.c | 10 ++-- test/objcopy_ref.c | 6 +- test/ohdr.c | 2 +- test/onion.c | 2 +- test/page_buffer.c | 5 +- test/ros3.c | 2 +- test/s3comms.c | 2 +- test/select_io_dset.c | 2 +- test/set_extent.c | 2 +- test/stab.c | 2 +- test/swmr.c | 2 +- test/testframe.c | 2 +- test/tfile.c | 12 ++-- test/timer.c | 2 +- test/tsohm.c | 4 +- test/unlink.c | 2 +- test/unregister.c | 2 +- test/vds.c | 8 ++- test/vds_env.c | 2 +- test/vfd.c | 2 +- test/vfd_plugin.c | 2 +- test/vol.c | 2 +- test/vol_plugin.c | 2 +- testpar/t_filters_parallel.c | 3 +- testpar/t_mpi.c | 3 +- testpar/t_pflush2.c | 6 +- testpar/t_pmulti_dset.c | 2 +- testpar/t_select_io_dset.c | 2 +- testpar/t_shapesame.c | 3 +- testpar/t_subfiling_vfd.c | 2 +- testpar/testphdf5.c | 3 +- tools/test/h5repack/h5repacktst.c | 3 +- tools/test/perform/perf_meta.c | 3 +- 90 files changed, 248 insertions(+), 280 deletions(-) diff --git a/.github/workflows/abi-report.yml b/.github/workflows/abi-report.yml index 4736dc5adb4..d69cc18aa1c 100644 --- a/.github/workflows/abi-report.yml +++ b/.github/workflows/abi-report.yml @@ -82,7 +82,7 @@ jobs: mkdir "${{ github.workspace }}/hdf5R" cd "${{ github.workspace }}/hdf5R" wget -q https://github.com/HDFGroup/hdf5/releases/download/hdf5-${{ inputs.file_ref }}/hdf5-${{ inputs.file_ref }}-ubuntu-2204.tar.gz - tar zxf hdf5-${{ inputs.file_ref }}-ubuntu-2204.tar.gz + tar zxf hdf5-${{ inputs.file_ref }}-ubuntu-2204_gcc.tar.gz - name: List files for the space (Linux) run: | diff --git a/.github/workflows/cmake-bintest.yml b/.github/workflows/cmake-bintest.yml index 4f815a4102e..d4d7308ecd2 100644 --- a/.github/workflows/cmake-bintest.yml +++ b/.github/workflows/cmake-bintest.yml @@ -189,12 +189,12 @@ jobs: ls ${{ runner.workspace }} # symlinks the compiler executables to a common location - # - name: Setup GNU Fortran - # uses: fortran-lang/setup-fortran@v1 - # id: setup-fortran - # with: - # compiler: gcc - # version: 12 + - name: Setup GNU Fortran + uses: fortran-lang/setup-fortran@v1 + id: setup-fortran + with: + compiler: gcc + version: 12 - name: Run ctest (MacOS) id: run-ctest diff --git a/.github/workflows/testxpr-cmake.yml b/.github/workflows/testxpr-cmake.yml index 172c2f7e6be..809832f3e3a 100644 --- a/.github/workflows/testxpr-cmake.yml +++ b/.github/workflows/testxpr-cmake.yml @@ -61,6 +61,8 @@ jobs: working-directory: ${{ runner.workspace }}/build - name: CMake Run Tests + env: + HDF5TestExpress: 0 run: ctest . --parallel 2 -C ${{ matrix.build_mode }} -V -R H5TESTXPR working-directory: ${{ runner.workspace }}/build diff --git a/c++/test/dsets.cpp b/c++/test/dsets.cpp index 9de6db1319f..65dabbe11c2 100644 --- a/c++/test/dsets.cpp +++ b/c++/test/dsets.cpp @@ -17,7 +17,6 @@ EXTERNAL ROUTINES/VARIABLES: These routines are in the test directory of the C library: - h5_reset() -- in h5test.c, resets the library by closing it h5_fileaccess() -- in h5test.c, returns a file access template ***************************************************************************/ diff --git a/c++/test/tlinks.cpp b/c++/test/tlinks.cpp index 7017217009a..3ce8c6823d3 100644 --- a/c++/test/tlinks.cpp +++ b/c++/test/tlinks.cpp @@ -752,7 +752,8 @@ test_links() /* Close 2nd FAPL */ H5Pclose(fapl2_id); - h5_clean_files(FILENAME, fapl_id); + h5_delete_all_test_files(FILENAME, fapl_id); + H5Pclose(fapl_id); } catch (Exception &E) { issue_fail_msg("test_links()", __LINE__, __FILE__, E.getCDetailMsg()); diff --git a/config/cmake/LIBAEC/CMakeLists.txt b/config/cmake/LIBAEC/CMakeLists.txt index bdf43f8baf7..29f1fc7f460 100644 --- a/config/cmake/LIBAEC/CMakeLists.txt +++ b/config/cmake/LIBAEC/CMakeLists.txt @@ -125,9 +125,9 @@ set (CMAKE_POSITION_INDEPENDENT_CODE ON) set (EXE_EXT "") if (WIN32) set (EXE_EXT ".exe") - add_definitions (-D_BIND_TO_CURRENT_VCLIBS_VERSION=1) - add_definitions (-D_CRT_SECURE_NO_WARNINGS) - add_definitions (-D_CONSOLE) + add_compile_definitions (_BIND_TO_CURRENT_VCLIBS_VERSION=1) + add_compile_definitions (_CRT_SECURE_NO_WARNINGS) + add_compile_definitions (_CONSOLE) endif () if (MSVC) @@ -161,7 +161,7 @@ configure_file( #----------------------------------------------------------------------------- # All libs/tests/examples need the main include directories #----------------------------------------------------------------------------- -set_directory_properties(PROPERTIES INCLUDE_DIRECTORIES +set_directory_properties(PROPERTIES INCLUDE_DIRECTORIES "${LIBAEC_BINARY_DIR};${LIBAEC_SOURCE_DIR}/src;${CMAKE_RUNTIME_OUTPUT_DIRECTORY}" ) diff --git a/config/cmake/LIBAEC/CPack.Info.plist.in b/config/cmake/LIBAEC/CPack.Info.plist.in index 08d371bd5d9..b936470fc29 100644 --- a/config/cmake/LIBAEC/CPack.Info.plist.in +++ b/config/cmake/LIBAEC/CPack.Info.plist.in @@ -17,7 +17,7 @@ CFBundleSignature ???? CFBundleVersion - @CPACK_PACKAGE_VERSIO@ + @CPACK_PACKAGE_VERSION@ CFBundleShortVersionString @CPACK_SHORT_VERSION_STRING@ CSResourcesFileMapped diff --git a/config/cmake/ZLIB/CMakeLists.txt b/config/cmake/ZLIB/CMakeLists.txt index d31503b0ac6..78d678074b0 100644 --- a/config/cmake/ZLIB/CMakeLists.txt +++ b/config/cmake/ZLIB/CMakeLists.txt @@ -42,7 +42,7 @@ HDF_DIR_PATHS(ZLIB) #----------------------------------------------------------------------------- # All libs/tests/examples need the main include directories #----------------------------------------------------------------------------- -set_directory_properties(PROPERTIES INCLUDE_DIRECTORIES +set_directory_properties(PROPERTIES INCLUDE_DIRECTORIES "${ZLIB_BINARY_DIR};${ZLIB_SOURCE_DIR};${CMAKE_RUNTIME_OUTPUT_DIRECTORY}" ) diff --git a/java/src/hdf/overview.html b/java/src/hdf/overview.html index 74907555534..84e945b2f87 100644 --- a/java/src/hdf/overview.html +++ b/java/src/hdf/overview.html @@ -91,6 +91,6 @@

and the HDF5 library.

To Obtain

-The JHI5 is included with the HDF5 library. +The JHI5 is included with the HDF5 library. diff --git a/test/accum.c b/test/accum.c index ac9754bf4b9..c0401ac3d10 100644 --- a/test/accum.c +++ b/test/accum.c @@ -91,7 +91,7 @@ main(void) puts("Testing the metadata accumulator"); /* File access property list */ - h5_reset(); + h5_test_init(); if ((fapl = h5_fileaccess()) < 0) FAIL_STACK_ERROR; h5_fixname(FILENAME[0], fapl, filename, sizeof filename); diff --git a/test/accum_swmr_reader.c b/test/accum_swmr_reader.c index a5b16eba860..05966a9f2b0 100644 --- a/test/accum_swmr_reader.c +++ b/test/accum_swmr_reader.c @@ -51,7 +51,7 @@ main(void) bool api_ctx_pushed = false; /* Whether API context pushed */ /* Testing setup */ - h5_reset(); + h5_test_init(); /* Skip this test if SWMR I/O is not supported for the VFD specified * by the environment variable. diff --git a/test/app_ref.c b/test/app_ref.c index 3e32b1ebb4e..bc6958d40ec 100644 --- a/test/app_ref.c +++ b/test/app_ref.c @@ -86,7 +86,7 @@ main(void) int i; char filename[1024]; - h5_reset(); + h5_test_init(); h5_fixname(FILENAME[0], H5P_DEFAULT, filename, sizeof filename); HDsrand((unsigned)time(NULL)); @@ -179,11 +179,11 @@ main(void) PASSED(); - /* Restore the default error handler (set in h5_reset()) */ + /* Restore the default error handler (set in h5_test_init()) */ h5_restore_err(); /* Clean up any file(s) created */ - h5_reset(); + h5_test_init(); fapl = H5Pcreate(H5P_FILE_ACCESS); h5_cleanup(FILENAME, fapl); diff --git a/test/big.c b/test/big.c index cf8a3f2ef38..549c65b87fa 100644 --- a/test/big.c +++ b/test/big.c @@ -591,7 +591,8 @@ test_sec2(hid_t fapl) quit: /* End with normal return code */ /* Clean up the test file */ - h5_clean_files(FILENAME, fapl); + h5_delete_all_test_files(FILENAME, fapl); + H5Pclose(fapl); HDremove(DNAME); return 0; @@ -628,7 +629,8 @@ test_stdio(hid_t fapl) quit: /* End with normal return code */ /* Clean up the test file */ - h5_clean_files(FILENAME, fapl); + h5_delete_all_test_files(FILENAME, fapl); + H5Pclose(fapl); HDremove(DNAME); fflush(stdout); return 0; @@ -683,7 +685,8 @@ test_family(hid_t fapl) quit: /* End with normal return code */ /* Clean up the test file */ - h5_clean_files(FILENAME, fapl); + h5_delete_all_test_files(FILENAME, fapl); + H5Pclose(fapl); HDremove(DNAME); return 0; diff --git a/test/btree2.c b/test/btree2.c index a44a2475732..95108b56425 100644 --- a/test/btree2.c +++ b/test/btree2.c @@ -9915,22 +9915,20 @@ main(void) hid_t fapl = H5I_INVALID_HID; /* File access property list for data files */ unsigned nerrors = 0; /* Cumulative error count */ unsigned reopen; /* Whether to reopen B-tree during tests */ - int ExpressMode; const char *driver_name; bool api_ctx_pushed = false; /* Whether API context pushed */ driver_name = h5_get_test_driver_name(); /* Reset library */ - h5_reset(); - fapl = h5_fileaccess(); - ExpressMode = GetTestExpress(); + h5_test_init(); + fapl = h5_fileaccess(); /* For the Direct I/O driver, skip intensive tests due to poor performance */ if (!strcmp(driver_name, "direct")) - ExpressMode = 2; + SetTestExpress(2); - if (ExpressMode > 1) + if (TestExpress > 1) printf("***Express test mode on. Some tests may be skipped\n"); /* Initialize v2 B-tree creation parameters */ @@ -9967,7 +9965,7 @@ main(void) nerrors += test_insert_level2_2internal_split(fapl, &cparam, &tparam); nerrors += test_insert_level2_3internal_redistrib(fapl, &cparam, &tparam); nerrors += test_insert_level2_3internal_split(fapl, &cparam, &tparam); - if (ExpressMode > 1) + if (TestExpress > 1) printf("***Express test mode on. test_insert_lots skipped\n"); else nerrors += test_insert_lots(fapl, &cparam, &tparam); @@ -9981,7 +9979,7 @@ main(void) nerrors += test_update_level1_3leaf_redistrib(fapl, &cparam2, &tparam); nerrors += test_update_level1_middle_split(fapl, &cparam2, &tparam); nerrors += test_update_make_level2(fapl, &cparam2, &tparam); - if (ExpressMode > 1) + if (TestExpress > 1) printf("***Express test mode on. test_update_lots skipped\n"); else nerrors += test_update_lots(fapl, &cparam2, &tparam); @@ -10008,7 +10006,7 @@ main(void) nerrors += test_remove_level2_2internal_merge_right(fapl, &cparam, &tparam); nerrors += test_remove_level2_3internal_merge(fapl, &cparam, &tparam); nerrors += test_remove_level2_collapse_right(fapl, &cparam, &tparam); - if (ExpressMode > 1) + if (TestExpress > 1) printf("***Express test mode on. test_remove_lots skipped\n"); else nerrors += test_remove_lots(driver_name, fapl, &cparam); diff --git a/test/cache_logging.c b/test/cache_logging.c index 5372021f335..bcc37cc72a8 100644 --- a/test/cache_logging.c +++ b/test/cache_logging.c @@ -132,7 +132,8 @@ test_logging_api(void) TEST_ERROR; HDremove(LOG_LOCATION); - h5_clean_files(FILENAME, fapl); + h5_delete_all_test_files(FILENAME, fapl); + H5Pclose(fapl); PASSED(); return 0; @@ -163,7 +164,7 @@ main(void) int nerrors = 0; /* Reset library */ - h5_reset(); + h5_test_init(); printf("Testing basic metadata cache logging functionality.\n"); diff --git a/test/chunk_info.c b/test/chunk_info.c index a5dde34c5a7..4591b7242b4 100644 --- a/test/chunk_info.c +++ b/test/chunk_info.c @@ -2445,7 +2445,7 @@ main(void) hid_t fapl = H5I_INVALID_HID; /* File access property list */ int nerrors = 0; /* Number of errors so far */ - h5_reset(); + h5_test_init(); /* Create a copy of file access property list */ if ((fapl = H5Pcreate(H5P_FILE_ACCESS)) < 0) diff --git a/test/cmpd_dset.c b/test/cmpd_dset.c index ed26b5459dc..40a6a8919cc 100644 --- a/test/cmpd_dset.c +++ b/test/cmpd_dset.c @@ -3334,7 +3334,7 @@ main(int argc, char *argv[]) char fname[256]; unsigned nerrors = 0; - h5_reset(); + h5_test_init(); /* Turn off optimized compound converter? */ if (argc > 1) { diff --git a/test/cross_read.c b/test/cross_read.c index ce1f90b9e10..3fbe9df89e9 100644 --- a/test/cross_read.c +++ b/test/cross_read.c @@ -342,7 +342,7 @@ main(void) char filename[1024]; int nerrors = 0; - h5_reset(); + h5_test_init(); /* * Skip tests for VFDs that aren't compatible with default VFD. diff --git a/test/del_many_dense_attrs.c b/test/del_many_dense_attrs.c index 0037c3c4270..b6cb4375af8 100644 --- a/test/del_many_dense_attrs.c +++ b/test/del_many_dense_attrs.c @@ -66,7 +66,7 @@ main(void) int i; /* Local index variable */ /* Testing setup */ - h5_reset(); + h5_test_init(); /* To exit from the file for SIGABRT signal */ if (signal(SIGABRT, catch_signal) == SIG_ERR) diff --git a/test/dsets.c b/test/dsets.c index ca985a85ec6..d33b7ae251d 100644 --- a/test/dsets.c +++ b/test/dsets.c @@ -15957,7 +15957,7 @@ main(void) check_dbl[i] = check_dbl_data + (i * DSET_DIM2); /* Testing setup */ - h5_reset(); + h5_test_init(); fapl = h5_fileaccess(); if (h5_driver_is_default_vfd_compatible(fapl, &driver_is_default_compatible) < 0) diff --git a/test/dt_arith.c b/test/dt_arith.c index 120ea303f69..d43a72ac3e6 100644 --- a/test/dt_arith.c +++ b/test/dt_arith.c @@ -425,7 +425,7 @@ fpe_handler(int H5_ATTR_UNUSED signo) static void reset_hdf5(void) { - h5_reset(); + h5_test_init(); if (without_hardware_g) h5_no_hwconv(); @@ -548,7 +548,7 @@ test_hard_query(void) PASSED(); - /* Restore the default error handler (set in h5_reset()) */ + /* Restore the default error handler (set in h5_test_init()) */ h5_restore_err(); reset_hdf5(); @@ -556,7 +556,7 @@ test_hard_query(void) return 0; error: - /* Restore the default error handler (set in h5_reset()) */ + /* Restore the default error handler (set in h5_test_init()) */ h5_restore_err(); reset_hdf5(); @@ -867,7 +867,7 @@ test_particular_fp_integer(void) #endif #endif - /* Restore the default error handler (set in h5_reset()) */ + /* Restore the default error handler (set in h5_test_init()) */ h5_restore_err(); reset_hdf5(); /*print statistics*/ @@ -1289,7 +1289,7 @@ test_derived_flt(void) PASSED(); - /* Restore the default error handler (set in h5_reset()) */ + /* Restore the default error handler (set in h5_test_init()) */ h5_restore_err(); reset_hdf5(); /*print statistics*/ @@ -1313,7 +1313,7 @@ test_derived_flt(void) } H5E_END_TRY - /* Restore the default error handler (set in h5_reset()) */ + /* Restore the default error handler (set in h5_test_init()) */ h5_restore_err(); reset_hdf5(); /*print statistics*/ @@ -1599,7 +1599,7 @@ test_derived_integer(void) PASSED(); - /* Restore the default error handler (set in h5_reset()) */ + /* Restore the default error handler (set in h5_test_init()) */ h5_restore_err(); reset_hdf5(); /*print statistics*/ @@ -1621,7 +1621,7 @@ test_derived_integer(void) } H5E_END_TRY - /* Restore the default error handler (set in h5_reset()) */ + /* Restore the default error handler (set in h5_test_init()) */ h5_restore_err(); reset_hdf5(); /*print statistics*/ @@ -2670,7 +2670,7 @@ test_conv_int_1(const char *name, hid_t src, hid_t dst) free(aligned); fflush(stdout); - /* Restore the default error handler (set in h5_reset()) */ + /* Restore the default error handler (set in h5_test_init()) */ h5_restore_err(); reset_hdf5(); /*print statistics*/ @@ -2686,7 +2686,7 @@ test_conv_int_1(const char *name, hid_t src, hid_t dst) free(aligned); fflush(stdout); - /* Restore the default error handler (set in h5_reset()) */ + /* Restore the default error handler (set in h5_test_init()) */ h5_restore_err(); reset_hdf5(); /*print statistics*/ @@ -3812,7 +3812,7 @@ test_conv_flt_1(const char *name, int run_test, hid_t src, hid_t dst) assert(0 && "Should not reach this point!"); return 1; #else - /* Restore the default error handler (set in h5_reset()) */ + /* Restore the default error handler (set in h5_test_init()) */ h5_restore_err(); reset_hdf5(); @@ -3841,7 +3841,7 @@ test_conv_flt_1(const char *name, int run_test, hid_t src, hid_t dst) assert(0 && "Should not reach this point!"); return 1; #else - /* Restore the default error handler (set in h5_reset()) */ + /* Restore the default error handler (set in h5_test_init()) */ h5_restore_err(); reset_hdf5(); @@ -5230,7 +5230,7 @@ test_conv_int_fp(const char *name, int run_test, hid_t src, hid_t dst) if (aligned) free(aligned); fflush(stdout); - /* Restore the default error handler (set in h5_reset()) */ + /* Restore the default error handler (set in h5_test_init()) */ h5_restore_err(); reset_hdf5(); /*print statistics*/ @@ -5251,7 +5251,7 @@ test_conv_int_fp(const char *name, int run_test, hid_t src, hid_t dst) free(aligned); fflush(stdout); - /* Restore the default error handler (set in h5_reset()) */ + /* Restore the default error handler (set in h5_test_init()) */ h5_restore_err(); reset_hdf5(); /*print statistics*/ @@ -6022,7 +6022,7 @@ main(void) */ without_hardware_g = true; - /* Restore the default error handler (set in h5_reset()) */ + /* Restore the default error handler (set in h5_test_init()) */ h5_restore_err(); reset_hdf5(); @@ -6040,12 +6040,12 @@ main(void) /* Test software integer-float conversion functions */ nerrors += (unsigned long)run_int_fp_conv("soft"); - /* Restore the default error handler (set in h5_reset()) */ + /* Restore the default error handler (set in h5_test_init()) */ h5_restore_err(); reset_hdf5(); - /* Restore the default error handler (set in h5_reset()) */ + /* Restore the default error handler (set in h5_test_init()) */ h5_restore_err(); if (nerrors) { diff --git a/test/dtypes.c b/test/dtypes.c index 023981c5bbe..d740d2a6f0f 100644 --- a/test/dtypes.c +++ b/test/dtypes.c @@ -152,7 +152,7 @@ static int opaque_funcs(void); static void reset_hdf5(void) { - h5_reset(); + h5_test_init(); #ifdef TEST_ALIGNMENT SET_ALIGNMENT(SCHAR, H5_SIZEOF_CHAR); SET_ALIGNMENT(UCHAR, H5_SIZEOF_CHAR); @@ -862,7 +862,7 @@ test_compound_2(void) PASSED(); - /* Restore the default error handler (set in h5_reset()) */ + /* Restore the default error handler (set in h5_test_init()) */ h5_restore_err(); reset_hdf5(); @@ -874,7 +874,7 @@ test_compound_2(void) free(bkg); free(orig); - /* Restore the default error handler (set in h5_reset()) */ + /* Restore the default error handler (set in h5_test_init()) */ h5_restore_err(); reset_hdf5(); @@ -984,7 +984,7 @@ test_compound_3(void) PASSED(); - /* Restore the default error handler (set in h5_reset()) */ + /* Restore the default error handler (set in h5_test_init()) */ h5_restore_err(); reset_hdf5(); @@ -995,7 +995,7 @@ test_compound_3(void) free(bkg); free(orig); - /* Restore the default error handler (set in h5_reset()) */ + /* Restore the default error handler (set in h5_test_init()) */ h5_restore_err(); reset_hdf5(); @@ -1112,7 +1112,7 @@ test_compound_4(void) PASSED(); - /* Restore the default error handler (set in h5_reset()) */ + /* Restore the default error handler (set in h5_test_init()) */ h5_restore_err(); reset_hdf5(); @@ -1123,7 +1123,7 @@ test_compound_4(void) free(bkg); free(orig); - /* Restore the default error handler (set in h5_reset()) */ + /* Restore the default error handler (set in h5_test_init()) */ h5_restore_err(); reset_hdf5(); @@ -1322,14 +1322,14 @@ test_compound_6(void) PASSED(); - /* Restore the default error handler (set in h5_reset()) */ + /* Restore the default error handler (set in h5_test_init()) */ h5_restore_err(); reset_hdf5(); return 0; error: - /* Restore the default error handler (set in h5_reset()) */ + /* Restore the default error handler (set in h5_test_init()) */ h5_restore_err(); reset_hdf5(); @@ -1464,14 +1464,14 @@ test_compound_7(void) PASSED(); - /* Restore the default error handler (set in h5_reset()) */ + /* Restore the default error handler (set in h5_test_init()) */ h5_restore_err(); reset_hdf5(); return 0; error: - /* Restore the default error handler (set in h5_reset()) */ + /* Restore the default error handler (set in h5_test_init()) */ h5_restore_err(); reset_hdf5(); @@ -5307,7 +5307,7 @@ test_conv_str_1(void) PASSED(); - /* Restore the default error handler (set in h5_reset()) */ + /* Restore the default error handler (set in h5_test_init()) */ h5_restore_err(); reset_hdf5(); @@ -5324,7 +5324,7 @@ test_conv_str_1(void) if (buf) free(buf); - /* Restore the default error handler (set in h5_reset()) */ + /* Restore the default error handler (set in h5_test_init()) */ h5_restore_err(); reset_hdf5(); @@ -5392,7 +5392,7 @@ test_conv_str_2(void) if (buf) free(buf); - /* Restore the default error handler (set in h5_reset()) */ + /* Restore the default error handler (set in h5_test_init()) */ h5_restore_err(); reset_hdf5(); @@ -5528,7 +5528,7 @@ test_conv_str_3(void) if (tag) H5free_memory(tag); /* Technically allocated by API call */ - /* Restore the default error handler (set in h5_reset()) */ + /* Restore the default error handler (set in h5_test_init()) */ h5_restore_err(); reset_hdf5(); @@ -5605,7 +5605,7 @@ test_conv_enum_1(void) if (buf) free(buf); - /* Restore the default error handler (set in h5_reset()) */ + /* Restore the default error handler (set in h5_test_init()) */ h5_restore_err(); reset_hdf5(); @@ -5763,7 +5763,7 @@ test_conv_bitfield(void) H5Tclose(dt); PASSED(); - /* Restore the default error handler (set in h5_reset()) */ + /* Restore the default error handler (set in h5_test_init()) */ h5_restore_err(); reset_hdf5(); @@ -5773,7 +5773,7 @@ test_conv_bitfield(void) H5Tclose(st); H5Tclose(dt); - /* Restore the default error handler (set in h5_reset()) */ + /* Restore the default error handler (set in h5_test_init()) */ h5_restore_err(); reset_hdf5(); @@ -5918,7 +5918,7 @@ test_bitfield_funcs(void) if (retval == 0) PASSED(); - /* Restore the default error handler (set in h5_reset()) */ + /* Restore the default error handler (set in h5_test_init()) */ h5_restore_err(); reset_hdf5(); diff --git a/test/earray.c b/test/earray.c index 3770ac44765..871c6fa46a9 100644 --- a/test/earray.c +++ b/test/earray.c @@ -2291,21 +2291,18 @@ test_skip_elmts(hid_t fapl, H5EA_create_t *cparam, earray_test_param_t *tparam, int main(void) { - H5EA_create_t cparam; /* Creation parameters for extensible array */ - earray_test_param_t tparam; /* Testing parameters */ - earray_test_type_t curr_test; /* Current test being worked on */ - earray_iter_type_t curr_iter; /* Current iteration type being worked on */ - hid_t fapl = H5I_INVALID_HID; /* File access property list for data files */ - unsigned nerrors = 0; /* Cumulative error count */ - time_t curr_time; /* Current time, for seeding random number generator */ - int ExpressMode; /* Test express value */ - bool api_ctx_pushed = false; /* Whether API context pushed */ + H5EA_create_t cparam; /* Creation parameters for extensible array */ + earray_test_param_t tparam; /* Testing parameters */ + earray_test_type_t curr_test; /* Current test being worked on */ + earray_iter_type_t curr_iter; /* Current iteration type being worked on */ + hid_t fapl = H5I_INVALID_HID; /* File access property list for data files */ + unsigned nerrors = 0; /* Cumulative error count */ + bool api_ctx_pushed = false; /* Whether API context pushed */ /* Reset library */ - h5_reset(); - fapl = h5_fileaccess(); - ExpressMode = GetTestExpress(); - if (ExpressMode > 1) + h5_test_init(); + fapl = h5_fileaccess(); + if (TestExpress > 1) printf("***Express test mode on. Some tests may be skipped\n"); /* Set the filename to use for this test (dependent on fapl) */ diff --git a/test/efc.c b/test/efc.c index b5399823c89..3da334fae98 100644 --- a/test/efc.c +++ b/test/efc.c @@ -2697,7 +2697,8 @@ main(void) puts("All external file cache tests passed."); - h5_clean_files(FILENAME, fapl_id); + h5_delete_all_test_files(FILENAME, fapl_id); + H5Pclose(fapl_id); for (i = 0; i < N_FILENAMES; i++) { free(filename[i]); diff --git a/test/enum.c b/test/enum.c index b64355cadba..2c8e8cd28d7 100644 --- a/test/enum.c +++ b/test/enum.c @@ -782,7 +782,7 @@ main(void) char name[1024]; int nerrors = 0; - h5_reset(); + h5_test_init(); fapl_id = h5_fileaccess(); /* Create the file */ diff --git a/test/err_compat.c b/test/err_compat.c index f2bd2ab61c4..c7abb42e9bb 100644 --- a/test/err_compat.c +++ b/test/err_compat.c @@ -489,7 +489,8 @@ main(void) if (H5Fclose(fid) < 0) TEST_ERROR; - h5_clean_files(FILENAME, fapl_id); + h5_delete_all_test_files(FILENAME, fapl_id); + H5Pclose(fapl_id); free(ipoints2); free(ipoints2_data); diff --git a/test/error_test.c b/test/error_test.c index 84db80e3f93..fe27300f431 100644 --- a/test/error_test.c +++ b/test/error_test.c @@ -1049,7 +1049,8 @@ main(void) if (test_filter_error(filename, fapl) < 0) TEST_ERROR; - h5_clean_files(FILENAME, fapl); + h5_delete_all_test_files(FILENAME, fapl); + H5Pclose(fapl); free(ipoints2); free(ipoints2_data); diff --git a/test/event_set.c b/test/event_set.c index 9e659aada15..0880157f430 100644 --- a/test/event_set.c +++ b/test/event_set.c @@ -655,7 +655,7 @@ main(void) int nerrors = 0; /* Error count */ /* Setup */ - h5_reset(); + h5_test_init(); fapl_id = h5_fileaccess(); /* Register dummy connector IDs */ diff --git a/test/evict_on_close.c b/test/evict_on_close.c index db2a96282ef..975b6258311 100644 --- a/test/evict_on_close.c +++ b/test/evict_on_close.c @@ -884,7 +884,7 @@ main(void) printf("Testing evict-on-close cache behavior\n"); /* Initialize */ - h5_reset(); + h5_test_init(); /* Test H5P call to set up EoC (does not require VFD-specific fapl) */ nerrors += check_evict_on_close_api() < 0 ? 1 : 0; diff --git a/test/extend.c b/test/extend.c index 554cf2ac918..26bc3d2faa6 100644 --- a/test/extend.c +++ b/test/extend.c @@ -255,7 +255,7 @@ main(void) char filename[1024]; int i, j; - h5_reset(); + h5_test_init(); fapl = h5_fileaccess(); /* Initialize buffer and space */ diff --git a/test/external.c b/test/external.c index efd24fa225b..89f9e7801f4 100644 --- a/test/external.c +++ b/test/external.c @@ -1367,7 +1367,7 @@ main(void) unsigned latest_format; /* default or latest file format */ int nerrors = 0; /* number of errors */ - h5_reset(); + h5_test_init(); /* Get a fapl for the old (default) file format */ fapl_id_old = h5_fileaccess(); diff --git a/test/external_env.c b/test/external_env.c index 6d6146aed8c..d1e50c6d824 100644 --- a/test/external_env.c +++ b/test/external_env.c @@ -144,7 +144,7 @@ main(void) unsigned latest_format; /* default or latest file format */ int nerrors = 0; /* number of errors */ - h5_reset(); + h5_test_init(); /* Get a fapl for the old (default) file format */ fapl_id_old = h5_fileaccess(); diff --git a/test/farray.c b/test/farray.c index a8f4352c984..0c47a607306 100644 --- a/test/farray.c +++ b/test/farray.c @@ -1622,21 +1622,18 @@ test_skip_elmts(hid_t fapl, H5FA_create_t *cparam, farray_test_param_t *tparam, int main(void) { - H5FA_create_t cparam; /* Creation parameters for fixed array */ - farray_test_param_t tparam; /* Testing parameters */ - farray_test_type_t curr_test; /* Current test being worked on */ - farray_iter_type_t curr_iter; /* Current iteration type being worked on */ - hid_t fapl = H5I_INVALID_HID; /* File access property list for data files */ - unsigned nerrors = 0; /* Cumulative error count */ - time_t curr_time; /* Current time, for seeding random number generator */ - int ExpressMode; /* Test express value */ - bool api_ctx_pushed = false; /* Whether API context pushed */ + H5FA_create_t cparam; /* Creation parameters for fixed array */ + farray_test_param_t tparam; /* Testing parameters */ + farray_test_type_t curr_test; /* Current test being worked on */ + farray_iter_type_t curr_iter; /* Current iteration type being worked on */ + hid_t fapl = H5I_INVALID_HID; /* File access property list for data files */ + unsigned nerrors = 0; /* Cumulative error count */ + bool api_ctx_pushed = false; /* Whether API context pushed */ /* Reset library */ - h5_reset(); - fapl = h5_fileaccess(); - ExpressMode = GetTestExpress(); - if (ExpressMode > 1) + h5_test_init(); + fapl = h5_fileaccess(); + if (TestExpress > 1) printf("***Express test mode on. Some tests may be skipped\n"); /* Set the filename to use for this test (dependent on fapl) */ diff --git a/test/fheap.c b/test/fheap.c index 21bbd32a797..3112a1c42e1 100644 --- a/test/fheap.c +++ b/test/fheap.c @@ -15957,7 +15957,6 @@ main(void) unsigned u, v; /* Local index variable */ unsigned nerrors = 0; /* Cumulative error count */ unsigned num_pb_fs = 1; /* The number of settings to test for page buffering and file space handling */ - int ExpressMode; /* Express testing level */ const char *driver_name; /* Environment variable */ bool contig_addr_vfd; /* Whether VFD used has a contiguous address space */ bool api_ctx_pushed = false; /* Whether API context pushed */ @@ -15969,10 +15968,9 @@ main(void) contig_addr_vfd = (bool)(strcmp(driver_name, "split") != 0 && strcmp(driver_name, "multi") != 0); /* Reset library */ - h5_reset(); + h5_test_init(); - def_fapl = h5_fileaccess(); - ExpressMode = GetTestExpress(); + def_fapl = h5_fileaccess(); /* * Caution when turning on ExpressMode 0: @@ -15984,9 +15982,9 @@ main(void) * Activate full testing when this feature is re-enabled * in the future for parallel build. */ - if (ExpressMode > 1) + if (TestExpress > 1) printf("***Express test mode on. Some tests may be skipped\n"); - else if (ExpressMode == 0) { + else if (TestExpress == 0) { #ifdef H5_HAVE_PARALLEL num_pb_fs = NUM_PB_FS - 2; #else @@ -16202,7 +16200,7 @@ main(void) /* If this test fails, uncomment the tests above, which build up to this * level of complexity gradually. -QAK */ - if (ExpressMode > 1) + if (TestExpress > 1) printf( "***Express test mode on. test_man_start_5th_recursive_indirect is skipped\n"); else @@ -16250,7 +16248,7 @@ main(void) nerrors += test_man_remove_first_row(fapl, &small_cparam, &tparam); nerrors += test_man_remove_first_two_rows(fapl, &small_cparam, &tparam); nerrors += test_man_remove_first_four_rows(fapl, &small_cparam, &tparam); - if (ExpressMode > 1) + if (TestExpress > 1) printf("***Express test mode on. Some tests skipped\n"); else { nerrors += test_man_remove_all_root_direct(fapl, &small_cparam, &tparam); @@ -16300,7 +16298,7 @@ main(void) nerrors += test_man_fill_1st_row_3rd_direct_fill_2nd_direct_less_one_wrap_start_block_add_skipped( fapl, &small_cparam, &tparam); - if (ExpressMode > 1) + if (TestExpress > 1) printf("***Express test mode on. Some tests skipped\n"); else { nerrors += @@ -16430,7 +16428,7 @@ main(void) } /* end block */ /* Random object insertion & deletion */ - if (ExpressMode > 1) + if (TestExpress > 1) printf("***Express test mode on. Some tests skipped\n"); else { /* Random tests using "small" heap creation parameters */ diff --git a/test/file_image.c b/test/file_image.c index 45bf5af29c7..834b758a3ff 100644 --- a/test/file_image.c +++ b/test/file_image.c @@ -649,7 +649,8 @@ test_core(void) FAIL_STACK_ERROR; /* Release resources */ - h5_clean_files(FILENAME, fapl); + h5_delete_all_test_files(FILENAME, fapl); + H5Pclose(fapl); free(udata); free(file_image); HDremove(copied_filename); @@ -924,7 +925,8 @@ test_get_file_image(const char *test_banner, const int file_name_num, hid_t fapl VERIFY(err == SUCCEED, "H5Pclose(core_fapl_id) failed."); /* tidy up */ - h5_clean_files(FILENAME2, fapl); + h5_delete_all_test_files(FILENAME2, fapl); + H5Pclose(fapl); /* discard the image buffer if it exists */ if (image_ptr != NULL) @@ -1070,7 +1072,8 @@ test_get_file_image_error_rejection(void) VERIFY(err == SUCCEED, "H5Fclose(file_id) failed."); /* tidy up */ - h5_clean_files(FILENAME2, fapl_id); + h5_delete_all_test_files(FILENAME2, fapl_id); + H5Pclose(fapl_id); /* discard the image buffer if it exists */ if (image_ptr != NULL) @@ -1174,7 +1177,8 @@ test_get_file_image_error_rejection(void) VERIFY(err == SUCCEED, "H5Fclose(2) failed."); /* tidy up */ - h5_clean_files(FILENAME2, fapl_id); + h5_delete_all_test_files(FILENAME2, fapl_id); + H5Pclose(fapl_id); /************************** Test #3 **********************************/ /* set up a split file driver test file, and try to get its image @@ -1236,7 +1240,8 @@ test_get_file_image_error_rejection(void) VERIFY(err == SUCCEED, "H5Fclose(2) failed."); /* tidy up */ - h5_clean_files(FILENAME2, fapl_id); + h5_delete_all_test_files(FILENAME2, fapl_id); + H5Pclose(fapl_id); /************************** Test #4 **********************************/ /* set up a family file driver test file, and try to get its image @@ -1296,7 +1301,8 @@ test_get_file_image_error_rejection(void) VERIFY(err == SUCCEED, "H5Fclose(2) failed."); /* tidy up */ - h5_clean_files(FILENAME2, fapl_id); + h5_delete_all_test_files(FILENAME2, fapl_id); + H5Pclose(fapl_id); PASSED(); @@ -1314,7 +1320,7 @@ main(void) bool driver_is_default_compatible; unsigned user; - h5_reset(); + h5_test_init(); printf("Testing File Image Functionality.\n"); @@ -1375,7 +1381,7 @@ main(void) errors += test_get_file_image_error_rejection(); - /* Restore the default error handler (set in h5_reset()) */ + /* Restore the default error handler (set in h5_test_init()) */ h5_restore_err(); if (errors) { diff --git a/test/filenotclosed.c b/test/filenotclosed.c index 66b0052b52b..cdd8eed09d2 100644 --- a/test/filenotclosed.c +++ b/test/filenotclosed.c @@ -77,7 +77,7 @@ main(void) exit(EXIT_SUCCESS); } - h5_reset(); + h5_test_init(); /* To exit from the file for SIGABRT signal */ if (signal(SIGABRT, catch_signal) == SIG_ERR) diff --git a/test/fillval.c b/test/fillval.c index c8f46387b74..96021d3c20b 100644 --- a/test/fillval.c +++ b/test/fillval.c @@ -2626,7 +2626,7 @@ main(int argc, char *argv[]) } /* end for */ } /* end if */ - h5_reset(); + h5_test_init(); fapl = h5_fileaccess(); if (h5_driver_is_default_vfd_compatible(fapl, &driver_is_default_compatible) < 0) diff --git a/test/filter_fail.c b/test/filter_fail.c index 10296175909..1d204fa3218 100644 --- a/test/filter_fail.c +++ b/test/filter_fail.c @@ -368,7 +368,7 @@ main(void) char filename[1024]; unsigned nerrors = 0; - h5_reset(); + h5_test_init(); fapl = h5_fileaccess(); h5_fixname(FILENAME[0], fapl, filename, sizeof filename); diff --git a/test/filter_plugin.c b/test/filter_plugin.c index 9207d9e847c..cc04cf60765 100644 --- a/test/filter_plugin.c +++ b/test/filter_plugin.c @@ -1441,7 +1441,7 @@ main(void) hid_t my_fapl_id; /* Testing setup */ - h5_reset(); + h5_test_init(); /* Get a VFD-dependent filename */ if ((old_ff_fapl_id = h5_fileaccess()) < 0) @@ -1491,7 +1491,7 @@ main(void) TEST_ERROR; } - /* Restore the default error handler (set in h5_reset()) */ + /* Restore the default error handler (set in h5_test_init()) */ h5_restore_err(); /*******************************************************************/ @@ -1501,7 +1501,7 @@ main(void) puts("\nTesting reading data with with dynamic plugin filters:"); /* Close the library so that all loaded plugin libraries are unloaded */ - h5_reset(); + h5_test_init(); if ((old_ff_fapl_id = h5_fileaccess()) < 0) TEST_ERROR; @@ -1542,7 +1542,7 @@ main(void) TEST_ERROR; } - /* Restore the default error handler (set in h5_reset()) */ + /* Restore the default error handler (set in h5_test_init()) */ h5_restore_err(); /*******************************************************************/ @@ -1550,7 +1550,7 @@ main(void) /*******************************************************************/ /* Close the library so that all loaded plugin libraries are unloaded */ - h5_reset(); + h5_test_init(); if ((old_ff_fapl_id = h5_fileaccess()) < 0) TEST_ERROR; @@ -1588,7 +1588,7 @@ main(void) TEST_ERROR; } else { - /* Restore the default error handler (set in h5_reset()) */ + /* Restore the default error handler (set in h5_test_init()) */ h5_restore_err(); if (H5Pclose(old_ff_fapl_id) < 0) diff --git a/test/flush1.c b/test/flush1.c index f9ecb15fa1e..e93684bf36a 100644 --- a/test/flush1.c +++ b/test/flush1.c @@ -183,7 +183,7 @@ main(void) char filename[1024]; /* filename */ bool use_swmr; /* whether or not to use SWMR I/O */ - h5_reset(); + h5_test_init(); if ((fapl_id = h5_fileaccess()) < 0) TEST_ERROR; diff --git a/test/flush2.c b/test/flush2.c index 12daa2be87f..b8f4e13d35d 100644 --- a/test/flush2.c +++ b/test/flush2.c @@ -231,7 +231,7 @@ main(void) H5E_auto2_t func; /* for shutting off error reporting */ bool driver_is_default_vfd_compatible; - h5_reset(); + h5_test_init(); if ((fapl_id = h5_fileaccess()) < 0) PUTS_ERROR("bad vfd-dependent fapl"); diff --git a/test/freespace.c b/test/freespace.c index b278d2a217f..2d812177af3 100644 --- a/test/freespace.c +++ b/test/freespace.c @@ -2878,7 +2878,7 @@ main(void) unsigned nerrors = 0; /* Cumulative error count */ bool api_ctx_pushed = false; /* Whether API context pushed */ - h5_reset(); + h5_test_init(); if ((fapl = h5_fileaccess()) < 0) { nerrors++; diff --git a/test/getname.c b/test/getname.c index 6802ae365c6..ffc90a61cad 100644 --- a/test/getname.c +++ b/test/getname.c @@ -3757,7 +3757,7 @@ main(void) bool driver_is_parallel; /* Reset the library and get the file access property list */ - h5_reset(); + h5_test_init(); fapl = h5_fileaccess(); h5_fixname(FILENAME[0], fapl, filename0, sizeof filename0); diff --git a/test/gheap.c b/test/gheap.c index 782c80c8288..f4bf3210d6f 100644 --- a/test/gheap.c +++ b/test/gheap.c @@ -561,7 +561,7 @@ main(void) hid_t fapl_id = H5I_INVALID_HID; bool api_ctx_pushed = false; /* Whether API context pushed */ - h5_reset(); + h5_test_init(); if ((fapl_id = h5_fileaccess()) < 0) goto error; diff --git a/test/h5test.c b/test/h5test.c index be3b246ebbb..c524d4b8d3d 100644 --- a/test/h5test.c +++ b/test/h5test.c @@ -141,29 +141,6 @@ h5_errors(hid_t estack, void H5_ATTR_UNUSED *client_data) return 0; } -/*------------------------------------------------------------------------- - * Function: h5_clean_files - * - * Purpose: Cleanup temporary test files (always). - * base_name contains the list of test file names. - * - * Return: void - * - *------------------------------------------------------------------------- - */ -void -h5_clean_files(const char *base_name[], hid_t fapl) -{ - int i; - - for (i = 0; base_name[i]; i++) { - h5_delete_test_file(base_name[i], fapl); - } - - /* Close the FAPL used to access the file */ - H5Pclose(fapl); -} /* end h5_clean_files() */ - /*------------------------------------------------------------------------- * Function: h5_delete_test_file * @@ -238,7 +215,8 @@ h5_cleanup(const char *base_name[], hid_t fapl) if (GetTestCleanup()) { /* Clean up files in base_name, and the FAPL */ - h5_clean_files(base_name, fapl); + h5_delete_all_test_files(base_name, fapl); + H5Pclose(fapl); retval = 1; } /* end if */ @@ -249,29 +227,6 @@ h5_cleanup(const char *base_name[], hid_t fapl) return retval; } /* end h5_cleanup() */ -/*------------------------------------------------------------------------- - * Function: h5_test_shutdown - * - * Purpose: Performs any special test cleanup required before the test - * ends. - * - * NOTE: This function should normally only be called once - * in a given test, usually just before leaving main(). It - * is intended for use in the single-file unit tests, not - * testhdf5. - * - * Return: void - * - *------------------------------------------------------------------------- - */ -void -h5_test_shutdown(void) -{ - - /* Restore the original error reporting routine */ - h5_restore_err(); -} /* end h5_test_shutdown() */ - /*------------------------------------------------------------------------- * Function: h5_restore_err * @@ -290,27 +245,6 @@ h5_restore_err(void) err_func = NULL; } -/*------------------------------------------------------------------------- - * Function: h5_reset - * - * Purpose: Reset the library by closing it - * - * Return: void - *------------------------------------------------------------------------- - */ -void -h5_reset(void) -{ - fflush(stdout); - fflush(stderr); - H5close(); - - /* Save current error stack reporting routine and redirect to our local one */ - assert(err_func == NULL); - H5Eget_auto2(H5E_DEFAULT, &err_func, NULL); - H5Eset_auto2(H5E_DEFAULT, h5_errors, NULL); -} - /*------------------------------------------------------------------------- * Function: h5_test_init * @@ -336,6 +270,9 @@ h5_test_init(void) assert(err_func == NULL); H5Eget_auto2(H5E_DEFAULT, &err_func, NULL); H5Eset_auto2(H5E_DEFAULT, h5_errors, NULL); + + /* Retrieve the TestExpress mode */ + GetTestExpress(); } /* end h5_test_init() */ /*------------------------------------------------------------------------- diff --git a/test/h5test.h b/test/h5test.h index 9ef94943a81..238bd38acd6 100644 --- a/test/h5test.h +++ b/test/h5test.h @@ -66,6 +66,28 @@ #define VERBOSE_MED (HDGetTestVerbosity() >= VERBO_MED) #define VERBOSE_HI (HDGetTestVerbosity() >= VERBO_HI) +/* + * The TestExpress mode for the testing framework + * + Values: + 0: Exhaustive run + Tests should take as long as necessary + 1: Full run. Default if H5_TEST_EXPRESS_LEVEL_DEFAULT + and HDF5TestExpress are not defined + Tests should take no more than 30 minutes + 2: Quick run + Tests should take no more than 10 minutes + 3: Smoke test. + Default if HDF5TestExpress is set to a value other than 0-3 + Tests should take less than 1 minute + + Design: + If the environment variable $HDF5TestExpress is defined, + or if a default testing level > 1 has been set via + H5_TEST_EXPRESS_LEVEL_DEFAULT, then test programs should + skip some tests so that they complete sooner. +*/ + /* * Test controls definitions. */ @@ -268,7 +290,6 @@ extern "C" { #endif /* Generally useful testing routines */ -H5TEST_DLL void h5_clean_files(const char *base_name[], hid_t fapl); H5TEST_DLL int h5_cleanup(const char *base_name[], hid_t fapl); H5TEST_DLL char *h5_fixname(const char *base_name, hid_t fapl, char *fullname, size_t size); H5TEST_DLL char *h5_fixname_superblock(const char *base_name, hid_t fapl, char *fullname, size_t size); @@ -278,7 +299,6 @@ H5TEST_DLL hid_t h5_fileaccess(void); H5TEST_DLL hid_t h5_fileaccess_flags(unsigned flags); H5TEST_DLL void h5_no_hwconv(void); H5TEST_DLL const char *h5_rmprefix(const char *filename); -H5TEST_DLL void h5_reset(void); H5TEST_DLL void h5_restore_err(void); H5TEST_DLL void h5_show_hostname(void); H5TEST_DLL h5_stat_size_t h5_get_file_size(const char *filename, hid_t fapl); @@ -303,16 +323,14 @@ H5TEST_DLL bool h5_driver_uses_multiple_files(const char *drv_name, un H5TEST_DLL herr_t h5_get_vfd_fapl(hid_t fapl_id); H5TEST_DLL herr_t h5_get_libver_fapl(hid_t fapl_id); -/* h5_clean_files() replacements */ +/* fapl must be closed by caller */ H5TEST_DLL void h5_delete_test_file(const char *base_name, hid_t fapl); H5TEST_DLL void h5_delete_all_test_files(const char *base_name[], hid_t fapl); -/* h5_reset() replacement */ +/* Performs any special actions before the test begins, + * including resetting the library by closing it */ H5TEST_DLL void h5_test_init(void); -/* h5_cleanup() replacement */ -H5TEST_DLL void h5_test_shutdown(void); - /* Routines for operating on the list of tests (for the "all in one" tests) */ H5TEST_DLL void TestUsage(void); H5TEST_DLL void AddTest(const char *TheName, void (*TheCall)(void), void (*Cleanup)(void), @@ -352,6 +370,7 @@ H5TEST_DLL char *getenv_all(MPI_Comm comm, int root, const char *name); #endif /* Extern global variables */ +H5TEST_DLLVAR int TestExpress; H5TEST_DLLVAR int TestVerbosity; H5TEST_DLLVAR size_t n_tests_run_g; H5TEST_DLLVAR size_t n_tests_passed_g; diff --git a/test/hdfs.c b/test/hdfs.c index 857a54c9c12..956621f384c 100644 --- a/test/hdfs.c +++ b/test/hdfs.c @@ -1589,7 +1589,7 @@ main(void) } #endif /* H5_HAVE_LIBHDFS */ - h5_reset(); + h5_test_init(); printf("Testing hdfs VFD functionality.\n"); diff --git a/test/istore.c b/test/istore.c index 5a1fa0ff498..d3b012b0e51 100644 --- a/test/istore.c +++ b/test/istore.c @@ -591,7 +591,7 @@ main(int argc, char *argv[]) has_sparse_support = is_sparse(); /* Reset library */ - h5_reset(); + h5_test_init(); fapl = h5_fileaccess(); /* Use larger file addresses... */ diff --git a/test/lheap.c b/test/lheap.c index 7b9863411fd..7377d949fd6 100644 --- a/test/lheap.c +++ b/test/lheap.c @@ -55,7 +55,7 @@ main(void) bool driver_is_default_compatible; /* Reset library */ - h5_reset(); + h5_test_init(); fapl = h5_fileaccess(); /* Push API context */ diff --git a/test/links.c b/test/links.c index ffac35651de..8c84e8eebf8 100644 --- a/test/links.c +++ b/test/links.c @@ -23112,7 +23112,7 @@ main(void) driver_name = h5_get_test_driver_name(); - h5_reset(); + h5_test_init(); fapl = h5_fileaccess(); if (h5_driver_is_default_vfd_compatible(fapl, &driver_is_default_compatible) < 0) diff --git a/test/links_env.c b/test/links_env.c index ed9c3ba7f0c..389cde662a4 100644 --- a/test/links_env.c +++ b/test/links_env.c @@ -157,7 +157,7 @@ main(void) exit(EXIT_SUCCESS); } - h5_reset(); + h5_test_init(); fapl = h5_fileaccess(); nerrors += external_link_env(fapl, false) < 0 ? 1 : 0; diff --git a/test/mdset.c b/test/mdset.c index 145618b60ea..d1678b5ed9d 100644 --- a/test/mdset.c +++ b/test/mdset.c @@ -642,7 +642,7 @@ main(void) unsigned i; int ret; - h5_reset(); + h5_test_init(); fapl_id = h5_fileaccess(); /* Initialize random number seed */ diff --git a/test/mf.c b/test/mf.c index 909a7ec89f1..e400348a11d 100644 --- a/test/mf.c +++ b/test/mf.c @@ -9136,7 +9136,7 @@ main(void) /* Get the VFD to use */ driver_name = h5_get_test_driver_name(); - h5_reset(); + h5_test_init(); fapl = h5_fileaccess(); diff --git a/test/mirror_vfd.c b/test/mirror_vfd.c index f7f88deb1a9..124fc6a6b0c 100644 --- a/test/mirror_vfd.c +++ b/test/mirror_vfd.c @@ -2411,7 +2411,7 @@ main(int argc, char **argv) struct mt_opts opts; int nerrors = 0; - h5_reset(); + h5_test_init(); g_log_stream = stdout; /* default debug/logging output stream */ diff --git a/test/mount.c b/test/mount.c index bc619b1b62b..92a0c13d84c 100644 --- a/test/mount.c +++ b/test/mount.c @@ -4458,7 +4458,7 @@ main(void) int nerrors = 0; hid_t fapl = H5I_INVALID_HID; - h5_reset(); + h5_test_init(); fapl = h5_fileaccess(); if (setup(fapl) < 0) goto error; diff --git a/test/mtime.c b/test/mtime.c index fad164b9e9c..53916b438a7 100644 --- a/test/mtime.c +++ b/test/mtime.c @@ -48,7 +48,7 @@ main(void) int token_cmp; bool driver_is_default_compatible; - h5_reset(); + h5_test_init(); fapl = h5_fileaccess(); TESTING("modification time messages"); diff --git a/test/ntypes.c b/test/ntypes.c index 5d6b37164b8..ae719961052 100644 --- a/test/ntypes.c +++ b/test/ntypes.c @@ -3183,7 +3183,7 @@ main(void) char filename[1024]; bool driver_is_parallel; - h5_reset(); + h5_test_init(); fapl = h5_fileaccess(); h5_fixname(FILENAME[0], fapl, filename, sizeof filename); diff --git a/test/objcopy.c b/test/objcopy.c index 9205e961c22..030ace34386 100644 --- a/test/objcopy.c +++ b/test/objcopy.c @@ -17123,22 +17123,20 @@ main(void) hid_t fcpl_shared, ocpl; unsigned max_compact, min_dense; int configuration; /* Configuration of tests. */ - int ExpressMode; - const char *driver_name; /* File Driver value from environment */ - bool same_file; /* Whether to run tests that only use one file */ + const char *driver_name; /* File Driver value from environment */ + bool same_file; /* Whether to run tests that only use one file */ bool driver_is_default_compatible; driver_name = h5_get_test_driver_name(); /* Setup */ - h5_reset(); + h5_test_init(); fapl = h5_fileaccess(); if (h5_driver_is_default_vfd_compatible(fapl, &driver_is_default_compatible) < 0) TEST_ERROR; - ExpressMode = GetTestExpress(); - if (ExpressMode > 1) + if (TestExpress > 1) printf("***Express test mode on. Some tests may be skipped\n"); /* Copy the file access property list */ diff --git a/test/objcopy_ref.c b/test/objcopy_ref.c index 58326d5409c..a04e6aa85cc 100644 --- a/test/objcopy_ref.c +++ b/test/objcopy_ref.c @@ -1818,14 +1818,12 @@ main(void) hid_t fcpl_shared, ocpl; unsigned max_compact, min_dense; int configuration; /* Configuration of tests. */ - int ExpressMode; /* Setup */ - h5_reset(); + h5_test_init(); fapl = h5_fileaccess(); - ExpressMode = GetTestExpress(); - if (ExpressMode > 1) + if (TestExpress > 1) printf("***Express test mode on. Some tests may be skipped\n"); /* Copy the file access property list */ diff --git a/test/ohdr.c b/test/ohdr.c index 87f88f64ac5..7f4e6bdce0a 100644 --- a/test/ohdr.c +++ b/test/ohdr.c @@ -1845,7 +1845,7 @@ main(void) single_file_vfd = !h5_driver_uses_multiple_files(driver_name, 0); /* Reset library */ - h5_reset(); + h5_test_init(); fapl = h5_fileaccess(); h5_fixname(FILENAME[0], fapl, filename, sizeof filename); diff --git a/test/onion.c b/test/onion.c index 1632c410b83..84ac6e70709 100644 --- a/test/onion.c +++ b/test/onion.c @@ -4913,7 +4913,7 @@ main(void) printf("Testing Onion VFD functionality.\n"); - h5_reset(); + h5_test_init(); /* The onion VFD only supports the sec2 VFD under the hood, so skip this * test when the environment variable has been set to something else diff --git a/test/page_buffer.c b/test/page_buffer.c index 4523b2aa904..5d36beb0389 100644 --- a/test/page_buffer.c +++ b/test/page_buffer.c @@ -2053,7 +2053,7 @@ main(void) const char *driver_name = NULL; /* File Driver value from environment */ bool api_ctx_pushed = false; /* Whether API context pushed */ - h5_reset(); + h5_test_init(); /* Get the VFD to use */ driver_name = h5_get_test_driver_name(); @@ -2086,7 +2086,8 @@ main(void) nerrors += test_stats_collection(fapl, driver_name); nerrors += test_pb_fapl_tolerance_at_open(); - h5_clean_files(FILENAME, fapl); + h5_delete_all_test_files(FILENAME, fapl); + H5Pclose(fapl); if (nerrors) goto error; diff --git a/test/ros3.c b/test/ros3.c index b88c8c61de8..b2e3912ec81 100644 --- a/test/ros3.c +++ b/test/ros3.c @@ -1103,7 +1103,7 @@ main(void) * Commence tests * ******************/ - h5_reset(); + h5_test_init(); if (CURLE_OK != curl_global_init(CURL_GLOBAL_DEFAULT)) { printf("Unable to set up curl, can't run ros3 tests\n"); diff --git a/test/s3comms.c b/test/s3comms.c index ab447f869d9..8efbc584b39 100644 --- a/test/s3comms.c +++ b/test/s3comms.c @@ -2129,7 +2129,7 @@ main(void) int nerrors = 0; const char *bucket_url_env = NULL; - h5_reset(); + h5_test_init(); #endif /* H5_HAVE_ROS3_VFD */ diff --git a/test/select_io_dset.c b/test/select_io_dset.c index 2f440d8eec0..c4a88caba3f 100644 --- a/test/select_io_dset.c +++ b/test/select_io_dset.c @@ -3208,7 +3208,7 @@ main(void) unsigned mwbuf; /* With/without modifying write buffer */ /* Testing setup */ - h5_reset(); + h5_test_init(); fapl = h5_fileaccess(); h5_fixname(FILENAME[0], fapl, filename, sizeof filename); diff --git a/test/set_extent.c b/test/set_extent.c index 1db56bab6b9..d9ba0415059 100644 --- a/test/set_extent.c +++ b/test/set_extent.c @@ -121,7 +121,7 @@ main(void) /* Initialize random number seed */ HDsrandom((unsigned)time(NULL)); - h5_reset(); + h5_test_init(); fapl = h5_fileaccess(); /* Copy the file access property list */ diff --git a/test/stab.c b/test/stab.c index 357f7682712..89481be24a1 100644 --- a/test/stab.c +++ b/test/stab.c @@ -1387,7 +1387,7 @@ main(void) contig_addr_vfd = (bool)(strcmp(driver_name, "split") != 0 && strcmp(driver_name, "multi") != 0); /* Reset library */ - h5_reset(); + h5_test_init(); fapl = h5_fileaccess(); if (h5_driver_is_default_vfd_compatible(fapl, &driver_is_default_compatible) < 0) diff --git a/test/swmr.c b/test/swmr.c index 94c98737c59..cb99917756a 100644 --- a/test/swmr.c +++ b/test/swmr.c @@ -7737,7 +7737,7 @@ main(void) bool file_locking_enabled = false; /* Checks if the file system supports locks */ /* Testing setup */ - h5_reset(); + h5_test_init(); /* Skip this test if SWMR I/O is not supported for the VFD specified * by the environment variable. diff --git a/test/testframe.c b/test/testframe.c index 133e8ac0c6b..ff12413a62e 100644 --- a/test/testframe.c +++ b/test/testframe.c @@ -41,7 +41,7 @@ static int num_errs = 0; /* Total number int TestVerbosity = VERBO_DEF; /* Default Verbosity is Low */ static int Summary = 0; /* Show test summary. Default is no. */ static int CleanUp = 1; /* Do cleanup or not. Default is yes. */ -static int TestExpress = -1; /* Do TestExpress or not. -1 means not set yet. */ +int TestExpress = -1; /* Do TestExpress or not. -1 means not set yet. */ static TestStruct *Test = NULL; /* Array of tests */ static unsigned TestAlloc = 0; /* Size of the Test array */ static unsigned Index = 0; diff --git a/test/tfile.c b/test/tfile.c index 028de9a3e94..968f410e7ea 100644 --- a/test/tfile.c +++ b/test/tfile.c @@ -4489,7 +4489,8 @@ test_filespace_info(const char *driver_name) } /* end for fs_persist */ /* close fapl_ and remove the file */ - h5_clean_files(FILESPACE_NAME, my_fapl); + h5_delete_all_test_files(FILESPACE_NAME, my_fapl); + H5Pclose(my_fapl); } /* end for new_format */ } /* test_filespace_info() */ @@ -4717,7 +4718,8 @@ test_file_freespace(const char *driver_name) /* Check that the file reverted to empty size */ VERIFY(mod_filesize, empty_filesize, "H5Fget_freespace"); - h5_clean_files(FILESPACE_NAME, my_fapl); + h5_delete_all_test_files(FILESPACE_NAME, my_fapl); + H5Pclose(my_fapl); } /* end for */ @@ -4805,7 +4807,8 @@ test_sects_freespace(const char *driver_name, bool new_format) if (!vol_is_native) { CHECK(H5Fclose(file), FAIL, "H5Fclose"); CHECK(H5Pclose(fcpl), FAIL, "H5Pclose"); - h5_clean_files(FILESPACE_NAME, fapl); + h5_delete_all_test_files(FILESPACE_NAME, fapl); + H5Pclose(fapl); CHECK(H5Pclose(fapl), FAIL, "H5Pclose"); MESSAGE(5, (" -- SKIPPED --\n")); return; @@ -4981,7 +4984,8 @@ test_sects_freespace(const char *driver_name, bool new_format) ret = H5Pclose(fcpl); CHECK(fcpl, FAIL, "H5Pclose"); - h5_clean_files(FILESPACE_NAME, fapl); + h5_delete_all_test_files(FILESPACE_NAME, fapl); + H5Pclose(fapl); } /* end test_sects_freespace() */ diff --git a/test/timer.c b/test/timer.c index e992cbaa734..81c356feff2 100644 --- a/test/timer.c +++ b/test/timer.c @@ -363,7 +363,7 @@ main(void) { int nerrors = 0; - h5_reset(); + h5_test_init(); printf("Testing platform-independent timer functionality.\n"); diff --git a/test/tsohm.c b/test/tsohm.c index 23d750dc779..cc639a6a2b2 100644 --- a/test/tsohm.c +++ b/test/tsohm.c @@ -615,7 +615,7 @@ size1_helper(hid_t file, const char *filename, hid_t fapl_id, bool test_file_clo /* Closing and re-opening the file takes a long time on systems without * local disks. Don't close and reopen if express testing is enabled. */ - if (GetTestExpress() > 1) + if (TestExpress > 1) test_file_closing = false; /* Initialize wdata */ @@ -1553,7 +1553,7 @@ size2_helper(hid_t fcpl_id, int test_file_closing, size2_helper_struct *ret_size /* Closing and re-opening the file takes a long time on systems without * local disks. Don't close and reopen if express testing is enabled. */ - if (GetTestExpress() > 1) + if (TestExpress > 1) test_file_closing = 0; /* Create a file and get its size */ diff --git a/test/unlink.c b/test/unlink.c index e9cb713e8ef..e7e6c2add52 100644 --- a/test/unlink.c +++ b/test/unlink.c @@ -2909,7 +2909,7 @@ main(void) HDsrandom((unsigned)time(NULL)); /* Open */ - h5_reset(); + h5_test_init(); fapl = h5_fileaccess(); /* Copy the file access property list */ diff --git a/test/unregister.c b/test/unregister.c index e1576c09e2a..843c6671240 100644 --- a/test/unregister.c +++ b/test/unregister.c @@ -280,7 +280,7 @@ main(void) bool api_ctx_pushed = false; /* Whether API context pushed */ /* Testing setup */ - h5_reset(); + h5_test_init(); fapl_id = h5_fileaccess(); /* Push API context */ diff --git a/test/vds.c b/test/vds.c index c08eec09288..8dafc5c6890 100644 --- a/test/vds.c +++ b/test/vds.c @@ -8608,7 +8608,8 @@ test_printf(unsigned config, hid_t vds_fapl, hid_t src_fapl) */ /* Clean up files so the source files do not exist yet */ H5Iinc_ref(vds_fapl); /* Prevent FAPL from being closed */ - h5_clean_files(FILENAME, vds_fapl); + h5_delete_all_test_files(FILENAME, vds_fapl); + H5Pclose(vds_fapl); /* Clear virtual layout in DCPL */ if (H5Pset_layout(dcpl, H5D_VIRTUAL) < 0) @@ -8918,7 +8919,8 @@ test_printf(unsigned config, hid_t vds_fapl, hid_t src_fapl) */ /* Clean up files so the source files do not exist yet */ H5Iinc_ref(vds_fapl); /* Prevent FAPL from being closed */ - h5_clean_files(FILENAME, vds_fapl); + h5_delete_all_test_files(FILENAME, vds_fapl); + H5Pclose(vds_fapl); /* Clear virtual layout in DCPL */ if (H5Pset_layout(dcpl, H5D_VIRTUAL) < 0) @@ -12323,7 +12325,7 @@ main(void) driver_name = h5_get_test_driver_name(); /* Testing setup */ - h5_reset(); + h5_test_init(); fapl = h5_fileaccess(); if (h5_using_parallel_driver(fapl, &driver_is_parallel) < 0) diff --git a/test/vds_env.c b/test/vds_env.c index 4432e0aad53..9e24067d75a 100644 --- a/test/vds_env.c +++ b/test/vds_env.c @@ -334,7 +334,7 @@ main(void) driver_name = h5_get_test_driver_name(); /* Testing setup */ - h5_reset(); + h5_test_init(); fapl = h5_fileaccess(); if (h5_using_parallel_driver(fapl, &driver_is_parallel) < 0) diff --git a/test/vfd.c b/test/vfd.c index 7025de907df..6198d4fe497 100644 --- a/test/vfd.c +++ b/test/vfd.c @@ -5886,7 +5886,7 @@ main(void) exit(EXIT_SUCCESS); } - h5_reset(); + h5_test_init(); printf("Testing basic Virtual File Driver functionality.\n"); diff --git a/test/vfd_plugin.c b/test/vfd_plugin.c index 91f8ec50c41..e588d5feab8 100644 --- a/test/vfd_plugin.c +++ b/test/vfd_plugin.c @@ -416,7 +416,7 @@ main(void) { int nerrors = 0; - h5_reset(); + h5_test_init(); puts("Testing VFD plugin functionality."); diff --git a/test/vol.c b/test/vol.c index 395b164bfe7..041e0c9b88b 100644 --- a/test/vol.c +++ b/test/vol.c @@ -2651,7 +2651,7 @@ main(void) /* Get the VFD to use */ driver_name = h5_get_test_driver_name(); - h5_reset(); + h5_test_init(); puts("Testing basic Virtual Object Layer (VOL) functionality."); diff --git a/test/vol_plugin.c b/test/vol_plugin.c index af46f3463d9..8ebc050c3b9 100644 --- a/test/vol_plugin.c +++ b/test/vol_plugin.c @@ -332,7 +332,7 @@ main(void) { int nerrors = 0; - h5_reset(); + h5_test_init(); puts("Testing VOL connector plugin functionality."); diff --git a/testpar/t_filters_parallel.c b/testpar/t_filters_parallel.c index f60431b0dad..fad597e17da 100644 --- a/testpar/t_filters_parallel.c +++ b/testpar/t_filters_parallel.c @@ -10319,7 +10319,8 @@ main(int argc, char **argv) TestAlarmOff(); - h5_clean_files(FILENAME, fapl_id); + h5_delete_all_test_files(FILENAME, fapl_id); + H5Pclose(fapl_id); fapl_id = H5I_INVALID_HID; if (dcpl_id >= 0) diff --git a/testpar/t_mpi.c b/testpar/t_mpi.c index 0f1e27b506e..c0dabf54431 100644 --- a/testpar/t_mpi.c +++ b/testpar/t_mpi.c @@ -1231,7 +1231,8 @@ main(int argc, char **argv) /* turn off alarm */ TestAlarmOff(); - h5_clean_files(FILENAME, fapl); + h5_delete_all_test_files(FILENAME, fapl); + H5Pclose(fapl); H5close(); /* MPI_Finalize must be called AFTER H5close which may use MPI calls */ diff --git a/testpar/t_pflush2.c b/testpar/t_pflush2.c index 2f860d4417d..826f7d4622d 100644 --- a/testpar/t_pflush2.c +++ b/testpar/t_pflush2.c @@ -200,8 +200,10 @@ main(int argc, char *argv[]) H5Eset_auto2(H5E_DEFAULT, func, NULL); - h5_clean_files(FLUSH_FILENAME, fapl_id1); - h5_clean_files(NOFLUSH_FILENAME, fapl_id2); + h5_delete_all_test_files(FLUSH_FILENAME, fapl_id1); + H5Pclose(fapl_id1); + h5_delete_all_test_files(NOFLUSH_FILENAME, fapl_id2); + H5Pclose(fapl_id2); if (data_g) { free(data_g); diff --git a/testpar/t_pmulti_dset.c b/testpar/t_pmulti_dset.c index a61e1b4dcc4..f0d49291ad4 100644 --- a/testpar/t_pmulti_dset.c +++ b/testpar/t_pmulti_dset.c @@ -648,7 +648,7 @@ main(int argc, char *argv[]) unsigned i; int ret; - h5_reset(); + h5_test_init(); /* Initialize MPI */ MPI_Init(&argc, &argv); diff --git a/testpar/t_select_io_dset.c b/testpar/t_select_io_dset.c index 9d3f1205051..2afe65e7b9d 100644 --- a/testpar/t_select_io_dset.c +++ b/testpar/t_select_io_dset.c @@ -4086,7 +4086,7 @@ main(int argc, char *argv[]) unsigned select; unsigned mwbuf; - h5_reset(); + h5_test_init(); /* Initialize MPI */ MPI_Init(&argc, &argv); diff --git a/testpar/t_shapesame.c b/testpar/t_shapesame.c index ecb94c3729c..8aeed30e078 100644 --- a/testpar/t_shapesame.c +++ b/testpar/t_shapesame.c @@ -4416,8 +4416,7 @@ main(int argc, char **argv) TestSummary(); /* Clean up test files */ - h5_clean_files(FILENAME, fapl); - + h5_delete_all_test_files(FILENAME, fapl); H5Pclose(fapl); nerrors += GetTestNumErrs(); diff --git a/testpar/t_subfiling_vfd.c b/testpar/t_subfiling_vfd.c index 8f0ac52c074..27c48250be4 100644 --- a/testpar/t_subfiling_vfd.c +++ b/testpar/t_subfiling_vfd.c @@ -3349,7 +3349,7 @@ main(int argc, char **argv) int main(void) { - h5_reset(); + h5_test_init(); printf("Testing Subfiling VFD functionality\n"); printf("SKIPPED - Subfiling VFD not built\n"); exit(EXIT_SUCCESS); diff --git a/testpar/testphdf5.c b/testpar/testphdf5.c index 992b8ee71af..960a5cf67a3 100644 --- a/testpar/testphdf5.c +++ b/testpar/testphdf5.c @@ -602,8 +602,7 @@ main(int argc, char **argv) TestSummary(); /* Clean up test files */ - h5_clean_files(FILENAME, fapl); - + h5_delete_all_test_files(FILENAME, fapl); H5Pclose(fapl); nerrors += GetTestNumErrs(); diff --git a/tools/test/h5repack/h5repacktst.c b/tools/test/h5repack/h5repacktst.c index 62d3a948c92..fccd339849a 100644 --- a/tools/test/h5repack/h5repacktst.c +++ b/tools/test/h5repack/h5repacktst.c @@ -1732,7 +1732,8 @@ main(void) hid_t fapl; fapl = h5_fileaccess(); - h5_clean_files(H5REPACK_FILENAMES, fapl); + h5_delete_all_test_files(H5REPACK_FILENAMES, fapl); + H5Pclose(fapl); } puts("All h5repack tests passed."); diff --git a/tools/test/perform/perf_meta.c b/tools/test/perform/perf_meta.c index 4f1863d36f3..401400a1ac9 100644 --- a/tools/test/perform/perf_meta.c +++ b/tools/test/perform/perf_meta.c @@ -746,7 +746,8 @@ main(int argc, char **argv) if (H5Sclose(small_space) < 0) goto error; - h5_clean_files(FILENAME, fapl); + h5_delete_all_test_files(FILENAME, fapl); + H5Pclose(fapl); #ifdef H5_HAVE_PARALLEL if (facc_type == FACC_MPIO) From efb0571e5c6da398dd336e485fa5be9f0744ada9 Mon Sep 17 00:00:00 2001 From: Allen Byrne <50328838+byrnHDF@users.noreply.github.com> Date: Thu, 20 Jun 2024 16:03:16 -0500 Subject: [PATCH 30/45] Skip examples if running sanitizers (#4592) --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a27b7e899b3..2a901c5a4c4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1196,7 +1196,7 @@ configure_file (${HDF_RESOURCES_DIR}/H5pubconf.h.in ${HDF5_SRC_BINARY_DIR}/H5pub #----------------------------------------------------------------------------- if (EXISTS "${HDF5_SOURCE_DIR}/HDF5Examples" AND IS_DIRECTORY "${HDF5_SOURCE_DIR}/HDF5Examples") option (HDF5_BUILD_EXAMPLES "Build HDF5 Library Examples" ON) - if (HDF5_BUILD_EXAMPLES) + if (HDF5_BUILD_EXAMPLES AND NOT USE_SANITIZER) include (${HDF_RESOURCES_DIR}/HDF5ExampleCache.cmake) set (HDF5_VERSION ${HDF5_PACKAGE_VERSION}) add_subdirectory (HDF5Examples) From 15b47eeb7e879cbe13e1da9248f7c510982cc289 Mon Sep 17 00:00:00 2001 From: Dana Robinson <43805+derobins@users.noreply.github.com> Date: Fri, 21 Jun 2024 09:02:07 -0700 Subject: [PATCH 31/45] Clean up s3comms test code (#4594) * Remove JS* macros * Remove dead code * Bring in line with other test code --- test/s3comms.c | 1705 +++++++++++++++++++----------------------------- 1 file changed, 668 insertions(+), 1037 deletions(-) diff --git a/test/s3comms.c b/test/s3comms.c index 8efbc584b39..fe7c8c6f8df 100644 --- a/test/s3comms.c +++ b/test/s3comms.c @@ -22,327 +22,23 @@ #ifdef H5_HAVE_ROS3_VFD -/***************************************************************************** - * - * FILE-LOCAL TESTING MACROS - * - * Purpose: - * - * 1) Upon test failure, goto-jump to single-location teardown in test - * function. E.g., `error:` (consistency with HDF corpus) or - * `failed:` (reflects purpose). - * >>> using "error", in part because `H5E_BEGIN_TRY` expects it. - * 2) Increase clarity and reduce overhead found with `TEST_ERROR`. - * e.g., "if(somefunction(arg, arg2) < 0) TEST_ERROR:" - * requires reading of entire line to know whether this if/call is - * part of the test setup, test operation, or a test unto itself. - * 3) Provide testing macros with optional user-supplied failure message; - * if not supplied (NULL), generate comparison output in the spirit of - * test-driven development. E.g., "expected 5 but was -3" - * User messages clarify test's purpose in code, encouraging description - * without relying on comments. - * 4) Configurable expected-actual order in generated comparison strings. - * Some prefer `VERIFY(expected, actual)`, others - * `VERIFY(actual, expected)`. Provide preprocessor ifdef switch - * to satisfy both parties, assuming one paradigm per test file. - * (One could #undef and redefine the flag through the file as desired, - * but _why_.) - * Provided as courtesy, per consideration for inclusion in the library - * proper. - * - * Macros: - * - * JSVERIFY_EXP_ACT - ifdef flag, configures comparison order - * FAIL_IF() - check condition - * FAIL_UNLESS() - check _not_ condition - * JSVERIFY() - long-int equality check; prints reason/comparison - * JSVERIFY_NOT() - long-int inequality check; prints - * JSVERIFY_STR() - string equality check; prints - * - *****************************************************************************/ - -/*---------------------------------------------------------------------------- - * - * ifdef flag: JSVERIFY_EXP_ACT - * - * JSVERIFY macros accept arguments as (EXPECTED, ACTUAL[, reason]) - * default, if this is undefined, is (ACTUAL, EXPECTED[, reason]) - * - *---------------------------------------------------------------------------- - */ -#define JSVERIFY_EXP_ACT 1L - -/*---------------------------------------------------------------------------- - * - * Macro: JSFAILED_AT() - * - * Purpose: - * - * Preface a test failure by printing "*FAILED*" and location to stdout - * Similar to `H5_FAILED(); AT();` from h5test.h - * - * *FAILED* at somefile.c:12 in function_name()... - * - *---------------------------------------------------------------------------- - */ -#define JSFAILED_AT() \ - { \ - printf("*FAILED* at %s:%d in %s()...\n", __FILE__, __LINE__, __func__); \ - } - -/*---------------------------------------------------------------------------- - * - * Macro: FAIL_IF() - * - * Purpose: - * - * Make tests more accessible and less cluttered than - * `if (thing == otherthing()) TEST_ERROR` - * paradigm. - * - * The following lines are roughly equivalent: - * - * `if (myfunc() < 0) TEST_ERROR;` (as seen elsewhere in HDF tests) - * `FAIL_IF(myfunc() < 0)` - * - * Prints a generic "FAILED AT" line to stdout and jumps to `error`, - * similar to `TEST_ERROR` in h5test.h - * - *---------------------------------------------------------------------------- - */ -#define FAIL_IF(condition) \ - if (condition) { \ - JSFAILED_AT() \ - goto error; \ - } - -/*---------------------------------------------------------------------------- - * - * Macro: FAIL_UNLESS() - * - * Purpose: - * - * TEST_ERROR wrapper to reduce cognitive overhead from "negative tests", - * e.g., "a != b". - * - * Opposite of FAIL_IF; fails if the given condition is _not_ true. - * - * `FAIL_IF( 5 != my_op() )` - * is equivalent to - * `FAIL_UNLESS( 5 == my_op() )` - * However, `JSVERIFY(5, my_op(), "bad return")` may be even clearer. - * (see JSVERIFY) - * - *---------------------------------------------------------------------------- - */ -#define FAIL_UNLESS(condition) \ - if (!(condition)) { \ - JSFAILED_AT() \ - goto error; \ - } - -/*---------------------------------------------------------------------------- - * - * Macro: JSERR_LONG() - * - * Purpose: - * - * Print an failure message for long-int arguments. - * ERROR-AT printed first. - * If `reason` is given, it is printed on own line and newlined after - * else, prints "expected/actual" aligned on own lines. - * - * *FAILED* at myfile.c:488 in somefunc()... - * forest must be made of trees. - * - * or - * - * *FAILED* at myfile.c:488 in somefunc()... - * ! Expected 425 - * ! Actual 3 - * - *---------------------------------------------------------------------------- - */ -static inline void -jserr_long(long expected, long actual, const char *reason) -{ - if (reason != NULL) { - printf("%s\n", reason); - } - else { - printf(" ! Expected %ld\n ! Actual %ld\n", expected, actual); - } -} - -#define JSERR_LONG(expected, actual, reason) \ - { \ - JSFAILED_AT() \ - jserr_long((long)(expected), (long)(actual), reason); \ - } - -/*---------------------------------------------------------------------------- - * - * Macro: JSERR_STR() - * - * Purpose: - * - * Print an failure message for string arguments. - * ERROR-AT printed first. - * If `reason` is given, it is printed on own line and newlined after - * else, prints "expected/actual" aligned on own lines. - * - * *FAILED* at myfile.c:421 in myfunc()... - * Blue and Red strings don't match! - * - * or - * - * *FAILED* at myfile.c:421 in myfunc()... - * !!! Expected: - * this is my expected - * string - * !!! Actual: - * not what I expected at all - * - *---------------------------------------------------------------------------- - */ -static inline void -jserr_str(const char *expected, const char *actual, const char *reason) -{ - if (reason != NULL) { - printf("%s\n", reason); - } - else { - printf("!!! Expected:\n%s\n!!!Actual:\n%s\n", expected, actual); - } -} - -#define JSERR_STR(expected, actual, reason) \ - { \ - JSFAILED_AT() \ - jserr_str((expected), (actual), (reason)); \ - } - -#ifdef JSVERIFY_EXP_ACT -/* VERIFY routines with parameter order (, [, ]) - */ - -/*---------------------------------------------------------------------------- - * - * Macro: JSVERIFY() - * - * Purpose: - * - * Verify that two long integers are equal. - * If unequal, print failure message - * (with `reason`, if not NULL; expected/actual if NULL) - * and jump to `error` at end of function - * - *---------------------------------------------------------------------------- - */ -#define JSVERIFY(expected, actual, reason) \ - if ((long)(actual) != (long)(expected)) { \ - JSERR_LONG((expected), (actual), (reason)) \ - goto error; \ - } /* JSVERIFY */ - -#if 0 /* UNUSED */ - -/*---------------------------------------------------------------------------- - * - * Macro: JSVERIFY_NOT() - * - * Purpose: - * - * Verify that two long integers are _not_ equal. - * If equal, print failure message - * (with `reason`, if not NULL; expected/actual if NULL) - * and jump to `error` at end of function - * - *---------------------------------------------------------------------------- - */ -#define JSVERIFY_NOT(expected, actual, reason) \ - if ((long)(actual) == (long)(expected)) { \ - JSERR_LONG((expected), (actual), (reason)) \ - goto error; \ - } /* JSVERIFY_NOT */ -#endif /* JSVERIFY_NOT unused */ - -/*---------------------------------------------------------------------------- - * - * Macro: JSVERIFY_STR() - * - * Purpose: - * - * Verify that two strings are equal. - * If unequal, print failure message - * (with `reason`, if not NULL; expected/actual if NULL) - * and jump to `error` at end of function - * - *---------------------------------------------------------------------------- - */ -#define JSVERIFY_STR(expected, actual, reason) \ - if (strcmp((actual), (expected)) != 0) { \ - JSERR_STR((expected), (actual), (reason)); \ - goto error; \ - } /* JSVERIFY_STR */ - -#else -/* JSVERIFY_EXP_ACT not defined - * - * Repeats macros above, but with actual/expected parameters reversed. - */ - -/*---------------------------------------------------------------------------- - * Macro: JSVERIFY() - * See: JSVERIFY documentation above. - *---------------------------------------------------------------------------- - */ -#define JSVERIFY(actual, expected, reason) \ - if ((long)(actual) != (long)(expected)) { \ - JSERR_LONG((expected), (actual), (reason)); \ - goto error; \ - } /* JSVERIFY */ - -#if 0 /* UNUSED */ - -/*---------------------------------------------------------------------------- - * Macro: JSVERIFY_NOT() - * See: JSVERIFY_NOT documentation above. - *---------------------------------------------------------------------------- - */ -#define JSVERIFY_NOT(actual, expected, reason) \ - if ((long)(actual) == (long)(expected)) { \ - JSERR_LONG((expected), (actual), (reason)) \ - goto error; \ - } /* JSVERIFY_NOT */ -#endif /* JSVERIFY_NOT unused */ - -/*---------------------------------------------------------------------------- - * Macro: JSVERIFY_STR() - * See: JSVERIFY_STR documentation above. - *---------------------------------------------------------------------------- - */ -#define JSVERIFY_STR(actual, expected, reason) \ - if (strcmp((actual), (expected)) != 0) { \ - JSERR_STR((expected), (actual), (reason)); \ - goto error; \ - } /* JSVERIFY_STR */ - -#endif /* ifdef/else JSVERIFY_EXP_ACT */ - #define S3_TEST_PROFILE_NAME "ros3_vfd_test" #define S3_TEST_RESOURCE_TEXT_RESTRICTED "t8.shakespeare.txt" #define S3_TEST_RESOURCE_TEXT_PUBLIC "Poe_Raven.txt" #define S3_TEST_RESOURCE_MISSING "missing.csv" -#define S3_TEST_RUN_TIMEOUT 0 /* run tests that might hang */ -#define S3_TEST_MAX_URL_SIZE 256 /* char array size */ +/* URL max size */ +#define S3_TEST_MAX_URL_SIZE 256 + +/* Read buffer max size */ +#define S3COMMS_READ_BUFFER_SIZE 256 -/* Global variables for aws test profile. +/* Global variables for AWS test profile. + * * An attempt is made to read ~/.aws/credentials and ~/.aws/config upon test * startup -- if unable to open either file or cannot load region, id, and key, - * tests connecting with S3 will not be run + * tests connecting with S3 will not be run. */ static int s3_test_credentials_loaded = 0; static char s3_test_aws_region[16] = ""; @@ -353,23 +49,18 @@ static char s3_test_bucket_url[S3_TEST_MAX_URL_SIZE] = ""; static bool s3_test_bucket_defined = false; /*--------------------------------------------------------------------------- + * Function: test_macro_format_credential * - * Function: test_macro_format_credential() - * - * Purpose: - * - * Demonstrate that the macro `S3COMMS_FORMAT_CREDENTIAL` - * performs as expected. + * Purpose: Demonstrate that the macro `S3COMMS_FORMAT_CREDENTIAL` + * performs as expected. * + * Return: PASS : 0 + * FAIL : 1 *---------------------------------------------------------------------------- */ -static herr_t +static int test_macro_format_credential(void) { - /************************ - * test-local variables * - ************************/ - char dest[256]; const char access[] = "AKIAIOSFODNN7EXAMPLE"; const char date[] = "20130524"; @@ -379,39 +70,36 @@ test_macro_format_credential(void) TESTING("test_macro_format_credential"); - FAIL_IF(S3COMMS_MAX_CREDENTIAL_SIZE < S3COMMS_FORMAT_CREDENTIAL(dest, access, date, region, service)) + if (S3COMMS_MAX_CREDENTIAL_SIZE < S3COMMS_FORMAT_CREDENTIAL(dest, access, date, region, service)) + FAIL_PUTS_ERROR("bad s3comms credential size"); - JSVERIFY_STR(expected, dest, NULL) + if (strncmp(expected, dest, 256)) + FAIL_PUTS_ERROR("incorrect credential string"); PASSED(); return 0; error: - return -1; - + return 1; } /* end test_macro_format_credential() */ /*--------------------------------------------------------------------------- + * Function: test_aws_canonical_request * - * Function: test_aws_canonical_request() - * - * Purpose: - * - * Demonstrate the construction of a Canonical Request (and Signed Headers) + * Purpose: Demonstrate the construction of a Canonical Request (and + * Signed Headers) * * Elided / not yet implemented: * Query strings * request "body" * + * Return: PASS : 0 + * FAIL : 1 *--------------------------------------------------------------------------- */ -static herr_t +static int test_aws_canonical_request(void) { - /************************* - * test-local structures * - *************************/ - struct header { const char *name; const char *value; @@ -422,14 +110,10 @@ test_aws_canonical_request(void) const char *exp_headers; const char *verb; const char *resource; - unsigned int listsize; + int listsize; struct header list[5]; }; - /************************ - * test-local variables * - ************************/ - struct testcase cases[] = { { "GET\n/some/" @@ -469,77 +153,85 @@ test_aws_canonical_request(void) }, /* unused; satisfies compiler */ }, }; /* struct testcase cases[] */ + struct testcase *C = NULL; - char cr_dest[512]; /* canonical request */ - hrb_t *hrb = NULL; /* http request buffer object */ - unsigned int i = 0; /* looping/indexing */ - unsigned int j = 0; /* looping/indexing */ - hrb_node_t *node = NULL; /* http headers list pointer */ - unsigned int n_cases = 3; - char sh_dest[64]; /* signed headers */ + char cr_dest[512]; /* Canonical request */ + hrb_t *hrb = NULL; /* http request buffer object */ + hrb_node_t *node = NULL; /* http headers list pointer */ + const int NCASES = 3; + char sh_dest[64]; /* Signed headers */ + herr_t ret; TESTING("test_aws_canonical_request"); - for (i = 0; i < n_cases; i++) { - /* pre-test bookkeeping - */ + for (int i = 0; i < NCASES; i++) { C = &cases[i]; - for (j = 0; j < 256; j++) { + + for (int j = 0; j < 256; j++) { cr_dest[j] = 0; - } /* zero request buffer */ - for (j = 0; j < 64; j++) { + } + + for (int j = 0; j < 64; j++) { sh_dest[j] = 0; - } /* zero headers buffer */ + } - /* create HTTP request object with given verb, resource/path - */ + /* Create HTTP request object with given verb, resource/path */ hrb = H5FD_s3comms_hrb_init_request(C->verb, C->resource, "HTTP/1.1"); assert(hrb->body == NULL); - /* Create headers list from test case input - */ - for (j = 0; j < C->listsize; j++) { - FAIL_IF(FAIL == H5FD_s3comms_hrb_node_set(&node, C->list[j].name, C->list[j].value)); + /* Create headers list from test case input */ + for (int j = 0; j < C->listsize; j++) { + if (H5FD_s3comms_hrb_node_set(&node, C->list[j].name, C->list[j].value) < 0) + TEST_ERROR; } hrb->first_header = node; - /* test - */ - JSVERIFY(SUCCEED, H5FD_s3comms_aws_canonical_request(cr_dest, 512, sh_dest, 64, hrb), - " unable to compose canonical request") - JSVERIFY_STR(C->exp_headers, sh_dest, NULL) - JSVERIFY_STR(C->exp_request, cr_dest, NULL) + /* Test */ + if (H5FD_s3comms_aws_canonical_request(cr_dest, 512, sh_dest, 64, hrb) < 0) + TEST_ERROR; + if (strncmp(C->exp_headers, sh_dest, 512)) + FAIL_PUTS_ERROR("header string mismatch"); + if (strncmp(C->exp_request, cr_dest, 512)) + FAIL_PUTS_ERROR("request string mismatch"); - /* tear-down - */ + /* Tear-down */ while (node != NULL) { - FAIL_IF(FAIL == H5FD_s3comms_hrb_node_set(&node, node->name, NULL)); + if (H5FD_s3comms_hrb_node_set(&node, node->name, NULL) < 0) + TEST_ERROR; } - assert(NULL == node); - FAIL_IF(FAIL == H5FD_s3comms_hrb_destroy(&hrb)); - assert(NULL == hrb); - - } /* for each test case */ - - /*************** - * ERROR CASES * - ***************/ + if (H5FD_s3comms_hrb_destroy(&hrb) < 0) + TEST_ERROR; + } - /* malformed hrb and/or node-list - */ - JSVERIFY(FAIL, H5FD_s3comms_aws_canonical_request(cr_dest, 20, sh_dest, 20, NULL), - "http request object cannot be null") + /* ERROR CASES - Malformed hrb and/or node-list */ + H5E_BEGIN_TRY + { + ret = H5FD_s3comms_aws_canonical_request(cr_dest, 20, sh_dest, 20, NULL); + } + H5E_END_TRY + if (ret == SUCCEED) + FAIL_PUTS_ERROR("http request object cannot be null"); hrb = H5FD_s3comms_hrb_init_request("GET", "/", "HTTP/1.1"); - JSVERIFY(FAIL, H5FD_s3comms_aws_canonical_request(NULL, 20, sh_dest, 20, hrb), - "canonical request destination cannot be NULL") + H5E_BEGIN_TRY + { + ret = H5FD_s3comms_aws_canonical_request(NULL, 20, sh_dest, 20, hrb); + } + H5E_END_TRY + if (ret == SUCCEED) + FAIL_PUTS_ERROR("canonical request destination cannot be NULL"); - JSVERIFY(FAIL, H5FD_s3comms_aws_canonical_request(cr_dest, 20, NULL, 20, hrb), - "signed headers destination cannot be null") + H5E_BEGIN_TRY + { + ret = H5FD_s3comms_aws_canonical_request(cr_dest, 20, NULL, 20, hrb); + } + H5E_END_TRY + if (ret == SUCCEED) + FAIL_PUTS_ERROR("signed headers destination cannot be null"); - FAIL_IF(FAIL == H5FD_s3comms_hrb_destroy(&hrb)) - assert(NULL == hrb); + if (H5FD_s3comms_hrb_destroy(&hrb) < 0) + TEST_ERROR; PASSED(); return 0; @@ -548,39 +240,28 @@ test_aws_canonical_request(void) if (node != NULL) { while (node != NULL) - (void)H5FD_s3comms_hrb_node_set(&node, node->name, NULL); - assert(node == NULL); + H5FD_s3comms_hrb_node_set(&node, node->name, NULL); } if (hrb != NULL) { - (void)H5FD_s3comms_hrb_destroy(&hrb); + H5FD_s3comms_hrb_destroy(&hrb); } - return -1; + return 1; } /* end test_aws_canonical_request() */ /*--------------------------------------------------------------------------- + * Function: test_bytes_to_hex * - * Function: test_bytes_to_hex - * - * Purpose: - * - * Define and verify behavior of `H5FD_s3comms_bytes_to_hex()`. - * - * Return: - * - * Success: 0 - * Failure: -1 + * Purpose: Define and verify behavior of `H5FD_s3comms_bytes_to_hex()`. * + * Return: PASS : 0 + * FAIL : 1 *--------------------------------------------------------------------------- */ -static herr_t +static int test_bytes_to_hex(void) { - /************************* - * test-local structures * - *************************/ - struct testcase { const char exp[17]; /* in size * 2 + 1 for null terminator */ const unsigned char in[8]; @@ -588,10 +269,6 @@ test_bytes_to_hex(void) bool lower; }; - /************************ - * test-local variables * - ************************/ - struct testcase cases[] = { { "52F3000C9A", @@ -609,57 +286,52 @@ test_bytes_to_hex(void) "", {17, 63, 26, 56}, 0, false, /* irrelevant */ }, }; - int i = 0; - int n_cases = 3; - char out[17]; - int out_off = 0; + const int NCASES = 3; + char out[17]; + herr_t ret; TESTING("bytes-to-hex"); - for (i = 0; i < n_cases; i++) { - for (out_off = 0; out_off < 17; out_off++) { + for (int i = 0; i < NCASES; i++) { + for (int out_off = 0; out_off < 17; out_off++) { out[out_off] = 0; } - JSVERIFY(SUCCEED, H5FD_s3comms_bytes_to_hex(out, cases[i].in, cases[i].size, cases[i].lower), NULL) + if (H5FD_s3comms_bytes_to_hex(out, cases[i].in, cases[i].size, cases[i].lower) < 0) + TEST_ERROR; - JSVERIFY_STR(cases[i].exp, out, NULL) + if (strncmp(cases[i].exp, out, 17)) + FAIL_PUTS_ERROR("incorrect bytes to hex conversion"); } - /* dest cannot be null - */ - JSVERIFY(FAIL, H5FD_s3comms_bytes_to_hex(NULL, (const unsigned char *)"nada", 5, false), - "destination cannot be null") + /* dest cannot be null */ + H5E_BEGIN_TRY + { + ret = H5FD_s3comms_bytes_to_hex(NULL, (const unsigned char *)"nada", 5, false); + } + H5E_END_TRY + if (ret == SUCCEED) + FAIL_PUTS_ERROR("dest parameter cannot be null"); PASSED(); return 0; error: - return -1; - + return 1; } /* end test_bytes_to_hex() */ /*--------------------------------------------------------------------------- + * Function: test_hrb_init_request * - * Function: test_hrb_init_request() - * - * Purpose: - * - * Define and verify behavior of `H5FD_s3comms_hrb_init_request()` + * Purpose: Define and verify behavior of `H5FD_s3comms_hrb_init_request()` * + * Return: PASS : 0 + * FAIL : 1 *--------------------------------------------------------------------------- */ -static herr_t +static int test_hrb_init_request(void) { - /********************* - * test-local macros * - *********************/ - - /************************* - * test-local structures * - *************************/ - struct testcase { const char msg[64]; const char *verb; @@ -669,10 +341,6 @@ test_hrb_init_request(void) bool ret_null; }; - /************************ - * test-local variables * - ************************/ - struct testcase cases[] = { { "get HTTP request just as we provided", @@ -715,67 +383,70 @@ test_hrb_init_request(void) true, }, }; - struct testcase *C = NULL; - unsigned int i = 0; - unsigned int ncases = 5; - hrb_t *req = NULL; + const int NCASES = 5; + hrb_t *req = NULL; TESTING("hrb_init_request"); - for (i = 0; i < ncases; i++) { - C = &cases[i]; + for (int i = 0; i < NCASES; i++) { + struct testcase *C = &cases[i]; + req = H5FD_s3comms_hrb_init_request(C->verb, C->resource, C->version); + if (cases[i].ret_null == true) { - FAIL_IF(req != NULL); + if (req != NULL) + TEST_ERROR; } else { - FAIL_IF(req == NULL); + if (req == NULL) + TEST_ERROR; if (C->verb == NULL) { - JSVERIFY_STR("GET", req->verb, NULL) + if (strcmp("GET", req->verb)) + TEST_ERROR; } else { - JSVERIFY_STR(req->verb, C->verb, NULL) + if (strcmp(req->verb, C->verb)) + TEST_ERROR; } - JSVERIFY_STR("HTTP/1.1", req->version, NULL) - JSVERIFY_STR(C->exp_res, req->resource, NULL) - FAIL_IF(req->first_header != NULL); - FAIL_IF(req->body != NULL); - JSVERIFY(0, req->body_len, NULL) - JSVERIFY(SUCCEED, H5FD_s3comms_hrb_destroy(&req), "unable to destroy hrb_t") - FAIL_IF(NULL != req); /* should annull pointer as well as free */ + if (strcmp("HTTP/1.1", req->version)) + TEST_ERROR; + if (strcmp(C->exp_res, req->resource)) + TEST_ERROR; + if (req->first_header != NULL) + TEST_ERROR; + if (req->body != NULL) + TEST_ERROR; + if (0 != req->body_len) + TEST_ERROR; + if (H5FD_s3comms_hrb_destroy(&req) < 0) + FAIL_PUTS_ERROR("unable to destroy hrb_t"); + /* Should annull pointer as well as free */ + if (NULL != req) + TEST_ERROR; } - - } /* end for each testcase */ + } PASSED(); return 0; error: - (void)H5FD_s3comms_hrb_destroy(&req); - - return -1; - + H5FD_s3comms_hrb_destroy(&req); + return 1; } /* end test_hrb_init_request() */ /*--------------------------------------------------------------------------- + * Function: test_hrb_node_set * - * Function: test_hrb_node_set() - * - * Purpose: - * - * Test operations on hrb_node_t structure + * Purpose: Test operations on hrb_node_t structure * + * Return: PASS : 0 + * FAIL : 1 *--------------------------------------------------------------------------- */ -static herr_t +static int test_hrb_node_set(void) { - /************************* - * test-local structures * - *************************/ - - /* bundle of name/value representing an hrb_node_t - */ + /* Bundle of name/value representing an hrb_node_t */ typedef struct node_mock_t { const char *name; const char *value; @@ -808,10 +479,6 @@ test_hrb_node_set(void) const char *expected[11]; } testcase; - /************************ - * test-local variables * - ************************/ - testcase cases[] = { { "cannot remove node from null list", @@ -1076,92 +743,84 @@ test_hrb_node_set(void) }, }, }; - unsigned testcases_count = 16; - unsigned test_i = 0; - hrb_node_t *list = NULL; + const int NCASES = 16; + hrb_node_t *list = NULL; TESTING("hrb_node_t (test_hrb_node_set)"); - for (test_i = 0; test_i < testcases_count; test_i++) { + for (int i = 0; i < NCASES; i++) { const hrb_node_t *node = NULL; - const testcase *test = &(cases[test_i]); + const testcase *test = &(cases[i]); unsigned mock_i = 0; - /********* - * SETUP * - *********/ + /* SETUP */ for (mock_i = 0; test->given[mock_i] != NULL; mock_i += 2) { const char *name = test->given[mock_i]; const char *value = test->given[mock_i + 1]; - FAIL_IF(SUCCEED != H5FD_s3comms_hrb_node_set(&list, name, value)) + if (H5FD_s3comms_hrb_node_set(&list, name, value) < 0) + TEST_ERROR; } - /******** - * TEST * - ********/ - /* perform modification on list - */ - JSVERIFY(test->returned, H5FD_s3comms_hrb_node_set(&list, test->delta.name, test->delta.value), - test->message) + /* TEST */ + + /* Modify list */ + if (test->returned != H5FD_s3comms_hrb_node_set(&list, test->delta.name, test->delta.value)) + FAIL_PUTS_ERROR(test->message); - /* verify resulting list - */ + /* Verify resulting list */ node = list; mock_i = 0; while (test->expected[mock_i] != NULL && node != NULL) { const char *name = test->expected[mock_i]; const char *value = test->expected[mock_i + 1]; - JSVERIFY_STR(name, node->name, NULL) - JSVERIFY_STR(value, node->value, NULL) + if (strcmp(name, node->name)) + TEST_ERROR; + if (strcmp(value, node->value)) + TEST_ERROR; mock_i += 2; node = node->next; } - FAIL_IF(test->expected[mock_i] != NULL) - FAIL_IF(node != NULL) + if (test->expected[mock_i] != NULL) + TEST_ERROR; + if (node != NULL) + TEST_ERROR; - /************ - * TEARDOWN * - ************/ + /* TEARDOWN */ while (list != NULL) { - FAIL_IF(SUCCEED != H5FD_s3comms_hrb_node_set(&list, list->name, NULL)) + if (H5FD_s3comms_hrb_node_set(&list, list->name, NULL) < 0) + TEST_ERROR; } - } /* end for each testcase */ + } PASSED(); return 0; error: while (list != NULL) { - (void)H5FD_s3comms_hrb_node_set(&list, list->name, NULL); + H5FD_s3comms_hrb_node_set(&list, list->name, NULL); } - return -1; + return 1; -} /* end test_hrb_node_t() */ +} /* end test_hrb_node_set() */ /*--------------------------------------------------------------------------- + * Function: test_HMAC_SHA256 * - * Function: test_HMAC_SHA256() - * - * Purpose: - * - * Define and verify behavior of `H5FD_s3comms_HMAC_SHA256()` + * Purpose: Define and verify behavior of `H5FD_s3comms_HMAC_SHA256()` * + * Return: PASS : 0 + * FAIL : 1 *--------------------------------------------------------------------------- */ -static herr_t +static int test_HMAC_SHA256(void) { - - /************************* - * test-local structures * - *************************/ - struct testcase { herr_t ret; /* SUCCEED/FAIL expected from call */ const unsigned char key[SHA256_DIGEST_LENGTH]; @@ -1172,10 +831,6 @@ test_HMAC_SHA256(void) size_t dest_size; /* if 0, `dest` is not malloc'd */ }; - /************************ - * test-local variables * - ************************/ - struct testcase cases[] = { { SUCCEED, @@ -1206,41 +861,28 @@ test_HMAC_SHA256(void) 0, /* dest -> null, resulting in immediate error */ }, }; - char *dest = NULL; - int i = 0; - int n_cases = 3; + char *dest = NULL; + const int NCASES = 3; TESTING("HMAC_SHA256"); - for (i = 0; i < n_cases; i++) { + for (int i = 0; i < NCASES; i++) { + if (cases[i].dest_size == 0) { dest = NULL; } else { - dest = (char *)malloc(sizeof(char) * cases[i].dest_size); - assert(dest != NULL); + if (NULL == (dest = (char *)malloc(sizeof(char) * cases[i].dest_size))) + TEST_ERROR; } - JSVERIFY( - cases[i].ret, - H5FD_s3comms_HMAC_SHA256(cases[i].key, cases[i].key_len, cases[i].msg, cases[i].msg_len, dest), - cases[i].msg); + if (cases[i].ret != + H5FD_s3comms_HMAC_SHA256(cases[i].key, cases[i].key_len, cases[i].msg, cases[i].msg_len, dest)) + TEST_ERROR; + if (cases[i].ret == SUCCEED) { -#ifdef VERBOSE - if (0 != strncmp(cases[i].exp, dest, strlen(cases[i].exp))) { - /* print out how wrong things are, and then fail - */ - dest = (char *)realloc(dest, cases[i].dest_size + 1); - assert(dest != NULL); - dest[cases[i].dest_size] = 0; - fprintf(stdout, "ERROR:\n!!! \"%s\"\n != \"%s\"\n", cases[i].exp, dest); + if (strncmp(cases[i].exp, dest, strlen(cases[i].exp))) TEST_ERROR; - } -#else /* VERBOSE not defined */ - /* simple pass/fail test - */ - JSVERIFY(0, strncmp(cases[i].exp, dest, strlen(cases[i].exp)), NULL); -#endif /* VERBOSE */ } free(dest); } @@ -1250,27 +892,21 @@ test_HMAC_SHA256(void) error: free(dest); - return -1; + return 1; } /* end test_HMAC_SHA256() */ /*--------------------------------------------------------------------------- + * Function: test_parse_url * - * Function: test_parse_url() * + * Return: PASS : 0 + * FAIL : 1 *--------------------------------------------------------------------------- */ -static herr_t +static int test_parse_url(void) { - /********************* - * test-local macros * - *********************/ - - /************************* - * test-local structures * - *************************/ - typedef struct { const char *scheme; const char *host; @@ -1280,20 +916,14 @@ test_parse_url(void) } const_purl_t; struct testcase { - const char *url; - herr_t exp_ret; /* expected return; */ - /* if FAIL, `expected` is unused */ - const_purl_t expected; + const char *url; + herr_t exp_ret; /* expected return */ + const_purl_t expected; /* unused if exp_ret is FAIL */ const char *msg; }; - /************************ - * test-local variables * - ************************/ - parsed_url_t *purl = NULL; - unsigned int i = 0; - unsigned int ncases = 15; + const int NCASES = 15; struct testcase cases[] = { { NULL, @@ -1471,100 +1101,277 @@ test_parse_url(void) * TESTS * *********/ - for (i = 0; i < ncases; i++) { - assert(purl == NULL); + for (int i = 0; i < NCASES; i++) { - JSVERIFY(cases[i].exp_ret, H5FD_s3comms_parse_url(cases[i].url, &purl), cases[i].msg) + if (cases[i].exp_ret != H5FD_s3comms_parse_url(cases[i].url, &purl)) + TEST_ERROR; if (cases[i].exp_ret == FAIL) { - /* on FAIL, `purl` should be untouched--remains NULL */ - FAIL_UNLESS(purl == NULL) + /* On FAIL, `purl` should be untouched--remains NULL */ + if (purl != NULL) + TEST_ERROR; } else { - /* on SUCCEED, `purl` should be set */ - FAIL_IF(purl == NULL) + /* On SUCCEED, `purl` should be set */ + if (purl == NULL) + TEST_ERROR; if (cases[i].expected.scheme != NULL) { - FAIL_IF(NULL == purl->scheme) - JSVERIFY_STR(cases[i].expected.scheme, purl->scheme, cases[i].msg) + if (NULL == purl->scheme) + TEST_ERROR; + if (strcmp(cases[i].expected.scheme, purl->scheme)) + TEST_ERROR; } else { - FAIL_UNLESS(NULL == purl->scheme) + if (NULL != purl->scheme) + TEST_ERROR; } if (cases[i].expected.host != NULL) { - FAIL_IF(NULL == purl->host) - JSVERIFY_STR(cases[i].expected.host, purl->host, cases[i].msg) + if (NULL == purl->host) + TEST_ERROR; + if (strcmp(cases[i].expected.host, purl->host)) + TEST_ERROR; } else { - FAIL_UNLESS(NULL == purl->host) + if (NULL != purl->host) + TEST_ERROR; } if (cases[i].expected.port != NULL) { - FAIL_IF(NULL == purl->port) - JSVERIFY_STR(cases[i].expected.port, purl->port, cases[i].msg) + if (NULL == purl->port) + TEST_ERROR; + if (strcmp(cases[i].expected.port, purl->port)) + TEST_ERROR; } else { - FAIL_UNLESS(NULL == purl->port) + if (NULL != purl->port) + TEST_ERROR; } if (cases[i].expected.path != NULL) { - FAIL_IF(NULL == purl->path) - JSVERIFY_STR(cases[i].expected.path, purl->path, cases[i].msg) + if (NULL == purl->path) + TEST_ERROR; + if (strcmp(cases[i].expected.path, purl->path)) + TEST_ERROR; } else { - FAIL_UNLESS(NULL == purl->path) + if (NULL != purl->path) + TEST_ERROR; } if (cases[i].expected.query != NULL) { - FAIL_IF(NULL == purl->query) - JSVERIFY_STR(cases[i].expected.query, purl->query, cases[i].msg) + if (NULL == purl->query) + TEST_ERROR; + if (strcmp(cases[i].expected.query, purl->query)) + TEST_ERROR; } else { - FAIL_UNLESS(NULL == purl->query) + if (NULL != purl->query) + TEST_ERROR; } - } /* end if parse-url return SUCCEED/FAIL */ + } - /* per-test cleanup - * well-behaved, even if `purl` is NULL - */ - FAIL_IF(FAIL == H5FD_s3comms_free_purl(purl)) - purl = NULL; + if (H5FD_s3comms_free_purl(purl) < 0) + TEST_ERROR; - } /* end for each testcase */ + purl = NULL; + } PASSED(); return 0; error: - /*********** - * cleanup * - ***********/ - (void)H5FD_s3comms_free_purl(purl); + H5FD_s3comms_free_purl(purl); - return -1; + return 1; } /* end test_parse_url() */ /*--------------------------------------------------------------------------- - * Function: test_s3r_get_filesize() + * Function: test_signing_key + * + * Purpose: Verify behavior of `H5FD_s3comms_signing_key()` + * + * Return: PASS : 0 + * FAIL : 1 *--------------------------------------------------------------------------- */ -static herr_t -test_s3r_get_filesize(void) +static int +test_signing_key(void) { + struct testcase { + const char *region; + const char *secret_key; + const char *when; + unsigned char exp[SHA256_DIGEST_LENGTH]; + }; - /************************ - * test-local variables * - ************************/ + struct testcase cases[] = { + { + "us-east-1", + "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", + "20130524T000000Z", + { + 0xdb, 0xb8, 0x93, 0xac, 0xc0, 0x10, 0x96, 0x49, 0x18, 0xf1, 0xfd, + 0x43, 0x3a, 0xdd, 0x87, 0xc7, 0x0e, 0x8b, 0x0d, 0xb6, 0xbe, 0x30, + 0xc1, 0xfb, 0xea, 0xfe, 0xfa, 0x5e, 0xc6, 0xba, 0x83, 0x78, + }, + }, + }; + + unsigned char *key = NULL; + const int NCASES = 1; + herr_t ret; + + TESTING("signing_key"); + + for (int i = 0; i < NCASES; i++) { + if (NULL == (key = (unsigned char *)malloc(sizeof(unsigned char) * SHA256_DIGEST_LENGTH))) + TEST_ERROR; + if (H5FD_s3comms_signing_key(key, cases[i].secret_key, cases[i].region, cases[i].when) < 0) + TEST_ERROR; + + if (strncmp((const char *)cases[i].exp, (const char *)key, SHA256_DIGEST_LENGTH)) + TEST_ERROR; + + free(key); + key = NULL; + } + + /* ERROR CASES */ + + if (NULL == (key = (unsigned char *)malloc(sizeof(unsigned char) * SHA256_DIGEST_LENGTH))) + TEST_ERROR; + + H5E_BEGIN_TRY + { + ret = H5FD_s3comms_signing_key(NULL, cases[0].secret_key, cases[0].region, cases[0].when); + } + H5E_END_TRY + if (ret == SUCCEED) + FAIL_PUTS_ERROR("destination cannot be NULL"); + + H5E_BEGIN_TRY + { + ret = H5FD_s3comms_signing_key(key, NULL, cases[0].region, cases[0].when); + } + H5E_END_TRY + if (ret == SUCCEED) + FAIL_PUTS_ERROR("secret key cannot be NULL"); + + H5E_BEGIN_TRY + { + ret = H5FD_s3comms_signing_key(key, cases[0].secret_key, NULL, cases[0].when); + } + H5E_END_TRY + if (ret == SUCCEED) + FAIL_PUTS_ERROR("aws region cannot be NULL"); + + H5E_BEGIN_TRY + { + ret = H5FD_s3comms_signing_key(key, cases[0].secret_key, cases[0].region, NULL); + } + H5E_END_TRY + if (ret == SUCCEED) + FAIL_PUTS_ERROR("time string cannot be NULL"); + + free(key); + + PASSED(); + return 0; + +error: + free(key); + return 1; +} /* end test_signing_key() */ + +/*--------------------------------------------------------------------------- + * Function: test_tostringtosign() + * + * Purpose: Verify that we can get the "string to sign" from a Canonical + * Request and related information. + * + * Return: PASS : 0 + * FAIL : 1 + *--------------------------------------------------------------------------- + */ +static int +test_tostringtosign(void) +{ + const char canonreq[] = "GET\n/" + "test.txt\n\nhost:examplebucket.s3.amazonaws.com\nrange:bytes=0-9\nx-amz-content-" + "sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\nx-amz-" + "date:20130524T000000Z\n\nhost;range;x-amz-content-sha256;x-amz-" + "date\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"; + const char iso8601now[] = "20130524T000000Z"; + const char region[] = "us-east-1"; + char s2s[512]; + herr_t ret; + + TESTING("s3comms tostringtosign"); + + if (H5FD_s3comms_tostringtosign(s2s, canonreq, iso8601now, region) < 0) + FAIL_PUTS_ERROR("unable to create string to sign"); + + if (strncmp("AWS4-HMAC-SHA256\n20130524T000000Z\n20130524/us-east-1/s3/" + "aws4_request\n7344ae5b7ee6c3e7e6b0fe0640412a37625d1fbfff95c48bbb2dc43964946972", + s2s, 512)) + TEST_ERROR; + + /* ERROR CASES */ + + H5E_BEGIN_TRY + { + ret = H5FD_s3comms_tostringtosign(s2s, NULL, iso8601now, region); + } + H5E_END_TRY + if (ret == SUCCEED) + FAIL_PUTS_ERROR("canonical request string cannot be NULL"); + + H5E_BEGIN_TRY + { + ret = H5FD_s3comms_tostringtosign(s2s, canonreq, NULL, region); + } + H5E_END_TRY + if (ret == SUCCEED) + FAIL_PUTS_ERROR("time string cannot be NULL"); + + H5E_BEGIN_TRY + { + ret = H5FD_s3comms_tostringtosign(s2s, canonreq, iso8601now, NULL); + } + H5E_END_TRY + if (ret == SUCCEED) + FAIL_PUTS_ERROR("aws region cannot be NULL"); + + PASSED(); + return 0; + +error: + return 1; + +} /* end test_tostringtosign() */ + +/*--------------------------------------------------------------------------- + * Function: test_s3r_get_filesize + * + * Purpose: Test H5FD_s3comms_s3r_get_filesize() + * + * Return: PASS : 0 + * FAIL : 1 + *--------------------------------------------------------------------------- + */ +static int +test_s3r_get_filesize(void) +{ char url_raven[S3_TEST_MAX_URL_SIZE]; s3r_t *handle = NULL; TESTING("s3r_get_filesize"); - /* setup -- compose url to target resource - */ + /* Setup -- compose url to target resource */ if (false == s3_test_bucket_defined) { SKIPPED(); puts(" environment variable HDF5_ROS3_TEST_BUCKET_URL not defined"); @@ -1572,52 +1379,51 @@ test_s3r_get_filesize(void) return 0; } - FAIL_IF(S3_TEST_MAX_URL_SIZE < snprintf(url_raven, S3_TEST_MAX_URL_SIZE, "%s/%s", s3_test_bucket_url, - S3_TEST_RESOURCE_TEXT_PUBLIC)); + if (S3_TEST_MAX_URL_SIZE < + snprintf(url_raven, S3_TEST_MAX_URL_SIZE, "%s/%s", s3_test_bucket_url, S3_TEST_RESOURCE_TEXT_PUBLIC)) + TEST_ERROR; - JSVERIFY(0, H5FD_s3comms_s3r_get_filesize(NULL), "filesize of the null handle should be 0") + if (0 != H5FD_s3comms_s3r_get_filesize(NULL)) + FAIL_PUTS_ERROR("filesize of the null handle should be 0"); - handle = H5FD_s3comms_s3r_open(url_raven, NULL, NULL, NULL, NULL); - FAIL_IF(handle == NULL) + if (NULL == (handle = H5FD_s3comms_s3r_open(url_raven, NULL, NULL, NULL, NULL))) + TEST_ERROR; - JSVERIFY(6464, H5FD_s3comms_s3r_get_filesize(handle), NULL) + if (6464 != H5FD_s3comms_s3r_get_filesize(handle)) + FAIL_PUTS_ERROR("incorrect file size - fragile, make sure the file size didn't change"); - FAIL_IF(SUCCEED != H5FD_s3comms_s3r_close(handle)) + if (H5FD_s3comms_s3r_close(handle) < 0) + TEST_ERROR; PASSED(); return 0; error: if (handle != NULL) - (void)H5FD_s3comms_s3r_close(handle); - - return -1; - + H5FD_s3comms_s3r_close(handle); + return 1; } /* end test_s3r_get_filesize() */ /*--------------------------------------------------------------------------- - * Function: test_s3r_open() + * Function: test_s3r_open + * + * Purpose: Test H5FD_s3comms_s3r_open() * + * Return: PASS : 0 + * FAIL : 1 *--------------------------------------------------------------------------- */ -static herr_t +static int test_s3r_open(void) { - - /************************ - * test-local variables * - ************************/ - char url_missing[S3_TEST_MAX_URL_SIZE]; char url_raven[S3_TEST_MAX_URL_SIZE]; - char url_raven_badport[S3_TEST_MAX_URL_SIZE]; char url_shakespeare[S3_TEST_MAX_URL_SIZE]; unsigned char signing_key[SHA256_DIGEST_LENGTH]; struct tm *now = NULL; char iso8601now[ISO8601_SIZE]; - s3r_t *handle = NULL; - bool curl_ready = false; - parsed_url_t *purl = NULL; + s3r_t *handle = NULL; + parsed_url_t *purl = NULL; TESTING("s3r_open"); @@ -1638,191 +1444,190 @@ test_s3r_open(void) * PRE-TEST SETUP * ******************/ - FAIL_IF(S3_TEST_MAX_URL_SIZE < snprintf(url_shakespeare, S3_TEST_MAX_URL_SIZE, "%s/%s", - s3_test_bucket_url, S3_TEST_RESOURCE_TEXT_RESTRICTED)); + if (S3_TEST_MAX_URL_SIZE < snprintf(url_shakespeare, S3_TEST_MAX_URL_SIZE, "%s/%s", s3_test_bucket_url, + S3_TEST_RESOURCE_TEXT_RESTRICTED)) + TEST_ERROR; - FAIL_IF(S3_TEST_MAX_URL_SIZE < snprintf(url_missing, S3_TEST_MAX_URL_SIZE, "%s/%s", s3_test_bucket_url, - S3_TEST_RESOURCE_MISSING)); + if (S3_TEST_MAX_URL_SIZE < + snprintf(url_missing, S3_TEST_MAX_URL_SIZE, "%s/%s", s3_test_bucket_url, S3_TEST_RESOURCE_MISSING)) + TEST_ERROR; - FAIL_IF(S3_TEST_MAX_URL_SIZE < snprintf(url_raven, S3_TEST_MAX_URL_SIZE, "%s/%s", s3_test_bucket_url, - S3_TEST_RESOURCE_TEXT_PUBLIC)); + if (S3_TEST_MAX_URL_SIZE < + snprintf(url_raven, S3_TEST_MAX_URL_SIZE, "%s/%s", s3_test_bucket_url, S3_TEST_RESOURCE_TEXT_PUBLIC)) + TEST_ERROR; /* Set given bucket url with invalid/inactive port number for badport. * Note, this sort of micro-management of parsed_url_t is not advised */ - FAIL_IF(FAIL == H5FD_s3comms_parse_url(s3_test_bucket_url, &purl)) + if (H5FD_s3comms_parse_url(s3_test_bucket_url, &purl) < 0) + TEST_ERROR; + if (purl->port == NULL) { - purl->port = (char *)H5MM_malloc(sizeof(char) * 5); - FAIL_IF(purl->port == NULL); - FAIL_IF(5 < snprintf(purl->port, 5, "9000")) + if (NULL == (purl->port = (char *)H5MM_malloc(sizeof(char) * 5))) + TEST_ERROR; + if (5 < snprintf(purl->port, 5, "9000")) + TEST_ERROR; } else if (strcmp(purl->port, "9000") != 0) { - FAIL_IF(5 < snprintf(purl->port, 5, "9000")) + if (5 < snprintf(purl->port, 5, "9000")) + TEST_ERROR; } else { - FAIL_IF(5 < snprintf(purl->port, 5, "1234")) + if (5 < snprintf(purl->port, 5, "1234")) + TEST_ERROR; } - FAIL_IF(S3_TEST_MAX_URL_SIZE < snprintf(url_raven_badport, S3_TEST_MAX_URL_SIZE, "%s://%s:%s/%s", - purl->scheme, purl->host, purl->port, - S3_TEST_RESOURCE_TEXT_PUBLIC)); - - curl_global_init(CURL_GLOBAL_DEFAULT); - curl_ready = true; - now = gmnow(); - FAIL_IF(now == NULL) - FAIL_IF(ISO8601NOW(iso8601now, now) != (ISO8601_SIZE - 1)); + if (NULL == (now = gmnow())) + TEST_ERROR; + if (ISO8601NOW(iso8601now, now) != (ISO8601_SIZE - 1)) + TEST_ERROR; /* It is desired to have means available to verify that signing_key * was set successfully and to an expected value. */ - FAIL_IF(FAIL == H5FD_s3comms_signing_key(signing_key, (const char *)s3_test_aws_secret_access_key, - (const char *)s3_test_aws_region, (const char *)iso8601now)); + if (H5FD_s3comms_signing_key(signing_key, (const char *)s3_test_aws_secret_access_key, + (const char *)s3_test_aws_region, (const char *)iso8601now) < 0) + TEST_ERROR; /************************* * OPEN NONEXISTENT FILE * *************************/ - /* attempt anonymously - */ - handle = H5FD_s3comms_s3r_open(url_missing, NULL, NULL, NULL, NULL); - FAIL_IF(handle != NULL); - - /* attempt with authentication - */ - handle = H5FD_s3comms_s3r_open( - url_missing, (const char *)s3_test_aws_region, (const char *)s3_test_aws_access_key_id, - (const unsigned char *)signing_key, (const char *)s3_test_aws_security_token); - FAIL_IF(handle != NULL); - - /************************* - * INACTIVE PORT ON HOST * - *************************/ - -#if S3_TEST_RUN_TIMEOUT - printf("Opening on inactive port may hang for a minute; waiting for timeout\n"); - handle = H5FD_s3comms_s3r_open(url_raven_badport, NULL, NULL, NULL, NULL); - FAIL_IF(handle != NULL); -#endif + /* Attempt anonymously */ + H5E_BEGIN_TRY + { + handle = H5FD_s3comms_s3r_open(url_missing, NULL, NULL, NULL, NULL); + } + H5E_END_TRY + if (handle != NULL) + TEST_ERROR; + + /* Attempt with authentication */ + H5E_BEGIN_TRY + { + handle = H5FD_s3comms_s3r_open( + url_missing, (const char *)s3_test_aws_region, (const char *)s3_test_aws_access_key_id, + (const unsigned char *)signing_key, (const char *)s3_test_aws_security_token); + } + H5E_END_TRY + if (handle != NULL) + TEST_ERROR; /******************************* * INVALID AUTHENTICATION INFO * *******************************/ - /* anonymous access on restricted file - */ - handle = H5FD_s3comms_s3r_open(url_shakespeare, NULL, NULL, NULL, NULL); - FAIL_IF(handle != NULL); - - /* passed in a bad ID - */ - handle = - H5FD_s3comms_s3r_open(url_shakespeare, (const char *)s3_test_aws_region, "I_MADE_UP_MY_ID", - (const unsigned char *)signing_key, (const char *)s3_test_aws_security_token); - FAIL_IF(handle != NULL); - - /* using an invalid signing key - */ - handle = H5FD_s3comms_s3r_open( - url_shakespeare, (const char *)s3_test_aws_region, (const char *)s3_test_aws_access_key_id, - (const unsigned char *)EMPTY_SHA256, (const char *)s3_test_aws_security_token); - FAIL_IF(handle != NULL); + /* Anonymous access on restricted file */ + H5E_BEGIN_TRY + { + handle = H5FD_s3comms_s3r_open(url_shakespeare, NULL, NULL, NULL, NULL); + } + H5E_END_TRY + if (handle != NULL) + TEST_ERROR; + + /* Pass in a bad ID */ + H5E_BEGIN_TRY + { + handle = H5FD_s3comms_s3r_open(url_shakespeare, (const char *)s3_test_aws_region, "I_MADE_UP_MY_ID", + (const unsigned char *)signing_key, + (const char *)s3_test_aws_security_token); + } + H5E_END_TRY + if (handle != NULL) + TEST_ERROR; + + /* Using an invalid signing key */ + H5E_BEGIN_TRY + { + handle = H5FD_s3comms_s3r_open( + url_shakespeare, (const char *)s3_test_aws_region, (const char *)s3_test_aws_access_key_id, + (const unsigned char *)EMPTY_SHA256, (const char *)s3_test_aws_security_token); + } + H5E_END_TRY + if (handle != NULL) + TEST_ERROR; /******************************* * SUCCESSFUL OPEN (AND CLOSE) * *******************************/ - /* anonymous - */ + /* Anonymous */ handle = H5FD_s3comms_s3r_open(url_raven, NULL, NULL, NULL, NULL); - FAIL_IF(handle == NULL); - JSVERIFY(6464, H5FD_s3comms_s3r_get_filesize(handle), "did not get expected filesize") - JSVERIFY(SUCCEED, H5FD_s3comms_s3r_close(handle), "unable to close file") + if (handle == NULL) + TEST_ERROR; + if (6464 != H5FD_s3comms_s3r_get_filesize(handle)) + FAIL_PUTS_ERROR("did not get expected filesize"); + if (H5FD_s3comms_s3r_close(handle) < 0) + TEST_ERROR; handle = NULL; - /* using authentication on anonymously-accessible file? - */ + /* Using authentication on anonymously-accessible file? */ handle = H5FD_s3comms_s3r_open( url_raven, (const char *)s3_test_aws_region, (const char *)s3_test_aws_access_key_id, (const unsigned char *)signing_key, (const char *)s3_test_aws_security_token); - FAIL_IF(handle == NULL); - JSVERIFY(6464, H5FD_s3comms_s3r_get_filesize(handle), NULL) - JSVERIFY(SUCCEED, H5FD_s3comms_s3r_close(handle), "unable to close file") + if (handle == NULL) + TEST_ERROR; + if (6464 != H5FD_s3comms_s3r_get_filesize(handle)) + FAIL_PUTS_ERROR("did not get expected filesize"); + if (H5FD_s3comms_s3r_close(handle)) + TEST_ERROR; handle = NULL; - /* authenticating - */ + /* Authenticating */ handle = H5FD_s3comms_s3r_open( url_shakespeare, (const char *)s3_test_aws_region, (const char *)s3_test_aws_access_key_id, (const unsigned char *)signing_key, (const char *)s3_test_aws_security_token); - FAIL_IF(handle == NULL); - JSVERIFY(5458199, H5FD_s3comms_s3r_get_filesize(handle), NULL) - JSVERIFY(SUCCEED, H5FD_s3comms_s3r_close(handle), "unable to close file") + if (handle == NULL) + TEST_ERROR; + if (5458199 != H5FD_s3comms_s3r_get_filesize(handle)) + FAIL_PUTS_ERROR("did not get expected filesize"); + if (H5FD_s3comms_s3r_close(handle) < 0) + TEST_ERROR; handle = NULL; - curl_global_cleanup(); - curl_ready = false; - - FAIL_IF(FAIL == H5FD_s3comms_free_purl(purl)) - purl = NULL; + if (H5FD_s3comms_free_purl(purl) < 0) + TEST_ERROR; PASSED(); return 0; error: - /*********** - * cleanup * - ***********/ - if (handle != NULL) H5FD_s3comms_s3r_close(handle); if (purl != NULL) H5FD_s3comms_free_purl(purl); - if (curl_ready == true) - curl_global_cleanup(); - - return -1; + return 1; } /* end test_s3r_open() */ /*--------------------------------------------------------------------------- + * Function: test_s3r_read * - * Function: test_s3r_read() - * - * Purpose: - * - * Specify and demonstrate the use and life cycle of an S3 Request handle - * `s3r_t`, through its related functions. + * Purpose: Specify and demonstrate the use and life cycle of an S3 + * request handle `s3r_t`, through its related functions. * * H5FD_s3comms_s3r_open * H5FD_s3comms_s3r_getsize << called by open() _only_ * H5FD_s3comms_s3r_read << called by getsize(), multiple times working * H5FD_s3comms_s3r_close * - * Shows most basic curl iteration. + * Shows most basic curl iteration * + * Return: PASS : 0 + * FAIL : 1 *--------------------------------------------------------------------------- */ -static herr_t +static int test_s3r_read(void) { - -#define S3COMMS_TEST_BUFFER_SIZE 256 - - /************************ - * test-local variables * - ************************/ - - char url_raven[S3_TEST_MAX_URL_SIZE]; - char buffer[S3COMMS_TEST_BUFFER_SIZE]; - s3r_t *handle = NULL; - bool curl_ready = false; - unsigned int i = 0; + char url_raven[S3_TEST_MAX_URL_SIZE]; + char buffer[S3COMMS_READ_BUFFER_SIZE]; + s3r_t *handle = NULL; + herr_t ret; TESTING("test_s3r_read"); - /* - * initial setup - */ + /* Initial setup */ if (false == s3_test_bucket_defined) { SKIPPED(); puts(" environment variable HDF5_ROS3_TEST_BUCKET_URL not defined"); @@ -1830,296 +1635,118 @@ test_s3r_read(void) return 0; } - curl_global_init(CURL_GLOBAL_DEFAULT); - curl_ready = true; - FAIL_IF(S3_TEST_MAX_URL_SIZE < snprintf(url_raven, S3_TEST_MAX_URL_SIZE, "%s/%s", s3_test_bucket_url, - S3_TEST_RESOURCE_TEXT_PUBLIC)); - - for (i = 0; i < S3COMMS_TEST_BUFFER_SIZE; i++) - buffer[i] = '\0'; + if (S3_TEST_MAX_URL_SIZE < + snprintf(url_raven, S3_TEST_MAX_URL_SIZE, "%s/%s", s3_test_bucket_url, S3_TEST_RESOURCE_TEXT_PUBLIC)) + TEST_ERROR; - /* open file - */ + /* Open file */ handle = H5FD_s3comms_s3r_open(url_raven, NULL, NULL, NULL, NULL); - FAIL_IF(handle == NULL) - JSVERIFY(6464, H5FD_s3comms_s3r_get_filesize(handle), NULL) - - for (i = 0; i < S3COMMS_TEST_BUFFER_SIZE; i++) - buffer[i] = '\0'; - - /********************** - * read start of file * - **********************/ - - JSVERIFY(SUCCEED, H5FD_s3comms_s3r_read(handle, (haddr_t)0, (size_t)118, buffer), NULL) - JSVERIFY_STR("Once upon a midnight dreary, while I pondered, weak and weary,\n" - "Over many a quaint and curious volume of forgotten lore", - buffer, NULL) - - for (i = 0; i < S3COMMS_TEST_BUFFER_SIZE; i++) - buffer[i] = '\0'; - - /************************ - * read arbitrary range * - ************************/ - - JSVERIFY(SUCCEED, H5FD_s3comms_s3r_read(handle, (haddr_t)2540, (size_t)54, buffer), NULL) - JSVERIFY_STR("the grave and stern decorum of the countenance it wore", buffer, NULL) - - for (i = 0; i < S3COMMS_TEST_BUFFER_SIZE; i++) - buffer[i] = '\0'; - - /********************** - * read one character * - **********************/ - - JSVERIFY(SUCCEED, H5FD_s3comms_s3r_read(handle, (haddr_t)2540, (size_t)1, buffer), NULL) - JSVERIFY_STR("t", buffer, NULL) - - for (i = 0; i < S3COMMS_TEST_BUFFER_SIZE; i++) - buffer[i] = '\0'; - - /*************** - * read to EoF * - ***************/ - - JSVERIFY(SUCCEED, H5FD_s3comms_s3r_read(handle, (haddr_t)6370, (size_t)0, buffer), NULL) - JSVERIFY( - 0, - strncmp( + if (handle == NULL) + TEST_ERROR; + if (6464 != H5FD_s3comms_s3r_get_filesize(handle)) + TEST_ERROR; + + /***************************** + * Tests that should succeed * + *****************************/ + + /* Read from start of file */ + memset(buffer, 0, S3COMMS_READ_BUFFER_SIZE); + if (H5FD_s3comms_s3r_read(handle, (haddr_t)0, (size_t)118, buffer) < 0) + TEST_ERROR; + if (strcmp("Once upon a midnight dreary, while I pondered, weak and weary,\n" + "Over many a quaint and curious volume of forgotten lore", + buffer)) + TEST_ERROR; + + /* Read arbitrary range */ + memset(buffer, 0, S3COMMS_READ_BUFFER_SIZE); + if (H5FD_s3comms_s3r_read(handle, (haddr_t)2540, (size_t)54, buffer) < 0) + TEST_ERROR; + if (strcmp("the grave and stern decorum of the countenance it wore", buffer)) + TEST_ERROR; + + /* Read one character */ + memset(buffer, 0, S3COMMS_READ_BUFFER_SIZE); + if (H5FD_s3comms_s3r_read(handle, (haddr_t)2540, (size_t)1, buffer) < 0) + TEST_ERROR; + if (strcmp("t", buffer)) + TEST_ERROR; + + /* Read to EOF */ + memset(buffer, 0, S3COMMS_READ_BUFFER_SIZE); + if (H5FD_s3comms_s3r_read(handle, (haddr_t)6370, (size_t)0, buffer) < 0) + TEST_ERROR; + if (strncmp( buffer, "And my soul from out that shadow that lies floating on the floor\nShall be lifted—nevermore!\n", - 94), - buffer) - - for (i = 0; i < S3COMMS_TEST_BUFFER_SIZE; i++) - buffer[i] = '\0'; - - /***************** - * read past eof * - *****************/ - - JSVERIFY(FAIL, - H5FD_s3comms_s3r_read(handle, (haddr_t)6400, (size_t)100, /* 6400+100 > 6464 */ - buffer), - NULL) - JSVERIFY(0, strcmp("", buffer), NULL) - - /************************ - * read starts past eof * - ************************/ - - JSVERIFY(FAIL, - H5FD_s3comms_s3r_read(handle, (haddr_t)1200699, /* 1200699 > 6464 */ - (size_t)100, buffer), - NULL) - JSVERIFY(0, strcmp("", buffer), NULL) - - /********************** - * read starts on eof * - **********************/ - - JSVERIFY(FAIL, H5FD_s3comms_s3r_read(handle, (haddr_t)6464, (size_t)0, buffer), NULL) - JSVERIFY(0, strcmp("", buffer), NULL) + 94)) + TEST_ERROR; + + /************************** + * Tests that should fail * + **************************/ + + /* Read past eof */ + memset(buffer, 0, S3COMMS_READ_BUFFER_SIZE); + H5E_BEGIN_TRY + { + ret = H5FD_s3comms_s3r_read(handle, (haddr_t)6400, (size_t)100, /* 6400+100 > 6464 */ buffer); + } + H5E_END_TRY + if (ret == SUCCEED) + TEST_ERROR; + if (strcmp("", buffer)) + TEST_ERROR; + + /* Read starts past eof */ + memset(buffer, 0, S3COMMS_READ_BUFFER_SIZE); + H5E_BEGIN_TRY + { + ret = H5FD_s3comms_s3r_read(handle, (haddr_t)1200699, /* 1200699 > 6464 */ (size_t)100, buffer); + } + H5E_END_TRY + if (ret == SUCCEED) + TEST_ERROR; + if (strcmp("", buffer)) + TEST_ERROR; + + /* Read starts on eof */ + memset(buffer, 0, S3COMMS_READ_BUFFER_SIZE); + H5E_BEGIN_TRY + { + ret = H5FD_s3comms_s3r_read(handle, (haddr_t)6464, (size_t)0, buffer); + } + H5E_END_TRY + if (ret == SUCCEED) + TEST_ERROR; + if (strcmp("", buffer)) + TEST_ERROR; /************* * TEAR DOWN * *************/ - JSVERIFY(SUCCEED, H5FD_s3comms_s3r_close(handle), "unable to close file") - handle = NULL; - - curl_global_cleanup(); - curl_ready = false; + if (H5FD_s3comms_s3r_close(handle) < 0) + TEST_ERROR; PASSED(); return 0; error: - /*********** - * cleanup * - ***********/ - if (handle != NULL) H5FD_s3comms_s3r_close(handle); - - if (curl_ready == true) - curl_global_cleanup(); - - return -1; - -#undef S3COMMS_TEST_BUFFER_SIZE - + return 1; } /* end test_s3r_read() */ -/*--------------------------------------------------------------------------- - * - * Function: test_signing_key() - * - * Purpose: - * - * Define and verify behavior of `H5FD_s3comms_signing_key()` - * - * More test cases would be a very good idea. - * - *--------------------------------------------------------------------------- - */ -static herr_t -test_signing_key(void) -{ - /************************* - * test-local structures * - *************************/ - - struct testcase { - const char *region; - const char *secret_key; - const char *when; - unsigned char exp[SHA256_DIGEST_LENGTH]; - }; - - /************************ - * test-local variables * - ************************/ - - struct testcase cases[] = { - { - "us-east-1", - "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", - "20130524T000000Z", - { - 0xdb, 0xb8, 0x93, 0xac, 0xc0, 0x10, 0x96, 0x49, 0x18, 0xf1, 0xfd, - 0x43, 0x3a, 0xdd, 0x87, 0xc7, 0x0e, 0x8b, 0x0d, 0xb6, 0xbe, 0x30, - 0xc1, 0xfb, 0xea, 0xfe, 0xfa, 0x5e, 0xc6, 0xba, 0x83, 0x78, - }, - }, - }; - int i = 0; - unsigned char *key = NULL; - int ncases = 1; - - TESTING("signing_key"); - - for (i = 0; i < ncases; i++) { - key = (unsigned char *)malloc(sizeof(unsigned char) * SHA256_DIGEST_LENGTH); - assert(key != NULL); - - JSVERIFY(SUCCEED, H5FD_s3comms_signing_key(key, cases[i].secret_key, cases[i].region, cases[i].when), - NULL) - - JSVERIFY(0, strncmp((const char *)cases[i].exp, (const char *)key, SHA256_DIGEST_LENGTH), - (const char *)cases[i].exp) - - free(key); - key = NULL; - } - - /*************** - * ERROR CASES * - ***************/ - - key = (unsigned char *)malloc(sizeof(unsigned char) * SHA256_DIGEST_LENGTH); - assert(key != NULL); - - JSVERIFY(FAIL, H5FD_s3comms_signing_key(NULL, cases[0].secret_key, cases[0].region, cases[0].when), - "destination cannot be NULL") - - JSVERIFY(FAIL, H5FD_s3comms_signing_key(key, NULL, cases[0].region, cases[0].when), - "secret key cannot be NULL") - - JSVERIFY(FAIL, H5FD_s3comms_signing_key(key, cases[0].secret_key, NULL, cases[0].when), - "aws region cannot be NULL") - - JSVERIFY(FAIL, H5FD_s3comms_signing_key(key, cases[0].secret_key, cases[0].region, NULL), - "time string cannot be NULL") - - free(key); - key = NULL; - - PASSED(); - return 0; - -error: - if (key != NULL) { - free(key); - } - - return -1; - -} /* end test_signing_key() */ - -/*--------------------------------------------------------------------------- - * - * Function: test_tostringtosign() - * - * Purpose: - * - * Verify that we can get the "string to sign" from a Canonical Request and - * related information. - * - * Demonstrate failure cases. - * - * Return: - * - * Success: 0 - * Failure: -1 - * - *--------------------------------------------------------------------------- - */ -static herr_t -test_tostringtosign(void) -{ - /************************ - * test-local variables * - ************************/ - - const char canonreq[] = "GET\n/" - "test.txt\n\nhost:examplebucket.s3.amazonaws.com\nrange:bytes=0-9\nx-amz-content-" - "sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\nx-amz-" - "date:20130524T000000Z\n\nhost;range;x-amz-content-sha256;x-amz-" - "date\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"; - const char iso8601now[] = "20130524T000000Z"; - const char region[] = "us-east-1"; - char s2s[512]; - - TESTING("s3comms tostringtosign"); - - JSVERIFY(SUCCEED, H5FD_s3comms_tostringtosign(s2s, canonreq, iso8601now, region), - "unable to create string to sign") - - JSVERIFY_STR("AWS4-HMAC-SHA256\n20130524T000000Z\n20130524/us-east-1/s3/" - "aws4_request\n7344ae5b7ee6c3e7e6b0fe0640412a37625d1fbfff95c48bbb2dc43964946972", - s2s, NULL) - - JSVERIFY(FAIL, H5FD_s3comms_tostringtosign(s2s, NULL, iso8601now, region), - "canonical request string cannot be NULL") - - JSVERIFY(FAIL, H5FD_s3comms_tostringtosign(s2s, canonreq, NULL, region), "time string cannot be NULL") - - JSVERIFY(FAIL, H5FD_s3comms_tostringtosign(s2s, canonreq, iso8601now, NULL), "aws region cannot be NULL") - - PASSED(); - return 0; - -error: - return -1; - -} /* end test_tostringtosign() */ - #endif /* H5_HAVE_ROS3_VFD */ /*------------------------------------------------------------------------- - * Function: main() - * - * Purpose: + * Function: main() * - * Run unit tests for S3 Communications (s3comms). - * - * Return: - * - * Success: 0 - * Failure: 1 + * Purpose: Run unit tests for S3 communications (s3comms) * + * Return: EXIT_SUCCESS/EXIT_FAILURE *------------------------------------------------------------------------- */ int @@ -2133,7 +1760,7 @@ main(void) #endif /* H5_HAVE_ROS3_VFD */ - printf("Testing S3Communications functionality.\n"); + printf("Testing S3 communications functionality\n"); #ifdef H5_HAVE_ROS3_VFD @@ -2146,6 +1773,7 @@ main(void) /* TODO: unit/regression test for H5FD_s3comms_load_aws_profile() * requires a few test files and/or manipulation of default path */ + /* attempt to load test credentials * if unable, certain tests will be skipped */ @@ -2164,28 +1792,31 @@ main(void) s3_test_bucket_defined = true; } - /* tests ordered roughly by dependence */ - nerrors += test_macro_format_credential() < 0 ? 1 : 0; - nerrors += test_bytes_to_hex() < 0 ? 1 : 0; - nerrors += test_HMAC_SHA256() < 0 ? 1 : 0; - nerrors += test_signing_key() < 0 ? 1 : 0; - nerrors += test_hrb_node_set() < 0 ? 1 : 0; - nerrors += test_hrb_init_request() < 0 ? 1 : 0; - nerrors += test_parse_url() < 0 ? 1 : 0; - nerrors += test_aws_canonical_request() < 0 ? 1 : 0; - nerrors += test_tostringtosign() < 0 ? 1 : 0; - nerrors += test_s3r_open() < 0 ? 1 : 0; - nerrors += test_s3r_get_filesize() < 0 ? 1 : 0; - nerrors += test_s3r_read() < 0 ? 1 : 0; + curl_global_init(CURL_GLOBAL_DEFAULT); + + nerrors += test_macro_format_credential(); + nerrors += test_aws_canonical_request(); + nerrors += test_bytes_to_hex(); + nerrors += test_hrb_init_request(); + nerrors += test_hrb_node_set(); + nerrors += test_HMAC_SHA256(); + nerrors += test_parse_url(); + nerrors += test_signing_key(); + nerrors += test_tostringtosign(); + + nerrors += test_s3r_get_filesize(); + nerrors += test_s3r_open(); + nerrors += test_s3r_read(); + + curl_global_cleanup(); if (nerrors) { - printf("***** %d S3comms TEST%s FAILED! *****\n", nerrors, nerrors > 1 ? "S" : ""); - return 1; + printf("***** %d s3comms TEST%s FAILED! *****\n", nerrors, nerrors > 1 ? "S" : ""); + return EXIT_FAILURE; } - printf("All S3comms tests passed.\n"); - - return 0; + printf("All s3comms tests passed.\n"); + return EXIT_SUCCESS; #else From cd6c779ccf68da2adb5a51428cb882a8ce4cff1a Mon Sep 17 00:00:00 2001 From: Allen Byrne <50328838+byrnHDF@users.noreply.github.com> Date: Mon, 24 Jun 2024 07:59:29 -0500 Subject: [PATCH 32/45] Add publish to bucket workflow (#4566) --- .github/workflows/abi-report.yml | 1 + .github/workflows/aocc-auto.yml | 1 + .github/workflows/aocc-cmake.yml | 1 + .github/workflows/autotools.yml | 5 +-- .github/workflows/cmake-bintest.yml | 4 +- .github/workflows/cmake-ctest.yml | 4 +- .github/workflows/cmake.yml | 5 +-- .github/workflows/cve.yml | 1 + .github/workflows/cygwin-auto.yml | 1 + .github/workflows/cygwin-cmake.yml | 1 + .github/workflows/daily-build.yml | 4 +- .github/workflows/hdfeos5.yml | 1 + .github/workflows/intel-auto.yml | 1 + .github/workflows/intel-cmake.yml | 1 + .github/workflows/main-auto.yml | 5 +-- .github/workflows/main-cmake.yml | 5 +-- .github/workflows/markdown-link-check.yml | 1 + .github/workflows/msys2-auto.yml | 1 + .github/workflows/netcdf.yml | 1 + .github/workflows/nvhpc-auto.yml | 1 + .github/workflows/nvhpc-cmake.yml | 1 + .github/workflows/publish-release.yml | 55 +++++++++++++++++++++++ .github/workflows/release-files.yml | 2 +- .github/workflows/release.yml | 4 +- .github/workflows/remove-files.yml | 2 +- .github/workflows/tarball.yml | 4 +- 26 files changed, 80 insertions(+), 33 deletions(-) create mode 100644 .github/workflows/publish-release.yml diff --git a/.github/workflows/abi-report.yml b/.github/workflows/abi-report.yml index d69cc18aa1c..d0cdcc22fbb 100644 --- a/.github/workflows/abi-report.yml +++ b/.github/workflows/abi-report.yml @@ -1,5 +1,6 @@ name: hdf5 1.14 Check Application Binary Interface (ABI) +# Triggers the workflow on a call from another workflow on: workflow_call: inputs: diff --git a/.github/workflows/aocc-auto.yml b/.github/workflows/aocc-auto.yml index df6b4592bc7..e69cbcf4e82 100644 --- a/.github/workflows/aocc-auto.yml +++ b/.github/workflows/aocc-auto.yml @@ -1,5 +1,6 @@ name: hdf5 1.14 PAR autotools aocc ompi +# Triggers the workflow on a call from another workflow on: workflow_call: inputs: diff --git a/.github/workflows/aocc-cmake.yml b/.github/workflows/aocc-cmake.yml index d4796f67f1d..b65a5a39813 100644 --- a/.github/workflows/aocc-cmake.yml +++ b/.github/workflows/aocc-cmake.yml @@ -1,5 +1,6 @@ name: hdf5 1.14 PAR CMake aocc ompi +# Triggers the workflow on a call from another workflow on: workflow_call: inputs: diff --git a/.github/workflows/autotools.yml b/.github/workflows/autotools.yml index 3f4193255ae..d777f448575 100644 --- a/.github/workflows/autotools.yml +++ b/.github/workflows/autotools.yml @@ -1,6 +1,6 @@ name: hdf5 1.14 autools CI -# Controls when the action will run. Triggers the workflow on push or pull request +# Triggers the workflow on push or pull request or on demand on: workflow_dispatch: push: @@ -23,9 +23,6 @@ concurrency: permissions: contents: read -# A workflow run is made up of one or more jobs that can run sequentially or -# in parallel. We just have one job, but the matrix items defined below will -# run in parallel. jobs: call-workflow-special-autotools: name: "Autotools Special Workflows" diff --git a/.github/workflows/cmake-bintest.yml b/.github/workflows/cmake-bintest.yml index d4d7308ecd2..d94cbd0db04 100644 --- a/.github/workflows/cmake-bintest.yml +++ b/.github/workflows/cmake-bintest.yml @@ -1,6 +1,6 @@ name: hdf5 1.14 examples bintest runs -# Controls when the action will run. Triggers the workflow on a schedule +# Triggers the workflow on a call from another workflow on: workflow_call: inputs: @@ -12,8 +12,6 @@ on: permissions: contents: read -# A workflow run is made up of one or more jobs that can run sequentially or -# in parallel jobs: test_binary_win: # Windows w/ MSVC + CMake diff --git a/.github/workflows/cmake-ctest.yml b/.github/workflows/cmake-ctest.yml index 6cf9b96209e..728763d8b4f 100644 --- a/.github/workflows/cmake-ctest.yml +++ b/.github/workflows/cmake-ctest.yml @@ -1,6 +1,6 @@ name: hdf5 1.14 ctest runs -# Controls when the action will run. Triggers the workflow on a call +# Triggers the workflow on a call from another workflow on: workflow_call: inputs: @@ -26,8 +26,6 @@ on: permissions: contents: read -# A workflow run is made up of one or more jobs that can run sequentially or -# in parallel jobs: build_and_test_win: # Windows w/ MSVC + CMake diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml index eceaaba3d8e..1db073e2929 100644 --- a/.github/workflows/cmake.yml +++ b/.github/workflows/cmake.yml @@ -1,6 +1,6 @@ name: hdf5 1.14 cmake CI -# Controls when the action will run. Triggers the workflow on push or pull request +# Triggers the workflow on push or pull request or on demand on: workflow_dispatch: push: @@ -23,9 +23,6 @@ concurrency: permissions: contents: read -# A workflow run is made up of one or more jobs that can run sequentially or -# in parallel. We just have one job, but the matrix items defined below will -# run in parallel. jobs: call-workflow-special-cmake: name: "CMake Special Workflows" diff --git a/.github/workflows/cve.yml b/.github/workflows/cve.yml index 6a66a5e08bb..7bd4cbd0e66 100644 --- a/.github/workflows/cve.yml +++ b/.github/workflows/cve.yml @@ -1,5 +1,6 @@ name: cve 1.14 +# Triggers the workflow on push or pull request or on demand on: workflow_dispatch: push: diff --git a/.github/workflows/cygwin-auto.yml b/.github/workflows/cygwin-auto.yml index e027f296bee..73c2c020404 100644 --- a/.github/workflows/cygwin-auto.yml +++ b/.github/workflows/cygwin-auto.yml @@ -1,5 +1,6 @@ name: hdf5 1.14 autotools cygwin +# Triggers the workflow on a call from another workflow on: workflow_call: inputs: diff --git a/.github/workflows/cygwin-cmake.yml b/.github/workflows/cygwin-cmake.yml index 5b1416b07aa..cd374a0b963 100644 --- a/.github/workflows/cygwin-cmake.yml +++ b/.github/workflows/cygwin-cmake.yml @@ -1,5 +1,6 @@ name: hdf5 1.14 CMake cygwin +# Triggers the workflow on a call from another workflow on: workflow_call: inputs: diff --git a/.github/workflows/daily-build.yml b/.github/workflows/daily-build.yml index e2b23e2b500..f27bd882c91 100644 --- a/.github/workflows/daily-build.yml +++ b/.github/workflows/daily-build.yml @@ -1,6 +1,6 @@ name: hdf5 1.14 daily build -# Controls when the action will run. Triggers the workflow on a schedule +# Triggers the workflow on a schedule or on demand on: workflow_dispatch: schedule: @@ -9,8 +9,6 @@ on: permissions: contents: read -# A workflow run is made up of one or more jobs that can run sequentially or -# in parallel. jobs: get-old-names: runs-on: ubuntu-latest diff --git a/.github/workflows/hdfeos5.yml b/.github/workflows/hdfeos5.yml index 4ca46bd2162..adbb73d3acb 100644 --- a/.github/workflows/hdfeos5.yml +++ b/.github/workflows/hdfeos5.yml @@ -1,5 +1,6 @@ name: hdfeos5 1.14 +# Triggers the workflow on push or pull request or on demand on: workflow_dispatch: push: diff --git a/.github/workflows/intel-auto.yml b/.github/workflows/intel-auto.yml index 129a7bec6cb..64c0a3fa3e3 100644 --- a/.github/workflows/intel-auto.yml +++ b/.github/workflows/intel-auto.yml @@ -1,5 +1,6 @@ name: hdf5 1.14 autotools icx CI +# Triggers the workflow on a call from another workflow on: workflow_call: inputs: diff --git a/.github/workflows/intel-cmake.yml b/.github/workflows/intel-cmake.yml index 5492c9967be..78d16705c3e 100644 --- a/.github/workflows/intel-cmake.yml +++ b/.github/workflows/intel-cmake.yml @@ -1,5 +1,6 @@ name: hdf5 1.14 CMake icx CI +# Triggers the workflow on a call from another workflow on: workflow_call: inputs: diff --git a/.github/workflows/main-auto.yml b/.github/workflows/main-auto.yml index 4197099d2b7..94023796ca6 100644 --- a/.github/workflows/main-auto.yml +++ b/.github/workflows/main-auto.yml @@ -1,6 +1,6 @@ name: hdf5 1.14 autotools CI -# Controls when the action will run. Triggers the workflow on a call +# Triggers the workflow on a call from another workflow on: workflow_call: inputs: @@ -16,9 +16,6 @@ on: permissions: contents: read -# A workflow run is made up of one or more jobs that can run sequentially or -# in parallel. We just have one job, but the matrix items defined below will -# run in parallel. jobs: # A workflow that builds the library and runs all the tests diff --git a/.github/workflows/main-cmake.yml b/.github/workflows/main-cmake.yml index 5e5fb054673..069e0b136c2 100644 --- a/.github/workflows/main-cmake.yml +++ b/.github/workflows/main-cmake.yml @@ -1,6 +1,6 @@ name: hdf5 1.14 CMake CI -# Controls when the action will run. Triggers the workflow on a call +# Triggers the workflow on a call from another workflow on: workflow_call: inputs: @@ -17,9 +17,6 @@ on: permissions: contents: read -# A workflow run is made up of one or more jobs that can run sequentially or -# in parallel. We just have one job, but the matrix items defined below will -# run in parallel. jobs: # A workflow that builds the library and runs all the tests diff --git a/.github/workflows/markdown-link-check.yml b/.github/workflows/markdown-link-check.yml index f925017bf10..f3f00138927 100644 --- a/.github/workflows/markdown-link-check.yml +++ b/.github/workflows/markdown-link-check.yml @@ -1,5 +1,6 @@ name: Check Markdown links +# Triggers the workflow on push or pull request or on demand on: workflow_dispatch: push: diff --git a/.github/workflows/msys2-auto.yml b/.github/workflows/msys2-auto.yml index adf84da517d..30c66da8766 100644 --- a/.github/workflows/msys2-auto.yml +++ b/.github/workflows/msys2-auto.yml @@ -1,5 +1,6 @@ name: hdf5 1.14 Autotools MSys2 +# Triggers the workflow on a call from another workflow on: workflow_call: inputs: diff --git a/.github/workflows/netcdf.yml b/.github/workflows/netcdf.yml index 805c322cb5f..1a88a1f9573 100644 --- a/.github/workflows/netcdf.yml +++ b/.github/workflows/netcdf.yml @@ -1,5 +1,6 @@ name: netCDF 1.14 +# Triggers the workflow on push or pull request or on demand on: workflow_dispatch: push: diff --git a/.github/workflows/nvhpc-auto.yml b/.github/workflows/nvhpc-auto.yml index a73dbcb3c67..66d4e38f4cd 100644 --- a/.github/workflows/nvhpc-auto.yml +++ b/.github/workflows/nvhpc-auto.yml @@ -1,5 +1,6 @@ name: hdf5 1.14 autotools nvhpc +# Triggers the workflow on a call from another workflow on: workflow_call: inputs: diff --git a/.github/workflows/nvhpc-cmake.yml b/.github/workflows/nvhpc-cmake.yml index 4a99cfd6ac7..41745567a92 100644 --- a/.github/workflows/nvhpc-cmake.yml +++ b/.github/workflows/nvhpc-cmake.yml @@ -1,5 +1,6 @@ name: hdf5 1.14 CMake nvhpc +# Triggers the workflow on a call from another workflow on: workflow_call: inputs: diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml new file mode 100644 index 00000000000..2139edff20d --- /dev/null +++ b/.github/workflows/publish-release.yml @@ -0,0 +1,55 @@ +name: hdf5 publishrelease + +# Triggers the workflow on demand +on: + workflow_dispatch: + inputs: + use_tag: + description: 'HDF5 Release version tag' + type: string + required: true + target_dir: + description: 'HDF5 target bucket directory' + type: string + required: true + permissions: + contents: read + +jobs: + publish-tag: + runs-on: ubuntu-latest + steps: + # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it + - name: Get Sources + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + with: + fetch-depth: 0 + ref: '${{ github.head_ref || github.ref_name }}' + + - name: Get hdf5 release + uses: dsaltares/fetch-gh-release-asset@master + with: + repo: 'HDFGroup/hdf5' + version: 'tags/${{ inputs.use_tag }}' + regex: true + target: 'HDF5/' + file: '${{ inputs.use_hdf }}-*.*' + + - name: Setup AWS CLI + uses: aws-actions/configure-aws-credentials@v1 + with: + aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} + aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + aws-region: ${{ secrets.AWS_REGION }} + + - name: Sync release to S3 bucket + run: | + aws s3 sync ./HDF5 s3://${{ secrets.AWS_S3_BUCKET }}/${{ vars.TARGET_PATH }}/${{ inputs.target_dir }}/downloads --delete + + - name: Uncompress source (Linux) + run: tar -zxvf ${{ github.workspace }}/${{ inputs.use_hdf }}.doxygen.tar.gz + + - name: Sync userguide to S3 bucket + run: | + aws s3 sync ./doxygen s3://${{ secrets.AWS_S3_BUCKET }}/${{ vars.TARGET_PATH }}/${{ inputs.target_dir }}/documentation --delete + diff --git a/.github/workflows/release-files.yml b/.github/workflows/release-files.yml index 7b92b8b98eb..06847d0a71e 100644 --- a/.github/workflows/release-files.yml +++ b/.github/workflows/release-files.yml @@ -1,6 +1,6 @@ name: hdf5 1.14 release-files -# Controls when the action will run. Triggers the workflow on a schedule +# Triggers the workflow on a call from another workflow on: workflow_call: inputs: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 4c52077ebe5..7faa3936b4a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,6 +1,6 @@ name: hdf5 1.14 release build -# Controls when the action will run. Triggers the workflow on a manual run +# Triggers the workflow on demand on: workflow_dispatch: inputs: @@ -13,8 +13,6 @@ on: permissions: contents: read -# A workflow run is made up of one or more jobs that can run sequentially or -# in parallel. jobs: log-the-inputs: runs-on: ubuntu-latest diff --git a/.github/workflows/remove-files.yml b/.github/workflows/remove-files.yml index 032130cc8ff..5f12525714a 100644 --- a/.github/workflows/remove-files.yml +++ b/.github/workflows/remove-files.yml @@ -1,6 +1,6 @@ name: hdf5 1.14 remove-files -# Controls when the action will run. Triggers the workflow on a schedule +# Triggers the workflow on a call from another workflow on: workflow_call: inputs: diff --git a/.github/workflows/tarball.yml b/.github/workflows/tarball.yml index db566f8c8d7..2b0519defac 100644 --- a/.github/workflows/tarball.yml +++ b/.github/workflows/tarball.yml @@ -1,6 +1,6 @@ name: hdf5 1.14 tarball -# Controls when the action will run. Triggers the workflow on a schedule +# Triggers the workflow on a call from another workflow on: workflow_call: inputs: @@ -34,8 +34,6 @@ on: permissions: contents: read -# A workflow run is made up of one or more jobs that can run sequentially or -# in parallel jobs: check_commits: name: Check for recent commits From 8b41a90d084b4fc5056b879148d9768973636c47 Mon Sep 17 00:00:00 2001 From: Allen Byrne <50328838+byrnHDF@users.noreply.github.com> Date: Mon, 24 Jun 2024 12:01:39 -0500 Subject: [PATCH 33/45] Update abi report CI workflow for last release (#4596) * Update abi report workflow to handle 1.14.4.3 release * Update name of java report --- .github/workflows/abi-report.yml | 14 ++++++++------ .github/workflows/daily-build.yml | 2 +- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/.github/workflows/abi-report.yml b/.github/workflows/abi-report.yml index d0cdcc22fbb..f73e42090fb 100644 --- a/.github/workflows/abi-report.yml +++ b/.github/workflows/abi-report.yml @@ -41,8 +41,10 @@ jobs: - name: Convert hdf5 reference name (Linux) id: convert-hdf5lib-refname run: | - FILE_DOTS=$(echo "${{ inputs.file_ref }}" | sed -r "s/([0-9]+)\_([0-9]+)\_([0-9]+).*/\1\.\2\.\3/") + FILE_DOTS=$(echo "${{ inputs.file_ref }}" | sed -r "s/([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+).*/\1\.\2\.\3-\4/") echo "HDF5R_DOTS=$FILE_DOTS" >> $GITHUB_OUTPUT + FILE_DOTSMAIN=$(echo "${{ inputs.file_ref }}" | sed -r "s/([0-9]+)\.([0-9]+)\.([0-9]+).*/\1\.\2\.\3/") + echo "HDF5R_DOTSMAIN=$FILE_DOTSMAIN" >> $GITHUB_OUTPUT - uses: actions/checkout@v4.1.1 @@ -82,8 +84,8 @@ jobs: run: | mkdir "${{ github.workspace }}/hdf5R" cd "${{ github.workspace }}/hdf5R" - wget -q https://github.com/HDFGroup/hdf5/releases/download/hdf5-${{ inputs.file_ref }}/hdf5-${{ inputs.file_ref }}-ubuntu-2204.tar.gz - tar zxf hdf5-${{ inputs.file_ref }}-ubuntu-2204_gcc.tar.gz + wget -q https://github.com/HDFGroup/hdf5/releases/download/hdf5_${{ inputs.file_ref }}/hdf5-${{ steps.convert-hdf5lib-refname.outputs.HDF5R_DOTS }}-ubuntu-2204_gcc.tar.gz + tar zxf hdf5-${{ steps.convert-hdf5lib-refname.outputs.HDF5R_DOTS }}-ubuntu-2204_gcc.tar.gz - name: List files for the space (Linux) run: | @@ -92,7 +94,7 @@ jobs: - name: Uncompress hdf5 reference binary (Linux) run: | cd "${{ github.workspace }}/hdf5R" - tar -zxvf ${{ github.workspace }}/hdf5R/hdf5/HDF5-${{ steps.convert-hdf5lib-refname.outputs.HDF5R_DOTS }}-Linux.tar.gz --strip-components 1 + tar -zxvf ${{ github.workspace }}/hdf5R/hdf5/HDF5-${{ inputs.file_ref }}-Linux.tar.gz --strip-components 1 - name: List files for the HDFR space (Linux) run: | @@ -114,7 +116,7 @@ jobs: - name: Run Java API report run: | - japi-compliance-checker ${{ steps.set-hdf5lib-refname.outputs.HDF5R_ROOT }}/lib/jarhdf5-${{ steps.convert-hdf5lib-refname.outputs.HDF5R_DOTS }}.jar ${{ steps.set-hdf5lib-name.outputs.HDF5_ROOT }}/lib/jarhdf5-${{ steps.set-hdf5lib-name.outputs.HDF5_VERS }}.jar + japi-compliance-checker ${{ steps.set-hdf5lib-refname.outputs.HDF5R_ROOT }}/lib/jarhdf5-${{ steps.convert-hdf5lib-refname.outputs.HDF5R_DOTSMAIN }}.jar ${{ steps.set-hdf5lib-name.outputs.HDF5_ROOT }}/lib/jarhdf5-${{ steps.set-hdf5lib-name.outputs.HDF5_VERS }}.jar - name: Run ABI report run: | @@ -146,7 +148,7 @@ jobs: - name: Copy ABI reports run: | - cp compat_reports/jarhdf5-/${{ steps.set-hdf5lib-refname.outputs.HDF5R_VERS }}_to_${{ steps.set-hdf5lib-name.outputs.HDF5_VERS }}/compat_report.html ${{ inputs.file_base }}-java_compat_report.html + cp compat_reports/jarhdf5-/${{ steps.convert-hdf5lib-refname.outputs.HDF5R_DOTSMAIN }}_to_${{ steps.set-hdf5lib-name.outputs.HDF5_VERS }}/compat_report.html ${{ inputs.file_base }}-java_compat_report.html ls -l compat_reports/${{ inputs.file_base }}/X_to_Y cp compat_reports/${{ inputs.file_base }}/X_to_Y/compat_report.html ${{ inputs.file_base }}-hdf5_compat_report.html ls -l compat_reports/${{ inputs.file_base }}_hl/X_to_Y diff --git a/.github/workflows/daily-build.yml b/.github/workflows/daily-build.yml index f27bd882c91..d80df6605da 100644 --- a/.github/workflows/daily-build.yml +++ b/.github/workflows/daily-build.yml @@ -50,7 +50,7 @@ jobs: needs: [call-workflow-tarball, call-workflow-ctest] uses: ./.github/workflows/abi-report.yml with: - file_ref: '1_14_3' + file_ref: '1.14.4.3' file_base: ${{ needs.call-workflow-tarball.outputs.file_base }} use_tag: snapshot-1.14 use_environ: snapshots From 55357bd8bcd917f74c3da2a98bfcdf9cc1767a0e Mon Sep 17 00:00:00 2001 From: mattjala <124107509+mattjala@users.noreply.github.com> Date: Mon, 24 Jun 2024 12:04:48 -0500 Subject: [PATCH 34/45] Document that ctx VOL property isn't drawn from the FAPL (#4597) --- src/H5CX.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/H5CX.c b/src/H5CX.c index 2b25288f41c..8454ef7374a 100644 --- a/src/H5CX.c +++ b/src/H5CX.c @@ -349,7 +349,9 @@ typedef struct H5CX_t { bool high_bound_valid; /* Whether high_bound property is valid */ /* Cached VOL settings */ - H5VL_connector_prop_t vol_connector_prop; /* Property for VOL connector ID & info */ + H5VL_connector_prop_t vol_connector_prop; /* Property for VOL connector ID & info + This is treated as an independent field with + no relation to the property H5F_ACS_VOL_CONN_NAME stored on the FAPL */ bool vol_connector_prop_valid; /* Whether property for VOL connector ID & info is valid */ void *vol_wrap_ctx; /* VOL connector's "wrap context" for creating IDs */ bool vol_wrap_ctx_valid; /* Whether VOL connector's "wrap context" for creating IDs is valid */ From f67a4334f10a9ef3a7f811a5d42273f6debd5873 Mon Sep 17 00:00:00 2001 From: Allen Byrne <50328838+byrnHDF@users.noreply.github.com> Date: Wed, 26 Jun 2024 11:28:38 -0500 Subject: [PATCH 35/45] Update macos workflow to 14 (keep 13 as alternate) (#4603) --- .github/workflows/cmake-bintest.yml | 2 +- .github/workflows/main-cmake.yml | 40 +++++++++++++++++++++++++---- 2 files changed, 36 insertions(+), 6 deletions(-) diff --git a/.github/workflows/cmake-bintest.yml b/.github/workflows/cmake-bintest.yml index d94cbd0db04..ca55ef04b8f 100644 --- a/.github/workflows/cmake-bintest.yml +++ b/.github/workflows/cmake-bintest.yml @@ -147,7 +147,7 @@ jobs: # MacOS w/ Clang + CMake # name: "MacOS Clang Binary Test" - runs-on: macos-13 + runs-on: macos-latest steps: - name: Install Dependencies (MacOS) run: brew install ninja doxygen diff --git a/.github/workflows/main-cmake.yml b/.github/workflows/main-cmake.yml index 069e0b136c2..91a582c53fe 100644 --- a/.github/workflows/main-cmake.yml +++ b/.github/workflows/main-cmake.yml @@ -33,6 +33,7 @@ jobs: name: - "Windows MSVC" - "Ubuntu gcc" + - "MacOS-13 Clang" - "MacOS Clang" # This is where we list the bulk of the options for each configuration. @@ -82,15 +83,35 @@ jobs: generator: "-G Ninja" run_tests: true + # MacOS w/ Clang + CMake + # + # We could also build with the Autotools via brew installing them, + # but that seems unnecessary + - name: "MacOS-13 Clang" + os: macos-13 + cpp: OFF + fortran: ON + java: ON + docs: ON + libaecfc: ON + localaec: OFF + zlibfc: ON + localzlib: OFF + parallel: OFF + mirror_vfd: ON + direct_vfd: OFF + ros3_vfd: OFF + generator: "-G Ninja" + run_tests: true # MacOS w/ Clang + CMake # # We could also build with the Autotools via brew installing them, # but that seems unnecessary - name: "MacOS Clang" - os: macos-13 - cpp: ON - fortran: OFF + os: macos-latest + cpp: OFF + fortran: ON java: ON docs: ON libaecfc: ON @@ -134,7 +155,16 @@ jobs: - name: Install Dependencies (macOS) run: brew install ninja - if: matrix.os == 'macos-13' + if: ${{ matrix.os == 'macos-13' || matrix.os == 'macos-latest' }} + + # symlinks the compiler executables to a common location + - name: Install GNU Fortran (macOS) + uses: fortran-lang/setup-fortran@v1 + id: setup-fortran + with: + compiler: gcc + version: 12 + if: ${{ matrix.os == 'macos-13' || matrix.os == 'macos-latest' }} - name: Install Dependencies uses: ssciwr/doxygen-install@v1 @@ -261,4 +291,4 @@ jobs: name: tgz-osx-${{ inputs.build_mode }}-binary path: ${{ runner.workspace }}/build/HDF5-*-Darwin.tar.gz if-no-files-found: error # 'warn' or 'ignore' are also available, defaults to `warn` - if: ${{ (matrix.os == 'macos-13') && (inputs.thread_safety != 'TS') }} + if: ${{ (matrix.os == 'macos-latest') && (inputs.thread_safety != 'TS') }} From 91e6811eba23c401deabaf613e98bab10576a7ea Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Wed, 26 Jun 2024 17:41:03 -0500 Subject: [PATCH 36/45] Removed unnecessary call to H5E_clear_stack (#4607) H5FO_opened and H5SL_search don't push errors on the stack --- src/H5Dint.c | 3 --- src/H5Gint.c | 4 ---- src/H5Tcommit.c | 3 --- 3 files changed, 10 deletions(-) diff --git a/src/H5Dint.c b/src/H5Dint.c index 8f28afb48ef..700d8306604 100644 --- a/src/H5Dint.c +++ b/src/H5Dint.c @@ -1494,9 +1494,6 @@ H5D_open(const H5G_loc_t *loc, hid_t dapl_id) /* Check if dataset was already open */ if (NULL == (shared_fo = (H5D_shared_t *)H5FO_opened(dataset->oloc.file, dataset->oloc.addr))) { - /* Clear any errors from H5FO_opened() */ - H5E_clear_stack(); - /* Open the dataset object */ if (H5D__open_oid(dataset, dapl_id) < 0) HGOTO_ERROR(H5E_DATASET, H5E_NOTFOUND, NULL, "not found"); diff --git a/src/H5Gint.c b/src/H5Gint.c index a7268adcbba..2580bf08ce0 100644 --- a/src/H5Gint.c +++ b/src/H5Gint.c @@ -437,10 +437,6 @@ H5G_open(const H5G_loc_t *loc) /* Check if group was already open */ if ((shared_fo = (H5G_shared_t *)H5FO_opened(grp->oloc.file, grp->oloc.addr)) == NULL) { - - /* Clear any errors from H5FO_opened() */ - H5E_clear_stack(); - /* Open the group object */ if (H5G__open_oid(grp) < 0) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, NULL, "not found"); diff --git a/src/H5Tcommit.c b/src/H5Tcommit.c index e1b4e0d1a7a..56b22042d66 100644 --- a/src/H5Tcommit.c +++ b/src/H5Tcommit.c @@ -1036,9 +1036,6 @@ H5T_open(const H5G_loc_t *loc) /* Check if datatype was already open */ if (NULL == (shared_fo = (H5T_shared_t *)H5FO_opened(loc->oloc->file, loc->oloc->addr))) { - /* Clear any errors from H5FO_opened() */ - H5E_clear_stack(); - /* Open the datatype object */ if (NULL == (dt = H5T__open_oid(loc))) HGOTO_ERROR(H5E_DATATYPE, H5E_NOTFOUND, NULL, "not found"); From 4489d0a7363f50d859b8d3a958993412ee09c1ba Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Wed, 26 Jun 2024 22:35:35 -0500 Subject: [PATCH 37/45] Bring subfiling VFD code closer to typical library code (#4595) Remove API calls, use FUNC_ENTER/LEAVE macros, use the library's error macros, rename functions to have more standardized names, etc. --- src/H5FDsubfiling/H5FDioc.c | 1032 +++++------- src/H5FDsubfiling/H5FDioc_int.c | 249 ++- src/H5FDsubfiling/H5FDioc_priv.h | 19 +- src/H5FDsubfiling/H5FDioc_threads.c | 656 +++----- src/H5FDsubfiling/H5FDsubfile_int.c | 185 +-- src/H5FDsubfiling/H5FDsubfiling.c | 1998 +++++++++++------------- src/H5FDsubfiling/H5FDsubfiling_priv.h | 1 - src/H5FDsubfiling/H5subfiling_common.c | 1870 ++++++++++------------ src/H5FDsubfiling/H5subfiling_common.h | 58 +- src/H5FDsubfiling/H5subfiling_err.h | 272 ---- 10 files changed, 2597 insertions(+), 3743 deletions(-) delete mode 100644 src/H5FDsubfiling/H5subfiling_err.h diff --git a/src/H5FDsubfiling/H5FDioc.c b/src/H5FDsubfiling/H5FDioc.c index f43f638ff0c..8ec066a0a68 100644 --- a/src/H5FDsubfiling/H5FDioc.c +++ b/src/H5FDsubfiling/H5FDioc.c @@ -88,16 +88,6 @@ typedef struct H5FD_ioc_t { #define REGION_OVERFLOW(A, Z) \ (ADDR_OVERFLOW(A) || SIZE_OVERFLOW(Z) || HADDR_UNDEF == (A) + (Z) || (HDoff_t)((A) + (Z)) < (HDoff_t)(A)) -#ifdef H5FD_IOC_DEBUG -#define H5FD_IOC_LOG_CALL(name) \ - do { \ - printf("called %s()\n", (name)); \ - fflush(stdout); \ - } while (0) -#else -#define H5FD_IOC_LOG_CALL(name) /* no-op */ -#endif - /* Private functions */ /* Prototypes */ static herr_t H5FD__ioc_term(void); @@ -111,13 +101,9 @@ static H5FD_t *H5FD__ioc_open(const char *name, unsigned flags, hid_t fapl_id, h static herr_t H5FD__ioc_close(H5FD_t *_file); static int H5FD__ioc_cmp(const H5FD_t *_f1, const H5FD_t *_f2); static herr_t H5FD__ioc_query(const H5FD_t *_file, unsigned long *flags /* out */); -static herr_t H5FD__ioc_get_type_map(const H5FD_t *_file, H5FD_mem_t *type_map); -static haddr_t H5FD__ioc_alloc(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, hsize_t size); -static herr_t H5FD__ioc_free(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, hsize_t size); static haddr_t H5FD__ioc_get_eoa(const H5FD_t *_file, H5FD_mem_t H5_ATTR_UNUSED type); static herr_t H5FD__ioc_set_eoa(H5FD_t *_file, H5FD_mem_t H5_ATTR_UNUSED type, haddr_t addr); static haddr_t H5FD__ioc_get_eof(const H5FD_t *_file, H5FD_mem_t H5_ATTR_UNUSED type); -static herr_t H5FD__ioc_get_handle(H5FD_t *_file, hid_t H5_ATTR_UNUSED fapl, void **file_handle); static herr_t H5FD__ioc_read(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, size_t size, void *buf); static herr_t H5FD__ioc_write(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, size_t size, @@ -126,26 +112,22 @@ static herr_t H5FD__ioc_read_vector(H5FD_t *file, hid_t dxpl_id, uint32_t count haddr_t addrs[], size_t sizes[], void *bufs[] /* out */); static herr_t H5FD__ioc_write_vector(H5FD_t *file, hid_t dxpl_id, uint32_t count, H5FD_mem_t types[], haddr_t addrs[], size_t sizes[], const void *bufs[] /* in */); -static herr_t H5FD__ioc_flush(H5FD_t *_file, hid_t dxpl_id, bool closing); static herr_t H5FD__ioc_truncate(H5FD_t *_file, hid_t dxpl_id, bool closing); -static herr_t H5FD__ioc_lock(H5FD_t *_file, bool rw); -static herr_t H5FD__ioc_unlock(H5FD_t *_file); static herr_t H5FD__ioc_del(const char *name, hid_t fapl); /* static herr_t H5FD__ioc_ctl(H5FD_t *file, uint64_t op_code, uint64_t flags, const void *input, void **result); */ -static herr_t H5FD__ioc_get_default_config(H5FD_ioc_config_t *config_out); static herr_t H5FD__ioc_validate_config(const H5FD_ioc_config_t *fa); -static herr_t H5FD__ioc_close_int(H5FD_ioc_t *file_ptr); +static herr_t H5FD__ioc_close_int(H5FD_ioc_t *file); -static herr_t H5FD__ioc_write_vector_internal(H5FD_t *_file, uint32_t count, H5FD_mem_t types[], +static herr_t H5FD__ioc_write_vector_internal(H5FD_ioc_t *file, uint32_t count, H5FD_mem_t types[], haddr_t addrs[], size_t sizes[], const void *bufs[] /* data_in */); -static herr_t H5FD__ioc_read_vector_internal(H5FD_t *_file, uint32_t count, haddr_t addrs[], size_t sizes[], - void *bufs[] /* data_out */); +static herr_t H5FD__ioc_read_vector_internal(H5FD_ioc_t *file, uint32_t count, haddr_t addrs[], + size_t sizes[], void *bufs[] /* data_out */); static const H5FD_class_t H5FD_ioc_g = { H5FD_CLASS_VERSION, /* VFD interface version */ @@ -168,23 +150,23 @@ static const H5FD_class_t H5FD_ioc_g = { H5FD__ioc_close, /* close */ H5FD__ioc_cmp, /* cmp */ H5FD__ioc_query, /* query */ - H5FD__ioc_get_type_map, /* get_type_map */ - H5FD__ioc_alloc, /* alloc */ - H5FD__ioc_free, /* free */ + NULL, /* get_type_map */ + NULL, /* alloc */ + NULL, /* free */ H5FD__ioc_get_eoa, /* get_eoa */ H5FD__ioc_set_eoa, /* set_eoa */ H5FD__ioc_get_eof, /* get_eof */ - H5FD__ioc_get_handle, /* get_handle */ + NULL, /* get_handle */ H5FD__ioc_read, /* read */ H5FD__ioc_write, /* write */ H5FD__ioc_read_vector, /* read_vector */ H5FD__ioc_write_vector, /* write_vector */ NULL, /* read_selection */ NULL, /* write_selection */ - H5FD__ioc_flush, /* flush */ + NULL, /* flush */ H5FD__ioc_truncate, /* truncate */ - H5FD__ioc_lock, /* lock */ - H5FD__ioc_unlock, /* unlock */ + NULL, /* lock */ + NULL, /* unlock */ H5FD__ioc_del, /* del */ NULL, /* ctl */ H5FD_FLMAP_DICHOTOMY /* fl_map */ @@ -211,7 +193,7 @@ H5FD_ioc_init(void) { hid_t ret_value = H5I_INVALID_HID; - H5FD_IOC_LOG_CALL(__func__); + FUNC_ENTER_NOAPI(H5I_INVALID_HID) /* Register the IOC VFD, if it isn't already registered */ if (H5I_VFL != H5I_get_type(H5FD_IOC_g)) { @@ -220,7 +202,7 @@ H5FD_ioc_init(void) int mpi_code; if ((H5FD_IOC_g = H5FD_register(&H5FD_ioc_g, sizeof(H5FD_class_t), false)) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_ID, H5E_CANTREGISTER, H5I_INVALID_HID, "can't register IOC VFD"); + HGOTO_ERROR(H5E_VFL, H5E_CANTREGISTER, H5I_INVALID_HID, "can't register IOC VFD"); /* Check if IOC VFD has been loaded dynamically */ env_var = getenv(HDF5_DRIVER); @@ -230,45 +212,43 @@ H5FD_ioc_init(void) /* Initialize MPI if not already initialized */ if (MPI_SUCCESS != (mpi_code = MPI_Initialized(&mpi_initialized))) - H5_SUBFILING_MPI_GOTO_ERROR(H5I_INVALID_HID, "MPI_Initialized failed", mpi_code); + HMPI_GOTO_ERROR(H5I_INVALID_HID, "MPI_Initialized failed", mpi_code); if (mpi_initialized) { /* If MPI is initialized, validate that it was initialized with MPI_THREAD_MULTIPLE */ if (MPI_SUCCESS != (mpi_code = MPI_Query_thread(&provided))) - H5_SUBFILING_MPI_GOTO_ERROR(H5I_INVALID_HID, "MPI_Query_thread failed", mpi_code); + HMPI_GOTO_ERROR(H5I_INVALID_HID, "MPI_Query_thread failed", mpi_code); if (provided != MPI_THREAD_MULTIPLE) - H5_SUBFILING_GOTO_ERROR( - H5E_VFL, H5E_CANTINIT, H5I_INVALID_HID, - "IOC VFD requires the use of MPI_Init_thread with MPI_THREAD_MULTIPLE"); + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, H5I_INVALID_HID, + "IOC VFD requires the use of MPI_Init_thread with MPI_THREAD_MULTIPLE"); } else { int required = MPI_THREAD_MULTIPLE; /* Otherwise, initialize MPI */ if (MPI_SUCCESS != (mpi_code = MPI_Init_thread(NULL, NULL, required, &provided))) - H5_SUBFILING_MPI_GOTO_ERROR(H5I_INVALID_HID, "MPI_Init_thread failed", mpi_code); + HMPI_GOTO_ERROR(H5I_INVALID_HID, "MPI_Init_thread failed", mpi_code); H5FD_mpi_self_initialized = true; if (provided != required) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTINIT, H5I_INVALID_HID, - "MPI doesn't support MPI_Init_thread with MPI_THREAD_MULTIPLE"); + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, H5I_INVALID_HID, + "MPI doesn't support MPI_Init_thread with MPI_THREAD_MULTIPLE"); } } /* Retrieve upper bound for MPI message tag value */ if (MPI_SUCCESS != (mpi_code = MPI_Comm_get_attr(MPI_COMM_WORLD, MPI_TAG_UB, &H5FD_IOC_tag_ub_val_ptr, &key_val_retrieved))) - H5_SUBFILING_MPI_GOTO_ERROR(H5I_INVALID_HID, "MPI_Comm_get_attr failed", mpi_code); + HMPI_GOTO_ERROR(H5I_INVALID_HID, "MPI_Comm_get_attr failed", mpi_code); if (!key_val_retrieved) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTINIT, H5I_INVALID_HID, - "couldn't retrieve value for MPI_TAG_UB"); + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, H5I_INVALID_HID, "couldn't retrieve value for MPI_TAG_UB"); } ret_value = H5FD_IOC_g; done: - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD_ioc_init() */ /*--------------------------------------------------------------------------- @@ -276,7 +256,7 @@ H5FD_ioc_init(void) * * Purpose: Shut down the IOC VFD. * - * Returns: SUCCEED (Can't fail) + * Return: SUCCEED/FAIL *--------------------------------------------------------------------------- */ static herr_t @@ -284,7 +264,7 @@ H5FD__ioc_term(void) { herr_t ret_value = SUCCEED; - H5FD_IOC_LOG_CALL(__func__); + FUNC_ENTER_PACKAGE if (H5FD_IOC_g >= 0) { /* Terminate MPI if the driver initialized it */ @@ -293,11 +273,10 @@ H5FD__ioc_term(void) int mpi_code; if (MPI_SUCCESS != (mpi_code = MPI_Finalized(&mpi_finalized))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Finalized failed", mpi_code); - if (!mpi_finalized) { + HMPI_GOTO_ERROR(FAIL, "MPI_Finalized failed", mpi_code); + if (!mpi_finalized) if (MPI_SUCCESS != (mpi_code = MPI_Finalize())) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Finalize failed", mpi_code); - } + HMPI_GOTO_ERROR(FAIL, "MPI_Finalize failed", mpi_code); H5FD_mpi_self_initialized = false; } @@ -307,7 +286,7 @@ H5FD__ioc_term(void) /* Reset VFL ID */ H5FD_IOC_g = H5I_INVALID_HID; - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__ioc_term() */ /*------------------------------------------------------------------------- @@ -322,38 +301,30 @@ H5FD__ioc_term(void) herr_t H5Pset_fapl_ioc(hid_t fapl_id, H5FD_ioc_config_t *vfd_config) { - H5FD_ioc_config_t *ioc_conf = NULL; - H5P_genplist_t *plist_ptr = NULL; - herr_t ret_value = SUCCEED; + H5FD_ioc_config_t ioc_conf; + H5P_genplist_t *plist = NULL; + herr_t ret_value = SUCCEED; - H5FD_IOC_LOG_CALL(__func__); + FUNC_ENTER_API(FAIL) - if (NULL == (plist_ptr = H5P_object_verify(fapl_id, H5P_FILE_ACCESS))) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list"); + if (NULL == (plist = H5P_object_verify(fapl_id, H5P_FILE_ACCESS))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list"); if (vfd_config == NULL) { - if (NULL == (ioc_conf = H5FL_CALLOC(H5FD_ioc_config_t))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, - "can't allocate IOC VFD configuration"); - /* Get IOC VFD defaults */ - if (H5FD__ioc_get_default_config(ioc_conf) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't get default IOC VFD configuration"); + if (H5FD__subfiling_get_default_ioc_config(&ioc_conf) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTSET, FAIL, "can't get default IOC VFD configuration"); - vfd_config = ioc_conf; + vfd_config = &ioc_conf; } if (H5FD__ioc_validate_config(vfd_config) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid IOC VFD configuration"); + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid IOC VFD configuration"); - ret_value = H5P_set_driver(plist_ptr, H5FD_IOC, vfd_config, NULL); + ret_value = H5P_set_driver(plist, H5FD_IOC, vfd_config, NULL); done: - if (ioc_conf) { - H5FL_FREE(H5FD_ioc_config_t, ioc_conf); - } - - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_API(ret_value) } /* end H5Pset_fapl_ioc() */ /*------------------------------------------------------------------------- @@ -371,68 +342,39 @@ H5Pset_fapl_ioc(hid_t fapl_id, H5FD_ioc_config_t *vfd_config) herr_t H5Pget_fapl_ioc(hid_t fapl_id, H5FD_ioc_config_t *config_out) { - const H5FD_ioc_config_t *config_ptr = NULL; - H5P_genplist_t *plist_ptr = NULL; + const H5FD_ioc_config_t *config = NULL; + H5P_genplist_t *plist = NULL; bool use_default_config = false; herr_t ret_value = SUCCEED; - H5FD_IOC_LOG_CALL(__func__); + FUNC_ENTER_API(FAIL) /* Check arguments */ if (config_out == NULL) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "config_out is NULL"); - - if (NULL == (plist_ptr = H5P_object_verify(fapl_id, H5P_FILE_ACCESS))) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list"); + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "config_out is NULL"); + if (NULL == (plist = H5P_object_verify(fapl_id, H5P_FILE_ACCESS))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list"); - if (H5FD_IOC != H5P_peek_driver(plist_ptr)) + if (H5FD_IOC != H5P_peek_driver(plist)) use_default_config = true; else { - config_ptr = H5P_peek_driver_info(plist_ptr); - if (NULL == config_ptr) + config = H5P_peek_driver_info(plist); + if (NULL == config) use_default_config = true; } if (use_default_config) { - if (H5FD__ioc_get_default_config(config_out) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get default IOC VFD configuration"); + if (H5FD__subfiling_get_default_ioc_config(config_out) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get default IOC VFD configuration"); } - else { + else /* Copy the IOC fapl data out */ - H5MM_memcpy(config_out, config_ptr, sizeof(H5FD_ioc_config_t)); - } + H5MM_memcpy(config_out, config, sizeof(H5FD_ioc_config_t)); done: - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_API(ret_value) } /* end H5Pget_fapl_ioc() */ -/*------------------------------------------------------------------------- - * Function: H5FD__ioc_get_default_config - * - * Purpose: This is called by H5Pset/get_fapl_ioc when called with no - * established configuration info. This simply fills in - * the basics. This avoids the necessity of having the - * user write code to initialize the config structure. - * - * Return: SUCCEED/FAIL - *------------------------------------------------------------------------- - */ -static herr_t -H5FD__ioc_get_default_config(H5FD_ioc_config_t *config_out) -{ - herr_t ret_value = SUCCEED; - - assert(config_out); - - memset(config_out, 0, sizeof(*config_out)); - - config_out->magic = H5FD_IOC_FAPL_MAGIC; - config_out->version = H5FD_IOC_CURR_FAPL_VERSION; - config_out->thread_pool_size = H5FD_IOC_DEFAULT_THREAD_POOL_SIZE; - - H5_SUBFILING_FUNC_LEAVE; -} - /*------------------------------------------------------------------------- * Function: H5FD__ioc_validate_config() * @@ -455,16 +397,17 @@ H5FD__ioc_validate_config(const H5FD_ioc_config_t *fa) { herr_t ret_value = SUCCEED; - assert(fa != NULL); + FUNC_ENTER_PACKAGE - if (fa->version != H5FD_IOC_CURR_FAPL_VERSION) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "Unknown H5FD_ioc_config_t version"); + assert(fa != NULL); if (fa->magic != H5FD_IOC_FAPL_MAGIC) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid H5FD_ioc_config_t magic value"); + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid H5FD_ioc_config_t magic value"); + if (fa->version != H5FD_IOC_CURR_FAPL_VERSION) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "Unknown H5FD_ioc_config_t version"); done: - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__ioc_validate_config() */ /*------------------------------------------------------------------------- @@ -485,7 +428,7 @@ H5FD__ioc_sb_size(H5FD_t H5_ATTR_UNUSED *_file) { hsize_t ret_value = 0; - H5FD_IOC_LOG_CALL(__func__); + FUNC_ENTER_PACKAGE_NOERR /* Configuration structure magic number */ ret_value += sizeof(uint32_t); @@ -502,7 +445,7 @@ H5FD__ioc_sb_size(H5FD_t H5_ATTR_UNUSED *_file) /* Subfiling stripe count (encoded as int64_t for future) */ ret_value += sizeof(int64_t); - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__ioc_sb_size */ /*------------------------------------------------------------------------- @@ -522,10 +465,10 @@ H5FD__ioc_sb_encode(H5FD_t *_file, char *name, unsigned char *buf) int64_t tmp64; herr_t ret_value = SUCCEED; - H5FD_IOC_LOG_CALL(__func__); + FUNC_ENTER_PACKAGE - if (NULL == (sf_context = H5_get_subfiling_object(file->context_id))) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get subfiling context object"); + if (NULL == (sf_context = H5FD__subfiling_get_object(file->context_id))) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get subfiling context object"); /* Encode driver name */ strncpy(name, "IOC", 9); @@ -548,7 +491,7 @@ H5FD__ioc_sb_encode(H5FD_t *_file, char *name, unsigned char *buf) INT64ENCODE(p, tmp64); done: - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__ioc_sb_encode */ /*------------------------------------------------------------------------- @@ -568,13 +511,13 @@ H5FD__ioc_sb_decode(H5FD_t *_file, const char *name, const unsigned char *buf) int64_t tmp64; herr_t ret_value = SUCCEED; - H5FD_IOC_LOG_CALL(__func__); + FUNC_ENTER_PACKAGE - if (NULL == (sf_context = H5_get_subfiling_object(file->context_id))) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get subfiling context object"); + if (NULL == (sf_context = H5FD__subfiling_get_object(file->context_id))) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get subfiling context object"); if (strncmp(name, "IOC", 9)) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "invalid driver name in superblock"); + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "invalid driver name in superblock"); /* Decode configuration structure magic number */ UINT32DECODE(p, file->fa.magic); @@ -595,26 +538,24 @@ H5FD__ioc_sb_decode(H5FD_t *_file, const char *name, const unsigned char *buf) /* Validate the decoded configuration */ if (H5FD__ioc_validate_config(&file->fa) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "decoded IOC VFD configuration info is invalid"); + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "decoded IOC VFD configuration info is invalid"); - if (H5_subfiling_validate_config(&file->subf_config) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, - "decoded subfiling configuration parameters are invalid"); + if (H5FD__subfiling_validate_config_params(&file->subf_config) < 0) + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "decoded subfiling configuration parameters are invalid"); if (file->subf_config.stripe_size != sf_context->sf_stripe_size) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, - "specified subfiling stripe size (%" PRId64 - ") doesn't match value stored in file (%" PRId64 ")", - sf_context->sf_stripe_size, file->subf_config.stripe_size); + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, + "specified subfiling stripe size (%" PRId64 + ") doesn't match value stored in file (%" PRId64 ")", + sf_context->sf_stripe_size, file->subf_config.stripe_size); if (file->subf_config.stripe_count != sf_context->sf_num_subfiles) - H5_SUBFILING_GOTO_ERROR( - H5E_VFL, H5E_BADVALUE, FAIL, - "specified subfiling stripe count (%d) doesn't match value stored in file (%" PRId32 ")", - sf_context->sf_num_subfiles, file->subf_config.stripe_count); + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, + "specified subfiling stripe count (%d) doesn't match value stored in file (%" PRId32 ")", + sf_context->sf_num_subfiles, file->subf_config.stripe_count); done: - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__ioc_sb_decode */ /*------------------------------------------------------------------------- @@ -635,11 +576,13 @@ H5FD__ioc_fapl_get(H5FD_t *_file) H5FD_ioc_t *file = (H5FD_ioc_t *)_file; void *ret_value = NULL; - H5FD_IOC_LOG_CALL(__func__); + FUNC_ENTER_PACKAGE - ret_value = H5FD__ioc_fapl_copy(&(file->fa)); + if (NULL == (ret_value = H5FD__ioc_fapl_copy(&file->fa))) + HGOTO_ERROR(H5E_VFL, H5E_CANTCOPY, NULL, "can't copy IOC fapl"); - H5_SUBFILING_FUNC_LEAVE; +done: + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__ioc_fapl_get() */ /*------------------------------------------------------------------------- @@ -658,13 +601,12 @@ H5FD__ioc_fapl_copy(const void *_old_fa) H5FD_ioc_config_t *new_fa_ptr = NULL; void *ret_value = NULL; - H5FD_IOC_LOG_CALL(__func__); + FUNC_ENTER_PACKAGE assert(old_fa_ptr); - new_fa_ptr = H5FL_CALLOC(H5FD_ioc_config_t); - if (NULL == new_fa_ptr) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTALLOC, NULL, "unable to allocate log file FAPL"); + if (NULL == (new_fa_ptr = H5FL_CALLOC(H5FD_ioc_config_t))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, NULL, "unable to allocate log file FAPL"); H5MM_memcpy(new_fa_ptr, old_fa_ptr, sizeof(H5FD_ioc_config_t)); @@ -675,7 +617,7 @@ H5FD__ioc_fapl_copy(const void *_old_fa) if (new_fa_ptr) new_fa_ptr = H5FL_FREE(H5FD_ioc_config_t, new_fa_ptr); - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__ioc_fapl_copy() */ /*-------------------------------------------------------------------------- @@ -692,7 +634,7 @@ H5FD__ioc_fapl_free(void *_fapl) H5FD_ioc_config_t *fapl = (H5FD_ioc_config_t *)_fapl; herr_t ret_value = SUCCEED; - H5FD_IOC_LOG_CALL(__func__); + FUNC_ENTER_PACKAGE_NOERR /* Check arguments */ assert(fapl); @@ -700,7 +642,7 @@ H5FD__ioc_fapl_free(void *_fapl) /* Free the property list */ fapl = H5FL_FREE(H5FD_ioc_config_t, fapl); - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__ioc_fapl_free() */ /*------------------------------------------------------------------------- @@ -717,86 +659,86 @@ H5FD__ioc_fapl_free(void *_fapl) static H5FD_t * H5FD__ioc_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr) { - H5FD_ioc_t *file_ptr = NULL; /* Ioc VFD info */ + H5FD_ioc_t *file = NULL; /* Ioc VFD info */ const H5FD_ioc_config_t *config_ptr = NULL; /* Driver-specific property list */ subfiling_context_t *sf_context = NULL; H5FD_ioc_config_t default_config; - H5P_genplist_t *plist_ptr = NULL; + H5P_genplist_t *plist = NULL; int ioc_flags; int mpi_inited = 0; int mpi_code; /* MPI return code */ H5FD_t *ret_value = NULL; - H5FD_IOC_LOG_CALL(__func__); + FUNC_ENTER_PACKAGE /* Check arguments */ if (!name || !*name) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "invalid file name"); + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "invalid file name"); if (0 == maxaddr || HADDR_UNDEF == maxaddr) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADRANGE, NULL, "bogus maxaddr"); + HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, NULL, "bogus maxaddr"); if (ADDR_OVERFLOW(maxaddr)) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, NULL, "bogus maxaddr"); + HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, NULL, "bogus maxaddr"); - if (NULL == (file_ptr = (H5FD_ioc_t *)H5FL_CALLOC(H5FD_ioc_t))) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTALLOC, NULL, "unable to allocate file struct"); - file_ptr->comm = MPI_COMM_NULL; - file_ptr->info = MPI_INFO_NULL; - file_ptr->file_id = UINT64_MAX; - file_ptr->context_id = -1; + if (NULL == (file = (H5FD_ioc_t *)H5FL_CALLOC(H5FD_ioc_t))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, NULL, "unable to allocate file struct"); + file->comm = MPI_COMM_NULL; + file->info = MPI_INFO_NULL; + file->file_id = UINT64_MAX; + file->context_id = -1; /* Initialize file pointer's subfiling parameters */ - file_ptr->subf_config.ioc_selection = SELECT_IOC_ONE_PER_NODE; - file_ptr->subf_config.stripe_size = H5FD_SUBFILING_DEFAULT_STRIPE_SIZE; - file_ptr->subf_config.stripe_count = H5FD_SUBFILING_DEFAULT_STRIPE_COUNT; + file->subf_config.ioc_selection = SELECT_IOC_ONE_PER_NODE; + file->subf_config.stripe_size = H5FD_SUBFILING_DEFAULT_STRIPE_SIZE; + file->subf_config.stripe_count = H5FD_SUBFILING_DEFAULT_STRIPE_COUNT; /* Get the driver-specific file access properties */ - if (NULL == (plist_ptr = (H5P_genplist_t *)H5I_object(fapl_id))) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file access property list"); + if (NULL == (plist = (H5P_genplist_t *)H5I_object(fapl_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file access property list"); if (H5FD_mpi_self_initialized) { - file_ptr->comm = MPI_COMM_WORLD; - file_ptr->info = MPI_INFO_NULL; + file->comm = MPI_COMM_WORLD; + file->info = MPI_INFO_NULL; mpi_inited = 1; } else { /* Get the MPI communicator and info object from the property list */ - if (H5P_get(plist_ptr, H5F_ACS_MPI_PARAMS_COMM_NAME, &file_ptr->comm) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTGET, NULL, "can't get MPI communicator"); - if (H5P_get(plist_ptr, H5F_ACS_MPI_PARAMS_INFO_NAME, &file_ptr->info) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTGET, NULL, "can't get MPI info object"); + if (H5P_get(plist, H5F_ACS_MPI_PARAMS_COMM_NAME, &file->comm) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, NULL, "can't get MPI communicator"); + if (H5P_get(plist, H5F_ACS_MPI_PARAMS_INFO_NAME, &file->info) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, NULL, "can't get MPI info object"); - if (file_ptr->comm == MPI_COMM_NULL) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_BADVALUE, NULL, "invalid or unset MPI communicator in FAPL"); + if (file->comm == MPI_COMM_NULL) + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, NULL, "invalid or unset MPI communicator in FAPL"); /* Get the status of MPI initialization */ if (MPI_SUCCESS != (mpi_code = MPI_Initialized(&mpi_inited))) - H5_SUBFILING_MPI_GOTO_ERROR(NULL, "MPI_Initialized failed", mpi_code); + HMPI_GOTO_ERROR(NULL, "MPI_Initialized failed", mpi_code); if (!mpi_inited) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_UNINITIALIZED, NULL, "MPI has not been initialized"); + HGOTO_ERROR(H5E_VFL, H5E_UNINITIALIZED, NULL, "MPI has not been initialized"); } /* Get the MPI rank of this process and the total number of processes */ - if (MPI_SUCCESS != (mpi_code = MPI_Comm_rank(file_ptr->comm, &file_ptr->mpi_rank))) - H5_SUBFILING_MPI_GOTO_ERROR(NULL, "MPI_Comm_rank failed", mpi_code); - if (MPI_SUCCESS != (mpi_code = MPI_Comm_size(file_ptr->comm, &file_ptr->mpi_size))) - H5_SUBFILING_MPI_GOTO_ERROR(NULL, "MPI_Comm_size failed", mpi_code); + if (MPI_SUCCESS != (mpi_code = MPI_Comm_rank(file->comm, &file->mpi_rank))) + HMPI_GOTO_ERROR(NULL, "MPI_Comm_rank failed", mpi_code); + if (MPI_SUCCESS != (mpi_code = MPI_Comm_size(file->comm, &file->mpi_size))) + HMPI_GOTO_ERROR(NULL, "MPI_Comm_size failed", mpi_code); - config_ptr = H5P_peek_driver_info(plist_ptr); + config_ptr = H5P_peek_driver_info(plist); if (!config_ptr || (H5P_FILE_ACCESS_DEFAULT == fapl_id)) { - if (H5FD__ioc_get_default_config(&default_config) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get default IOC VFD configuration"); + if (H5FD__subfiling_get_default_ioc_config(&default_config) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, NULL, "can't get default IOC VFD configuration"); config_ptr = &default_config; } /* Fill in the file config values */ - H5MM_memcpy(&file_ptr->fa, config_ptr, sizeof(H5FD_ioc_config_t)); + H5MM_memcpy(&file->fa, config_ptr, sizeof(H5FD_ioc_config_t)); /* Fully resolve the given filepath and get its dirname */ - if (H5_resolve_pathname(name, file_ptr->comm, &file_ptr->file_path) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTGET, NULL, "can't resolve filepath"); - if (H5_dirname(file_ptr->file_path, &file_ptr->file_dir) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTGET, NULL, "can't get filepath dirname"); + if (H5FD__subfiling_resolve_pathname(name, file->comm, &file->file_path) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, NULL, "can't resolve filepath"); + if (H5_dirname(file->file_path, &file->file_dir) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, NULL, "can't get filepath dirname"); /* Translate the HDF5 file open flags into standard POSIX open flags */ ioc_flags = (H5F_ACC_RDWR & flags) ? O_RDWR : O_RDONLY; @@ -807,158 +749,130 @@ H5FD__ioc_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr) if (H5F_ACC_EXCL & flags) ioc_flags |= O_EXCL; - if (NULL == (plist_ptr = (H5P_genplist_t *)H5I_object(fapl_id))) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file access property list"); - /* Retrieve the subfiling configuration for the current file */ - if (H5_subfiling_get_config_prop(plist_ptr, &file_ptr->subf_config) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get subfiling configuration from FAPL"); - if (H5_subfiling_validate_config(&file_ptr->subf_config) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_PLIST, H5E_BADVALUE, NULL, "invalid subfiling configuration"); + if (H5FD__subfiling_get_config_prop(plist, &file->subf_config) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, NULL, "can't get subfiling configuration from FAPL"); + if (H5FD__subfiling_validate_config_params(&file->subf_config) < 0) + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, NULL, "invalid subfiling configuration"); /* Retrieve the HDF5 stub file ID for the current file */ - if (H5_subfiling_get_file_id_prop(plist_ptr, &file_ptr->file_id) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get stub file ID from FAPL"); - if (file_ptr->file_id == UINT64_MAX) { - /* Since this VFD does no displaying of error stacks itself - * (it relies on the Subfiling VFD to do this), we must print - * the error stack here if we know it wasn't stacked under the - * Subfiling VFD. - */ - H5_SUBFILING_DONE_ERROR( - H5E_PLIST, H5E_BADVALUE, NULL, - "subfiling stub file ID property was missing from FAPL - IOC VFD wasn't correctly stacked under " - "the Subfiling VFD and cannot currently be used alone"); - PRINT_ERROR_STACK; - goto done; - } + if (H5FD__subfiling_get_file_id_prop(plist, &file->file_id) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, NULL, "can't get stub file ID from FAPL"); + if (file->file_id == UINT64_MAX) + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, NULL, + "subfiling stub file ID property was missing from FAPL - IOC VFD wasn't correctly " + "stacked under the subfiling VFD and cannot currently be used alone"); /* - * Open the subfiles for this HDF5 file. A subfiling - * context ID will be returned, which is used for - * further interactions with this file's subfiles. + * Open the subfiles for this HDF5 file. A subfiling context ID will be + * returned, which is used for further interactions with this file's subfiles. */ - if (H5_open_subfiles(file_ptr->file_path, file_ptr->file_id, &file_ptr->subf_config, ioc_flags, - file_ptr->comm, &file_ptr->context_id) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to open subfiles for file '%s'", - name); + if (H5FD__subfiling_open_subfiles(file->file_path, file->file_id, &file->subf_config, ioc_flags, + file->comm, &file->context_id) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to open subfiles for file '%s'", name); /* * Initialize I/O concentrator threads if this MPI rank is an I/O * concentrator and the threads haven't already been initialized by * a different open of this file */ - sf_context = H5_get_subfiling_object(file_ptr->context_id); + sf_context = H5FD__subfiling_get_object(file->context_id); if (sf_context && sf_context->topology->rank_is_ioc && !sf_context->threads_inited) { - if (initialize_ioc_threads(sf_context) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, - "unable to initialize I/O concentrator threads"); + if (H5FD__ioc_init_threads(sf_context) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to initialize I/O concentrator threads"); sf_context->threads_inited = true; } - ret_value = (H5FD_t *)file_ptr; + ret_value = (H5FD_t *)file; done: /* - * Check if any ranks failed before exit. The objective - * here is twofold: + * Check if any ranks failed before exit. The objective here is twofold: * - * - prevent possible hangs caused by ranks sending - * messages to I/O concentrators that failed and - * didn't spin up - * - use the barrier semantics of MPI_Allreduce to - * ensure that the I/O concentrators are fully up - * and running before proceeding. + * - prevent possible hangs caused by ranks sending messages to I/O + * concentrators that failed and didn't spin up + * - use the barrier semantics of MPI_Allreduce to ensure that the I/O + * concentrators are fully up and running before proceeding. */ if (mpi_inited) { MPI_Comm reduce_comm = MPI_COMM_WORLD; int mpi_size = -1; int err_result = (ret_value == NULL); - if (file_ptr && (file_ptr->comm != MPI_COMM_NULL)) - reduce_comm = file_ptr->comm; + if (file && (file->comm != MPI_COMM_NULL)) + reduce_comm = file->comm; if (MPI_SUCCESS != (mpi_code = MPI_Comm_size(reduce_comm, &mpi_size))) - H5_SUBFILING_MPI_DONE_ERROR(NULL, "MPI_Comm_size failed", mpi_code); + HMPI_DONE_ERROR(NULL, "MPI_Comm_size failed", mpi_code); - if (mpi_size > 1) { + if (mpi_size > 1) if (MPI_SUCCESS != (mpi_code = MPI_Allreduce(MPI_IN_PLACE, &err_result, 1, MPI_INT, MPI_MAX, reduce_comm))) - H5_SUBFILING_MPI_DONE_ERROR(NULL, "MPI_Allreduce failed", mpi_code); - } + HMPI_DONE_ERROR(NULL, "MPI_Allreduce failed", mpi_code); if (err_result) - H5_SUBFILING_DONE_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, - "one or more MPI ranks were unable to open file '%s'", name); + HDONE_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, + "one or more MPI ranks were unable to open file '%s'", name); } - if (NULL == ret_value) { - if (file_ptr) { - if (H5FD__ioc_close_int(file_ptr) < 0) - H5_SUBFILING_DONE_ERROR(H5E_FILE, H5E_CLOSEERROR, NULL, "can't close IOC file"); - } - } /* end if error */ + if (NULL == ret_value) + if (file) + if (H5FD__ioc_close_int(file) < 0) + HDONE_ERROR(H5E_FILE, H5E_CLOSEERROR, NULL, "can't close IOC file"); - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__ioc_open() */ static herr_t -H5FD__ioc_close_int(H5FD_ioc_t *file_ptr) +H5FD__ioc_close_int(H5FD_ioc_t *file) { int mpi_finalized; int mpi_code; herr_t ret_value = SUCCEED; - assert(file_ptr); + FUNC_ENTER_PACKAGE + + assert(file); if (MPI_SUCCESS != (mpi_code = MPI_Finalized(&mpi_finalized))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Finalized failed", mpi_code); + HMPI_DONE_ERROR(FAIL, "MPI_Finalized failed", mpi_code); - if (file_ptr->context_id >= 0) { - subfiling_context_t *sf_context = H5_get_subfiling_object(file_ptr->context_id); + if (file->context_id >= 0) { + subfiling_context_t *sf_context = H5FD__subfiling_get_object(file->context_id); /* Don't allow IOC threads to be finalized until everyone gets here */ - if (!mpi_finalized && (file_ptr->mpi_size > 1)) - if (MPI_SUCCESS != (mpi_code = MPI_Barrier(file_ptr->comm))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Barrier failed", mpi_code); + if (!mpi_finalized && file->mpi_size > 1) + if (MPI_SUCCESS != (mpi_code = MPI_Barrier(file->comm))) + HMPI_DONE_ERROR(FAIL, "MPI_Barrier failed", mpi_code); - /* Only finalize IOC threads and close subfiles if this is - * the last file holding a reference to the context + /* Only finalize IOC threads and close subfiles if this is the last file + * holding a reference to the context */ if (sf_context && sf_context->file_ref == 1) { - if (sf_context->topology->rank_is_ioc && sf_context->threads_inited) { - if (finalize_ioc_threads(sf_context) < 0) - /* Note that closing of subfiles is collective */ - H5_SUBFILING_DONE_ERROR(H5E_VFL, H5E_CANTCLOSEFILE, FAIL, - "unable to finalize IOC threads"); - } + if (sf_context->topology->rank_is_ioc && sf_context->threads_inited) + if (H5FD__ioc_finalize_threads(sf_context) < 0) + /* Fall through: closing of subfiles is collective */ + HDONE_ERROR(H5E_VFL, H5E_CANTCLOSEFILE, FAIL, "unable to finalize IOC threads"); - if (H5_close_subfiles(file_ptr->context_id, file_ptr->comm) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTCLOSEFILE, FAIL, - "unable to close subfiling file(s)"); + if (H5FD__subfiling_close_subfiles(file->context_id, file->comm) < 0) + HDONE_ERROR(H5E_VFL, H5E_CANTCLOSEFILE, FAIL, "unable to close subfiling file(s)"); } - - file_ptr->context_id = -1; } if (!mpi_finalized) { - if (H5_mpi_comm_free(&file_ptr->comm) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "unable to free MPI Communicator"); - if (H5_mpi_info_free(&file_ptr->info) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "unable to free MPI Info object"); + if (H5_mpi_comm_free(&file->comm) < 0) + HDONE_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "unable to free MPI Communicator"); + if (H5_mpi_info_free(&file->info) < 0) + HDONE_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "unable to free MPI Info object"); } -done: - free(file_ptr->file_path); - file_ptr->file_path = NULL; - - H5MM_free(file_ptr->file_dir); - file_ptr->file_dir = NULL; + H5MM_free(file->file_path); + H5MM_free(file->file_dir); /* Release the file info */ - file_ptr = H5FL_FREE(H5FD_ioc_t, file_ptr); + H5FL_FREE(H5FD_ioc_t, file); - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /*------------------------------------------------------------------------- @@ -976,13 +890,13 @@ H5FD__ioc_close(H5FD_t *_file) H5FD_ioc_t *file = (H5FD_ioc_t *)_file; herr_t ret_value = SUCCEED; - H5FD_IOC_LOG_CALL(__func__); + FUNC_ENTER_PACKAGE if (H5FD__ioc_close_int(file) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't close IOC file"); + HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't close IOC file"); done: - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__ioc_close() */ /*------------------------------------------------------------------------- @@ -1001,14 +915,14 @@ H5FD__ioc_cmp(const H5FD_t *_f1, const H5FD_t *_f2) const H5FD_ioc_t *f2 = (const H5FD_ioc_t *)_f2; herr_t ret_value = 0; /* Return value */ - H5FD_IOC_LOG_CALL(__func__); + FUNC_ENTER_PACKAGE_NOERR assert(f1); assert(f2); ret_value = (f1->file_id > f2->file_id) - (f1->file_id < f2->file_id); - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__ioc_cmp */ /*------------------------------------------------------------------------- @@ -1025,7 +939,7 @@ H5FD__ioc_query(const H5FD_t H5_ATTR_UNUSED *_file, unsigned long *flags /* out { herr_t ret_value = SUCCEED; - H5FD_IOC_LOG_CALL(__func__); + FUNC_ENTER_PACKAGE_NOERR /* Set the VFL feature flags that this driver supports */ if (flags) { @@ -1035,71 +949,9 @@ H5FD__ioc_query(const H5FD_t H5_ATTR_UNUSED *_file, unsigned long *flags /* out *flags |= H5FD_FEAT_HAS_MPI; /* This driver uses MPI */ } - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__ioc_query() */ -/*------------------------------------------------------------------------- - * Function: H5FD__ioc_get_type_map - * - * Purpose: Retrieve the memory type mapping for this file - * - * Return: SUCCEED/FAIL - *------------------------------------------------------------------------- - */ -static herr_t -H5FD__ioc_get_type_map(const H5FD_t H5_ATTR_UNUSED *_file, H5FD_mem_t H5_ATTR_UNUSED *type_map) -{ - herr_t ret_value = SUCCEED; - - H5FD_IOC_LOG_CALL(__func__); - - /* TODO: placeholder for now */ - - H5_SUBFILING_FUNC_LEAVE; -} /* end H5FD__ioc_get_type_map() */ - -/*------------------------------------------------------------------------- - * Function: H5FD__ioc_alloc - * - * Purpose: Allocate file memory. - * - * Return: Address of allocated space (HADDR_UNDEF if error). - *------------------------------------------------------------------------- - */ -static haddr_t -H5FD__ioc_alloc(H5FD_t H5_ATTR_UNUSED *_file, H5FD_mem_t H5_ATTR_UNUSED type, hid_t H5_ATTR_UNUSED dxpl_id, - hsize_t H5_ATTR_UNUSED size) -{ - haddr_t ret_value = HADDR_UNDEF; /* Return value */ - - H5FD_IOC_LOG_CALL(__func__); - - /* TODO: placeholder for now */ - - H5_SUBFILING_FUNC_LEAVE; -} /* end H5FD__ioc_alloc() */ - -/*------------------------------------------------------------------------- - * Function: H5FD__ioc_free - * - * Purpose: Free the resources for the ioc VFD. - * - * Return: SUCCEED/FAIL - *------------------------------------------------------------------------- - */ -static herr_t -H5FD__ioc_free(H5FD_t H5_ATTR_UNUSED *_file, H5FD_mem_t H5_ATTR_UNUSED type, hid_t H5_ATTR_UNUSED dxpl_id, - haddr_t H5_ATTR_UNUSED addr, hsize_t H5_ATTR_UNUSED size) -{ - herr_t ret_value = SUCCEED; /* Return value */ - - H5FD_IOC_LOG_CALL(__func__); - - /* TODO: placeholder for now */ - - H5_SUBFILING_FUNC_LEAVE; -} /* end H5FD__ioc_free() */ - /*------------------------------------------------------------------------- * Function: H5FD__ioc_get_eoa * @@ -1115,17 +967,14 @@ H5FD__ioc_free(H5FD_t H5_ATTR_UNUSED *_file, H5FD_mem_t H5_ATTR_UNUSED type, hid static haddr_t H5FD__ioc_get_eoa(const H5FD_t *_file, H5FD_mem_t H5_ATTR_UNUSED type) { - const H5FD_ioc_t *file = (const H5FD_ioc_t *)_file; - haddr_t ret_value = HADDR_UNDEF; + const H5FD_ioc_t *file = (const H5FD_ioc_t *)_file; - H5FD_IOC_LOG_CALL(__func__); + FUNC_ENTER_PACKAGE_NOERR /* Sanity check */ assert(file); - ret_value = file->eoa; - - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(file->eoa) } /* end H5FD__ioc_get_eoa */ /*------------------------------------------------------------------------- @@ -1144,14 +993,14 @@ H5FD__ioc_set_eoa(H5FD_t *_file, H5FD_mem_t H5_ATTR_UNUSED type, haddr_t addr) H5FD_ioc_t *file = (H5FD_ioc_t *)_file; herr_t ret_value = SUCCEED; /* Return value */ - H5FD_IOC_LOG_CALL(__func__); + FUNC_ENTER_PACKAGE_NOERR /* Sanity check */ assert(file); file->eoa = addr; - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__ioc_set_eoa() */ /*------------------------------------------------------------------------- @@ -1170,48 +1019,23 @@ static haddr_t H5FD__ioc_get_eof(const H5FD_t *_file, H5FD_mem_t H5_ATTR_UNUSED type) { const H5FD_ioc_t *file = (const H5FD_ioc_t *)_file; - haddr_t ret_value = HADDR_UNDEF; /* Return value */ subfiling_context_t *sf_context = NULL; + haddr_t ret_value = HADDR_UNDEF; /* Return value */ - H5FD_IOC_LOG_CALL(__func__); + FUNC_ENTER_PACKAGE_NOERR /* Sanity check */ assert(file); - sf_context = H5_get_subfiling_object(file->context_id); - if (sf_context) { + sf_context = H5FD__subfiling_get_object(file->context_id); + if (sf_context) ret_value = sf_context->sf_eof; - goto done; - } else ret_value = file->eof; -done: - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__ioc_get_eof */ -/*-------------------------------------------------------------------------- - * Function: H5FD__ioc_get_handle - * - * Purpose: Returns a pointer to the file handle of low-level virtual - * file driver. - * - * Return: SUCCEED/FAIL - *-------------------------------------------------------------------------- - */ -static herr_t -H5FD__ioc_get_handle(H5FD_t H5_ATTR_UNUSED *_file, hid_t H5_ATTR_UNUSED fapl, - void H5_ATTR_UNUSED **file_handle) -{ - herr_t ret_value = SUCCEED; - - H5FD_IOC_LOG_CALL(__func__); - - /* TODO: placeholder for now */ - - H5_SUBFILING_FUNC_LEAVE; -} /* end H5FD__ioc_get_handle */ - /*------------------------------------------------------------------------- * Function: H5FD__ioc_read * @@ -1220,36 +1044,32 @@ H5FD__ioc_get_handle(H5FD_t H5_ATTR_UNUSED *_file, hid_t H5_ATTR_UNUSED fapl, * properties in DXPL_ID. * * Return: Success: SUCCEED - * The read result is written into the BUF buffer - * which should be allocated by the caller. * Failure: FAIL - * The contents of BUF are undefined. *------------------------------------------------------------------------- */ static herr_t H5FD__ioc_read(H5FD_t *_file, H5FD_mem_t H5_ATTR_UNUSED type, hid_t H5_ATTR_UNUSED dxpl_id, haddr_t addr, size_t size, void *buf) { -#ifndef NDEBUG - H5FD_ioc_t *file = (H5FD_ioc_t *)_file; -#endif - herr_t ret_value = SUCCEED; + H5FD_ioc_t *file = (H5FD_ioc_t *)_file; + herr_t ret_value = SUCCEED; - H5FD_IOC_LOG_CALL(__func__); + FUNC_ENTER_PACKAGE assert(file && file->pub.cls); assert(buf); /* Check for overflow conditions */ if (!H5_addr_defined(addr)) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "addr undefined, addr = %" PRIuHADDR, addr); + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "addr undefined, addr = %" PRIuHADDR, addr); if (REGION_OVERFLOW(addr, size)) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, "addr overflow, addr = %" PRIuHADDR, addr); + HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, "addr overflow, addr = %" PRIuHADDR, addr); - ret_value = H5FD__ioc_read_vector_internal(_file, 1, &addr, &size, &buf); + if (H5FD__ioc_read_vector_internal(file, 1, &addr, &size, &buf) < 0) + HGOTO_ERROR(H5E_VFL, H5E_READERROR, FAIL, "can't read data"); done: - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__ioc_read() */ /*------------------------------------------------------------------------- @@ -1266,56 +1086,51 @@ static herr_t H5FD__ioc_write(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED dxpl_id, haddr_t addr, size_t size, const void *buf) { - herr_t ret_value = SUCCEED; + H5FD_ioc_t *file = (H5FD_ioc_t *)_file; + herr_t ret_value = SUCCEED; - addr += _file->base_addr; + FUNC_ENTER_PACKAGE - ret_value = H5FD__ioc_write_vector_internal(_file, 1, &type, &addr, &size, &buf); + addr += file->pub.base_addr; + if (H5FD__ioc_write_vector_internal(file, 1, &type, &addr, &size, &buf) < 0) + HGOTO_ERROR(H5E_VFL, H5E_WRITEERROR, FAIL, "can't write data"); - H5_SUBFILING_FUNC_LEAVE; +done: + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__ioc_write() */ static herr_t H5FD__ioc_read_vector(H5FD_t *_file, hid_t dxpl_id, uint32_t count, H5FD_mem_t types[], haddr_t addrs[], size_t sizes[], void *bufs[] /* out */) { - H5FD_ioc_t *file_ptr = (H5FD_ioc_t *)_file; + H5FD_ioc_t *file = (H5FD_ioc_t *)_file; herr_t ret_value = SUCCEED; /* Return value */ - /* Check arguments */ - if (!file_ptr) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "file pointer cannot be NULL"); - - if ((!types) && (count > 0)) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, - "types parameter can't be NULL if count is positive"); + FUNC_ENTER_PACKAGE - if ((!addrs) && (count > 0)) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, - "addrs parameter can't be NULL if count is positive"); - - if ((!sizes) && (count > 0)) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, - "sizes parameter can't be NULL if count is positive"); - - if ((!bufs) && (count > 0)) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, - "bufs parameter can't be NULL if count is positive"); - - /* Get the default dataset transfer property list if the user didn't provide - * one */ - if (H5P_DEFAULT == dxpl_id) { + /* Check arguments */ + if (!file) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "file pointer cannot be NULL"); + if (!types && count > 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "types parameter can't be NULL if count is positive"); + if (!addrs && count > 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "addrs parameter can't be NULL if count is positive"); + if (!sizes && count > 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "sizes parameter can't be NULL if count is positive"); + if (!bufs && count > 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "bufs parameter can't be NULL if count is positive"); + + /* Get the default dataset transfer property list if the user didn't provide one */ + if (H5P_DEFAULT == dxpl_id) dxpl_id = H5P_DATASET_XFER_DEFAULT; - } - else { - if (true != H5P_isa_class(dxpl_id, H5P_DATASET_XFER)) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data transfer property list"); - } + else if (true != H5P_isa_class(dxpl_id, H5P_DATASET_XFER)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data transfer property list"); - ret_value = H5FD__ioc_read_vector_internal(_file, count, addrs, sizes, bufs); + if (H5FD__ioc_read_vector_internal(file, count, addrs, sizes, bufs) < 0) + HGOTO_ERROR(H5E_VFL, H5E_READERROR, FAIL, "can't read vector of data"); done: - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } static herr_t @@ -1325,61 +1140,32 @@ H5FD__ioc_write_vector(H5FD_t *_file, hid_t dxpl_id, uint32_t count, H5FD_mem_t H5FD_ioc_t *file = (H5FD_ioc_t *)_file; herr_t ret_value = SUCCEED; /* Return value */ + FUNC_ENTER_PACKAGE + /* Check arguments */ if (!file) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "file pointer cannot be NULL"); - - if ((!types) && (count > 0)) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, - "types parameter can't be NULL if count is positive"); - - if ((!addrs) && (count > 0)) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, - "addrs parameter can't be NULL if count is positive"); - - if ((!sizes) && (count > 0)) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, - "sizes parameter can't be NULL if count is positive"); - - if ((!bufs) && (count > 0)) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, - "bufs parameter can't be NULL if count is positive"); - - /* Get the default dataset transfer property list if the user didn't provide - * one */ - if (H5P_DEFAULT == dxpl_id) { + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "file pointer cannot be NULL"); + if (!types && count > 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "types parameter can't be NULL if count is positive"); + if (!addrs && count > 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "addrs parameter can't be NULL if count is positive"); + if (!sizes && count > 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "sizes parameter can't be NULL if count is positive"); + if (!bufs && count > 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "bufs parameter can't be NULL if count is positive"); + + /* Get the default dataset transfer property list if the user didn't provide one */ + if (H5P_DEFAULT == dxpl_id) dxpl_id = H5P_DATASET_XFER_DEFAULT; - } - else { - if (true != H5P_isa_class(dxpl_id, H5P_DATASET_XFER)) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data transfer property list"); - } + else if (true != H5P_isa_class(dxpl_id, H5P_DATASET_XFER)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data transfer property list"); - ret_value = H5FD__ioc_write_vector_internal(_file, count, types, addrs, sizes, bufs); + if (H5FD__ioc_write_vector_internal(file, count, types, addrs, sizes, bufs) < 0) + HGOTO_ERROR(H5E_VFL, H5E_WRITEERROR, FAIL, "can't write vector of data"); done: - H5_SUBFILING_FUNC_LEAVE; -} /* end H5FDioc__write_vector() */ - -/*------------------------------------------------------------------------- - * Function: H5FD__ioc_flush - * - * Purpose: Flushes all data to disk for underlying VFD. - * - * Return: SUCCEED/FAIL - *------------------------------------------------------------------------- - */ -static herr_t -H5FD__ioc_flush(H5FD_t H5_ATTR_UNUSED *_file, hid_t H5_ATTR_UNUSED dxpl_id, bool H5_ATTR_UNUSED closing) -{ - herr_t ret_value = SUCCEED; - - H5FD_IOC_LOG_CALL(__func__); - - /* TODO: placeholder for now */ - - H5_SUBFILING_FUNC_LEAVE; -} /* end H5FD__ioc_flush() */ + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5FD__ioc__write_vector() */ /*------------------------------------------------------------------------- * Function: H5FD__ioc_truncate @@ -1395,63 +1181,21 @@ H5FD__ioc_truncate(H5FD_t *_file, hid_t H5_ATTR_UNUSED dxpl_id, bool H5_ATTR_UNU H5FD_ioc_t *file = (H5FD_ioc_t *)_file; herr_t ret_value = SUCCEED; - H5FD_IOC_LOG_CALL(__func__); + FUNC_ENTER_PACKAGE_NOERR assert(file); - /* TODO: placeholder for now since Subfiling does the truncation */ - if (!H5_addr_eq(file->eoa, file->last_eoa)) { + /* TODO: placeholder for now since subfiling does the truncation */ + if (!H5_addr_eq(file->eoa, file->last_eoa)) file->last_eoa = file->eoa; - } - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__ioc_truncate */ -/*-------------------------------------------------------------------------- - * Function: H5FD__ioc_lock - * - * Purpose: Sets a file lock. - * - * Return: SUCCEED/FAIL - *-------------------------------------------------------------------------- - */ -static herr_t -H5FD__ioc_lock(H5FD_t H5_ATTR_UNUSED *_file, bool H5_ATTR_UNUSED rw) -{ - herr_t ret_value = SUCCEED; - - H5FD_IOC_LOG_CALL(__func__); - - /* TODO: placeholder for now */ - - H5_SUBFILING_FUNC_LEAVE; -} /* end H5FD__ioc_lock */ - -/*-------------------------------------------------------------------------- - * Function: H5FD__ioc_unlock - * - * Purpose: Removes a file lock. - * - * Return: SUCCEED/FAIL - *-------------------------------------------------------------------------- - */ -static herr_t -H5FD__ioc_unlock(H5FD_t H5_ATTR_UNUSED *_file) -{ - herr_t ret_value = SUCCEED; - - H5FD_IOC_LOG_CALL(__func__); - - /* TODO: placeholder for now */ - - H5_SUBFILING_FUNC_LEAVE; -} /* end H5FD__ioc_unlock */ - static herr_t H5FD__ioc_del(const char *name, hid_t fapl) { H5P_genplist_t *plist; - h5_stat_t st; MPI_Comm comm = MPI_COMM_NULL; MPI_Info info = MPI_INFO_NULL; FILE *config_file = NULL; @@ -1462,49 +1206,45 @@ H5FD__ioc_del(const char *name, hid_t fapl) int mpi_code; herr_t ret_value = SUCCEED; - /* TODO: Eventually this routine should share common code - * with H5_subfiling_common's routines so it doesn't get - * out of sync - */ + FUNC_ENTER_PACKAGE if (NULL == (plist = H5P_object_verify(fapl, H5P_FILE_ACCESS))) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list"); + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list"); assert(H5FD_IOC == H5P_peek_driver(plist)); - if (H5FD_mpi_self_initialized) { + if (H5FD_mpi_self_initialized) comm = MPI_COMM_WORLD; - } else { /* Get the MPI communicator and info from the fapl */ if (H5P_get(plist, H5F_ACS_MPI_PARAMS_INFO_NAME, &info) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get MPI info object"); + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get MPI info object"); if (H5P_get(plist, H5F_ACS_MPI_PARAMS_COMM_NAME, &comm) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get MPI communicator"); + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get MPI communicator"); } /* Get the MPI rank of this process */ if (MPI_SUCCESS != (mpi_code = MPI_Comm_rank(comm, &mpi_rank))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Comm_rank failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Comm_rank failed", mpi_code); if (mpi_rank == 0) { - int64_t read_n_subfiles = 0; - int32_t n_subfiles = 0; - char *prefix_env = NULL; - int num_digits = 0; + int64_t read_n_subfiles = 0; + int32_t n_subfiles = 0; + char *prefix_env = NULL; + int num_digits = 0; + h5_stat_t st; memset(&st, 0, sizeof(h5_stat_t)); if (HDstat(name, &st) < 0) - H5_SUBFILING_SYS_GOTO_ERROR(H5E_FILE, H5E_SYSERRSTR, FAIL, "HDstat failed"); + HSYS_GOTO_ERROR(H5E_FILE, H5E_SYSERRSTR, FAIL, "HDstat failed"); if (H5_basename(name, &base_filename) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't get file basename"); + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't get file basename"); if (H5_dirname(name, &file_dirname) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't get file dirname"); + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't get file dirname"); /* Try to open the subfiling configuration file and get the number of IOCs */ - if (NULL == (tmp_filename = malloc(PATH_MAX))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, - "can't allocate config file name buffer"); + if (NULL == (tmp_filename = H5MM_malloc(PATH_MAX))) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't allocate config file name buffer"); /* Check if a prefix has been set for the configuration file name */ prefix_env = getenv(H5FD_SUBFILING_CONFIG_FILE_PREFIX); @@ -1516,20 +1256,14 @@ H5FD__ioc_del(const char *name, hid_t fapl) (uint64_t)st.st_ino); if (NULL == (config_file = fopen(tmp_filename, "r"))) { - if (ENOENT == errno) { -#ifdef H5FD_IOC_DEBUG - printf("** WARNING: couldn't delete Subfiling configuration file '%s'\n", tmp_filename); -#endif - - H5_SUBFILING_GOTO_DONE(SUCCEED); - } + if (ENOENT == errno) + HGOTO_DONE(SUCCEED); else - H5_SUBFILING_SYS_GOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, - "can't open subfiling config file"); + HSYS_GOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "can't open subfiling config file"); } - if (H5_get_subfiling_config_from_file(config_file, NULL, &read_n_subfiles) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_FILE, H5E_READERROR, FAIL, "can't read subfiling config file"); + if (H5FD__subfiling_get_config_from_file(config_file, NULL, &read_n_subfiles) < 0) + HGOTO_ERROR(H5E_FILE, H5E_READERROR, FAIL, "can't read subfiling config file"); H5_CHECK_OVERFLOW(read_n_subfiles, int64_t, int32_t); n_subfiles = (int32_t)read_n_subfiles; @@ -1537,15 +1271,13 @@ H5FD__ioc_del(const char *name, hid_t fapl) /* Delete the Subfiling configuration file */ if (EOF == fclose(config_file)) { config_file = NULL; - H5_SUBFILING_SYS_GOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, - "can't close subfiling config file"); + HSYS_GOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't close subfiling config file"); } config_file = NULL; if (HDremove(tmp_filename) < 0) - H5_SUBFILING_SYS_GOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, - "can't delete subfiling config file"); + HSYS_GOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't delete subfiling config file"); /* Try to delete each of the subfiles */ num_digits = (int)(log10(n_subfiles) + 1); @@ -1555,49 +1287,46 @@ H5FD__ioc_del(const char *name, hid_t fapl) snprintf(tmp_filename, PATH_MAX, "%s/" H5FD_SUBFILING_FILENAME_TEMPLATE, file_dirname, base_filename, (uint64_t)st.st_ino, num_digits, i + 1, n_subfiles); - if (HDremove(tmp_filename) < 0) { -#ifdef H5FD_IOC_DEBUG - printf("** WARNING: couldn't delete subfile '%s'\n", tmp_filename); -#endif - + if (HDremove(tmp_filename) < 0) if (ENOENT != errno) - H5_SUBFILING_SYS_GOTO_ERROR(H5E_FILE, H5E_CANTDELETEFILE, FAIL, "can't delete subfile"); - } + HSYS_GOTO_ERROR(H5E_FILE, H5E_CANTDELETEFILE, FAIL, "can't delete subfile"); } /* Delete the HDF5 stub file */ if (HDremove(name) < 0) - H5_SUBFILING_SYS_GOTO_ERROR(H5E_FILE, H5E_CANTDELETEFILE, FAIL, "can't delete HDF5 file"); + HSYS_GOTO_ERROR(H5E_FILE, H5E_CANTDELETEFILE, FAIL, "can't delete HDF5 file"); } done: if (config_file) if (EOF == fclose(config_file)) - H5_SUBFILING_DONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't close subfiling config file"); + HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't close subfiling config file"); /* Set up a barrier (don't want processes to run ahead of the delete) */ if (comm != MPI_COMM_NULL) { int comm_size = -1; if (MPI_SUCCESS != (mpi_code = MPI_Comm_size(comm, &comm_size))) - H5_SUBFILING_MPI_DONE_ERROR(FAIL, "MPI_Comm_size failed", mpi_code); + HMPI_DONE_ERROR(FAIL, "MPI_Comm_size failed", mpi_code); if (comm_size > 1) if (MPI_SUCCESS != (mpi_code = MPI_Barrier(comm))) - H5_SUBFILING_MPI_DONE_ERROR(FAIL, "MPI_Barrier failed", mpi_code); + HMPI_DONE_ERROR(FAIL, "MPI_Barrier failed", mpi_code); } - /* Free duplicated MPI Communicator and Info objects */ - if (H5_mpi_comm_free(&comm) < 0) - H5_SUBFILING_DONE_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "unable to free MPI communicator"); - if (H5_mpi_info_free(&info) < 0) - H5_SUBFILING_DONE_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "unable to free MPI info object"); + if (!H5FD_mpi_self_initialized) { + /* Free duplicated MPI Communicator and Info objects */ + if (H5_mpi_comm_free(&comm) < 0) + HDONE_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "unable to free MPI communicator"); + if (H5_mpi_info_free(&info) < 0) + HDONE_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "unable to free MPI info object"); + } - free(tmp_filename); + H5MM_free(tmp_filename); H5MM_free(file_dirname); H5MM_free(base_filename); - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /*-------------------------------------------------------------------------- @@ -1617,30 +1346,31 @@ H5FD__ioc_del(const char *name, hid_t fapl) *-------------------------------------------------------------------------- */ static herr_t -H5FD__ioc_write_vector_internal(H5FD_t *_file, uint32_t count, H5FD_mem_t H5_ATTR_UNUSED types[], +H5FD__ioc_write_vector_internal(H5FD_ioc_t *file, uint32_t count, H5FD_mem_t H5_ATTR_UNUSED types[], haddr_t addrs[], size_t sizes[], const void *bufs[] /* in */) { subfiling_context_t *sf_context = NULL; MPI_Request *mpi_reqs = NULL; - H5FD_ioc_t *file_ptr = (H5FD_ioc_t *)_file; io_req_t **sf_io_reqs = NULL; int64_t sf_context_id = -1; size_t io_size = 0; bool extend_sizes = false; herr_t ret_value = SUCCEED; - assert(_file); - assert((addrs) || (count == 0)); - assert((sizes) || (count == 0)); - assert((bufs) || (count == 0)); + FUNC_ENTER_PACKAGE if (count == 0) - H5_SUBFILING_GOTO_DONE(SUCCEED); + HGOTO_DONE(SUCCEED); - sf_context_id = file_ptr->context_id; + assert(file); + assert(addrs); + assert(sizes); + assert(bufs); + + sf_context_id = file->context_id; - if (NULL == (sf_context = H5_get_subfiling_object(sf_context_id))) - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_CANTGET, FAIL, "can't get subfiling context from ID"); + if (NULL == (sf_context = H5FD__subfiling_get_object(sf_context_id))) + HGOTO_ERROR(H5E_IO, H5E_CANTGET, FAIL, "can't get subfiling context from ID"); assert(sf_context->topology); /* @@ -1652,88 +1382,81 @@ H5FD__ioc_write_vector_internal(H5FD_t *_file, uint32_t count, H5FD_mem_t H5_ATT * that blocking write calls do not return early before the data is * actually written. */ - if (NULL == (sf_io_reqs = calloc((size_t)count, sizeof(*sf_io_reqs)))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't allocate I/O request array"); - if (NULL == (mpi_reqs = malloc(2 * (size_t)count * sizeof(*mpi_reqs)))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't allocate MPI request array"); - - /* Each pass thru the following should queue an MPI write - * to a new IOC. Both the IOC selection and offset within the - * particular subfile are based on the combination of striping - * factors and the virtual file offset (addrs[i]). + if (NULL == (sf_io_reqs = H5MM_calloc((size_t)count * sizeof(*sf_io_reqs)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't allocate I/O request array"); + if (NULL == (mpi_reqs = H5MM_malloc(2 * (size_t)count * sizeof(*mpi_reqs)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't allocate MPI request array"); + + /* Each pass thru the following should queue an MPI write to a new IOC. Both + * the IOC selection and offset within the particular subfile are based on + * the combination of striping factors and the virtual file offset (addrs[i]). */ for (size_t i = 0; i < (size_t)count; i++) { - herr_t write_status; - if (!extend_sizes) { - if ((i > 0) && (sizes[i] == 0)) { + if (i > 0 && sizes[i] == 0) extend_sizes = true; - io_size = sizes[i - 1]; - } - else { + else io_size = sizes[i]; - } } if (io_size == 0) - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "invalid size argument of 0"); + HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "invalid size argument of 0"); H5_CHECK_OVERFLOW(addrs[i], haddr_t, int64_t); H5_CHECK_OVERFLOW(io_size, size_t, int64_t); - write_status = ioc__write_independent_async(sf_context_id, (int64_t)addrs[i], (int64_t)io_size, - bufs[i], &sf_io_reqs[i]); - - if (write_status < 0) - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "couldn't queue write operation"); + if (H5FD__ioc_write_independent_async(sf_context_id, (int64_t)addrs[i], (int64_t)io_size, bufs[i], + &sf_io_reqs[i]) < 0) + HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "couldn't queue write operation"); mpi_reqs[(2 * i)] = sf_io_reqs[i]->io_transfer_req; mpi_reqs[(2 * i) + 1] = sf_io_reqs[i]->io_comp_req; } - /* Here, we should have queued 'count' async requests. - * We can can now try to complete those before returning - * to the caller for the next set of IO operations. + /* Here, we should have queued 'count' async requests. We can can now try to + * complete those before returning to the caller for the next set of IO + * operations. */ - if (ioc__async_completion(mpi_reqs, 2 * (size_t)count) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "can't complete I/O requests"); + if (H5FD__ioc_async_completion(mpi_reqs, 2 * (size_t)count) < 0) + HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "can't complete I/O requests"); done: - free(mpi_reqs); + H5MM_free(mpi_reqs); if (sf_io_reqs) { for (size_t i = 0; i < count; i++) - free(sf_io_reqs[i]); - free(sf_io_reqs); + H5MM_free(sf_io_reqs[i]); + H5MM_free(sf_io_reqs); } - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } static herr_t -H5FD__ioc_read_vector_internal(H5FD_t *_file, uint32_t count, haddr_t addrs[], size_t sizes[], +H5FD__ioc_read_vector_internal(H5FD_ioc_t *file, uint32_t count, haddr_t addrs[], size_t sizes[], void *bufs[] /* out */) { subfiling_context_t *sf_context = NULL; MPI_Request *mpi_reqs = NULL; - H5FD_ioc_t *file_ptr = (H5FD_ioc_t *)_file; io_req_t **sf_io_reqs = NULL; int64_t sf_context_id = -1; size_t io_size = 0; bool extend_sizes = false; herr_t ret_value = SUCCEED; - assert(_file); - assert((addrs) || (count == 0)); - assert((sizes) || (count == 0)); - assert((bufs) || (count == 0)); + FUNC_ENTER_PACKAGE if (count == 0) - H5_SUBFILING_GOTO_DONE(SUCCEED); + HGOTO_DONE(SUCCEED); + + assert(file); + assert(addrs); + assert(sizes); + assert(bufs); - sf_context_id = file_ptr->context_id; + sf_context_id = file->context_id; - if (NULL == (sf_context = H5_get_subfiling_object(sf_context_id))) - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_CANTGET, FAIL, "can't get subfiling context from ID"); + if (NULL == (sf_context = H5FD__subfiling_get_object(sf_context_id))) + HGOTO_ERROR(H5E_IO, H5E_CANTGET, FAIL, "can't get subfiling context from ID"); assert(sf_context->topology); /* @@ -1743,52 +1466,43 @@ H5FD__ioc_read_vector_internal(H5FD_t *_file, uint32_t count, haddr_t addrs[], s * that the actual I/O call (currently, HDpread) has completed and * the data read from the file has been transferred to the caller. */ - if (NULL == (sf_io_reqs = calloc((size_t)count, sizeof(*sf_io_reqs)))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't allocate I/O request array"); - if (NULL == (mpi_reqs = malloc((size_t)count * sizeof(*mpi_reqs)))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't allocate MPI request array"); + if (NULL == (sf_io_reqs = H5MM_calloc((size_t)count * sizeof(*sf_io_reqs)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't allocate I/O request array"); + if (NULL == (mpi_reqs = H5MM_malloc((size_t)count * sizeof(*mpi_reqs)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't allocate MPI request array"); for (size_t i = 0; i < (size_t)count; i++) { - herr_t read_status; - if (!extend_sizes) { - if ((i > 0) && (sizes[i] == 0)) { + if (i > 0 && sizes[i] == 0) extend_sizes = true; - io_size = sizes[i - 1]; - } - else { + else io_size = sizes[i]; - } } H5_CHECK_OVERFLOW(addrs[i], haddr_t, int64_t); H5_CHECK_OVERFLOW(io_size, size_t, int64_t); - read_status = ioc__read_independent_async(sf_context_id, (int64_t)addrs[i], (int64_t)io_size, bufs[i], - &sf_io_reqs[i]); - - if (read_status < 0) - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "couldn't queue read operation"); + if (H5FD__ioc_read_independent_async(sf_context_id, (int64_t)addrs[i], (int64_t)io_size, bufs[i], + &sf_io_reqs[i]) < 0) + HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "couldn't queue read operation"); mpi_reqs[i] = sf_io_reqs[i]->io_transfer_req; } - /* Here, we should have queued 'count' async requests - * (one to each required IOC). - * - * We can can now try to complete those before returning - * to the caller for the next set of IO operations. + /* Here, we should have queued 'count' async requests, one to each required + * IOC. We can can now try to complete those before returning to the caller + * for the next set of IO operations. */ - if (ioc__async_completion(mpi_reqs, (size_t)count) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "can't complete I/O requests"); + if (H5FD__ioc_async_completion(mpi_reqs, (size_t)count) < 0) + HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "can't complete I/O requests"); done: - free(mpi_reqs); + H5MM_free(mpi_reqs); if (sf_io_reqs) { for (size_t i = 0; i < count; i++) - free(sf_io_reqs[i]); - free(sf_io_reqs); + H5MM_free(sf_io_reqs[i]); + H5MM_free(sf_io_reqs); } - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } diff --git a/src/H5FDsubfiling/H5FDioc_int.c b/src/H5FDsubfiling/H5FDioc_int.c index 75a36d0cb04..e528a362f80 100644 --- a/src/H5FDsubfiling/H5FDioc_int.c +++ b/src/H5FDsubfiling/H5FDioc_int.c @@ -17,21 +17,21 @@ #include "H5FDioc_priv.h" /* - * Given a file offset, the stripe size, the - * number of IOCs and the number of subfiles, - * calculate the target IOC for I/O, the index - * of the target subfile out of the subfiles - * that the IOC controls and the file offset - * into that subfile + * Given a file offset, the stripe size, the number of IOCs and the number of + * subfiles, calculate the target IOC for I/O, the index of the target subfile + * out of the subfiles that the IOC controls and the file offset into that subfile */ static inline void -calculate_target_ioc(int64_t file_offset, int64_t stripe_size, int num_io_concentrators, int num_subfiles, - int64_t *target_ioc, int64_t *ioc_file_offset, int64_t *ioc_subfile_idx) +H5FD__ioc_calculate_target_ioc(int64_t file_offset, int64_t stripe_size, int num_io_concentrators, + int num_subfiles, int64_t *target_ioc, int64_t *ioc_file_offset, + int64_t *ioc_subfile_idx) { int64_t stripe_idx; int64_t subfile_row; int64_t subfile_idx; + FUNC_ENTER_PACKAGE_NOERR + assert(stripe_size > 0); assert(num_io_concentrators > 0); assert(num_subfiles > 0); @@ -46,24 +46,12 @@ calculate_target_ioc(int64_t file_offset, int64_t stripe_size, int num_io_concen *target_ioc = (stripe_idx % num_subfiles) % num_io_concentrators; *ioc_file_offset = (subfile_row * stripe_size) + (file_offset % stripe_size); *ioc_subfile_idx = subfile_idx; -} -/* - * Utility routine to hack around casting away const - */ -static inline void * -cast_to_void(const void *data) -{ - union { - const void *const_ptr_to_data; - void *ptr_to_data; - } eliminate_const_warning; - eliminate_const_warning.const_ptr_to_data = data; - return eliminate_const_warning.ptr_to_data; + FUNC_LEAVE_NOAPI_VOID } /*------------------------------------------------------------------------- - * Function: ioc__write_independent_async + * Function: H5FD__ioc_write_independent_async * * Purpose: The IO operations can be striped across a selection of * IO concentrators. The read and write independent calls @@ -75,24 +63,22 @@ cast_to_void(const void *data) * zero and all offsets that reside within modulo range of * the subfiling stripe_size. * - * We cycle through all 'n_io_conentrators' and send a - * descriptor to each IOC that has a non-zero sized IO - * request to fulfill. + * We cycle through all 'n_io_conentrators' and send a descriptor + * to each IOC that has a non-zero sized IO request to fulfill. * - * Sending descriptors to an IOC usually gets an ACK or - * NACK in response. For the write operations, we post - * asynch READs to receive ACKs from IOC ranks that have - * allocated memory receive the data to write to the - * subfile. Upon receiving an ACK, we send the actual - * user data to the IOC. + * Sending descriptors to an IOC usually gets an ACK or NACK in + * response. For the write operations, we post asynch READs to + * receive ACKs from IOC ranks that have allocated memory receive + * the data to write to the subfile. Upon receiving an ACK, we + * send the actual user data to the IOC. * * Return: Non-negative on success/Negative on failure * *------------------------------------------------------------------------- */ herr_t -ioc__write_independent_async(int64_t context_id, int64_t offset, int64_t elements, const void *data, - io_req_t **io_req) +H5FD__ioc_write_independent_async(int64_t context_id, int64_t offset, int64_t elements, const void *data, + io_req_t **io_req) { subfiling_context_t *sf_context = NULL; MPI_Request ack_request = MPI_REQUEST_NULL; @@ -108,10 +94,12 @@ ioc__write_independent_async(int64_t context_id, int64_t offset, int64_t element int mpi_code; herr_t ret_value = SUCCEED; + FUNC_ENTER_PACKAGE + assert(io_req); - if (NULL == (sf_context = H5_get_subfiling_object(context_id))) - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "can't get subfiling context from ID"); + if (NULL == (sf_context = H5FD__subfiling_get_object(context_id))) + HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "can't get subfiling context from ID"); assert(sf_context->topology); assert(sf_context->topology->io_concentrators); @@ -120,59 +108,51 @@ ioc__write_independent_async(int64_t context_id, int64_t offset, int64_t element num_subfiles = sf_context->sf_num_subfiles; /* - * Calculate the IOC that we'll send the I/O request to - * and the offset within that IOC's subfile + * Calculate the IOC that we'll send the I/O request to and the offset within + * that IOC's subfile */ - calculate_target_ioc(offset, sf_context->sf_stripe_size, num_io_concentrators, num_subfiles, &ioc_start, - &ioc_offset, &ioc_subfile_idx); + H5FD__ioc_calculate_target_ioc(offset, sf_context->sf_stripe_size, num_io_concentrators, num_subfiles, + &ioc_start, &ioc_offset, &ioc_subfile_idx); /* - * Wait for memory to be allocated on the target IOC before - * beginning send of user data. Once that memory has been - * allocated, we will receive an ACK (or NACK) message from - * the IOC to allow us to proceed. + * Wait for memory to be allocated on the target IOC before beginning send of + * user data. Once that memory has been allocated, we will receive an ACK (or + * NACK) message from the IOC to allow us to proceed. * - * On ACK, the IOC will send the tag to be used for sending - * data. This allows us to distinguish between multiple - * concurrent writes from a single rank. + * On ACK, the IOC will send the tag to be used for sending data. This allows + * us to distinguish between multiple concurrent writes from a single rank. * * Post an early non-blocking receive for the MPI tag here. */ if (MPI_SUCCESS != (mpi_code = MPI_Irecv(&data_tag, 1, MPI_INT, io_concentrators[ioc_start], WRITE_INDEP_ACK, sf_context->sf_data_comm, &ack_request))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Irecv failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Irecv failed", mpi_code); - /* - * Prepare and send an I/O request to the IOC identified - * by the file offset - */ + /* Prepare and send an I/O request to the IOC identified by the file offset */ msg[0] = elements; msg[1] = ioc_offset; msg[2] = ioc_subfile_idx; if (MPI_SUCCESS != (mpi_code = MPI_Send(msg, 1, H5_subfiling_rpc_msg_type, io_concentrators[ioc_start], WRITE_INDEP, sf_context->sf_msg_comm))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Send failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Send failed", mpi_code); /* Wait to receive the data tag from the IOC */ if (MPI_SUCCESS != (mpi_code = MPI_Wait(&ack_request, MPI_STATUS_IGNORE))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Wait failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Wait failed", mpi_code); if (data_tag == 0) - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "received NACK from IOC"); + HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "received NACK from IOC"); - /* - * Allocate the I/O request object that will - * be returned to the caller - */ - if (NULL == (sf_io_request = malloc(sizeof(io_req_t)))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_WRITEERROR, FAIL, "couldn't allocate I/O request"); + /* Allocate the I/O request object that will be returned to the caller */ + if (NULL == (sf_io_request = H5MM_malloc(sizeof(io_req_t)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_WRITEERROR, FAIL, "couldn't allocate I/O request"); H5_CHECK_OVERFLOW(ioc_start, int64_t, int); sf_io_request->ioc = (int)ioc_start; sf_io_request->context_id = context_id; sf_io_request->offset = offset; sf_io_request->elements = elements; - sf_io_request->data = cast_to_void(data); + sf_io_request->data = H5FD__subfiling_cast_to_void(data); sf_io_request->io_transfer_req = MPI_REQUEST_NULL; sf_io_request->io_comp_req = MPI_REQUEST_NULL; sf_io_request->io_comp_tag = -1; @@ -184,7 +164,7 @@ ioc__write_independent_async(int64_t context_id, int64_t offset, int64_t element if (MPI_SUCCESS != (mpi_code = MPI_Irecv(&sf_io_request->io_comp_tag, 1, MPI_INT, io_concentrators[ioc_start], WRITE_DATA_DONE, sf_context->sf_data_comm, &sf_io_request->io_comp_req))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Irecv failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Irecv failed", mpi_code); /* * Start the actual data transfer using the ack received @@ -194,46 +174,40 @@ ioc__write_independent_async(int64_t context_id, int64_t offset, int64_t element if (MPI_SUCCESS != (mpi_code = MPI_Isend(data, (int)elements, MPI_BYTE, io_concentrators[ioc_start], data_tag, sf_context->sf_data_comm, &sf_io_request->io_transfer_req))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Isend failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Isend failed", mpi_code); /* - * NOTE: When we actually have the async I/O support, - * the request should be queued before we return to - * the caller. Having queued the I/O operation, we - * might want to get additional work started before - * allowing the queued I/O requests to make further - * progress and/or to complete, so we just return + * NOTE: When we actually have the async I/O support, the request should be + * queued before we return to the caller. Having queued the I/O operation, we + * might want to get additional work started before allowing the queued I/O + * requests to make further progress and/or to complete, so we just return * to the caller. */ - *io_req = sf_io_request; done: if (ret_value < 0) { - if (ack_request != MPI_REQUEST_NULL) { + if (ack_request != MPI_REQUEST_NULL) if (MPI_SUCCESS != (mpi_code = MPI_Wait(&ack_request, MPI_STATUS_IGNORE))) - H5_SUBFILING_MPI_DONE_ERROR(FAIL, "MPI_Wait failed", mpi_code); - } + HMPI_DONE_ERROR(FAIL, "MPI_Wait failed", mpi_code); if (sf_io_request) { - if (sf_io_request->io_transfer_req != MPI_REQUEST_NULL) { + if (sf_io_request->io_transfer_req != MPI_REQUEST_NULL) if (MPI_SUCCESS != (mpi_code = MPI_Wait(&sf_io_request->io_transfer_req, MPI_STATUS_IGNORE))) - H5_SUBFILING_MPI_DONE_ERROR(FAIL, "MPI_Wait failed", mpi_code); - } - if (sf_io_request->io_comp_req != MPI_REQUEST_NULL) { + HMPI_DONE_ERROR(FAIL, "MPI_Wait failed", mpi_code); + if (sf_io_request->io_comp_req != MPI_REQUEST_NULL) if (MPI_SUCCESS != (mpi_code = MPI_Wait(&sf_io_request->io_comp_req, MPI_STATUS_IGNORE))) - H5_SUBFILING_MPI_DONE_ERROR(FAIL, "MPI_Wait failed", mpi_code); - } + HMPI_DONE_ERROR(FAIL, "MPI_Wait failed", mpi_code); } - free(sf_io_request); + H5MM_free(sf_io_request); *io_req = NULL; } - H5_SUBFILING_FUNC_LEAVE; -} /* end ioc__write_independent_async() */ + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5FD__ioc_write_independent_async() */ /*------------------------------------------------------------------------- - * Function: Internal ioc__read_independent_async + * Function: Internal H5FD__ioc_read_independent_async * * Purpose: The IO operations can be striped across a selection of * IO concentrators. The read and write independent calls @@ -259,8 +233,8 @@ ioc__write_independent_async(int64_t context_id, int64_t offset, int64_t element *------------------------------------------------------------------------- */ herr_t -ioc__read_independent_async(int64_t context_id, int64_t offset, int64_t elements, void *data, - io_req_t **io_req) +H5FD__ioc_read_independent_async(int64_t context_id, int64_t offset, int64_t elements, void *data, + io_req_t **io_req) { subfiling_context_t *sf_context = NULL; MPI_Request ack_request = MPI_REQUEST_NULL; @@ -277,12 +251,14 @@ ioc__read_independent_async(int64_t context_id, int64_t offset, int64_t elements int mpi_code; herr_t ret_value = SUCCEED; + FUNC_ENTER_PACKAGE + assert(io_req); H5_CHECK_OVERFLOW(elements, int64_t, int); - if (NULL == (sf_context = H5_get_subfiling_object(context_id))) - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "can't get subfiling context from ID"); + if (NULL == (sf_context = H5FD__subfiling_get_object(context_id))) + HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "can't get subfiling context from ID"); assert(sf_context->topology); assert(sf_context->topology->io_concentrators); @@ -291,35 +267,30 @@ ioc__read_independent_async(int64_t context_id, int64_t offset, int64_t elements num_subfiles = sf_context->sf_num_subfiles; /* - * If we are using 1 subfile per IOC, we can optimize reads - * a little since each read will go to a separate IOC and we - * won't be in danger of data being received in an - * unpredictable order. However, if some IOCs own more than - * 1 subfile, we need to associate each read with a unique - * message tag to make sure the data is received in the - * correct order. We also need a unique message tag in the - * case where only 1 subfile is used in total. In this case, - * vector I/O calls are passed directly down to this VFD without - * being split up into multiple I/O requests, so we need the - * tag to distinguish each I/O request. + * If we are using 1 subfile per IOC, we can optimize reads a little since + * each read will go to a separate IOC and we won't be in danger of data + * being received in an unpredictable order. However, if some IOCs own more + * than 1 subfile, we need to associate each read with a unique message tag + * to make sure the data is received in the correct order. We also need a + * unique message tag in the case where only 1 subfile is used in total. In + * this case, vector I/O calls are passed directly down to this VFD without + * being split up into multiple I/O requests, so we need the tag to + * distinguish each I/O request. */ need_data_tag = (num_subfiles == 1) || (num_subfiles != num_io_concentrators); if (!need_data_tag) data_tag = READ_INDEP_DATA; /* - * Calculate the IOC that we'll send the I/O request to - * and the offset within that IOC's subfile + * Calculate the IOC that we'll send the I/O request to and the offset within + * that IOC's subfile */ - calculate_target_ioc(offset, sf_context->sf_stripe_size, num_io_concentrators, num_subfiles, &ioc_start, - &ioc_offset, &ioc_subfile_idx); + H5FD__ioc_calculate_target_ioc(offset, sf_context->sf_stripe_size, num_io_concentrators, num_subfiles, + &ioc_start, &ioc_offset, &ioc_subfile_idx); - /* - * Allocate the I/O request object that will - * be returned to the caller - */ - if (NULL == (sf_io_request = malloc(sizeof(io_req_t)))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_READERROR, FAIL, "couldn't allocate I/O request"); + /* Allocate the I/O request object that will be returned to the caller */ + if (NULL == (sf_io_request = H5MM_malloc(sizeof(io_req_t)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_READERROR, FAIL, "couldn't allocate I/O request"); H5_CHECK_OVERFLOW(ioc_start, int64_t, int); sf_io_request->ioc = (int)ioc_start; @@ -333,82 +304,72 @@ ioc__read_independent_async(int64_t context_id, int64_t offset, int64_t elements if (need_data_tag) { /* - * Post an early non-blocking receive for IOC to send an ACK - * (or NACK) message with a data tag that we will use for - * receiving data + * Post an early non-blocking receive for IOC to send an ACK (or NACK) + * message with a data tag that we will use for receiving data */ if (MPI_SUCCESS != (mpi_code = MPI_Irecv(&data_tag, 1, MPI_INT, io_concentrators[ioc_start], READ_INDEP_ACK, sf_context->sf_data_comm, &ack_request))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Irecv failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Irecv failed", mpi_code); - /* - * Prepare and send an I/O request to the IOC identified - * by the file offset - */ + /* Prepare and send an I/O request to the IOC identified by the file offset */ msg[0] = elements; msg[1] = ioc_offset; msg[2] = ioc_subfile_idx; if (MPI_SUCCESS != (mpi_code = MPI_Send(msg, 1, H5_subfiling_rpc_msg_type, io_concentrators[ioc_start], READ_INDEP, sf_context->sf_msg_comm))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Send failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Send failed", mpi_code); /* Wait to receive the data tag from the IOC */ if (MPI_SUCCESS != (mpi_code = MPI_Wait(&ack_request, MPI_STATUS_IGNORE))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Wait failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Wait failed", mpi_code); if (data_tag == 0) - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "received NACK from IOC"); + HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "received NACK from IOC"); } /* - * Post a non-blocking receive for the data from the IOC - * using the selected data tag (either the one received - * from the IOC or the static READ_INDEP_DATA tag) + * Post a non-blocking receive for the data from the IOC using the selected + * data tag (either the one received from the IOC or the static + * READ_INDEP_DATA tag) */ if (MPI_SUCCESS != (mpi_code = MPI_Irecv(data, (int)elements, MPI_BYTE, io_concentrators[ioc_start], data_tag, sf_context->sf_data_comm, &sf_io_request->io_transfer_req))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Irecv failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Irecv failed", mpi_code); if (!need_data_tag) { - /* - * Prepare and send an I/O request to the IOC identified - * by the file offset - */ + /* Prepare and send an I/O request to the IOC identified by the file offset */ msg[0] = elements; msg[1] = ioc_offset; msg[2] = ioc_subfile_idx; if (MPI_SUCCESS != (mpi_code = MPI_Send(msg, 1, H5_subfiling_rpc_msg_type, io_concentrators[ioc_start], READ_INDEP, sf_context->sf_msg_comm))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Send failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Send failed", mpi_code); } *io_req = sf_io_request; done: if (ret_value < 0) { - if (ack_request != MPI_REQUEST_NULL) { + if (ack_request != MPI_REQUEST_NULL) if (MPI_SUCCESS != (mpi_code = MPI_Wait(&ack_request, MPI_STATUS_IGNORE))) - H5_SUBFILING_MPI_DONE_ERROR(FAIL, "MPI_Wait failed", mpi_code); - } - if (sf_io_request) { - if (sf_io_request->io_transfer_req != MPI_REQUEST_NULL) { + HMPI_DONE_ERROR(FAIL, "MPI_Wait failed", mpi_code); + if (sf_io_request) + if (sf_io_request->io_transfer_req != MPI_REQUEST_NULL) if (MPI_SUCCESS != (mpi_code = MPI_Wait(&sf_io_request->io_transfer_req, MPI_STATUS_IGNORE))) - H5_SUBFILING_MPI_DONE_ERROR(FAIL, "MPI_Wait failed", mpi_code); - } - } + HMPI_DONE_ERROR(FAIL, "MPI_Wait failed", mpi_code); - free(sf_io_request); + H5MM_free(sf_io_request); *io_req = NULL; } - H5_SUBFILING_FUNC_LEAVE; -} /* end ioc__read_independent_async() */ + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5FD__ioc_read_independent_async() */ /*------------------------------------------------------------------------- - * Function: ioc__async_completion + * Function: H5FD__ioc_async_completion * * Purpose: IOC function to complete outstanding I/O requests. * Currently just a wrapper around MPI_Waitall on the given @@ -419,11 +380,13 @@ ioc__read_independent_async(int64_t context_id, int64_t offset, int64_t elements *------------------------------------------------------------------------- */ herr_t -ioc__async_completion(MPI_Request *mpi_reqs, size_t num_reqs) +H5FD__ioc_async_completion(MPI_Request *mpi_reqs, size_t num_reqs) { herr_t ret_value = SUCCEED; int mpi_code; + FUNC_ENTER_PACKAGE + assert(mpi_reqs); H5_CHECK_OVERFLOW(num_reqs, size_t, int); @@ -433,9 +396,9 @@ ioc__async_completion(MPI_Request *mpi_reqs, size_t num_reqs) */ H5_GCC_DIAG_OFF("stringop-overflow") if (MPI_SUCCESS != (mpi_code = MPI_Waitall((int)num_reqs, mpi_reqs, MPI_STATUSES_IGNORE))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Waitall failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Waitall failed", mpi_code); H5_GCC_DIAG_ON("stringop-overflow") done: - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } diff --git a/src/H5FDsubfiling/H5FDioc_priv.h b/src/H5FDsubfiling/H5FDioc_priv.h index b7e0c7350cb..eeaeb6a955e 100644 --- a/src/H5FDsubfiling/H5FDioc_priv.h +++ b/src/H5FDsubfiling/H5FDioc_priv.h @@ -37,7 +37,6 @@ #include "H5Pprivate.h" /* Property lists */ #include "H5subfiling_common.h" -#include "H5subfiling_err.h" #include "mercury_thread.h" #include "mercury_thread_mutex.h" @@ -411,17 +410,13 @@ extern int *H5FD_IOC_tag_ub_val_ptr; extern "C" { #endif -H5_DLL int initialize_ioc_threads(void *_sf_context); -H5_DLL int finalize_ioc_threads(void *_sf_context); - -H5_DLL herr_t ioc__write_independent_async(int64_t context_id, int64_t offset, int64_t elements, - const void *data, io_req_t **io_req); -H5_DLL herr_t ioc__read_independent_async(int64_t context_id, int64_t offset, int64_t elements, void *data, - io_req_t **io_req); - -H5_DLL herr_t ioc__async_completion(MPI_Request *mpi_reqs, size_t num_reqs); - -H5_DLL int wait_for_thread_main(void); +H5_DLL herr_t H5FD__ioc_init_threads(void *_sf_context); +H5_DLL herr_t H5FD__ioc_finalize_threads(void *_sf_context); +H5_DLL herr_t H5FD__ioc_write_independent_async(int64_t context_id, int64_t offset, int64_t elements, + const void *data, io_req_t **io_req); +H5_DLL herr_t H5FD__ioc_read_independent_async(int64_t context_id, int64_t offset, int64_t elements, + void *data, io_req_t **io_req); +H5_DLL herr_t H5FD__ioc_async_completion(MPI_Request *mpi_reqs, size_t num_reqs); #ifdef __cplusplus } diff --git a/src/H5FDsubfiling/H5FDioc_threads.c b/src/H5FDsubfiling/H5FDioc_threads.c index 4358d624ed7..a8f9610f4a4 100644 --- a/src/H5FDsubfiling/H5FDioc_threads.c +++ b/src/H5FDsubfiling/H5FDioc_threads.c @@ -64,33 +64,31 @@ static int sf_read_ops = 0; static double sf_pwrite_time = 0.0; static double sf_pread_time = 0.0; static double sf_write_wait_time = 0.0; -static double sf_read_wait_time = 0.0; static double sf_queue_delay_time = 0.0; #endif /* Prototypes */ -static HG_THREAD_RETURN_TYPE ioc_thread_main(void *arg); -static int ioc_main(ioc_data_t *ioc_data); - -static int ioc_file_queue_write_indep(sf_work_request_t *msg, int ioc_idx, int source, MPI_Comm comm, - uint32_t counter); -static int ioc_file_queue_read_indep(sf_work_request_t *msg, int ioc_idx, int source, MPI_Comm comm, - uint32_t counter); - -static int ioc_file_write_data(int fd, int64_t file_offset, void *data_buffer, int64_t data_size, - int ioc_idx); -static int ioc_file_read_data(int fd, int64_t file_offset, void *data_buffer, int64_t data_size, int ioc_idx); -static int ioc_file_truncate(sf_work_request_t *msg); -static int ioc_file_report_eof(sf_work_request_t *msg, MPI_Comm comm); - -static ioc_io_queue_entry_t *ioc_io_queue_alloc_entry(void); -static void ioc_io_queue_complete_entry(ioc_data_t *ioc_data, ioc_io_queue_entry_t *entry_ptr); -static void ioc_io_queue_dispatch_eligible_entries(ioc_data_t *ioc_data, bool try_lock); -static void ioc_io_queue_free_entry(ioc_io_queue_entry_t *q_entry_ptr); -static void ioc_io_queue_add_entry(ioc_data_t *ioc_data, sf_work_request_t *wk_req_ptr); +static HG_THREAD_RETURN_TYPE H5FD__ioc_thread_main(void *arg); + +static int H5FD__ioc_file_queue_write_indep(sf_work_request_t *msg, int ioc_idx, int source, MPI_Comm comm, + uint32_t counter); +static int H5FD__ioc_file_queue_read_indep(sf_work_request_t *msg, int ioc_idx, int source, MPI_Comm comm, + uint32_t counter); + +static int H5FD__ioc_file_write_data(int fd, int64_t file_offset, void *data_buffer, int64_t data_size, + int ioc_idx); +static int H5FD__ioc_file_read_data(int fd, int64_t file_offset, void *data_buffer, int64_t data_size, + int ioc_idx); +static int H5FD__ioc_file_truncate(sf_work_request_t *msg); +static int H5FD__ioc_file_report_eof(sf_work_request_t *msg, MPI_Comm comm); + +static ioc_io_queue_entry_t *H5FD__ioc_io_queue_alloc_entry(void); +static void H5FD__ioc_io_queue_complete_entry(ioc_data_t *ioc_data, ioc_io_queue_entry_t *entry_ptr); +static void H5FD__ioc_io_queue_dispatch_eligible_entries(ioc_data_t *ioc_data, bool try_lock); +static void H5FD__ioc_io_queue_add_entry(ioc_data_t *ioc_data, sf_work_request_t *wk_req_ptr); /*------------------------------------------------------------------------- - * Function: initialize_ioc_threads + * Function: H5FD__ioc_init_threads * * Purpose: The principal entry point to initialize the execution * context for an I/O Concentrator (IOC). The main thread @@ -104,27 +102,25 @@ static void ioc_io_queue_add_entry(ioc_data_t *ioc_data, sf_work_request_t *wk_r * *------------------------------------------------------------------------- */ -int -initialize_ioc_threads(void *_sf_context) +herr_t +H5FD__ioc_init_threads(void *_sf_context) { subfiling_context_t *sf_context = _sf_context; ioc_data_t *ioc_data = NULL; unsigned thread_pool_size = H5FD_IOC_DEFAULT_THREAD_POOL_SIZE; char *env_value; - int ret_value = 0; + herr_t ret_value = SUCCEED; #ifdef H5FD_IOC_COLLECT_STATS double t_start = 0.0, t_end = 0.0; #endif + FUNC_ENTER_PACKAGE + assert(sf_context); - /* - * Allocate and initialize IOC data that will be passed - * to the IOC main thread - */ - if (NULL == (ioc_data = malloc(sizeof(*ioc_data)))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, (-1), - "can't allocate IOC data for IOC main thread"); + /* Allocate and initialize IOC data that will be passed to the IOC main thread */ + if (NULL == (ioc_data = H5MM_malloc(sizeof(*ioc_data)))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "can't allocate IOC data for IOC main thread"); ioc_data->sf_context_id = sf_context->sf_context_id; ioc_data->io_thread_pool = NULL; ioc_data->io_queue = (ioc_io_queue_t){/* magic = */ H5FD_IOC__IO_Q_MAGIC, @@ -164,28 +160,26 @@ initialize_ioc_threads(void *_sf_context) #endif if (hg_thread_mutex_init(&ioc_data->io_queue.q_mutex) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, (-1), "can't initialize IOC thread queue mutex"); + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "can't initialize IOC thread queue mutex"); /* Allow experimentation with the number of helper threads */ if ((env_value = getenv(H5FD_IOC_THREAD_POOL_SIZE)) != NULL) { int value_check = atoi(env_value); - if (value_check > 0) { + if (value_check > 0) thread_pool_size = (unsigned int)value_check; - } } /* Initialize a thread pool for the I/O concentrator's worker threads */ if (hg_thread_pool_init(thread_pool_size, &ioc_data->io_thread_pool) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, (-1), "can't initialize IOC worker thread pool"); + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "can't initialize IOC worker thread pool"); /* Create the main IOC thread that will receive and dispatch I/O requests */ - if (hg_thread_create(&ioc_data->ioc_main_thread, ioc_thread_main, ioc_data) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, (-1), "can't create IOC main thread"); + if (hg_thread_create(&ioc_data->ioc_main_thread, H5FD__ioc_thread_main, ioc_data) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "can't create IOC main thread"); - /* Wait until ioc_main() reports that it is ready */ - while (atomic_load(&ioc_data->sf_ioc_ready) != 1) { + /* Wait until H5FD__ioc_thread_main() reports that it is ready */ + while (atomic_load(&ioc_data->sf_ioc_ready) != 1) usleep(20); - } #ifdef H5FD_IOC_COLLECT_STATS t_end = MPI_Wtime(); @@ -200,15 +194,17 @@ initialize_ioc_threads(void *_sf_context) #endif done: - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } -int -finalize_ioc_threads(void *_sf_context) +herr_t +H5FD__ioc_finalize_threads(void *_sf_context) { subfiling_context_t *sf_context = _sf_context; ioc_data_t *ioc_data = NULL; - int ret_value = 0; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_PACKAGE assert(sf_context); assert(sf_context->topology->rank_is_ioc); @@ -220,7 +216,7 @@ finalize_ioc_threads(void *_sf_context) /* Shutdown the main IOC thread */ atomic_store(&ioc_data->sf_shutdown_flag, 1); - /* Allow ioc_main to exit.*/ + /* Allow H5FD__ioc_thread_main to exit.*/ do { usleep(20); } while (0 != atomic_load(&ioc_data->sf_shutdown_flag)); @@ -236,42 +232,17 @@ finalize_ioc_threads(void *_sf_context) } if (ioc_data->io_queue.num_failed > 0) - H5_SUBFILING_DONE_ERROR(H5E_IO, H5E_CLOSEERROR, -1, "%" PRId32 " I/O requests failed", - ioc_data->io_queue.num_failed); + HDONE_ERROR(H5E_VFL, H5E_CLOSEERROR, FAIL, "%" PRId32 " I/O requests failed", + ioc_data->io_queue.num_failed); - free(ioc_data); + H5MM_free(ioc_data); sf_context->ioc_data = NULL; - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /*------------------------------------------------------------------------- - * Function: ioc_thread_main - * - * Purpose: An IO Concentrator instance is initialized with the - * specified subfiling context. - * - * Return: The IO concentrator thread executes as long as the HDF5 - * file associated with this context is open. At file close, - * the thread will return from 'ioc_main' and the thread - * exit status will be checked by the main program. - * - *------------------------------------------------------------------------- - */ -static HG_THREAD_RETURN_TYPE -ioc_thread_main(void *arg) -{ - hg_thread_ret_t thread_ret = (hg_thread_ret_t)0; - ioc_data_t *ioc_data = (ioc_data_t *)arg; - - /* Pass along the ioc_data_t */ - ioc_main(ioc_data); - - return thread_ret; -} - -/*------------------------------------------------------------------------- - * Function: ioc_main + * Function: H5FD__ioc_thread_main * * Purpose: This is the principal function run by the I/O Concentrator * main thread. It remains within a loop until allowed to @@ -286,8 +257,8 @@ ioc_thread_main(void *arg) * As each incoming message is received, it gets added to * a queue for processing by a thread_pool thread. The * message handlers are dispatched via the - * "handle_work_request" routine. - + * "H5FD__ioc_handle_work_request" routine. + * * Subfiling is effectively a software RAID-0 implementation * where having multiple I/O Concentrators and independent * subfiles is equated to the multiple disks and a true @@ -328,17 +299,18 @@ ioc_thread_main(void *arg) * *------------------------------------------------------------------------- */ -static int -ioc_main(ioc_data_t *ioc_data) +static HG_THREAD_RETURN_TYPE +H5FD__ioc_thread_main(void *arg) { - subfiling_context_t *context = NULL; + ioc_data_t *ioc_data = (ioc_data_t *)arg; + subfiling_context_t *context = NULL; sf_work_request_t wk_req; int shutdown_requested; - int ret_value = 0; + hg_thread_ret_t ret_value = (hg_thread_ret_t)SUCCEED; assert(ioc_data); - context = H5_get_subfiling_object(ioc_data->sf_context_id); + context = H5FD__subfiling_get_object(ioc_data->sf_context_id); assert(context); /* We can't have opened any files at this point.. @@ -348,7 +320,7 @@ ioc_main(ioc_data_t *ioc_data) * represent an open file). */ - /* tell initialize_ioc_threads() that ioc_main() is ready to enter its main loop */ + /* tell H5FD__ioc_init_threads() that ioc_main() is ready to enter its main loop */ atomic_store(&ioc_data->sf_ioc_ready, 1); shutdown_requested = 0; @@ -362,50 +334,44 @@ ioc_main(ioc_data_t *ioc_data) /* Probe for incoming work requests */ if (MPI_SUCCESS != (mpi_code = (MPI_Iprobe(MPI_ANY_SOURCE, MPI_ANY_TAG, context->sf_msg_comm, &flag, &status)))) - H5_SUBFILING_MPI_GOTO_ERROR(-1, "MPI_Iprobe failed", mpi_code); + HGOTO_DONE((hg_thread_ret_t)FAIL); if (flag) { - double queue_start_time; - int count; - int source = status.MPI_SOURCE; - int tag = status.MPI_TAG; + int count; + int source = status.MPI_SOURCE; + int tag = status.MPI_TAG; - if ((tag != READ_INDEP) && (tag != WRITE_INDEP) && (tag != TRUNC_OP) && (tag != GET_EOF_OP)) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, -1, "invalid work request operation (%d)", - tag); + if (tag != READ_INDEP && tag != WRITE_INDEP && tag != TRUNC_OP && tag != GET_EOF_OP) + HGOTO_DONE((hg_thread_ret_t)FAIL); if (MPI_SUCCESS != (mpi_code = MPI_Get_count(&status, MPI_BYTE, &count))) - H5_SUBFILING_MPI_GOTO_ERROR(-1, "MPI_Get_count failed", mpi_code); + HGOTO_DONE((hg_thread_ret_t)FAIL); if (count < 0) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, -1, "invalid work request message size (%d)", - count); - + HGOTO_DONE((hg_thread_ret_t)FAIL); if ((size_t)count > sizeof(sf_work_request_t)) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, -1, "work request message is too large (%d)", - count); + HGOTO_DONE((hg_thread_ret_t)FAIL); /* * Zero out work request, since the received message should * be smaller than sizeof(sf_work_request_t) */ memset(&wk_req, 0, sizeof(sf_work_request_t)); - if (MPI_SUCCESS != (mpi_code = MPI_Recv(&wk_req, count, MPI_BYTE, source, tag, context->sf_msg_comm, MPI_STATUS_IGNORE))) - H5_SUBFILING_MPI_GOTO_ERROR(-1, "MPI_Recv failed", mpi_code); + HGOTO_DONE((hg_thread_ret_t)FAIL); /* Dispatch work request to worker threads in thread pool */ - queue_start_time = MPI_Wtime(); - wk_req.tag = tag; wk_req.source = source; wk_req.ioc_idx = context->topology->ioc_idx; wk_req.context_id = ioc_data->sf_context_id; - wk_req.start_time = queue_start_time; +#ifdef H5FD_IOC_COLLECT_STATS + wk_req.start_time = MPI_Wtime(); +#endif - ioc_io_queue_add_entry(ioc_data, &wk_req); + H5FD__ioc_io_queue_add_entry(ioc_data, &wk_req); assert(atomic_load(&ioc_data->sf_io_ops_pending) >= 0); } @@ -415,7 +381,7 @@ ioc_main(ioc_data_t *ioc_data) HDnanosleep(&sleep_spec, NULL); } - ioc_io_queue_dispatch_eligible_entries(ioc_data, flag ? 0 : 1); + H5FD__ioc_io_queue_dispatch_eligible_entries(ioc_data, flag ? 0 : 1); shutdown_requested = atomic_load(&ioc_data->sf_shutdown_flag); } @@ -424,8 +390,8 @@ ioc_main(ioc_data_t *ioc_data) atomic_store(&ioc_data->sf_shutdown_flag, 0); done: - H5_SUBFILING_FUNC_LEAVE; -} /* ioc_main() */ + return ret_value; +} /* H5FD__ioc_thread_main() */ #ifdef H5_SUBFILING_DEBUG static const char * @@ -463,7 +429,7 @@ translate_opcode(io_op_t op) #endif /*------------------------------------------------------------------------- - * Function: handle_work_request + * Function: H5FD__ioc_handle_work_request * * Purpose: Handle a work request from the thread pool work queue. * We dispatch the specific function as indicated by the @@ -480,7 +446,7 @@ translate_opcode(io_op_t op) *------------------------------------------------------------------------- */ static HG_THREAD_RETURN_TYPE -handle_work_request(void *arg) +H5FD__ioc_handle_work_request(void *arg) { ioc_io_queue_entry_t *q_entry_ptr = (ioc_io_queue_entry_t *)arg; subfiling_context_t *sf_context = NULL; @@ -494,7 +460,7 @@ handle_work_request(void *arg) assert(q_entry_ptr->magic == H5FD_IOC__IO_Q_ENTRY_MAGIC); assert(q_entry_ptr->in_progress); - sf_context = H5_get_subfiling_object(file_context_id); + sf_context = H5FD__subfiling_get_object(file_context_id); assert(sf_context); ioc_data = sf_context->ioc_data; @@ -504,27 +470,28 @@ handle_work_request(void *arg) switch (msg->tag) { case WRITE_INDEP: - op_ret = ioc_file_queue_write_indep(msg, msg->ioc_idx, msg->source, sf_context->sf_data_comm, - q_entry_ptr->counter); + op_ret = H5FD__ioc_file_queue_write_indep(msg, msg->ioc_idx, msg->source, + sf_context->sf_data_comm, q_entry_ptr->counter); break; case READ_INDEP: - op_ret = ioc_file_queue_read_indep(msg, msg->ioc_idx, msg->source, sf_context->sf_data_comm, - q_entry_ptr->counter); + op_ret = H5FD__ioc_file_queue_read_indep(msg, msg->ioc_idx, msg->source, sf_context->sf_data_comm, + q_entry_ptr->counter); break; case TRUNC_OP: - op_ret = ioc_file_truncate(msg); + op_ret = H5FD__ioc_file_truncate(msg); break; case GET_EOF_OP: - op_ret = ioc_file_report_eof(msg, sf_context->sf_eof_comm); + op_ret = H5FD__ioc_file_report_eof(msg, sf_context->sf_eof_comm); break; default: #ifdef H5_SUBFILING_DEBUG - H5_subfiling_log(file_context_id, "%s: IOC %d received unknown message with tag %x from rank %d", - __func__, msg->ioc_idx, msg->tag, msg->source); + H5FD__subfiling_log(file_context_id, + "%s: IOC %d received unknown message with tag %x from rank %d", __func__, + msg->ioc_idx, msg->tag, msg->source); #endif op_ret = -1; @@ -535,11 +502,11 @@ handle_work_request(void *arg) if (op_ret < 0) { #ifdef H5_SUBFILING_DEBUG - H5_subfiling_log(file_context_id, - "%s: IOC %d request(%s) from rank(%d), (%" PRId64 ", %" PRId64 ", %" PRId64 - ") FAILED with ret %d", - __func__, msg->ioc_idx, translate_opcode((io_op_t)msg->tag), msg->source, - msg->header[0], msg->header[1], msg->header[2], op_ret); + H5FD__subfiling_log(file_context_id, + "%s: IOC %d request(%s) from rank(%d), (%" PRId64 ", %" PRId64 ", %" PRId64 + ") FAILED with ret %d", + __func__, msg->ioc_idx, translate_opcode((io_op_t)msg->tag), msg->source, + msg->header[0], msg->header[1], msg->header[2], op_ret); #endif q_entry_ptr->wk_ret = op_ret; @@ -553,14 +520,14 @@ handle_work_request(void *arg) #endif /* complete the I/O request */ - ioc_io_queue_complete_entry(ioc_data, q_entry_ptr); + H5FD__ioc_io_queue_complete_entry(ioc_data, q_entry_ptr); assert(atomic_load(&ioc_data->sf_io_ops_pending) >= 0); /* Check the I/O Queue to see if there are any dispatchable entries */ - ioc_io_queue_dispatch_eligible_entries(ioc_data, 1); + H5FD__ioc_io_queue_dispatch_eligible_entries(ioc_data, 1); - H5_SUBFILING_FUNC_LEAVE; + return ret_value; } /*------------------------------------------------------------------------- @@ -595,36 +562,25 @@ H5FD_ioc_end_thread_exclusive(void) } static herr_t -send_ack_to_client(int ack_val, int dest_rank, int source_rank, int msg_tag, MPI_Comm comm) +H5FD__ioc_send_ack_to_client(int ack_val, int dest_rank, int msg_tag, MPI_Comm comm) { - int mpi_code; - herr_t ret_value = SUCCEED; - assert(ack_val > 0); - (void)source_rank; - - if (MPI_SUCCESS != (mpi_code = MPI_Send(&ack_val, 1, MPI_INT, dest_rank, msg_tag, comm))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Send", mpi_code); + if (MPI_SUCCESS != MPI_Send(&ack_val, 1, MPI_INT, dest_rank, msg_tag, comm)) + return FAIL; -done: - H5_SUBFILING_FUNC_LEAVE; + return SUCCEED; } static herr_t -send_nack_to_client(int dest_rank, int source_rank, int msg_tag, MPI_Comm comm) +H5FD__ioc_send_nack_to_client(int dest_rank, int msg_tag, MPI_Comm comm) { - int nack = 0; - int mpi_code; - herr_t ret_value = SUCCEED; - - (void)source_rank; + int nack = 0; - if (MPI_SUCCESS != (mpi_code = MPI_Send(&nack, 1, MPI_INT, dest_rank, msg_tag, comm))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Send", mpi_code); + if (MPI_SUCCESS != MPI_Send(&nack, 1, MPI_INT, dest_rank, msg_tag, comm)) + return FAIL; -done: - H5_SUBFILING_FUNC_LEAVE; + return SUCCEED; } /* @@ -635,7 +591,7 @@ from the thread pool threads... */ /*------------------------------------------------------------------------- - * Function: ioc_file_queue_write_indep + * Function: H5FD__ioc_file_queue_write_indep * * Purpose: Implement the IOC independent write function. The * function is invoked as a result of the IOC receiving the @@ -644,14 +600,15 @@ from the thread pool threads... * subfile. We utilize pwrite for the actual file writing. * File flushing is done at file close. * - * Return: The integer status returned by the Internal read_independent + * Return: The integer status returned by the internal read_independent * function. Successful operations will return 0. * Errors: An MPI related error value. * *------------------------------------------------------------------------- */ static int -ioc_file_queue_write_indep(sf_work_request_t *msg, int ioc_idx, int source, MPI_Comm comm, uint32_t counter) +H5FD__ioc_file_queue_write_indep(sf_work_request_t *msg, int ioc_idx, int source, MPI_Comm comm, + uint32_t counter) { subfiling_context_t *sf_context = NULL; MPI_Status msg_status; @@ -673,7 +630,6 @@ ioc_file_queue_write_indep(sf_work_request_t *msg, int ioc_idx, int source, MPI_ int rcv_tag; int sf_fid; int data_bytes_received; - int write_ret; int mpi_code; int ret_value = 0; @@ -688,10 +644,10 @@ ioc_file_queue_write_indep(sf_work_request_t *msg, int ioc_idx, int source, MPI_ if (data_size < 0) { send_nack = true; - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_BADVALUE, -1, "invalid data size for write"); + HGOTO_DONE(FAIL); } - sf_context = H5_get_subfiling_object(file_context_id); + sf_context = H5FD__subfiling_get_object(file_context_id); assert(sf_context); stripe_id = file_offset + data_size; @@ -711,17 +667,17 @@ ioc_file_queue_write_indep(sf_work_request_t *msg, int ioc_idx, int source, MPI_ t_queue_delay = t_start - msg->start_time; #ifdef H5_SUBFILING_DEBUG - H5_subfiling_log(file_context_id, - "[ioc(%d) %s]: msg from %d: datasize=%ld\toffset=%ld, queue_delay = %lf seconds\n", - ioc_idx, __func__, source, data_size, file_offset, t_queue_delay); + H5FD__subfiling_log(file_context_id, + "[ioc(%d) %s]: msg from %d: datasize=%ld\toffset=%ld, queue_delay = %lf seconds\n", + ioc_idx, __func__, source, data_size, file_offset, t_queue_delay); #endif #endif /* Allocate space to receive data sent from the client */ - if (NULL == (recv_buf = malloc((size_t)data_size))) { + if (NULL == (recv_buf = H5MM_malloc((size_t)data_size))) { send_nack = true; - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, -1, "couldn't allocate receive buffer for data"); + HGOTO_DONE(FAIL); } /* @@ -736,22 +692,20 @@ ioc_file_queue_write_indep(sf_work_request_t *msg, int ioc_idx, int source, MPI_ rcv_tag %= (*H5FD_IOC_tag_ub_val_ptr - IO_TAG_BASE); rcv_tag += IO_TAG_BASE; - if (send_ack_to_client(rcv_tag, source, ioc_idx, WRITE_INDEP_ACK, comm) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_WRITEERROR, -1, "couldn't send ACK to client"); + if (H5FD__ioc_send_ack_to_client(rcv_tag, source, WRITE_INDEP_ACK, comm) < 0) + HGOTO_DONE(FAIL); /* Receive data from client */ H5_CHECK_OVERFLOW(data_size, int64_t, int); if (MPI_SUCCESS != (mpi_code = MPI_Recv(recv_buf, (int)data_size, MPI_BYTE, source, rcv_tag, comm, &msg_status))) - H5_SUBFILING_MPI_GOTO_ERROR(-1, "MPI_Recv failed", mpi_code); + HGOTO_DONE(FAIL); if (MPI_SUCCESS != (mpi_code = MPI_Get_count(&msg_status, MPI_BYTE, &data_bytes_received))) - H5_SUBFILING_MPI_GOTO_ERROR(-1, "MPI_Get_count failed", mpi_code); + HGOTO_DONE(FAIL); if (data_bytes_received != data_size) - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_WRITEERROR, -1, - "message size mismatch -- expected = %" PRId64 ", actual = %d", data_size, - data_bytes_received); + HGOTO_DONE(FAIL); #ifdef H5FD_IOC_COLLECT_STATS t_end = MPI_Wtime(); @@ -761,8 +715,8 @@ ioc_file_queue_write_indep(sf_work_request_t *msg, int ioc_idx, int source, MPI_ t_start = t_end; #ifdef H5_SUBFILING_DEBUG - H5_subfiling_log(file_context_id, "[ioc(%d) %s] MPI_Recv(%ld bytes, from = %d) status = %d\n", ioc_idx, - __func__, data_size, source, mpi_code); + H5FD__subfiling_log(file_context_id, "[ioc(%d) %s] MPI_Recv(%ld bytes, from = %d) status = %d\n", ioc_idx, + __func__, data_size, source, mpi_code); #endif #endif @@ -772,16 +726,14 @@ ioc_file_queue_write_indep(sf_work_request_t *msg, int ioc_idx, int source, MPI_ #ifdef H5_SUBFILING_DEBUG if (sf_fid < 0) - H5_subfiling_log(file_context_id, "%s: WARNING: attempt to write data to closed subfile FID %d", - __func__, sf_fid); + H5FD__subfiling_log(file_context_id, "%s: WARNING: attempt to write data to closed subfile FID %d", + __func__, sf_fid); #endif if (sf_fid >= 0) { /* Actually write data received from client into subfile */ - if ((write_ret = ioc_file_write_data(sf_fid, file_offset, recv_buf, data_size, ioc_idx)) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_WRITEERROR, -1, - "write function(FID=%d, Source=%d) returned an error (%d)", sf_fid, - source, write_ret); + if (H5FD__ioc_file_write_data(sf_fid, file_offset, recv_buf, data_size, ioc_idx) < 0) + HGOTO_DONE(FAIL); #ifdef H5FD_IOC_COLLECT_STATS t_end = MPI_Wtime(); @@ -807,22 +759,21 @@ ioc_file_queue_write_indep(sf_work_request_t *msg, int ioc_idx, int source, MPI_ * completed and it is safe to return from the write call */ if (MPI_SUCCESS != (mpi_code = MPI_Send(&rcv_tag, 1, MPI_INT, source, WRITE_DATA_DONE, comm))) - H5_SUBFILING_MPI_GOTO_ERROR(-1, "MPI_Send failed", mpi_code); + HGOTO_DONE(FAIL); done: - if (send_nack) { + if (send_nack) /* Send NACK back to client so client can handle failure gracefully */ - if (send_nack_to_client(source, ioc_idx, WRITE_INDEP_ACK, comm) < 0) - H5_SUBFILING_DONE_ERROR(H5E_IO, H5E_WRITEERROR, -1, "couldn't send NACK to client"); - } + if (H5FD__ioc_send_nack_to_client(source, WRITE_INDEP_ACK, comm) < 0) + ret_value = FAIL; - free(recv_buf); + H5MM_free(recv_buf); - H5_SUBFILING_FUNC_LEAVE; -} /* ioc_file_queue_write_indep() */ + return ret_value; +} /* H5FD__ioc_file_queue_write_indep() */ /*------------------------------------------------------------------------- - * Function: ioc_file_queue_read_indep + * Function: H5FD__ioc_file_queue_read_indep * * Purpose: Implement the IOC independent read function. The * function is invoked as a result of the IOC receiving the @@ -837,7 +788,8 @@ ioc_file_queue_write_indep(sf_work_request_t *msg, int ioc_idx, int source, MPI_ *------------------------------------------------------------------------- */ static int -ioc_file_queue_read_indep(sf_work_request_t *msg, int ioc_idx, int source, MPI_Comm comm, uint32_t counter) +H5FD__ioc_file_queue_read_indep(sf_work_request_t *msg, int ioc_idx, int source, MPI_Comm comm, + uint32_t counter) { subfiling_context_t *sf_context = NULL; bool send_empty_buf = true; @@ -856,29 +808,25 @@ ioc_file_queue_read_indep(sf_work_request_t *msg, int ioc_idx, int source, MPI_C char *send_buf = NULL; int send_tag; int sf_fid; - int read_ret; - int mpi_code; int ret_value = 0; assert(msg); file_context_id = msg->context_id; - sf_context = H5_get_subfiling_object(file_context_id); + sf_context = H5FD__subfiling_get_object(file_context_id); assert(sf_context); /* - * If we are using 1 subfile per IOC, we can optimize reads - * a little since each read will go to a separate IOC and we - * won't be in danger of data being received in an - * unpredictable order. However, if some IOCs own more than - * 1 subfile, we need to associate each read with a unique - * message tag to make sure the data is received in the - * correct order. We also need a unique message tag in the - * case where only 1 subfile is used in total. In this case, - * vector I/O calls are passed directly down to this VFD without - * being split up into multiple I/O requests, so we need the - * tag to distinguish each I/O request. + * If we are using 1 subfile per IOC, we can optimize reads a little since + * each read will go to a separate IOC and we won't be in danger of data + * being received in an unpredictable order. However, if some IOCs own more + * than 1 subfile, we need to associate each read with a unique message tag + * to make sure the data is received in the correct order. We also need a + * unique message tag in the case where only 1 subfile is used in total. In + * this case, vector I/O calls are passed directly down to this VFD without + * being split up into multiple I/O requests, so we need the tag to + * distinguish each I/O request. */ need_data_tag = (sf_context->sf_num_subfiles == 1) || (sf_context->sf_num_subfiles != sf_context->topology->n_io_concentrators); @@ -895,7 +843,7 @@ ioc_file_queue_read_indep(sf_work_request_t *msg, int ioc_idx, int source, MPI_C send_nack = true; send_empty_buf = false; } - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_BADVALUE, -1, "invalid data size for read"); + HGOTO_DONE(FAIL); } /* Flag that we've attempted to read data from the file */ @@ -909,20 +857,20 @@ ioc_file_queue_read_indep(sf_work_request_t *msg, int ioc_idx, int source, MPI_C t_queue_delay = t_start - msg->start_time; #ifdef H5_SUBFILING_DEBUG - H5_subfiling_log(file_context_id, - "[ioc(%d) %s] msg from %d: datasize=%ld\toffset=%ld queue_delay=%lf seconds\n", ioc_idx, - __func__, source, data_size, file_offset, t_queue_delay); + H5FD__subfiling_log(file_context_id, + "[ioc(%d) %s] msg from %d: datasize=%ld\toffset=%ld queue_delay=%lf seconds\n", + ioc_idx, __func__, source, data_size, file_offset, t_queue_delay); #endif #endif /* Allocate space to send data read from file to client */ - if (NULL == (send_buf = malloc((size_t)data_size))) { + if (NULL == (send_buf = H5MM_malloc((size_t)data_size))) { if (need_data_tag) { send_nack = true; send_empty_buf = false; } - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, -1, "couldn't allocate send buffer for data"); + HGOTO_DONE(FAIL); } if (need_data_tag) { @@ -939,9 +887,9 @@ ioc_file_queue_read_indep(sf_work_request_t *msg, int ioc_idx, int source, MPI_C send_tag %= (*H5FD_IOC_tag_ub_val_ptr - IO_TAG_BASE); send_tag += IO_TAG_BASE; - if (send_ack_to_client(send_tag, source, ioc_idx, READ_INDEP_ACK, comm) < 0) { + if (H5FD__ioc_send_ack_to_client(send_tag, source, READ_INDEP_ACK, comm) < 0) { send_empty_buf = false; - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_READERROR, -1, "couldn't send ACK to client"); + HGOTO_DONE(FAIL); } } @@ -949,20 +897,17 @@ ioc_file_queue_read_indep(sf_work_request_t *msg, int ioc_idx, int source, MPI_C assert(subfile_idx < sf_context->sf_num_fids); sf_fid = sf_context->sf_fids[subfile_idx]; if (sf_fid < 0) - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_BADVALUE, -1, "subfile file descriptor %d is invalid", sf_fid); + HGOTO_DONE(FAIL); - if ((read_ret = ioc_file_read_data(sf_fid, file_offset, send_buf, data_size, ioc_idx)) < 0) { - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_READERROR, read_ret, - "read function(FID=%d, Source=%d) returned an error (%d)", sf_fid, source, - read_ret); - } + if (H5FD__ioc_file_read_data(sf_fid, file_offset, send_buf, data_size, ioc_idx) < 0) + HGOTO_DONE(FAIL); send_empty_buf = false; /* Send read data to the client */ H5_CHECK_OVERFLOW(data_size, int64_t, int); - if (MPI_SUCCESS != (mpi_code = MPI_Send(send_buf, (int)data_size, MPI_BYTE, source, send_tag, comm))) - H5_SUBFILING_MPI_GOTO_ERROR(-1, "MPI_Send failed", mpi_code); + if (MPI_SUCCESS != MPI_Send(send_buf, (int)data_size, MPI_BYTE, source, send_tag, comm)) + HGOTO_DONE(FAIL); #ifdef H5FD_IOC_COLLECT_STATS t_end = MPI_Wtime(); @@ -971,31 +916,29 @@ ioc_file_queue_read_indep(sf_work_request_t *msg, int ioc_idx, int source, MPI_C sf_queue_delay_time += t_queue_delay; #ifdef H5_SUBFILING_DEBUG - H5_subfiling_log(sf_context->sf_context_id, "[ioc(%d)] MPI_Send to source(%d) completed\n", ioc_idx, - source); + H5FD__subfiling_log(sf_context->sf_context_id, "[ioc(%d)] MPI_Send to source(%d) completed\n", ioc_idx, + source); #endif #endif done: - if (need_data_tag && send_nack) { + if (need_data_tag && send_nack) /* Send NACK back to client so client can handle failure gracefully */ - if (send_nack_to_client(source, ioc_idx, READ_INDEP_ACK, comm) < 0) - H5_SUBFILING_DONE_ERROR(H5E_IO, H5E_READERROR, -1, "couldn't send NACK to client"); - } - if (send_empty_buf) { + if (H5FD__ioc_send_nack_to_client(source, READ_INDEP_ACK, comm) < 0) + ret_value = FAIL; + if (send_empty_buf) /* * Send an empty message back to client on failure. The client will * likely get a message truncation error, but at least shouldn't hang. */ - if (MPI_SUCCESS != (mpi_code = MPI_Send(NULL, 0, MPI_BYTE, source, send_tag, comm))) - H5_SUBFILING_MPI_DONE_ERROR(-1, "MPI_Send failed", mpi_code); - } + if (MPI_SUCCESS != MPI_Send(NULL, 0, MPI_BYTE, source, send_tag, comm)) + ret_value = FAIL; - free(send_buf); + H5MM_free(send_buf); return ret_value; -} /* end ioc_file_queue_read_indep() */ +} /* end H5FD__ioc_file_queue_read_indep() */ /* ====================================================== @@ -1007,7 +950,7 @@ being thread safe. */ static int -ioc_file_write_data(int fd, int64_t file_offset, void *data_buffer, int64_t data_size, int ioc_idx) +H5FD__ioc_file_write_data(int fd, int64_t file_offset, void *data_buffer, int64_t data_size, int ioc_idx) { ssize_t bytes_remaining = (ssize_t)data_size; ssize_t bytes_written = 0; @@ -1036,9 +979,8 @@ ioc_file_write_data(int fd, int64_t file_offset, void *data_buffer, int64_t data this_data += bytes_written; file_offset += bytes_written; } - else { - H5_SUBFILING_SYS_GOTO_ERROR(H5E_IO, H5E_WRITEERROR, -1, "HDpwrite failed"); - } + else + HGOTO_DONE(FAIL); } /* We don't usually use this for each file write. We usually do the file @@ -1049,11 +991,11 @@ ioc_file_write_data(int fd, int64_t file_offset, void *data_buffer, int64_t data #endif done: - H5_SUBFILING_FUNC_LEAVE; -} /* end ioc_file_write_data() */ + return ret_value; +} /* end H5FD__ioc_file_write_data() */ static int -ioc_file_read_data(int fd, int64_t file_offset, void *data_buffer, int64_t data_size, int ioc_idx) +H5FD__ioc_file_read_data(int fd, int64_t file_offset, void *data_buffer, int64_t data_size, int ioc_idx) { useconds_t delay = 100; ssize_t bytes_remaining = (ssize_t)data_size; @@ -1098,11 +1040,11 @@ ioc_file_read_data(int fd, int64_t file_offset, void *data_buffer, int64_t data_ else { if (retries == 0) { #ifdef H5FD_IOC_DEBUG - printf("[ioc(%d) %s]: TIMEOUT: file_offset=%" PRId64 ", data_size=%ld\n", ioc_idx, __func__, - file_offset, data_size); + printf("[ioc(%d) %s]: TIMEOUT: file_offset=%" PRId64 ", data_size=%" PRId64 "\n", ioc_idx, + __func__, file_offset, data_size); #endif - H5_SUBFILING_SYS_GOTO_ERROR(H5E_IO, H5E_READERROR, -1, "HDpread failed"); + HGOTO_DONE(FAIL); } retries--; @@ -1112,11 +1054,11 @@ ioc_file_read_data(int fd, int64_t file_offset, void *data_buffer, int64_t data_ } done: - H5_SUBFILING_FUNC_LEAVE; -} /* end ioc_file_read_data() */ + return ret_value; +} /* end H5FD__ioc_file_read_data() */ static int -ioc_file_truncate(sf_work_request_t *msg) +H5FD__ioc_file_truncate(sf_work_request_t *msg) { subfiling_context_t *sf_context = NULL; int64_t file_context_id; @@ -1124,7 +1066,6 @@ ioc_file_truncate(sf_work_request_t *msg) int64_t subfile_idx; int fd; int ioc_idx; - int mpi_code; int ret_value = 0; assert(msg); @@ -1139,23 +1080,23 @@ ioc_file_truncate(sf_work_request_t *msg) (void)ioc_idx; #endif - if (NULL == (sf_context = H5_get_subfiling_object(file_context_id))) - H5_SUBFILING_GOTO_ERROR(H5E_FILE, H5E_CANTGET, -1, "couldn't retrieve subfiling context"); + if (NULL == (sf_context = H5FD__subfiling_get_object(file_context_id))) + HGOTO_DONE(FAIL); assert(subfile_idx < sf_context->sf_num_fids); fd = sf_context->sf_fids[subfile_idx]; - if (HDftruncate(fd, (off_t)length) != 0) - H5_SUBFILING_SYS_GOTO_ERROR(H5E_FILE, H5E_SEEKERROR, -1, "HDftruncate failed"); + if (HDftruncate(fd, (HDoff_t)length) != 0) + HGOTO_DONE(FAIL); /* * Send a completion message back to the source that * requested the truncation operation */ - if (MPI_SUCCESS != (mpi_code = MPI_Send(msg->header, 1, H5_subfiling_rpc_msg_type, msg->source, - TRUNC_COMPLETED, sf_context->sf_eof_comm))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Send failed", mpi_code); + if (MPI_SUCCESS != MPI_Send(msg->header, 1, H5_subfiling_rpc_msg_type, msg->source, TRUNC_COMPLETED, + sf_context->sf_eof_comm)) + HGOTO_DONE(FAIL); #ifdef H5FD_IOC_DEBUG printf("[ioc(%d) %s]: truncated subfile to %lld bytes. ret = %d\n", ioc_idx, __func__, (long long)length, @@ -1164,11 +1105,11 @@ ioc_file_truncate(sf_work_request_t *msg) #endif done: - H5_SUBFILING_FUNC_LEAVE; -} /* end ioc_file_truncate() */ + return ret_value; +} /* end H5FD__ioc_file_truncate() */ /*------------------------------------------------------------------------- - * Function: ioc_file_report_eof + * Function: H5FD__ioc_file_report_eof * * Purpose: Determine the target subfile's eof and report this value * to the requesting rank. @@ -1183,9 +1124,8 @@ ioc_file_truncate(sf_work_request_t *msg) * *------------------------------------------------------------------------- */ - static int -ioc_file_report_eof(sf_work_request_t *msg, MPI_Comm comm) +H5FD__ioc_file_report_eof(sf_work_request_t *msg, MPI_Comm comm) { subfiling_context_t *sf_context = NULL; h5_stat_t sb; @@ -1195,7 +1135,6 @@ ioc_file_report_eof(sf_work_request_t *msg, MPI_Comm comm) int fd; int source; int ioc_idx; - int mpi_code; int ret_value = 0; assert(msg); @@ -1206,8 +1145,8 @@ ioc_file_report_eof(sf_work_request_t *msg, MPI_Comm comm) subfile_idx = msg->header[0]; - if (NULL == (sf_context = H5_get_subfiling_object(file_context_id))) - H5_SUBFILING_GOTO_ERROR(H5E_FILE, H5E_CANTGET, -1, "couldn't retrieve subfiling context"); + if (NULL == (sf_context = H5FD__subfiling_get_object(file_context_id))) + HGOTO_DONE(FAIL); assert(subfile_idx < sf_context->sf_num_fids); @@ -1215,27 +1154,27 @@ ioc_file_report_eof(sf_work_request_t *msg, MPI_Comm comm) memset(&sb, 0, sizeof(h5_stat_t)); if (HDfstat(fd, &sb) < 0) - H5_SUBFILING_SYS_GOTO_ERROR(H5E_FILE, H5E_SYSERRSTR, -1, "HDfstat failed"); + HGOTO_DONE(FAIL); eof_req_reply[0] = (int64_t)ioc_idx; eof_req_reply[1] = (int64_t)(sb.st_size); eof_req_reply[2] = subfile_idx; #ifdef H5_SUBFILING_DEBUG - H5_subfiling_log(file_context_id, "%s: reporting file EOF as %" PRId64 ".", __func__, eof_req_reply[1]); + H5FD__subfiling_log(file_context_id, "%s: reporting file EOF as %" PRId64 ".", __func__, + eof_req_reply[1]); #endif /* return the subfile EOF to the querying rank */ - if (MPI_SUCCESS != - (mpi_code = MPI_Send(eof_req_reply, 1, H5_subfiling_rpc_msg_type, source, GET_EOF_COMPLETED, comm))) - H5_SUBFILING_MPI_GOTO_ERROR(-1, "MPI_Send", mpi_code); + if (MPI_SUCCESS != MPI_Send(eof_req_reply, 1, H5_subfiling_rpc_msg_type, source, GET_EOF_COMPLETED, comm)) + HGOTO_DONE(FAIL); done: - H5_SUBFILING_FUNC_LEAVE; -} /* ioc_file_report_eof() */ + return ret_value; +} /* H5FD__ioc_file_report_eof() */ /*------------------------------------------------------------------------- - * Function: ioc_io_queue_alloc_entry + * Function: H5FD__ioc_io_queue_alloc_entry * * Purpose: Allocate and initialize an instance of * ioc_io_queue_entry_t. Return pointer to the new @@ -1247,36 +1186,19 @@ ioc_file_report_eof(sf_work_request_t *msg, MPI_Comm comm) *------------------------------------------------------------------------- */ static ioc_io_queue_entry_t * -ioc_io_queue_alloc_entry(void) +H5FD__ioc_io_queue_alloc_entry(void) { ioc_io_queue_entry_t *q_entry_ptr = NULL; - q_entry_ptr = (ioc_io_queue_entry_t *)malloc(sizeof(ioc_io_queue_entry_t)); - - if (q_entry_ptr) { - - q_entry_ptr->magic = H5FD_IOC__IO_Q_ENTRY_MAGIC; - q_entry_ptr->next = NULL; - q_entry_ptr->prev = NULL; - q_entry_ptr->in_progress = false; - q_entry_ptr->counter = 0; - - /* will memcpy the wk_req field, so don't bother to initialize */ - /* will initialize thread_wk field before use */ - - q_entry_ptr->wk_ret = 0; - -#ifdef H5FD_IOC_COLLECT_STATS - q_entry_ptr->q_time = 0; - q_entry_ptr->dispatch_time = 0; -#endif - } + q_entry_ptr = (ioc_io_queue_entry_t *)H5MM_calloc(sizeof(ioc_io_queue_entry_t)); + if (q_entry_ptr) + q_entry_ptr->magic = H5FD_IOC__IO_Q_ENTRY_MAGIC; return q_entry_ptr; -} /* ioc_io_queue_alloc_entry() */ +} /* H5FD__ioc_io_queue_alloc_entry() */ /*------------------------------------------------------------------------- - * Function: ioc_io_queue_add_entry + * Function: H5FD__ioc_io_queue_add_entry * * Purpose: Add an I/O request to the tail of the IOC I/O Queue. * @@ -1291,14 +1213,14 @@ ioc_io_queue_alloc_entry(void) * * Note that this does not dispatch the request even if it * is eligible for immediate dispatch. This is done with - * a call to ioc_io_queue_dispatch_eligible_entries(). + * a call to H5FD__ioc_io_queue_dispatch_eligible_entries(). * * Return: void. * *------------------------------------------------------------------------- */ static void -ioc_io_queue_add_entry(ioc_data_t *ioc_data, sf_work_request_t *wk_req_ptr) +H5FD__ioc_io_queue_add_entry(ioc_data_t *ioc_data, sf_work_request_t *wk_req_ptr) { ioc_io_queue_entry_t *entry_ptr = NULL; @@ -1306,7 +1228,7 @@ ioc_io_queue_add_entry(ioc_data_t *ioc_data, sf_work_request_t *wk_req_ptr) assert(ioc_data->io_queue.magic == H5FD_IOC__IO_Q_MAGIC); assert(wk_req_ptr); - entry_ptr = ioc_io_queue_alloc_entry(); + entry_ptr = H5FD__ioc_io_queue_alloc_entry(); assert(entry_ptr); assert(entry_ptr->magic == H5FD_IOC__IO_Q_ENTRY_MAGIC); @@ -1327,7 +1249,7 @@ ioc_io_queue_add_entry(ioc_data_t *ioc_data, sf_work_request_t *wk_req_ptr) atomic_fetch_add(&ioc_data->sf_io_ops_pending, 1); #ifdef H5_SUBFILING_DEBUG - H5_subfiling_log( + H5FD__subfiling_log( wk_req_ptr->context_id, "%s: request %d queued. op = %d, req = (%lld, %lld, %lld), q-ed/disp/ops_pend = %d/%d/%d.", __func__, entry_ptr->counter, (entry_ptr->wk_req.tag), (long long)(entry_ptr->wk_req.header[0]), @@ -1341,33 +1263,27 @@ ioc_io_queue_add_entry(ioc_data_t *ioc_data, sf_work_request_t *wk_req_ptr) #ifdef H5FD_IOC_COLLECT_STATS entry_ptr->q_time = H5_now_usec(); - if (ioc_data->io_queue.q_len > ioc_data->io_queue.max_q_len) { + if (ioc_data->io_queue.q_len > ioc_data->io_queue.max_q_len) ioc_data->io_queue.max_q_len = ioc_data->io_queue.q_len; - } - if (ioc_data->io_queue.num_pending > ioc_data->io_queue.max_num_pending) { + if (ioc_data->io_queue.num_pending > ioc_data->io_queue.max_num_pending) ioc_data->io_queue.max_num_pending = ioc_data->io_queue.num_pending; - } - if (entry_ptr->wk_req.tag == READ_INDEP) { + if (entry_ptr->wk_req.tag == READ_INDEP) ioc_data->io_queue.ind_read_requests++; - } - else if (entry_ptr->wk_req.tag == WRITE_INDEP) { + else if (entry_ptr->wk_req.tag == WRITE_INDEP) ioc_data->io_queue.ind_write_requests++; - } - else if (entry_ptr->wk_req.tag == TRUNC_OP) { + else if (entry_ptr->wk_req.tag == TRUNC_OP) ioc_data->io_queue.truncate_requests++; - } - else if (entry_ptr->wk_req.tag == GET_EOF_OP) { + else if (entry_ptr->wk_req.tag == GET_EOF_OP) ioc_data->io_queue.get_eof_requests++; - } ioc_data->io_queue.requests_queued++; #endif #ifdef H5_SUBFILING_DEBUG if (ioc_data->io_queue.q_len != atomic_load(&ioc_data->sf_io_ops_pending)) { - H5_subfiling_log( + H5FD__subfiling_log( wk_req_ptr->context_id, "%s: ioc_data->io_queue->q_len = %d != %d = atomic_load(&ioc_data->sf_io_ops_pending).", __func__, ioc_data->io_queue.q_len, atomic_load(&ioc_data->sf_io_ops_pending)); @@ -1379,10 +1295,10 @@ ioc_io_queue_add_entry(ioc_data_t *ioc_data, sf_work_request_t *wk_req_ptr) hg_thread_mutex_unlock(&ioc_data->io_queue.q_mutex); return; -} /* ioc_io_queue_add_entry() */ +} /* H5FD__ioc_io_queue_add_entry() */ /*------------------------------------------------------------------------- - * Function: ioc_io_queue_dispatch_eligible_entries + * Function: H5FD__ioc_io_queue_dispatch_eligible_entries * * Purpose: Scan the IOC I/O Queue for dispatchable entries, and * dispatch any such entries found. @@ -1421,7 +1337,7 @@ ioc_io_queue_add_entry(ioc_data_t *ioc_data, sf_work_request_t *wk_req_ptr) * can become O(N**2) in the worst case. */ static void -ioc_io_queue_dispatch_eligible_entries(ioc_data_t *ioc_data, bool try_lock) +H5FD__ioc_io_queue_dispatch_eligible_entries(ioc_data_t *ioc_data, bool try_lock) { bool conflict_detected; int64_t entry_offset; @@ -1445,24 +1361,18 @@ ioc_io_queue_dispatch_eligible_entries(ioc_data_t *ioc_data, bool try_lock) /* sanity check on first element in the I/O queue */ assert((entry_ptr == NULL) || (entry_ptr->prev == NULL)); - - while ((entry_ptr) && (ioc_data->io_queue.num_pending > 0)) { - + while (entry_ptr && ioc_data->io_queue.num_pending > 0) { assert(entry_ptr->magic == H5FD_IOC__IO_Q_ENTRY_MAGIC); /* Check for a get EOF or truncate operation at head of queue */ - if (ioc_data->io_queue.q_head->in_progress) { - if ((ioc_data->io_queue.q_head->wk_req.tag == TRUNC_OP) || - (ioc_data->io_queue.q_head->wk_req.tag == GET_EOF_OP)) { - - /* we have a truncate or get eof operation in progress -- thus no other operations - * can be dispatched until the truncate or get eof operation completes. Just break - * out of the loop. - */ - + if (ioc_data->io_queue.q_head->in_progress) + /* We have a truncate or get eof operation in progress -- thus no other operations + * can be dispatched until the truncate or get eof operation completes. Just break + * out of the loop. + */ + if (ioc_data->io_queue.q_head->wk_req.tag == TRUNC_OP || + ioc_data->io_queue.q_head->wk_req.tag == GET_EOF_OP) break; - } - } if (!entry_ptr->in_progress) { @@ -1473,46 +1383,30 @@ ioc_io_queue_dispatch_eligible_entries(ioc_data_t *ioc_data, bool try_lock) scan_ptr = entry_ptr->prev; - assert((scan_ptr == NULL) || (scan_ptr->magic == H5FD_IOC__IO_Q_ENTRY_MAGIC)); - - if ((entry_ptr->wk_req.tag == TRUNC_OP) || (entry_ptr->wk_req.tag == GET_EOF_OP)) { - - if (scan_ptr != NULL) { - - /* the TRUNC_OP or GET_EOF_OP is not at the head of the queue, and thus cannot - * be dispatched. Further, no operation can be dispatched if a truncate request - * appears before it in the queue. Thus we have done all we can and will break - * out of the loop. - */ + assert(scan_ptr == NULL || scan_ptr->magic == H5FD_IOC__IO_Q_ENTRY_MAGIC); + if (entry_ptr->wk_req.tag == TRUNC_OP || entry_ptr->wk_req.tag == GET_EOF_OP) + /* the TRUNC_OP or GET_EOF_OP is not at the head of the queue, and thus cannot + * be dispatched. Further, no operation can be dispatched if a truncate request + * appears before it in the queue. Thus we have done all we can and will break + * out of the loop. + */ + if (scan_ptr != NULL) break; - } - } - - while ((scan_ptr) && (!conflict_detected)) { + while (scan_ptr && !conflict_detected) { /* check for overlaps */ scan_offset = scan_ptr->wk_req.header[1]; scan_len = scan_ptr->wk_req.header[0]; - /* at present, I/O requests are scalar -- i.e. single blocks specified by offset and length. - * when this changes, this if statement will have to be updated accordingly. - */ - if (((scan_offset + scan_len) > entry_offset) && ((entry_offset + entry_len) > scan_offset)) { - + if ((scan_offset + scan_len) > entry_offset && (entry_offset + entry_len) > scan_offset) /* the two request overlap -- unless they are both reads, we have detected a conflict */ - - /* TODO: update this if statement when we add collective I/O */ - if ((entry_ptr->wk_req.tag != READ_INDEP) || (scan_ptr->wk_req.tag != READ_INDEP)) { - + if (entry_ptr->wk_req.tag != READ_INDEP || scan_ptr->wk_req.tag != READ_INDEP) conflict_detected = true; - } - } scan_ptr = scan_ptr->prev; } if (!conflict_detected) { /* dispatch I/O request */ - assert(scan_ptr == NULL); assert(!entry_ptr->in_progress); @@ -1526,11 +1420,11 @@ ioc_io_queue_dispatch_eligible_entries(ioc_data_t *ioc_data, bool try_lock) assert(ioc_data->io_queue.num_pending + ioc_data->io_queue.num_in_progress == ioc_data->io_queue.q_len); - entry_ptr->thread_wk.func = handle_work_request; + entry_ptr->thread_wk.func = H5FD__ioc_handle_work_request; entry_ptr->thread_wk.args = entry_ptr; #ifdef H5_SUBFILING_DEBUG - H5_subfiling_log( + H5FD__subfiling_log( entry_ptr->wk_req.context_id, "%s: request %d dispatched. op = %d, req = (%lld, %lld, %lld), " "q-ed/disp/ops_pend = %d/%d/%d.", @@ -1541,9 +1435,8 @@ ioc_io_queue_dispatch_eligible_entries(ioc_data_t *ioc_data, bool try_lock) #endif #ifdef H5FD_IOC_COLLECT_STATS - if (ioc_data->io_queue.num_in_progress > ioc_data->io_queue.max_num_in_progress) { + if (ioc_data->io_queue.num_in_progress > ioc_data->io_queue.max_num_in_progress) ioc_data->io_queue.max_num_in_progress = ioc_data->io_queue.num_in_progress; - } ioc_data->io_queue.requests_dispatched++; @@ -1560,10 +1453,10 @@ ioc_io_queue_dispatch_eligible_entries(ioc_data_t *ioc_data, bool try_lock) assert(ioc_data->io_queue.q_len == atomic_load(&ioc_data->sf_io_ops_pending)); hg_thread_mutex_unlock(&ioc_data->io_queue.q_mutex); -} /* ioc_io_queue_dispatch_eligible_entries() */ +} /* H5FD__ioc_io_queue_dispatch_eligible_entries() */ /*------------------------------------------------------------------------- - * Function: ioc_io_queue_complete_entry + * Function: H5FD__ioc_io_queue_complete_entry * * Purpose: Update the IOC I/O Queue for the completion of an I/O * request. @@ -1581,13 +1474,8 @@ ioc_io_queue_dispatch_eligible_entries(ioc_data_t *ioc_data, bool try_lock) *------------------------------------------------------------------------- */ static void -ioc_io_queue_complete_entry(ioc_data_t *ioc_data, ioc_io_queue_entry_t *entry_ptr) +H5FD__ioc_io_queue_complete_entry(ioc_data_t *ioc_data, ioc_io_queue_entry_t *entry_ptr) { -#ifdef H5FD_IOC_COLLECT_STATS - uint64_t queued_time; - uint64_t execution_time; -#endif - assert(ioc_data); assert(ioc_data->io_queue.magic == H5FD_IOC__IO_Q_MAGIC); assert(entry_ptr); @@ -1611,13 +1499,13 @@ ioc_io_queue_complete_entry(ioc_data_t *ioc_data, ioc_io_queue_entry_t *entry_pt atomic_fetch_sub(&ioc_data->sf_io_ops_pending, 1); #ifdef H5_SUBFILING_DEBUG - H5_subfiling_log(entry_ptr->wk_req.context_id, - "%s: request %d completed with ret %d. op = %d, req = (%lld, %lld, %lld), " - "q-ed/disp/ops_pend = %d/%d/%d.", - __func__, entry_ptr->counter, entry_ptr->wk_ret, (entry_ptr->wk_req.tag), - (long long)(entry_ptr->wk_req.header[0]), (long long)(entry_ptr->wk_req.header[1]), - (long long)(entry_ptr->wk_req.header[2]), ioc_data->io_queue.num_pending, - ioc_data->io_queue.num_in_progress, atomic_load(&ioc_data->sf_io_ops_pending)); + H5FD__subfiling_log(entry_ptr->wk_req.context_id, + "%s: request %d completed with ret %d. op = %d, req = (%lld, %lld, %lld), " + "q-ed/disp/ops_pend = %d/%d/%d.", + __func__, entry_ptr->counter, entry_ptr->wk_ret, (entry_ptr->wk_req.tag), + (long long)(entry_ptr->wk_req.header[0]), (long long)(entry_ptr->wk_req.header[1]), + (long long)(entry_ptr->wk_req.header[2]), ioc_data->io_queue.num_pending, + ioc_data->io_queue.num_in_progress, atomic_load(&ioc_data->sf_io_ops_pending)); /* * If this I/O request is a truncate or "get eof" op, make sure @@ -1630,52 +1518,14 @@ ioc_io_queue_complete_entry(ioc_data_t *ioc_data, ioc_io_queue_entry_t *entry_pt assert(ioc_data->io_queue.q_len == atomic_load(&ioc_data->sf_io_ops_pending)); #ifdef H5FD_IOC_COLLECT_STATS - /* Compute the queued and execution time */ - queued_time = entry_ptr->dispatch_time - entry_ptr->q_time; - execution_time = H5_now_usec() - entry_ptr->dispatch_time; - ioc_data->io_queue.requests_completed++; entry_ptr->q_time = H5_now_usec(); - #endif hg_thread_mutex_unlock(&ioc_data->io_queue.q_mutex); - ioc_io_queue_free_entry(entry_ptr); - - entry_ptr = NULL; - - return; -} /* ioc_io_queue_complete_entry() */ - -/*------------------------------------------------------------------------- - * Function: ioc_io_queue_free_entry - * - * Purpose: Free the supplied instance of ioc_io_queue_entry_t. - * - * Verify that magic field is set to - * H5FD_IOC__IO_Q_ENTRY_MAGIC, and that the next and prev - * fields are NULL. - * - * Return: void. - * - *------------------------------------------------------------------------- - */ -static void -ioc_io_queue_free_entry(ioc_io_queue_entry_t *q_entry_ptr) -{ - /* use assertions for error checking, since the following should never fail. */ - assert(q_entry_ptr); - assert(q_entry_ptr->magic == H5FD_IOC__IO_Q_ENTRY_MAGIC); - assert(q_entry_ptr->next == NULL); - assert(q_entry_ptr->prev == NULL); - - q_entry_ptr->magic = 0; - - free(q_entry_ptr); - - q_entry_ptr = NULL; + H5MM_free(entry_ptr); return; -} /* H5FD_ioc__free_c_io_q_entry() */ +} /* H5FD__ioc_io_queue_complete_entry() */ diff --git a/src/H5FDsubfiling/H5FDsubfile_int.c b/src/H5FDsubfiling/H5FDsubfile_int.c index a7dd86455cb..bf01fc0a2e4 100644 --- a/src/H5FDsubfiling/H5FDsubfile_int.c +++ b/src/H5FDsubfiling/H5FDsubfile_int.c @@ -73,16 +73,18 @@ H5FD__subfiling__truncate_sub_files(hid_t context_id, int64_t logical_file_eof, int mpi_code; herr_t ret_value = SUCCEED; + FUNC_ENTER_PACKAGE + if (MPI_SUCCESS != (mpi_code = MPI_Comm_size(comm, &mpi_size))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Comm_size failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Comm_size failed", mpi_code); /* Barrier on entry */ if (mpi_size > 1) if (MPI_SUCCESS != (mpi_code = MPI_Barrier(comm))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Barrier failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Barrier failed", mpi_code); - if (NULL == (sf_context = (subfiling_context_t *)H5_get_subfiling_object(context_id))) - H5_SUBFILING_GOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "can't get subfile context"); + if (NULL == (sf_context = H5FD__subfiling_get_object(context_id))) + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "can't get subfile context"); if (sf_context->topology->rank_is_ioc) { int64_t num_full_stripes; @@ -96,24 +98,22 @@ H5FD__subfiling__truncate_sub_files(hid_t context_id, int64_t logical_file_eof, num_subfiles_owned = sf_context->sf_num_fids; - if (NULL == (recv_reqs = malloc((size_t)num_subfiles_owned * sizeof(*recv_reqs)))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, - "can't allocate receive requests array"); - if (NULL == (recv_msgs = malloc((size_t)num_subfiles_owned * 3 * sizeof(*recv_msgs)))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't allocate message array"); + if (NULL == (recv_reqs = H5MM_malloc((size_t)num_subfiles_owned * sizeof(*recv_reqs)))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "can't allocate receive requests array"); + if (NULL == (recv_msgs = H5MM_malloc((size_t)num_subfiles_owned * 3 * sizeof(*recv_msgs)))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "can't allocate message array"); /* * Post early receives for messages from the IOC main * thread that will signal completion of the truncate * operation */ - for (int i = 0; i < num_subfiles_owned; i++) { + for (int i = 0; i < num_subfiles_owned; i++) if (MPI_SUCCESS != (mpi_code = MPI_Irecv(&recv_msgs[3 * i], 1, H5_subfiling_rpc_msg_type, sf_context->topology->io_concentrators[sf_context->topology->ioc_idx], TRUNC_COMPLETED, sf_context->sf_eof_comm, &recv_reqs[i]))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Irecv failed", mpi_code); - } + HMPI_GOTO_ERROR(FAIL, "MPI_Irecv failed", mpi_code); /* Compute the EOF for each subfile this IOC owns */ for (int i = 0; i < num_subfiles_owned; i++) { @@ -123,12 +123,10 @@ H5FD__subfiling__truncate_sub_files(hid_t context_id, int64_t logical_file_eof, global_subfile_idx = (i * sf_context->topology->n_io_concentrators) + sf_context->topology->ioc_idx; - if (global_subfile_idx < num_leftover_stripes) { + if (global_subfile_idx < num_leftover_stripes) subfile_eof += sf_context->sf_stripe_size; - } - else if (global_subfile_idx == num_leftover_stripes) { + else if (global_subfile_idx == num_leftover_stripes) subfile_eof += partial_stripe_len % sf_context->sf_stripe_size; - } /* Direct the IOC to truncate this subfile to the correct EOF */ msg[0] = subfile_eof; @@ -139,54 +137,26 @@ H5FD__subfiling__truncate_sub_files(hid_t context_id, int64_t logical_file_eof, (mpi_code = MPI_Send(msg, 1, H5_subfiling_rpc_msg_type, sf_context->topology->io_concentrators[sf_context->topology->ioc_idx], TRUNC_OP, sf_context->sf_msg_comm))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Send failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Send failed", mpi_code); } /* Wait for truncate operations to complete */ H5_GCC_DIAG_OFF("stringop-overflow") if (MPI_SUCCESS != (mpi_code = MPI_Waitall(num_subfiles_owned, recv_reqs, MPI_STATUSES_IGNORE))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Waitall", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Waitall", mpi_code); H5_GCC_DIAG_ON("stringop-overflow") - - /* sanity check -- compute the file eof using the same mechanism used to - * compute the subfile eof. Assert that the computed value and the - * actual value match. - * - * Do this only for debug builds -- probably delete this before release. - * - * JRM -- 12/15/21 - */ - -#ifndef NDEBUG - { - int64_t test_file_eof = 0; - - for (int i = 0; i < sf_context->sf_num_subfiles; i++) { - test_file_eof += num_full_stripes * sf_context->sf_stripe_size; - - if (i < num_leftover_stripes) { - test_file_eof += sf_context->sf_stripe_size; - } - else if (i == num_leftover_stripes) { - test_file_eof += partial_stripe_len % sf_context->sf_stripe_size; - } - } - - assert(test_file_eof == logical_file_eof); - } -#endif /* NDEBUG */ } /* Barrier on exit */ if (mpi_size > 1) if (MPI_SUCCESS != (mpi_code = MPI_Barrier(comm))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Barrier failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Barrier failed", mpi_code); done: - free(recv_msgs); - free(recv_reqs); + H5MM_free(recv_msgs); + H5MM_free(recv_reqs); - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /* H5FD__subfiling__truncate_sub_files() */ /*------------------------------------------------------------------------- @@ -207,43 +177,42 @@ H5FD__subfiling__truncate_sub_files(hid_t context_id, int64_t logical_file_eof, * subfile's EOF. * * 3) Await reply from each IOC, storing the reply in - * the appropriate entry in the array allocated in 1. + * the appropriate entry in the array allocated in 1). * - * 4) After all IOCs have replied, compute the offset of - * each subfile in the logical file. Take the maximum - * of these values, and report this value as the overall - * EOF. + * 4) After all IOCs have replied, compute the offset of each + * subfile in the logical file. Take the maximum of these + * values, and report this value as the overall EOF. * * Note that this operation is not collective, and can return * invalid data if other ranks perform writes while this * operation is in progress. * - * SUBFILING NOTE: + * NOTE: * The EOF calculation for subfiling is somewhat different * than for the more traditional HDF5 file implementations. * This statement derives from the fact that unlike "normal" * HDF5 files, subfiling introduces a multi-file representation - * of a single HDF5 file. The plurality of subfiles represents + * of a single HDF5 file. This set of subfiles represents * a software RAID-0 based HDF5 file. As such, each subfile * contains a designated portion of the address space of the * virtual HDF5 storage. We have no notion of HDF5 datatypes, - * datasets, metadata, or other HDF5 structures; only BYTES. + * datasets, metadata, or other HDF5 structures; only bytes. * * The organization of the bytes within subfiles is consistent - * with the RAID-0 striping, i.e. there are IO Concentrators - * (IOCs) which correspond to a stripe-count (in Lustre) as - * well as a stripe_size. The combination of these two - * variables determines the "address" (a combination of IOC - * and a file offset) of any storage operation. - * - * Having a defined storage layout, the virtual file EOF - * calculation should be the MAXIMUM value returned by the - * collection of IOCs. Every MPI rank which hosts an IOC - * maintains its own EOF by updating that value for each - * WRITE operation that completes, i.e. if a new local EOF - * is greater than the existing local EOF, the new EOF - * will replace the old. The local EOF calculation is as - * follows. + * with the RAID-0 striping, i.e. there are IO Concentrators (IOCs) + * which correspond to a stripe-count (as in Lustre) as well as a + * stripe_size. The combination of these two variables determines + * the "address" (a combination of IOC and a file offset) of any + * storage operation. + * + * Having a defined storage layout, the virtual file EOF calculation + * should be the maximum value returned by the collection of IOCs. + * Every MPI rank which hosts an IOC maintains its own EOF by + * updating that value for each write operation that completes, i.e. + * if a new local EOF is greater than the existing local EOF, the + * new EOF will replace the old. The local EOF calculation is as + * follows: + * * 1. At file creation, each IOC is assigned a rank value * (0 to N-1, where N is the total number of IOCs) and * a 'sf_base_addr' = 'ioc_idx' * 'sf_stripe_size') @@ -251,10 +220,11 @@ H5FD__subfiling__truncate_sub_files(hid_t context_id, int64_t logical_file_eof, * is simply the 'sf_stripe_size' * 'n_ioc_concentrators' * * 2. For every write operation, the IOC receives a message - * containing a file_offset and the data_size. + * containing a file_offset and data_size. * * 3. The file_offset + data_size are in turn used to * create a stripe_id: + * * IOC-(ioc_rank) IOC-(ioc_rank+1) * |<- sf_base_address |<- sf_base_address | * ID +--------------------+--------------------+ @@ -266,6 +236,7 @@ H5FD__subfiling__truncate_sub_files(hid_t context_id, int64_t logical_file_eof, * * The new 'stripe_id' is then used to calculate a * potential new EOF: + * * sf_eof = (stripe_id * sf_blocksize_per_stripe) + sf_base_addr * + ((file_offset + data_size) % sf_stripe_size) * @@ -290,10 +261,12 @@ H5FD__subfiling__get_real_eof(hid_t context_id, int64_t *logical_eof_ptr) int mpi_code; /* MPI return code */ herr_t ret_value = SUCCEED; /* Return value */ + FUNC_ENTER_PACKAGE + assert(logical_eof_ptr); - if (NULL == (sf_context = (subfiling_context_t *)H5_get_subfiling_object(context_id))) - H5_SUBFILING_GOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "can't get subfile context"); + if (NULL == (sf_context = H5FD__subfiling_get_object(context_id))) + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "can't get subfile context"); assert(sf_context->topology); @@ -303,12 +276,12 @@ H5FD__subfiling__get_real_eof(hid_t context_id, int64_t *logical_eof_ptr) assert(n_io_concentrators > 0); assert(num_subfiles >= n_io_concentrators); - if (NULL == (sf_eofs = malloc((size_t)num_subfiles * sizeof(int64_t)))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't allocate subfile EOFs array"); - if (NULL == (recv_reqs = malloc((size_t)num_subfiles * sizeof(*recv_reqs)))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't allocate receive requests array"); - if (NULL == (recv_msg = malloc((size_t)num_subfiles * sizeof(msg)))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't allocate message array"); + if (NULL == (sf_eofs = H5MM_malloc((size_t)num_subfiles * sizeof(int64_t)))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "can't allocate subfile EOFs array"); + if (NULL == (recv_reqs = H5MM_malloc((size_t)num_subfiles * sizeof(*recv_reqs)))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "can't allocate receive requests array"); + if (NULL == (recv_msg = H5MM_malloc((size_t)num_subfiles * sizeof(msg)))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "can't allocate message array"); for (int i = 0; i < num_subfiles; i++) { sf_eofs[i] = -1; @@ -321,7 +294,7 @@ H5FD__subfiling__get_real_eof(hid_t context_id, int64_t *logical_eof_ptr) if (MPI_SUCCESS != (mpi_code = MPI_Irecv(&recv_msg[3 * i], 1, H5_subfiling_rpc_msg_type, ioc_rank, GET_EOF_COMPLETED, sf_context->sf_eof_comm, &recv_reqs[i]))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Irecv", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Irecv", mpi_code); } /* Send each subfile's IOC a message requesting that subfile's EOF */ @@ -337,13 +310,13 @@ H5FD__subfiling__get_real_eof(hid_t context_id, int64_t *logical_eof_ptr) if (MPI_SUCCESS != (mpi_code = MPI_Send(msg, 1, H5_subfiling_rpc_msg_type, ioc_rank, GET_EOF_OP, sf_context->sf_msg_comm))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Send", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Send", mpi_code); } /* Wait for EOF communication to complete */ H5_GCC_DIAG_OFF("stringop-overflow") if (MPI_SUCCESS != (mpi_code = MPI_Waitall(num_subfiles, recv_reqs, MPI_STATUSES_IGNORE))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Waitall", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Waitall", mpi_code); H5_GCC_DIAG_ON("stringop-overflow") for (int i = 0; i < num_subfiles; i++) { @@ -358,55 +331,47 @@ H5FD__subfiling__get_real_eof(hid_t context_id, int64_t *logical_eof_ptr) sf_eofs[i] = recv_msg[(3 * i) + 1]; } - /* 4) After all IOCs have replied, compute the offset of - * each subfile in the logical file. Take the maximum - * of these values, and report this value as the overall - * EOF. + /* After all IOCs have replied, compute the offset of each subfile in the + * logical file. Take the maximum of these values, and report this value + * as the overall EOF. */ for (int i = 0; i < num_subfiles; i++) { - - /* compute number of complete stripes */ + /* Compute number of complete stripes */ sf_logical_eof = sf_eofs[i] / sf_context->sf_stripe_size; - /* multiply by stripe size */ + /* Multiply by stripe size */ sf_logical_eof *= sf_context->sf_stripe_size * num_subfiles; - /* if the subfile doesn't end on a stripe size boundary, must add in a partial stripe */ + /* If the subfile doesn't end on a stripe size boundary, must add in a partial stripe */ if (sf_eofs[i] % sf_context->sf_stripe_size > 0) { - - /* add in the size of the partial stripe up to but not including this subfile */ + /* Add in the size of the partial stripe up to but not including this subfile */ sf_logical_eof += i * sf_context->sf_stripe_size; - /* finally, add in the number of bytes in the last partial stripe depth in the subfile */ + /* Finally, add in the number of bytes in the last partial stripe depth in the subfile */ sf_logical_eof += sf_eofs[i] % sf_context->sf_stripe_size; } - if (sf_logical_eof > logical_eof) { - + if (sf_logical_eof > logical_eof) logical_eof = sf_logical_eof; - } } #ifdef H5_SUBFILING_DEBUG - H5_subfiling_log(context_id, "%s: calculated logical EOF = %" PRId64 ".", __func__, logical_eof); + H5FD__subfiling_log(context_id, "%s: calculated logical EOF = %" PRId64 ".", __func__, logical_eof); #endif *logical_eof_ptr = logical_eof; done: - if (ret_value < 0) { - for (int i = 0; i < num_subfiles; i++) { - if (recv_reqs && (recv_reqs[i] != MPI_REQUEST_NULL)) { + if (ret_value < 0) + for (int i = 0; i < num_subfiles; i++) + if (recv_reqs && (recv_reqs[i] != MPI_REQUEST_NULL)) if (MPI_SUCCESS != (mpi_code = MPI_Cancel(&recv_reqs[i]))) - H5_SUBFILING_MPI_DONE_ERROR(FAIL, "MPI_Cancel", mpi_code); - } - } - } + HMPI_DONE_ERROR(FAIL, "MPI_Cancel", mpi_code); - free(recv_msg); - free(recv_reqs); - free(sf_eofs); + H5MM_free(recv_msg); + H5MM_free(recv_reqs); + H5MM_free(sf_eofs); - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /* H5FD__subfiling__get_real_eof() */ diff --git a/src/H5FDsubfiling/H5FDsubfiling.c b/src/H5FDsubfiling/H5FDsubfiling.c index 6fbd3696200..affcfcbe94a 100644 --- a/src/H5FDsubfiling/H5FDsubfiling.c +++ b/src/H5FDsubfiling/H5FDsubfiling.c @@ -79,7 +79,7 @@ static bool H5FD_mpi_self_initialized = false; * Document additional subfiling fields here. * * Recall that the existing fields are inherited from the sec2 driver - * and should be kept or not as appropriate for the sub-filing VFD. + * and should be kept or not as appropriate for the subfiling VFD. * * ***************************************************************************/ @@ -178,110 +178,109 @@ static herr_t H5FD__subfiling_read_vector(H5FD_t *file, hid_t dxpl_id, uint32_t static herr_t H5FD__subfiling_write_vector(H5FD_t *file, hid_t dxpl_id, uint32_t count, H5FD_mem_t types[], haddr_t addrs[], size_t sizes[], const void *bufs[] /* in */); static herr_t H5FD__subfiling_truncate(H5FD_t *_file, hid_t dxpl_id, bool closing); -#if 0 -static herr_t H5FD__subfiling_lock(H5FD_t *_file, bool rw); -static herr_t H5FD__subfiling_unlock(H5FD_t *_file); -#endif -static herr_t H5FD__subfiling_del(const char *name, hid_t fapl); -static herr_t H5FD__subfiling_ctl(H5FD_t *_file, uint64_t op_code, uint64_t flags, const void *input, - void **output); +static herr_t H5FD__subfiling_del(const char *name, hid_t fapl); +static herr_t H5FD__subfiling_ctl(H5FD_t *_file, uint64_t op_code, uint64_t flags, const void *input, + void **output); static herr_t H5FD__subfiling_get_default_config(hid_t fapl_id, H5FD_subfiling_config_t *config_out); static herr_t H5FD__subfiling_validate_config(const H5FD_subfiling_config_t *fa); -static int H5FD__copy_plist(hid_t fapl_id, hid_t *id_out_ptr); +static herr_t H5FD__copy_plist(hid_t fapl_id, hid_t *id_out_ptr); -static herr_t H5FD__subfiling_close_int(H5FD_subfiling_t *file_ptr); +static herr_t H5FD__subfiling_close_int(H5FD_subfiling_t *file); -static herr_t H5FD__subfiling_io_helper(H5FD_subfiling_t *file_ptr, size_t io_count, H5FD_mem_t types[], +static herr_t H5FD__subfiling_io_helper(H5FD_subfiling_t *file, size_t io_count, H5FD_mem_t types[], haddr_t addrs[], size_t sizes[], H5_flexible_const_ptr_t bufs[], H5FD_subfiling_io_type_t io_type); -static herr_t H5FD__subfiling_mirror_writes_to_stub(H5FD_subfiling_t *file_ptr, uint32_t count, +static herr_t H5FD__subfiling_mirror_writes_to_stub(H5FD_subfiling_t *file, uint32_t count, H5FD_mem_t types[], haddr_t addrs[], size_t sizes[], const void *bufs[]); -static herr_t generate_io_vectors(subfiling_context_t *sf_context, size_t in_count, H5FD_mem_t types[], - haddr_t file_offsets[], size_t nelemts[], H5_flexible_const_ptr_t bufs[], - size_t dtype_extent, H5FD_subfiling_io_type_t io_type, size_t *ioreq_count, - uint32_t *iovec_len, H5FD_mem_t **io_types, haddr_t **io_addrs, - size_t **io_sizes, H5_flexible_const_ptr_t **io_bufs); -static void get_iovec_sizes(subfiling_context_t *sf_context, size_t in_count, haddr_t file_offsets[], - size_t nelemts[], size_t dtype_extent, size_t *max_iovec_depth, - size_t *max_num_subfiles); -static herr_t translate_io_req_to_iovec(subfiling_context_t *sf_context, size_t iovec_idx, size_t iovec_len, - size_t iovec_count, H5FD_mem_t type, haddr_t addr, size_t io_size, - H5_flexible_const_ptr_t io_buf, H5FD_subfiling_io_type_t io_type, - H5FD_mem_t *io_types, haddr_t *io_addrs, size_t *io_sizes, - H5_flexible_const_ptr_t *io_bufs); -static herr_t iovec_fill_first(subfiling_context_t *sf_context, size_t iovec_len, int64_t cur_iovec_depth, - int64_t target_datasize, int64_t start_mem_offset, int64_t start_file_offset, - int64_t first_io_len, H5_flexible_const_ptr_t buf, - H5FD_subfiling_io_type_t io_type, haddr_t *io_addrs_ptr, size_t *io_sizes_ptr, - H5_flexible_const_ptr_t *io_bufs_ptr); -static herr_t iovec_fill_last(subfiling_context_t *sf_context, size_t iovec_len, int64_t cur_iovec_depth, - int64_t target_datasize, int64_t start_mem_offset, int64_t start_file_offset, - int64_t last_io_len, H5_flexible_const_ptr_t buf, - H5FD_subfiling_io_type_t io_type, haddr_t *io_addrs_ptr, size_t *io_sizes_ptr, - H5_flexible_const_ptr_t *io_bufs_ptr); -static herr_t iovec_fill_first_last(subfiling_context_t *sf_context, size_t iovec_len, - int64_t cur_iovec_depth, int64_t target_datasize, - int64_t start_mem_offset, int64_t start_file_offset, int64_t first_io_len, - int64_t last_io_len, H5_flexible_const_ptr_t buf, - H5FD_subfiling_io_type_t io_type, haddr_t *io_addrs_ptr, - size_t *io_sizes_ptr, H5_flexible_const_ptr_t *io_bufs_ptr); -static herr_t iovec_fill_uniform(subfiling_context_t *sf_context, size_t iovec_len, int64_t cur_iovec_depth, - int64_t target_datasize, int64_t start_mem_offset, int64_t start_file_offset, - H5_flexible_const_ptr_t buf, H5FD_subfiling_io_type_t io_type, - haddr_t *io_addrs_ptr, size_t *io_sizes_ptr, - H5_flexible_const_ptr_t *io_bufs_ptr); +static herr_t H5FD__subfiling_generate_io_vectors(subfiling_context_t *sf_context, size_t in_count, + H5FD_mem_t types[], haddr_t file_offsets[], + size_t nelemts[], H5_flexible_const_ptr_t bufs[], + H5FD_subfiling_io_type_t io_type, size_t *ioreq_count, + uint32_t *iovec_len, H5FD_mem_t **io_types, + haddr_t **io_addrs, size_t **io_sizes, + H5_flexible_const_ptr_t **io_bufs); +static void H5FD__subfiling_get_iovec_sizes(subfiling_context_t *sf_context, size_t in_count, + haddr_t file_offsets[], size_t nelemts[], size_t *max_iovec_depth, + size_t *max_num_subfiles); +static herr_t H5FD__subfiling_translate_io_req_to_iovec( + subfiling_context_t *sf_context, size_t iovec_idx, size_t iovec_len, size_t iovec_count, H5FD_mem_t type, + haddr_t addr, size_t io_size, H5_flexible_const_ptr_t io_buf, H5FD_subfiling_io_type_t io_type, + H5FD_mem_t *io_types, haddr_t *io_addrs, size_t *io_sizes, H5_flexible_const_ptr_t *io_bufs); +static herr_t H5FD__subfiling_iovec_fill_first(subfiling_context_t *sf_context, size_t iovec_len, + int64_t cur_iovec_depth, int64_t target_datasize, + int64_t start_mem_offset, int64_t start_file_offset, + int64_t first_io_len, H5_flexible_const_ptr_t buf, + H5FD_subfiling_io_type_t io_type, haddr_t *io_addrs_ptr, + size_t *io_sizes_ptr, H5_flexible_const_ptr_t *io_bufs_ptr); +static herr_t H5FD__subfiling_iovec_fill_last(subfiling_context_t *sf_context, size_t iovec_len, + int64_t cur_iovec_depth, int64_t target_datasize, + int64_t start_mem_offset, int64_t start_file_offset, + int64_t last_io_len, H5_flexible_const_ptr_t buf, + H5FD_subfiling_io_type_t io_type, haddr_t *io_addrs_ptr, + size_t *io_sizes_ptr, H5_flexible_const_ptr_t *io_bufs_ptr); +static herr_t H5FD__subfiling_iovec_fill_first_last( + subfiling_context_t *sf_context, size_t iovec_len, int64_t cur_iovec_depth, int64_t target_datasize, + int64_t start_mem_offset, int64_t start_file_offset, int64_t first_io_len, int64_t last_io_len, + H5_flexible_const_ptr_t buf, H5FD_subfiling_io_type_t io_type, haddr_t *io_addrs_ptr, + size_t *io_sizes_ptr, H5_flexible_const_ptr_t *io_bufs_ptr); +static herr_t H5FD__subfiling_iovec_fill_uniform(subfiling_context_t *sf_context, size_t iovec_len, + int64_t cur_iovec_depth, int64_t target_datasize, + int64_t start_mem_offset, int64_t start_file_offset, + H5_flexible_const_ptr_t buf, + H5FD_subfiling_io_type_t io_type, haddr_t *io_addrs_ptr, + size_t *io_sizes_ptr, H5_flexible_const_ptr_t *io_bufs_ptr); #ifdef H5_SUBFILING_DEBUG -void H5_subfiling_dump_iovecs(subfiling_context_t *sf_context, size_t ioreq_count, size_t iovec_len, - H5FD_subfiling_io_type_t io_type, H5FD_mem_t *io_types, haddr_t *io_addrs, - size_t *io_sizes, H5_flexible_const_ptr_t *io_bufs); +static void H5_subfiling_dump_iovecs(subfiling_context_t *sf_context, size_t ioreq_count, size_t iovec_len, + H5FD_subfiling_io_type_t io_type, H5FD_mem_t *io_types, + haddr_t *io_addrs, size_t *io_sizes, H5_flexible_const_ptr_t *io_bufs); #endif void H5FD__subfiling_mpi_finalize(void); static const H5FD_class_t H5FD_subfiling_g = { - H5FD_CLASS_VERSION, /* VFD interface version */ - H5_VFD_SUBFILING, /* value */ - H5FD_SUBFILING_NAME, /* name */ - MAXADDR, /* maxaddr */ - H5F_CLOSE_WEAK, /* fc_degree */ - H5FD__subfiling_term, /* terminate */ - H5FD__subfiling_sb_size, /* sb_size */ - H5FD__subfiling_sb_encode, /* sb_encode */ - H5FD__subfiling_sb_decode, /* sb_decode */ - sizeof(H5FD_subfiling_config_t), /* fapl_size */ - H5FD__subfiling_fapl_get, /* fapl_get */ - H5FD__subfiling_fapl_copy, /* fapl_copy */ - H5FD__subfiling_fapl_free, /* fapl_free */ - 0, /* dxpl_size */ - NULL, /* dxpl_copy */ - NULL, /* dxpl_free */ - H5FD__subfiling_open, /* open */ - H5FD__subfiling_close, /* close */ - H5FD__subfiling_cmp, /* cmp */ - H5FD__subfiling_query, /* query */ - NULL, /* get_type_map */ - NULL, /* alloc */ - NULL, /* free */ - H5FD__subfiling_get_eoa, /* get_eoa */ - H5FD__subfiling_set_eoa, /* set_eoa */ - H5FD__subfiling_get_eof, /* get_eof */ - H5FD__subfiling_get_handle, /* get_handle */ - H5FD__subfiling_read, /* read */ - H5FD__subfiling_write, /* write */ - H5FD__subfiling_read_vector, /* read_vector */ - H5FD__subfiling_write_vector, /* write_vector */ - NULL, /* read_selection */ - NULL, /* write_selection */ - NULL, /* flush */ - H5FD__subfiling_truncate, /* truncate */ - NULL /* H5FD__subfiling_lock */, /* lock */ - NULL /* H5FD__subfiling_unlock */, /* unlock */ - H5FD__subfiling_del, /* del */ - H5FD__subfiling_ctl, /* ctl */ - H5FD_FLMAP_DICHOTOMY /* fl_map */ + H5FD_CLASS_VERSION, /* VFD interface version */ + H5_VFD_SUBFILING, /* value */ + H5FD_SUBFILING_NAME, /* name */ + MAXADDR, /* maxaddr */ + H5F_CLOSE_WEAK, /* fc_degree */ + H5FD__subfiling_term, /* terminate */ + H5FD__subfiling_sb_size, /* sb_size */ + H5FD__subfiling_sb_encode, /* sb_encode */ + H5FD__subfiling_sb_decode, /* sb_decode */ + sizeof(H5FD_subfiling_config_t), /* fapl_size */ + H5FD__subfiling_fapl_get, /* fapl_get */ + H5FD__subfiling_fapl_copy, /* fapl_copy */ + H5FD__subfiling_fapl_free, /* fapl_free */ + 0, /* dxpl_size */ + NULL, /* dxpl_copy */ + NULL, /* dxpl_free */ + H5FD__subfiling_open, /* open */ + H5FD__subfiling_close, /* close */ + H5FD__subfiling_cmp, /* cmp */ + H5FD__subfiling_query, /* query */ + NULL, /* get_type_map */ + NULL, /* alloc */ + NULL, /* free */ + H5FD__subfiling_get_eoa, /* get_eoa */ + H5FD__subfiling_set_eoa, /* set_eoa */ + H5FD__subfiling_get_eof, /* get_eof */ + H5FD__subfiling_get_handle, /* get_handle */ + H5FD__subfiling_read, /* read */ + H5FD__subfiling_write, /* write */ + H5FD__subfiling_read_vector, /* read_vector */ + H5FD__subfiling_write_vector, /* write_vector */ + NULL, /* read_selection */ + NULL, /* write_selection */ + NULL, /* flush */ + H5FD__subfiling_truncate, /* truncate */ + NULL, /* lock */ + NULL, /* unlock */ + H5FD__subfiling_del, /* del */ + H5FD__subfiling_ctl, /* ctl */ + H5FD_FLMAP_DICHOTOMY /* fl_map */ }; /* Declare a free list to manage the H5FD_subfiling_t struct */ @@ -295,8 +294,17 @@ H5FL_DEFINE_STATIC(H5FD_subfiling_t); void H5FD__subfiling_mpi_finalize(void) { - H5close(); + /* + * Don't call normal FUNC_ENTER() since we don't want to initialize the + * whole library just to release it all right away. It is safe to call + * this function for an uninitialized library. + */ + FUNC_ENTER_NOAPI_NOINIT_NOERR + + H5_term_library(); MPI_Finalize(); + + FUNC_LEAVE_NOAPI_VOID } /*------------------------------------------------------------------------- @@ -315,6 +323,8 @@ H5FD_subfiling_init(void) { hid_t ret_value = H5I_INVALID_HID; /* Return value */ + FUNC_ENTER_NOAPI(H5I_INVALID_HID) + /* Register the Subfiling VFD, if it isn't already registered */ if (H5I_VFL != H5I_get_type(H5FD_SUBFILING_g)) { int mpi_initialized = 0; @@ -322,44 +332,34 @@ H5FD_subfiling_init(void) int mpi_code; if ((H5FD_SUBFILING_g = H5FD_register(&H5FD_subfiling_g, sizeof(H5FD_class_t), false)) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_ID, H5E_CANTREGISTER, H5I_INVALID_HID, - "can't register subfiling VFD"); - - /* Initialize error reporting */ - if ((H5subfiling_err_stack_g = H5Ecreate_stack()) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTINIT, H5I_INVALID_HID, "can't create HDF5 error stack"); - if ((H5subfiling_err_class_g = H5Eregister_class(H5SUBFILING_ERR_CLS_NAME, H5SUBFILING_ERR_LIB_NAME, - H5SUBFILING_ERR_VER)) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTINIT, H5I_INVALID_HID, - "can't register error class with HDF5 error API"); + HGOTO_ERROR(H5E_VFL, H5E_CANTREGISTER, H5I_INVALID_HID, "can't register subfiling VFD"); /* Initialize MPI if not already initialized */ if (MPI_SUCCESS != (mpi_code = MPI_Initialized(&mpi_initialized))) - H5_SUBFILING_MPI_GOTO_ERROR(H5I_INVALID_HID, "MPI_Initialized failed", mpi_code); + HMPI_GOTO_ERROR(H5I_INVALID_HID, "MPI_Initialized failed", mpi_code); if (mpi_initialized) { /* If MPI is initialized, validate that it was initialized with MPI_THREAD_MULTIPLE */ if (MPI_SUCCESS != (mpi_code = MPI_Query_thread(&provided))) - H5_SUBFILING_MPI_GOTO_ERROR(H5I_INVALID_HID, "MPI_Query_thread failed", mpi_code); + HMPI_GOTO_ERROR(H5I_INVALID_HID, "MPI_Query_thread failed", mpi_code); if (provided != MPI_THREAD_MULTIPLE) - H5_SUBFILING_GOTO_ERROR( - H5E_VFL, H5E_CANTINIT, H5I_INVALID_HID, - "Subfiling VFD requires the use of MPI_Init_thread with MPI_THREAD_MULTIPLE"); + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, H5I_INVALID_HID, + "Subfiling VFD requires the use of MPI_Init_thread with MPI_THREAD_MULTIPLE"); } else { int required = MPI_THREAD_MULTIPLE; if (MPI_SUCCESS != (mpi_code = MPI_Init_thread(NULL, NULL, required, &provided))) - H5_SUBFILING_MPI_GOTO_ERROR(H5I_INVALID_HID, "MPI_Init_thread failed", mpi_code); + HMPI_GOTO_ERROR(H5I_INVALID_HID, "MPI_Init_thread failed", mpi_code); H5FD_mpi_self_initialized = true; if (provided != required) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTINIT, H5I_INVALID_HID, - "MPI doesn't support MPI_Init_thread with MPI_THREAD_MULTIPLE"); + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, H5I_INVALID_HID, + "MPI doesn't support MPI_Init_thread with MPI_THREAD_MULTIPLE"); if (atexit(H5FD__subfiling_mpi_finalize) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTINIT, H5I_INVALID_HID, - "can't register atexit handler for MPI_Finalize"); + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, H5I_INVALID_HID, + "can't register atexit handler for MPI_Finalize"); } /* @@ -369,9 +369,9 @@ H5FD_subfiling_init(void) HDcompile_assert(sizeof(((sf_work_request_t *)NULL)->header) == 3 * sizeof(int64_t)); if (H5_subfiling_rpc_msg_type == MPI_DATATYPE_NULL) { if (MPI_SUCCESS != (mpi_code = MPI_Type_contiguous(3, MPI_INT64_T, &H5_subfiling_rpc_msg_type))) - H5_SUBFILING_MPI_GOTO_ERROR(H5I_INVALID_HID, "MPI_Type_contiguous failed", mpi_code); + HMPI_GOTO_ERROR(H5I_INVALID_HID, "MPI_Type_contiguous failed", mpi_code); if (MPI_SUCCESS != (mpi_code = MPI_Type_commit(&H5_subfiling_rpc_msg_type))) - H5_SUBFILING_MPI_GOTO_ERROR(H5I_INVALID_HID, "MPI_Type_commit failed", mpi_code); + HMPI_GOTO_ERROR(H5I_INVALID_HID, "MPI_Type_commit failed", mpi_code); } } @@ -379,7 +379,7 @@ H5FD_subfiling_init(void) ret_value = H5FD_SUBFILING_g; done: - H5_SUBFILING_FUNC_LEAVE_API; + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD_subfiling_init() */ /*--------------------------------------------------------------------------- @@ -396,6 +396,8 @@ H5FD__subfiling_term(void) { herr_t ret_value = SUCCEED; + FUNC_ENTER_PACKAGE + if (H5FD_SUBFILING_g >= 0) { int mpi_finalized; int mpi_code; @@ -406,52 +408,31 @@ H5FD__subfiling_term(void) * shuts down after MPI_Finalize() is called in an application. */ if (MPI_SUCCESS != (mpi_code = MPI_Finalized(&mpi_finalized))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Finalized failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Finalized failed", mpi_code); /* Free RPC message MPI Datatype */ if (H5_subfiling_rpc_msg_type != MPI_DATATYPE_NULL) { if (!mpi_finalized) { if (MPI_SUCCESS != (mpi_code = MPI_Type_free(&H5_subfiling_rpc_msg_type))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Type_free failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Type_free failed", mpi_code); } #ifdef H5_SUBFILING_DEBUG else - printf("** WARNING **: HDF5 is terminating the Subfiling VFD after MPI_Finalize() was " - "called - an HDF5 ID was probably left unclosed\n"); + printf("** WARNING **: HDF5 is terminating the Subfiling VFD after MPI_Finalize() was called " + "- an HDF5 ID was probably left unclosed\n"); #endif } /* Clean up resources */ - if (H5_subfiling_terminate() < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, - "can't cleanup internal subfiling resources"); - - /* Unregister from HDF5 error API */ - if (H5subfiling_err_class_g >= 0) { - if (H5Eunregister_class(H5subfiling_err_class_g) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CLOSEERROR, FAIL, - "can't unregister error class from HDF5 error API"); - } - if (H5subfiling_err_stack_g >= 0) { - /* Print the current error stack before destroying it */ - PRINT_ERROR_STACK; - - /* Destroy the error stack */ - if (H5Eclose_stack(H5subfiling_err_stack_g) < 0) { - H5_SUBFILING_DONE_ERROR(H5E_VFL, H5E_CLOSEERROR, FAIL, "can't close HDF5 error stack"); - PRINT_ERROR_STACK; - } /* end if */ - - H5subfiling_err_stack_g = H5I_INVALID_HID; - H5subfiling_err_class_g = H5I_INVALID_HID; - } + if (H5FD__subfiling_terminate() < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "can't cleanup internal subfiling resources"); } done: /* Reset VFL ID */ H5FD_SUBFILING_g = H5I_INVALID_HID; - H5_SUBFILING_FUNC_LEAVE_API; + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__subfiling_term() */ /*------------------------------------------------------------------------- @@ -478,66 +459,64 @@ H5Pset_fapl_subfiling(hid_t fapl_id, const H5FD_subfiling_config_t *vfd_config) MPI_Info info = MPI_INFO_NULL; herr_t ret_value = SUCCEED; + FUNC_ENTER_API(FAIL) + /* Ensure Subfiling (and therefore MPI) is initialized before doing anything */ if (H5FD_subfiling_init() < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "can't initialize subfiling VFD"); + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "can't initialize subfiling VFD"); if (NULL == (plist = H5P_object_verify(fapl_id, H5P_FILE_ACCESS))) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list"); + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list"); if (vfd_config == NULL) { - if (NULL == (subfiling_conf = calloc(1, sizeof(*subfiling_conf)))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, - "can't allocate subfiling VFD configuration"); - subfiling_conf->ioc_fapl_id = H5I_INVALID_HID; + if (NULL == (subfiling_conf = H5MM_calloc(sizeof(*subfiling_conf)))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "can't allocate subfiling VFD configuration"); /* Get subfiling VFD defaults */ if (H5FD__subfiling_get_default_config(fapl_id, subfiling_conf) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, - "can't get default subfiling VFD configuration"); + HGOTO_ERROR(H5E_VFL, H5E_CANTSET, FAIL, "can't get default subfiling VFD configuration"); vfd_config = subfiling_conf; } /* Check if any MPI parameters were set on the FAPL */ if (H5P_get(plist, H5F_ACS_MPI_PARAMS_COMM_NAME, &comm) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get MPI communicator from plist"); + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get MPI communicator from plist"); if (H5P_get(plist, H5F_ACS_MPI_PARAMS_INFO_NAME, &info) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get MPI info from plist"); + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get MPI info from plist"); if (comm == MPI_COMM_NULL) comm = MPI_COMM_WORLD; /* Set MPI parameters on IOC FAPL */ if (NULL == (ioc_plist = H5P_object_verify(vfd_config->ioc_fapl_id, H5P_FILE_ACCESS))) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list"); + HGOTO_ERROR(H5E_VFL, H5E_BADTYPE, FAIL, "not a file access property list"); if (H5P_set(ioc_plist, H5F_ACS_MPI_PARAMS_COMM_NAME, &comm) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set MPI communicator on plist"); + HGOTO_ERROR(H5E_VFL, H5E_CANTSET, FAIL, "can't set MPI communicator on plist"); if (H5P_set(ioc_plist, H5F_ACS_MPI_PARAMS_INFO_NAME, &info) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set MPI info on plist"); + HGOTO_ERROR(H5E_VFL, H5E_CANTSET, FAIL, "can't set MPI info on plist"); if (H5FD__subfiling_validate_config(vfd_config) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid subfiling VFD configuration"); + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid subfiling VFD configuration"); /* Set Subfiling configuration on IOC FAPL */ - if (H5_subfiling_set_config_prop(ioc_plist, &vfd_config->shared_cfg) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, - "can't set subfiling configuration on IOC FAPL"); + if (H5FD__subfiling_set_config_prop(ioc_plist, &vfd_config->shared_cfg) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTSET, FAIL, "can't set subfiling configuration on IOC FAPL"); ret_value = H5P_set_driver(plist, H5FD_SUBFILING, vfd_config, NULL); done: if (H5_mpi_comm_free(&comm) < 0) - H5_SUBFILING_DONE_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "can't free MPI Communicator"); + HDONE_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "can't free MPI Communicator"); if (H5_mpi_info_free(&info) < 0) - H5_SUBFILING_DONE_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "can't free MPI Info object"); + HDONE_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "can't free MPI Info object"); if (subfiling_conf) { if (subfiling_conf->ioc_fapl_id >= 0 && H5I_dec_ref(subfiling_conf->ioc_fapl_id) < 0) - H5_SUBFILING_DONE_ERROR(H5E_PLIST, H5E_CANTDEC, FAIL, "can't close IOC FAPL"); - free(subfiling_conf); + HDONE_ERROR(H5E_VFL, H5E_CANTDEC, FAIL, "can't close IOC FAPL"); + H5MM_free(subfiling_conf); } - H5_SUBFILING_FUNC_LEAVE_API; + FUNC_LEAVE_API(ret_value) } /* end H5Pset_fapl_subfiling() */ /*------------------------------------------------------------------------- @@ -553,50 +532,52 @@ H5Pset_fapl_subfiling(hid_t fapl_id, const H5FD_subfiling_config_t *vfd_config) herr_t H5Pget_fapl_subfiling(hid_t fapl_id, H5FD_subfiling_config_t *config_out) { - const H5FD_subfiling_config_t *config_ptr = NULL; + const H5FD_subfiling_config_t *config = NULL; H5P_genplist_t *plist = NULL; bool use_default_config = false; herr_t ret_value = SUCCEED; - if (config_out == NULL) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "config_out is NULL"); + FUNC_ENTER_API(FAIL) + if (config_out == NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "config_out is NULL"); if (NULL == (plist = H5P_object_verify(fapl_id, H5P_FILE_ACCESS))) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list"); + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list"); if (H5FD_SUBFILING != H5P_peek_driver(plist)) use_default_config = true; else { - config_ptr = H5P_peek_driver_info(plist); - if (NULL == config_ptr) + if (NULL == (config = H5P_peek_driver_info(plist))) use_default_config = true; } if (use_default_config) { if (H5FD__subfiling_get_default_config(fapl_id, config_out) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, - "can't get default Subfiling VFD configuration"); + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get default Subfiling VFD configuration"); } else { /* Copy the subfiling fapl data out */ - H5MM_memcpy(config_out, config_ptr, sizeof(H5FD_subfiling_config_t)); + H5MM_memcpy(config_out, config, sizeof(H5FD_subfiling_config_t)); /* Copy the driver info value */ - if (H5FD__copy_plist(config_ptr->ioc_fapl_id, &(config_out->ioc_fapl_id)) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "can't copy IOC FAPL"); + if (H5FD__copy_plist(config->ioc_fapl_id, &(config_out->ioc_fapl_id)) < 0) + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "can't copy IOC FAPL"); } done: - H5_SUBFILING_FUNC_LEAVE_API; + FUNC_LEAVE_API(ret_value) } /* end H5Pget_fapl_subfiling() */ static herr_t H5FD__subfiling_get_default_config(hid_t fapl_id, H5FD_subfiling_config_t *config_out) { - MPI_Comm comm = MPI_COMM_NULL; - MPI_Info info = MPI_INFO_NULL; - char *h5_require_ioc; - herr_t ret_value = SUCCEED; + H5P_genplist_t *plist; /* Property list pointer */ + MPI_Comm comm = MPI_COMM_NULL; + MPI_Info info = MPI_INFO_NULL; + char *h5_require_ioc; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_PACKAGE assert(config_out); @@ -618,45 +599,59 @@ H5FD__subfiling_get_default_config(hid_t fapl_id, H5FD_subfiling_config_t *confi } /* Check if any MPI parameters were set on the FAPL */ - if (H5Pget_mpi_params(fapl_id, &comm, &info) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get MPI Comm/Info"); + if (NULL == (plist = (H5P_genplist_t *)H5I_object(fapl_id))) + HGOTO_ERROR(H5E_VFL, H5E_BADID, FAIL, "can't find object for ID"); + if (H5P_get(plist, H5F_ACS_MPI_PARAMS_COMM_NAME, &comm) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get MPI communicator from plist"); + if (H5P_get(plist, H5F_ACS_MPI_PARAMS_INFO_NAME, &info) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get MPI info from plist"); if (comm == MPI_COMM_NULL) { comm = MPI_COMM_WORLD; /* Set MPI_COMM_WORLD on FAPL if no MPI parameters were set */ - if (H5Pset_mpi_params(fapl_id, comm, info) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set MPI Comm/Info"); + if (H5P_set(plist, H5F_ACS_MPI_PARAMS_COMM_NAME, &comm) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTSET, FAIL, "can't set MPI communicator"); + if (H5P_set(plist, H5F_ACS_MPI_PARAMS_INFO_NAME, &info) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTSET, FAIL, "can't set MPI info object"); } /* Create a default FAPL and choose an appropriate underlying driver */ - if ((config_out->ioc_fapl_id = H5Pcreate(H5P_FILE_ACCESS)) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_PLIST, H5E_CANTCREATE, FAIL, "can't create default FAPL"); + if (H5FD__copy_plist(H5P_FILE_ACCESS_DEFAULT, &config_out->ioc_fapl_id) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTCREATE, FAIL, "can't create default FAPL"); + if (NULL == (plist = (H5P_genplist_t *)H5I_object(config_out->ioc_fapl_id))) + HGOTO_ERROR(H5E_VFL, H5E_BADID, FAIL, "can't find object for ID"); if (config_out->require_ioc) { - if (H5Pset_mpi_params(config_out->ioc_fapl_id, comm, info) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't get MPI Comm/Info on IOC FAPL"); + H5FD_ioc_config_t ioc_config; - if (H5Pset_fapl_ioc(config_out->ioc_fapl_id, NULL) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set IOC VFD on IOC FAPL"); + if (H5P_set(plist, H5F_ACS_MPI_PARAMS_COMM_NAME, &comm) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTSET, FAIL, "can't set MPI communicator"); + if (H5P_set(plist, H5F_ACS_MPI_PARAMS_INFO_NAME, &info) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTSET, FAIL, "can't set MPI info object"); + + if (H5FD__subfiling_get_default_ioc_config(&ioc_config) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get default IOC config"); + if (H5P_set_driver(plist, H5FD_IOC, &ioc_config, NULL) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTSET, FAIL, "can't set IOC VFD on IOC FAPL"); } else { - if (H5Pset_fapl_sec2(config_out->ioc_fapl_id) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set Sec2 VFD on IOC FAPL"); + if (H5P_set_driver(plist, H5FD_SEC2, NULL, NULL) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTSET, FAIL, "can't set sec2 VFD on IOC FAPL"); } done: if (H5_mpi_comm_free(&comm) < 0) - H5_SUBFILING_DONE_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "can't free MPI Communicator"); + HDONE_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "can't free MPI Communicator"); if (H5_mpi_info_free(&info) < 0) - H5_SUBFILING_DONE_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "can't free MPI Info object"); + HDONE_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "can't free MPI Info object"); if (ret_value < 0) { - if (config_out->ioc_fapl_id >= 0 && H5Pclose(config_out->ioc_fapl_id) < 0) - H5_SUBFILING_DONE_ERROR(H5E_PLIST, H5E_CANTCLOSEOBJ, FAIL, "can't close FAPL"); + if (config_out->ioc_fapl_id >= 0 && H5I_dec_ref(config_out->ioc_fapl_id) < 0) + HDONE_ERROR(H5E_VFL, H5E_CANTDEC, FAIL, "can't close FAPL"); config_out->ioc_fapl_id = H5I_INVALID_HID; } - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /*------------------------------------------------------------------------- @@ -681,26 +676,24 @@ H5FD__subfiling_validate_config(const H5FD_subfiling_config_t *fa) { herr_t ret_value = SUCCEED; - assert(fa != NULL); + FUNC_ENTER_PACKAGE - if (fa->version != H5FD_SUBFILING_CURR_FAPL_VERSION) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unknown H5FD_subfiling_config_t version"); + assert(fa != NULL); if (fa->magic != H5FD_SUBFILING_FAPL_MAGIC) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid H5FD_subfiling_config_t magic value"); - + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid H5FD_subfiling_config_t magic value"); + if (fa->version != H5FD_SUBFILING_CURR_FAPL_VERSION) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unknown H5FD_subfiling_config_t version"); if (fa->ioc_fapl_id < 0) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid IOC FAPL ID"); - + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid IOC FAPL ID"); if (!fa->require_ioc) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, - "Subfiling VFD currently always requires IOC VFD to be used"); - - if (H5_subfiling_validate_config(&fa->shared_cfg) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid subfiling configuration parameters"); + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, + "Subfiling VFD currently always requires IOC VFD to be used"); + if (H5FD__subfiling_validate_config_params(&fa->shared_cfg) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid subfiling configuration parameters"); done: - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__subfiling_validate_config() */ /*------------------------------------------------------------------------- @@ -719,6 +712,8 @@ H5FD__subfiling_sb_size(H5FD_t *_file) H5FD_subfiling_t *file = (H5FD_subfiling_t *)_file; hsize_t ret_value = 0; + FUNC_ENTER_PACKAGE_NOERR + assert(file); /* Configuration structure magic number */ @@ -745,13 +740,11 @@ H5FD__subfiling_sb_size(H5FD_t *_file) * to retrieve the context object here so we can check for * errors later. */ - if (NULL == (sf_context = H5_get_subfiling_object(file->context_id))) { + if (NULL == (sf_context = H5FD__subfiling_get_object(file->context_id))) file->fail_to_encode = true; - } else { - if (sf_context->config_file_prefix) { + if (sf_context->config_file_prefix) ret_value += strlen(sf_context->config_file_prefix) + 1; - } } /* Add superblock information from IOC file if necessary */ @@ -772,7 +765,7 @@ H5FD__subfiling_sb_size(H5FD_t *_file) if (ret_value > H5FD_SUBFILING_MAX_DRV_INFO_SIZE) file->fail_to_encode = true; - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__subfiling_sb_size() */ /*------------------------------------------------------------------------- @@ -796,14 +789,16 @@ H5FD__subfiling_sb_encode(H5FD_t *_file, char *name, unsigned char *buf) size_t prefix_len = 0; herr_t ret_value = SUCCEED; + FUNC_ENTER_PACKAGE + /* Check if the "fail to encode flag" is set */ if (file->fail_to_encode) - H5_SUBFILING_GOTO_ERROR( + HGOTO_ERROR( H5E_VFL, H5E_CANTENCODE, FAIL, "can't encode subfiling driver info message - message was too large or internal error occurred"); - if (NULL == (sf_context = H5_get_subfiling_object(file->context_id))) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get subfiling context object"); + if (NULL == (sf_context = H5FD__subfiling_get_object(file->context_id))) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get subfiling context object"); /* Encode driver name */ strncpy(name, "Subfilin", 9); @@ -842,21 +837,12 @@ H5FD__subfiling_sb_encode(H5FD_t *_file, char *name, unsigned char *buf) } /* Encode IOC VFD configuration information if necessary */ - if (file->sf_file) { - char ioc_name[9]; - - memset(ioc_name, 0, sizeof(ioc_name)); - - if (H5FD_sb_encode(file->sf_file, ioc_name, p + 9) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTENCODE, FAIL, - "unable to encode IOC VFD's superblock information"); - - /* Copy the IOC VFD's name into our buffer */ - H5MM_memcpy(p, ioc_name, 9); - } + if (file->sf_file) + if (H5FD_sb_encode(file->sf_file, (char *)p, p + 9) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTENCODE, FAIL, "unable to encode IOC VFD's superblock information"); done: - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__subfiling_sb_encode() */ /*------------------------------------------------------------------------- @@ -879,17 +865,19 @@ H5FD__subfiling_sb_decode(H5FD_t *_file, const char *name, const unsigned char * int32_t tmp32; herr_t ret_value = SUCCEED; + FUNC_ENTER_PACKAGE + /* Check if we previously failed to encode the info */ if (file->fail_to_encode) - H5_SUBFILING_GOTO_ERROR( + HGOTO_ERROR( H5E_VFL, H5E_CANTDECODE, FAIL, "can't decode subfiling driver info message - message wasn't encoded (or encoded improperly)"); - if (NULL == (sf_context = H5_get_subfiling_object(file->context_id))) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get subfiling context object"); + if (NULL == (sf_context = H5FD__subfiling_get_object(file->context_id))) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get subfiling context object"); if (strncmp(name, "Subfilin", 9)) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "invalid driver name in superblock"); + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "invalid driver name in superblock"); /* Decode configuration structure magic number */ UINT32DECODE(p, file->fa.magic); @@ -915,9 +903,9 @@ H5FD__subfiling_sb_decode(H5FD_t *_file, const char *name, const unsigned char * /* Decode config file prefix string */ if (tmpu64 > 0) { if (!sf_context->config_file_prefix) { - if (NULL == (sf_context->config_file_prefix = malloc(tmpu64))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, - "can't allocate space for config file prefix string"); + if (NULL == (sf_context->config_file_prefix = H5MM_malloc(tmpu64))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, + "can't allocate space for config file prefix string"); H5MM_memcpy(sf_context->config_file_prefix, p, tmpu64); @@ -928,36 +916,27 @@ H5FD__subfiling_sb_decode(H5FD_t *_file, const char *name, const unsigned char * p += tmpu64; } - if (file->sf_file) { - char ioc_name[9]; - - H5MM_memcpy(ioc_name, p, 9); - p += 9; - - if (H5FD_sb_load(file->sf_file, ioc_name, p) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTDECODE, FAIL, - "unable to decode IOC VFD's superblock information"); - } + if (file->sf_file) + if (H5FD_sb_load(file->sf_file, (const char *)p, p + 9) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTDECODE, FAIL, "unable to decode IOC VFD's superblock information"); /* Validate the decoded configuration */ if (H5FD__subfiling_validate_config(&file->fa) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, - "decoded subfiling configuration info is invalid"); + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "decoded subfiling configuration info is invalid"); if (file->fa.shared_cfg.stripe_size != sf_context->sf_stripe_size) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, - "specified subfiling stripe size (%" PRId64 - ") doesn't match value stored in file (%" PRId64 ")", - sf_context->sf_stripe_size, file->fa.shared_cfg.stripe_size); + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, + "specified subfiling stripe size (%" PRId64 + ") doesn't match value stored in file (%" PRId64 ")", + sf_context->sf_stripe_size, file->fa.shared_cfg.stripe_size); if (file->fa.shared_cfg.stripe_count != sf_context->sf_num_subfiles) - H5_SUBFILING_GOTO_ERROR( - H5E_VFL, H5E_BADVALUE, FAIL, - "specified subfiling stripe count (%d) doesn't match value stored in file (%" PRId32 ")", - sf_context->sf_num_subfiles, file->fa.shared_cfg.stripe_count); + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, + "specified subfiling stripe count (%d) doesn't match value stored in file (%" PRId32 ")", + sf_context->sf_num_subfiles, file->fa.shared_cfg.stripe_count); done: - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__subfiling_sb_decode() */ /*------------------------------------------------------------------------- @@ -967,7 +946,6 @@ H5FD__subfiling_sb_decode(H5FD_t *_file, const char *name, const unsigned char * * create an identical file. * * Return: Success: Ptr to new file access property list value. - * * Failure: NULL * *------------------------------------------------------------------------- @@ -979,31 +957,27 @@ H5FD__subfiling_fapl_get(H5FD_t *_file) H5FD_subfiling_config_t *fa = NULL; void *ret_value = NULL; - fa = (H5FD_subfiling_config_t *)H5MM_calloc(sizeof(H5FD_subfiling_config_t)); + FUNC_ENTER_PACKAGE - if (fa == NULL) { - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); - } + if (NULL == (fa = H5MM_calloc(sizeof(H5FD_subfiling_config_t)))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, NULL, "memory allocation failed"); /* Copy the fields of the structure */ - H5MM_memcpy(fa, &(file->fa), sizeof(H5FD_subfiling_config_t)); + H5MM_memcpy(fa, &file->fa, sizeof(H5FD_subfiling_config_t)); /* Copy the driver info value */ - if (H5FD__copy_plist(file->fa.ioc_fapl_id, &(fa->ioc_fapl_id)) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_BADVALUE, NULL, "can't copy IOC FAPL"); + if (H5FD__copy_plist(file->fa.ioc_fapl_id, &fa->ioc_fapl_id) < 0) + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, NULL, "can't copy IOC FAPL"); /* Set return value */ ret_value = fa; done: - if (ret_value == NULL) { - - if (fa != NULL) { + if (ret_value == NULL) + if (fa != NULL) H5MM_xfree(fa); - } - } - H5_SUBFILING_FUNC_LEAVE_API; + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__subfiling_fapl_get() */ /*------------------------------------------------------------------------- @@ -1012,31 +986,30 @@ H5FD__subfiling_fapl_get(H5FD_t *_file) * Purpose: Sanity-wrapped H5P_copy_plist() for each channel. * Utility function for operation in multiple locations. * - * Return: 0 on success, -1 on error. + * Return: Non-negative on success/Negative on failure *------------------------------------------------------------------------- */ -/* TODO: no need for this function */ -static int -H5FD__copy_plist(hid_t fapl_id, hid_t *id_out_ptr) +static herr_t +H5FD__copy_plist(hid_t fapl_id, hid_t *id) { - int ret_value = 0; - H5P_genplist_t *plist_ptr = NULL; + H5P_genplist_t *plist = NULL; + int ret_value = SUCCEED; + + FUNC_ENTER_PACKAGE - assert(id_out_ptr != NULL); + assert(id != NULL); if (false == H5P_isa_class(fapl_id, H5P_FILE_ACCESS)) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADTYPE, -1, "not a file access property list"); + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list"); - plist_ptr = (H5P_genplist_t *)H5I_object(fapl_id); - if (NULL == plist_ptr) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADTYPE, -1, "unable to get property list"); + if (NULL == (plist = (H5P_genplist_t *)H5I_object(fapl_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "unable to get property list"); - *id_out_ptr = H5P_copy_plist(plist_ptr, false); - if (H5I_INVALID_HID == *id_out_ptr) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_BADTYPE, -1, "unable to copy file access property list"); + if (H5I_INVALID_HID == (*id = H5P_copy_plist(plist, false))) + HGOTO_ERROR(H5E_VFL, H5E_BADTYPE, FAIL, "unable to copy file access property list"); done: - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__copy_plist() */ /*------------------------------------------------------------------------- @@ -1045,7 +1018,6 @@ H5FD__copy_plist(hid_t fapl_id, hid_t *id_out_ptr) * Purpose: Copies the subfiling-specific file access properties. * * Return: Success: Ptr to a new property list - * * Failure: NULL * *------------------------------------------------------------------------- @@ -1057,27 +1029,24 @@ H5FD__subfiling_fapl_copy(const void *_old_fa) H5FD_subfiling_config_t *new_fa = NULL; void *ret_value = NULL; - new_fa = (H5FD_subfiling_config_t *)H5MM_malloc(sizeof(H5FD_subfiling_config_t)); - if (new_fa == NULL) { - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); - } + FUNC_ENTER_PACKAGE + + if (NULL == (new_fa = H5MM_malloc(sizeof(H5FD_subfiling_config_t)))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, NULL, "memory allocation failed"); H5MM_memcpy(new_fa, old_fa, sizeof(H5FD_subfiling_config_t)); - if (H5FD__copy_plist(old_fa->ioc_fapl_id, &(new_fa->ioc_fapl_id)) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_BADVALUE, NULL, "can't copy the IOC FAPL"); + if (H5FD__copy_plist(old_fa->ioc_fapl_id, &new_fa->ioc_fapl_id) < 0) + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, NULL, "can't copy the IOC FAPL"); ret_value = new_fa; done: - if (ret_value == NULL) { - - if (new_fa != NULL) { + if (ret_value == NULL) + if (new_fa != NULL) H5MM_xfree(new_fa); - } - } - H5_SUBFILING_FUNC_LEAVE_API; + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__subfiling_fapl_copy() */ /*------------------------------------------------------------------------- @@ -1095,15 +1064,17 @@ H5FD__subfiling_fapl_free(void *_fa) H5FD_subfiling_config_t *fa = (H5FD_subfiling_config_t *)_fa; herr_t ret_value = SUCCEED; + FUNC_ENTER_PACKAGE + assert(fa != NULL); /* sanity check */ if (fa->ioc_fapl_id >= 0 && H5I_dec_ref(fa->ioc_fapl_id) < 0) - H5_SUBFILING_DONE_ERROR(H5E_PLIST, H5E_CANTDEC, FAIL, "can't close IOC FAPL"); + HDONE_ERROR(H5E_VFL, H5E_CANTDEC, FAIL, "can't close IOC FAPL"); fa->ioc_fapl_id = H5I_INVALID_HID; H5MM_xfree(fa); - H5_SUBFILING_FUNC_LEAVE_API; + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__subfiling_fapl_free() */ /*------------------------------------------------------------------------- @@ -1121,248 +1092,207 @@ H5FD__subfiling_fapl_free(void *_fa) static H5FD_t * H5FD__subfiling_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr) { - H5FD_subfiling_t *file_ptr = NULL; /* Subfiling VFD info */ - const H5FD_subfiling_config_t *config_ptr = NULL; /* Driver-specific property list */ + H5FD_subfiling_t *file = NULL; /* Subfiling VFD info */ + const H5FD_subfiling_config_t *config = NULL; /* Driver-specific property list */ H5FD_subfiling_config_t default_config; - H5FD_class_t *driver = NULL; /* VFD for file */ - H5P_genplist_t *plist_ptr = NULL; + H5FD_class_t *driver = NULL; /* VFD for file */ + H5P_genplist_t *plist = NULL; H5FD_driver_prop_t driver_prop; /* Property for driver ID & info */ bool bcasted_eof = false; int64_t sf_eof = -1; int mpi_code; /* MPI return code */ H5FD_t *ret_value = NULL; + FUNC_ENTER_PACKAGE + /* Check arguments */ if (!name || !*name) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "invalid file name"); + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "invalid file name"); if (0 == maxaddr || HADDR_UNDEF == maxaddr) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADRANGE, NULL, "bogus maxaddr"); + HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, NULL, "bogus maxaddr"); if (ADDR_OVERFLOW(maxaddr)) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, NULL, "bogus maxaddr"); - - if (NULL == (file_ptr = (H5FD_subfiling_t *)H5FL_CALLOC(H5FD_subfiling_t))) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTALLOC, NULL, "unable to allocate file struct"); - file_ptr->comm = MPI_COMM_NULL; - file_ptr->info = MPI_INFO_NULL; - file_ptr->file_id = UINT64_MAX; - file_ptr->context_id = -1; - file_ptr->fa.ioc_fapl_id = H5I_INVALID_HID; - file_ptr->ext_comm = MPI_COMM_NULL; - file_ptr->fail_to_encode = false; + HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, NULL, "bogus maxaddr"); + + if (NULL == (file = (H5FD_subfiling_t *)H5FL_CALLOC(H5FD_subfiling_t))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, NULL, "unable to allocate file struct"); + file->comm = MPI_COMM_NULL; + file->info = MPI_INFO_NULL; + file->file_id = UINT64_MAX; + file->context_id = -1; + file->fa.ioc_fapl_id = H5I_INVALID_HID; + file->ext_comm = MPI_COMM_NULL; + file->fail_to_encode = false; /* Get the driver-specific file access properties */ - if (NULL == (plist_ptr = (H5P_genplist_t *)H5I_object(fapl_id))) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file access property list"); + if (NULL == (plist = (H5P_genplist_t *)H5I_object(fapl_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file access property list"); if (H5FD_mpi_self_initialized) { - file_ptr->comm = MPI_COMM_WORLD; - file_ptr->info = MPI_INFO_NULL; + file->comm = MPI_COMM_WORLD; + file->info = MPI_INFO_NULL; } else { /* Get the MPI communicator and info object from the property list */ - if (H5P_get(plist_ptr, H5F_ACS_MPI_PARAMS_COMM_NAME, &file_ptr->comm) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTGET, NULL, "can't get MPI communicator"); - if (H5P_get(plist_ptr, H5F_ACS_MPI_PARAMS_INFO_NAME, &file_ptr->info) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTGET, NULL, "can't get MPI info object"); + if (H5P_get(plist, H5F_ACS_MPI_PARAMS_COMM_NAME, &file->comm) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, NULL, "can't get MPI communicator"); + if (H5P_get(plist, H5F_ACS_MPI_PARAMS_INFO_NAME, &file->info) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, NULL, "can't get MPI info object"); - if (file_ptr->comm == MPI_COMM_NULL) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_BADVALUE, NULL, "invalid or unset MPI communicator in FAPL"); + if (file->comm == MPI_COMM_NULL) + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, NULL, "invalid or unset MPI communicator in FAPL"); } /* Get the MPI rank of this process and the total number of processes */ - if (MPI_SUCCESS != (mpi_code = MPI_Comm_rank(file_ptr->comm, &file_ptr->mpi_rank))) - H5_SUBFILING_MPI_GOTO_ERROR(NULL, "MPI_Comm_rank failed", mpi_code); - if (MPI_SUCCESS != (mpi_code = MPI_Comm_size(file_ptr->comm, &file_ptr->mpi_size))) - H5_SUBFILING_MPI_GOTO_ERROR(NULL, "MPI_Comm_size failed", mpi_code); + if (MPI_SUCCESS != (mpi_code = MPI_Comm_rank(file->comm, &file->mpi_rank))) + HMPI_GOTO_ERROR(NULL, "MPI_Comm_rank failed", mpi_code); + if (MPI_SUCCESS != (mpi_code = MPI_Comm_size(file->comm, &file->mpi_size))) + HMPI_GOTO_ERROR(NULL, "MPI_Comm_size failed", mpi_code); /* Work around an HDF5 metadata cache bug with distributed metadata writes when MPI size == 1 */ - if (file_ptr->mpi_size == 1) { + if (file->mpi_size == 1) { H5AC_cache_config_t mdc_config; /* Get the current initial metadata cache resize configuration */ - if (H5P_get(plist_ptr, H5F_ACS_META_CACHE_INIT_CONFIG_NAME, &mdc_config) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get metadata cache initial config"); + if (H5P_get(plist, H5F_ACS_META_CACHE_INIT_CONFIG_NAME, &mdc_config) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, NULL, "can't get metadata cache initial config"); mdc_config.metadata_write_strategy = H5AC_METADATA_WRITE_STRATEGY__PROCESS_0_ONLY; - if (H5P_set(plist_ptr, H5F_ACS_META_CACHE_INIT_CONFIG_NAME, &mdc_config) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_PLIST, H5E_CANTSET, NULL, "can't set metadata cache initial config"); + if (H5P_set(plist, H5F_ACS_META_CACHE_INIT_CONFIG_NAME, &mdc_config) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTSET, NULL, "can't set metadata cache initial config"); } - config_ptr = H5P_peek_driver_info(plist_ptr); - if (!config_ptr || (H5P_FILE_ACCESS_DEFAULT == fapl_id)) { + config = H5P_peek_driver_info(plist); + if (!config || (H5P_FILE_ACCESS_DEFAULT == fapl_id)) { if (H5FD__subfiling_get_default_config(fapl_id, &default_config) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, - "can't get default subfiling VFD configuration"); - config_ptr = &default_config; + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, NULL, "can't get default subfiling VFD configuration"); + config = &default_config; } - H5MM_memcpy(&file_ptr->fa, config_ptr, sizeof(H5FD_subfiling_config_t)); - if (H5FD__copy_plist(config_ptr->ioc_fapl_id, &(file_ptr->fa.ioc_fapl_id)) < 0) { - file_ptr->fa.ioc_fapl_id = H5I_INVALID_HID; - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_BADVALUE, NULL, "can't copy FAPL"); + H5MM_memcpy(&file->fa, config, sizeof(H5FD_subfiling_config_t)); + if (H5FD__copy_plist(config->ioc_fapl_id, &file->fa.ioc_fapl_id) < 0) { + file->fa.ioc_fapl_id = H5I_INVALID_HID; + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, NULL, "can't copy FAPL"); } /* Check the "native" driver (IOC/sec2/etc.) */ - if (NULL == (plist_ptr = H5I_object(file_ptr->fa.ioc_fapl_id))) - H5_SUBFILING_GOTO_ERROR(H5E_PLIST, H5E_BADVALUE, NULL, "invalid IOC FAPL"); + if (NULL == (plist = H5I_object(file->fa.ioc_fapl_id))) + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, NULL, "invalid IOC FAPL"); - if (H5P_peek(plist_ptr, H5F_ACS_FILE_DRV_NAME, &driver_prop) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get driver ID & info"); + if (H5P_peek(plist, H5F_ACS_FILE_DRV_NAME, &driver_prop) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, NULL, "can't get driver ID & info"); if (NULL == (driver = (H5FD_class_t *)H5I_object(driver_prop.driver_id))) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_BADVALUE, NULL, - "invalid driver ID in file access property list"); + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, NULL, "invalid driver ID in file access property list"); if (driver->value != H5_VFD_IOC) - H5_SUBFILING_GOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, - "unable to open file '%s' - only IOC VFD is currently supported for subfiles", - name); + HGOTO_ERROR(H5E_VFL, H5E_CANTOPENFILE, NULL, + "unable to open file '%s' - only IOC VFD is currently supported for subfiles", name); /* Fully resolve the given filepath and get its dirname */ - if (H5_resolve_pathname(name, file_ptr->comm, &file_ptr->file_path) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTGET, NULL, "can't resolve filepath"); - if (H5_dirname(file_ptr->file_path, &file_ptr->file_dir) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTGET, NULL, "can't get filepath dirname"); + if (H5FD__subfiling_resolve_pathname(name, file->comm, &file->file_path) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, NULL, "can't resolve filepath"); + if (H5_dirname(file->file_path, &file->file_dir) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, NULL, "can't get filepath dirname"); /* * Create/open the HDF5 stub file and get its inode value for * the internal mapping from file inode to subfiling context. */ - if (H5_open_subfiling_stub_file(file_ptr->file_path, flags, file_ptr->comm, &file_ptr->stub_file, - &file_ptr->file_id) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "can't open HDF5 stub file"); + if (H5FD__subfiling_open_stub_file(file->file_path, flags, file->comm, &file->stub_file, &file->file_id) < + 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTOPENFILE, NULL, "can't open HDF5 stub file"); /* Set stub file ID on IOC fapl so it can reuse on open */ - if (H5_subfiling_set_file_id_prop(plist_ptr, file_ptr->file_id) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_PLIST, H5E_CANTSET, NULL, "can't set stub file ID on FAPL"); + if (H5FD__subfiling_set_file_id_prop(plist, file->file_id) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTSET, NULL, "can't set stub file ID on FAPL"); /* Open the HDF5 file's subfiles */ - if (H5FD_open(false, &file_ptr->sf_file, name, flags, file_ptr->fa.ioc_fapl_id, HADDR_UNDEF) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTOPENFILE, NULL, "unable to open IOC file"); - - if (driver->value == H5_VFD_IOC) { - /* Get a copy of the context ID for later use */ - if (H5_subfile_fid_to_context(file_ptr->file_id, &file_ptr->context_id) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTGET, NULL, - "unable to retrieve subfiling context ID for this file"); - file_ptr->fa.require_ioc = true; - } - else if (driver->value == H5_VFD_SEC2) { - int ioc_flags; - - /* Translate the HDF5 file open flags into standard POSIX open flags */ - ioc_flags = (H5F_ACC_RDWR & flags) ? O_RDWR : O_RDONLY; - if (H5F_ACC_TRUNC & flags) - ioc_flags |= O_TRUNC; - if (H5F_ACC_CREAT & flags) - ioc_flags |= O_CREAT; - if (H5F_ACC_EXCL & flags) - ioc_flags |= O_EXCL; + if (H5FD_open(false, &file->sf_file, name, flags, file->fa.ioc_fapl_id, HADDR_UNDEF) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTOPENFILE, NULL, "unable to open IOC file"); - /* - * Open the subfiles for this HDF5 file. A subfiling - * context ID will be returned, which is used for - * further interactions with this file's subfiles. - */ - if (H5_open_subfiles(file_ptr->file_path, file_ptr->file_id, &file_ptr->fa.shared_cfg, ioc_flags, - file_ptr->comm, &file_ptr->context_id) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to open subfiling files = %s\n", - name); - } + /* Get a copy of the context ID for later use */ + if (H5FD__subfile_fid_to_context(file->file_id, &file->context_id) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, NULL, "unable to retrieve subfiling context ID for this file"); + file->fa.require_ioc = true; - if (file_ptr->mpi_rank == 0) { - if (H5FD__subfiling__get_real_eof(file_ptr->context_id, &sf_eof) < 0) + if (file->mpi_rank == 0) + if (H5FD__subfiling__get_real_eof(file->context_id, &sf_eof) < 0) sf_eof = -1; - } - - if (file_ptr->mpi_size > 1) { - if (MPI_SUCCESS != (mpi_code = MPI_Bcast(&sf_eof, 1, MPI_INT64_T, 0, file_ptr->comm))) - H5_SUBFILING_MPI_GOTO_ERROR(NULL, "MPI_Bcast", mpi_code); - } - + if (file->mpi_size > 1) + if (MPI_SUCCESS != (mpi_code = MPI_Bcast(&sf_eof, 1, MPI_INT64_T, 0, file->comm))) + HMPI_GOTO_ERROR(NULL, "MPI_Bcast", mpi_code); bcasted_eof = true; - if (sf_eof < 0) - H5_SUBFILING_GOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "lead MPI process failed to get file EOF"); + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, NULL, "lead MPI process failed to get file EOF"); - file_ptr->eof = (haddr_t)sf_eof; - file_ptr->local_eof = file_ptr->eof; + file->eof = (haddr_t)sf_eof; + file->local_eof = file->eof; - ret_value = (H5FD_t *)file_ptr; + ret_value = (H5FD_t *)file; done: - if (config_ptr == &default_config) - if (H5I_dec_ref(config_ptr->ioc_fapl_id) < 0) - H5_SUBFILING_DONE_ERROR(H5E_PLIST, H5E_CANTCLOSEOBJ, NULL, "can't close IOC FAPL"); + if (config == &default_config) + if (H5I_dec_ref(config->ioc_fapl_id) < 0) + HDONE_ERROR(H5E_VFL, H5E_CANTCLOSEOBJ, NULL, "can't close IOC FAPL"); - if (NULL == ret_value) { - if (file_ptr) { + if (NULL == ret_value) + if (file) { /* Participate in possible MPI collectives on failure */ - if (file_ptr->comm != MPI_COMM_NULL) { + if (file->comm != MPI_COMM_NULL) if (!bcasted_eof) { sf_eof = -1; - if (file_ptr->mpi_size > 1) { - if (MPI_SUCCESS != (mpi_code = MPI_Bcast(&sf_eof, 1, MPI_INT64_T, 0, file_ptr->comm))) - H5_SUBFILING_MPI_DONE_ERROR(NULL, "MPI_Bcast failed", mpi_code); - } + if (file->mpi_size > 1) + if (MPI_SUCCESS != (mpi_code = MPI_Bcast(&sf_eof, 1, MPI_INT64_T, 0, file->comm))) + HMPI_DONE_ERROR(NULL, "MPI_Bcast failed", mpi_code); } - } - if (H5FD__subfiling_close_int(file_ptr) < 0) - H5_SUBFILING_DONE_ERROR(H5E_FILE, H5E_CLOSEERROR, NULL, "couldn't close file"); + if (H5FD__subfiling_close_int(file) < 0) + HDONE_ERROR(H5E_VFL, H5E_CLOSEERROR, NULL, "couldn't close file"); } - } - H5_SUBFILING_FUNC_LEAVE_API; + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__subfiling_open() */ static herr_t -H5FD__subfiling_close_int(H5FD_subfiling_t *file_ptr) +H5FD__subfiling_close_int(H5FD_subfiling_t *file) { int mpi_finalized; int mpi_code; herr_t ret_value = SUCCEED; - assert(file_ptr); + FUNC_ENTER_PACKAGE - if (MPI_SUCCESS != (mpi_code = MPI_Finalized(&mpi_finalized))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Finalized failed", mpi_code); + assert(file); - if (file_ptr->sf_file && H5FD_close(file_ptr->sf_file) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_CANTCLOSEFILE, FAIL, "unable to close subfile"); - if (file_ptr->stub_file && H5FD_close(file_ptr->stub_file) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_CANTCLOSEFILE, FAIL, "unable to close HDF5 stub file"); + if (file->sf_file && H5FD_close(file->sf_file) < 0) + HDONE_ERROR(H5E_VFL, H5E_CANTCLOSEFILE, FAIL, "unable to close subfile"); + if (file->stub_file && H5FD_close(file->stub_file) < 0) + HDONE_ERROR(H5E_VFL, H5E_CANTCLOSEFILE, FAIL, "unable to close HDF5 stub file"); - /* if set, close the copy of the plist for the underlying VFD. */ - if ((file_ptr->fa.ioc_fapl_id >= 0) && (H5I_dec_ref(file_ptr->fa.ioc_fapl_id) < 0)) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_ARGS, FAIL, "can't close IOC FAPL"); - file_ptr->fa.ioc_fapl_id = H5I_INVALID_HID; + /* If set, close the copy of the plist for the underlying VFD. */ + if (file->fa.ioc_fapl_id >= 0 && H5I_dec_ref(file->fa.ioc_fapl_id) < 0) + HDONE_ERROR(H5E_VFL, H5E_CANTDEC, FAIL, "can't close IOC FAPL"); + if (MPI_SUCCESS != (mpi_code = MPI_Finalized(&mpi_finalized))) + HMPI_DONE_ERROR(FAIL, "MPI_Finalized failed", mpi_code); if (!mpi_finalized) { - if (H5_mpi_comm_free(&file_ptr->comm) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "unable to free MPI Communicator"); - if (H5_mpi_info_free(&file_ptr->info) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "unable to free MPI Info object"); - - if (H5_mpi_comm_free(&file_ptr->ext_comm) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "can't free MPI communicator"); + if (H5_mpi_comm_free(&file->comm) < 0) + HDONE_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "unable to free MPI Communicator"); + if (H5_mpi_info_free(&file->info) < 0) + HDONE_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "unable to free MPI Info object"); + if (H5_mpi_comm_free(&file->ext_comm) < 0) + HDONE_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "can't free MPI communicator"); } - file_ptr->fail_to_encode = false; + H5MM_free(file->file_path); + H5MM_free(file->file_dir); -done: - free(file_ptr->file_path); - file_ptr->file_path = NULL; - - H5MM_free(file_ptr->file_dir); - file_ptr->file_dir = NULL; - - if (file_ptr->context_id >= 0 && H5_free_subfiling_object(file_ptr->context_id) < 0) - H5_SUBFILING_DONE_ERROR(H5E_FILE, H5E_CANTFREE, FAIL, "can't free subfiling context object"); + if (file->context_id >= 0 && H5FD__subfiling_free_object(file->context_id) < 0) + HDONE_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "can't free subfiling context object"); /* Release the file info */ - file_ptr = H5FL_FREE(H5FD_subfiling_t, file_ptr); + H5FL_FREE(H5FD_subfiling_t, file); - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /*------------------------------------------------------------------------- @@ -1378,14 +1308,16 @@ H5FD__subfiling_close_int(H5FD_subfiling_t *file_ptr) static herr_t H5FD__subfiling_close(H5FD_t *_file) { - H5FD_subfiling_t *file_ptr = (H5FD_subfiling_t *)_file; + H5FD_subfiling_t *file = (H5FD_subfiling_t *)_file; herr_t ret_value = SUCCEED; - if (H5FD__subfiling_close_int(file_ptr) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "unable to close file"); + FUNC_ENTER_PACKAGE + + if (H5FD__subfiling_close_int(file) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTCLOSEFILE, FAIL, "unable to close file"); done: - H5_SUBFILING_FUNC_LEAVE_API; + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__subfiling_close() */ /*------------------------------------------------------------------------- @@ -1395,8 +1327,7 @@ H5FD__subfiling_close(H5FD_t *_file) * arbitrary (but consistent) ordering. * * Return: Success: A value like strcmp() - * Failure: never fails (arguments were checked by the - * caller). + * Failure: never fails (arguments were checked by the caller). * *------------------------------------------------------------------------- */ @@ -1407,12 +1338,14 @@ H5FD__subfiling_cmp(const H5FD_t *_f1, const H5FD_t *_f2) const H5FD_subfiling_t *f2 = (const H5FD_subfiling_t *)_f2; int ret_value = 0; + FUNC_ENTER_PACKAGE_NOERR + assert(f1); assert(f2); ret_value = H5FD_cmp(f1->sf_file, f2->sf_file); - H5_SUBFILING_FUNC_LEAVE_API; + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__subfiling_cmp() */ /*------------------------------------------------------------------------- @@ -1432,7 +1365,7 @@ H5FD__subfiling_cmp(const H5FD_t *_f1, const H5FD_t *_f2) static herr_t H5FD__subfiling_query(const H5FD_t H5_ATTR_UNUSED *_file, unsigned long *flags /* out */) { - herr_t ret_value = SUCCEED; + FUNC_ENTER_PACKAGE_NOERR /* Set the VFL feature flags that this driver supports */ if (flags) { @@ -1442,7 +1375,7 @@ H5FD__subfiling_query(const H5FD_t H5_ATTR_UNUSED *_file, unsigned long *flags / *flags |= H5FD_FEAT_HAS_MPI; /* This driver uses MPI */ } - H5_SUBFILING_FUNC_LEAVE_API; + FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5FD__subfiling_query() */ /*------------------------------------------------------------------------- @@ -1459,12 +1392,11 @@ H5FD__subfiling_query(const H5FD_t H5_ATTR_UNUSED *_file, unsigned long *flags / static haddr_t H5FD__subfiling_get_eoa(const H5FD_t *_file, H5FD_mem_t H5_ATTR_UNUSED type) { - const H5FD_subfiling_t *file = (const H5FD_subfiling_t *)_file; - haddr_t ret_value = HADDR_UNDEF; + const H5FD_subfiling_t *file = (const H5FD_subfiling_t *)_file; - ret_value = file->eoa; + FUNC_ENTER_PACKAGE_NOERR - H5_SUBFILING_FUNC_LEAVE_API; + FUNC_LEAVE_NOAPI(file->eoa) } /* end H5FD__subfiling_get_eoa() */ /*------------------------------------------------------------------------- @@ -1481,21 +1413,23 @@ H5FD__subfiling_get_eoa(const H5FD_t *_file, H5FD_mem_t H5_ATTR_UNUSED type) static herr_t H5FD__subfiling_set_eoa(H5FD_t *_file, H5FD_mem_t type, haddr_t addr) { - H5FD_subfiling_t *file_ptr = (H5FD_subfiling_t *)_file; + H5FD_subfiling_t *file = (H5FD_subfiling_t *)_file; herr_t ret_value = SUCCEED; - file_ptr->eoa = addr; + FUNC_ENTER_PACKAGE + + file->eoa = addr; /* Set EOA for HDF5 stub file */ - if (file_ptr->mpi_rank == 0) { - if (H5FD_set_eoa(file_ptr->stub_file, type, addr) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "can't set HDF5 stub file EOA"); - } + if (file->mpi_rank == 0) + if (H5FD_set_eoa(file->stub_file, type, addr) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTSET, FAIL, "can't set HDF5 stub file EOA"); - ret_value = H5FD_set_eoa(file_ptr->sf_file, type, addr); + if (H5FD_set_eoa(file->sf_file, type, addr) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTSET, FAIL, "can't set subfile EOA"); done: - H5_SUBFILING_FUNC_LEAVE_API; + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__subfiling_set_eoa() */ /*------------------------------------------------------------------------- @@ -1517,12 +1451,11 @@ H5FD__subfiling_set_eoa(H5FD_t *_file, H5FD_mem_t type, haddr_t addr) static haddr_t H5FD__subfiling_get_eof(const H5FD_t *_file, H5FD_mem_t H5_ATTR_UNUSED type) { - const H5FD_subfiling_t *file = (const H5FD_subfiling_t *)_file; - haddr_t ret_value = HADDR_UNDEF; + const H5FD_subfiling_t *file = (const H5FD_subfiling_t *)_file; - ret_value = file->eof; + FUNC_ENTER_PACKAGE_NOERR - H5_SUBFILING_FUNC_LEAVE_API; + FUNC_LEAVE_NOAPI(file->eof) } /* end H5FD__subfiling_get_eof() */ /*------------------------------------------------------------------------- @@ -1540,13 +1473,16 @@ H5FD__subfiling_get_handle(H5FD_t *_file, hid_t H5_ATTR_UNUSED fapl, void **file H5FD_subfiling_t *file = (H5FD_subfiling_t *)_file; herr_t ret_value = SUCCEED; + FUNC_ENTER_PACKAGE + if (!file_handle) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "file handle not valid"); + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "file handle not valid"); - H5FD_get_vfd_handle(file->sf_file, file->fa.ioc_fapl_id, file_handle); + if (H5FD_get_vfd_handle(file->sf_file, file->fa.ioc_fapl_id, file_handle) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get subfile handle"); done: - H5_SUBFILING_FUNC_LEAVE_API; + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__subfiling_get_handle() */ /*------------------------------------------------------------------------- @@ -1566,32 +1502,33 @@ static herr_t H5FD__subfiling_read(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED dxpl_id, haddr_t addr, size_t size, void *buf /*out*/) { - H5FD_subfiling_t *file_ptr = (H5FD_subfiling_t *)_file; + H5FD_subfiling_t *file = (H5FD_subfiling_t *)_file; herr_t ret_value = SUCCEED; - assert(file_ptr); - assert(file_ptr->pub.driver_id == H5FD_SUBFILING); + FUNC_ENTER_PACKAGE + + assert(file); assert(buf); - if (H5FD__subfiling_io_helper(file_ptr, 1, &type, &addr, &size, (H5_flexible_const_ptr_t *)&buf, + if (H5FD__subfiling_io_helper(file, 1, &type, &addr, &size, (H5_flexible_const_ptr_t *)&buf, IO_TYPE_READ) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "read from subfiles failed"); + HGOTO_ERROR(H5E_VFL, H5E_READERROR, FAIL, "read from subfiles failed"); /* Point to the end of the current I/O */ addr += (haddr_t)size; /* Update current file position and EOF */ - file_ptr->pos = addr; - file_ptr->op = OP_READ; + file->pos = addr; + file->op = OP_READ; done: if (ret_value < 0) { /* Reset last file I/O information */ - file_ptr->pos = HADDR_UNDEF; - file_ptr->op = OP_UNKNOWN; + file->pos = HADDR_UNDEF; + file->op = OP_UNKNOWN; } /* end if */ - H5_SUBFILING_FUNC_LEAVE_API; + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__subfiling_read() */ /*------------------------------------------------------------------------- @@ -1609,44 +1546,45 @@ static herr_t H5FD__subfiling_write(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED dxpl_id, haddr_t addr, size_t size, const void *buf /*in*/) { - H5FD_subfiling_t *file_ptr = (H5FD_subfiling_t *)_file; + H5FD_subfiling_t *file = (H5FD_subfiling_t *)_file; herr_t ret_value = SUCCEED; - assert(file_ptr); - assert(file_ptr->pub.driver_id == H5FD_SUBFILING); + FUNC_ENTER_PACKAGE + + assert(file); assert(buf); - if (H5FD__subfiling_io_helper(file_ptr, 1, &type, &addr, &size, (H5_flexible_const_ptr_t *)&buf, + if (H5FD__subfiling_io_helper(file, 1, &type, &addr, &size, (H5_flexible_const_ptr_t *)&buf, IO_TYPE_WRITE) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "write to subfiles failed"); + HGOTO_ERROR(H5E_VFL, H5E_WRITEERROR, FAIL, "write to subfiles failed"); /* Point to the end of the current I/O */ addr += (haddr_t)size; /* Update current file position and EOF */ - file_ptr->pos = addr; - file_ptr->op = OP_WRITE; + file->pos = addr; + file->op = OP_WRITE; /* Mimic the MPI I/O VFD */ - file_ptr->eof = HADDR_UNDEF; + file->eof = HADDR_UNDEF; - if (file_ptr->pos > file_ptr->local_eof) - file_ptr->local_eof = file_ptr->pos; + if (file->pos > file->local_eof) + file->local_eof = file->pos; done: if (ret_value < 0) { /* Reset last file I/O information */ - file_ptr->pos = HADDR_UNDEF; - file_ptr->op = OP_UNKNOWN; + file->pos = HADDR_UNDEF; + file->op = OP_UNKNOWN; } /* end if */ - H5_SUBFILING_FUNC_LEAVE_API; + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__subfiling_write() */ /*------------------------------------------------------------------------- - * Function: H5FD__subfile_read_vector (internal function) + * Function: H5FD__subfile_read_vector * - * Purpose: Vector Read function for the sub-filing VFD. + * Purpose: Vector Read function for the subfiling VFD. * * Perform count reads from the specified file at the offsets * provided in the addrs array, with the lengths and memory @@ -1657,23 +1595,7 @@ H5FD__subfiling_write(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED dxpl_ * list dxpl_id (which may be the constant H5P_DEFAULT). * * Return: Success: SUCCEED - * All reads have completed successfully, and - * the results havce been into the supplied - * buffers. - * * Failure: FAIL - * The contents of supplied buffers are undefined. - * - * Notes: Thus function doesn't actually implement vector read. - * Instead, it converts the vector read call into a series - * of scalar read calls. Fix this when time permits. - * - * Also, it didn't support the sizes and types optimization. - * I implemented a version of this which is more generous - * than that currently defined in the RFC. This is good - * enough for now, but the final version should follow - * the RFC. - * JRM -- 10/5/21 * *------------------------------------------------------------------------- */ @@ -1681,47 +1603,36 @@ static herr_t H5FD__subfiling_read_vector(H5FD_t *_file, hid_t dxpl_id, uint32_t count, H5FD_mem_t types[], haddr_t addrs[], size_t sizes[], void *bufs[] /* out */) { - H5FD_subfiling_t *file_ptr = (H5FD_subfiling_t *)_file; + H5FD_subfiling_t *file = (H5FD_subfiling_t *)_file; herr_t ret_value = SUCCEED; - assert(file_ptr); - assert(file_ptr->pub.driver_id == H5FD_SUBFILING); - assert((types) || (count == 0)); - assert((addrs) || (count == 0)); - assert((sizes) || (count == 0)); - assert((bufs) || (count == 0)); + FUNC_ENTER_PACKAGE - /* - * Verify that the first elements of the sizes and - * types arrays are valid. - */ - assert((count == 0) || (sizes[0] != 0)); - assert((count == 0) || (types[0] != H5FD_MEM_NOLIST)); + assert(file); + assert(count == 0 || types); + assert(count == 0 || addrs); + assert(count == 0 || sizes); + assert(count == 0 || bufs); + + /* Verify that the first elements of the sizes and types arrays are valid */ + assert(count == 0 || sizes[0] != 0); + assert(count == 0 || types[0] != H5FD_MEM_NOLIST); /* Get the default dataset transfer property list if the user didn't provide one */ - if (H5P_DEFAULT == dxpl_id) { + if (H5P_DEFAULT == dxpl_id) dxpl_id = H5P_DATASET_XFER_DEFAULT; - } - else { - if (true != H5P_isa_class(dxpl_id, H5P_DATASET_XFER)) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data transfer property list"); - } + else if (true != H5P_isa_class(dxpl_id, H5P_DATASET_XFER)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data transfer property list"); /* Set DXPL for operation */ H5CX_set_dxpl(dxpl_id); - if (file_ptr->fa.require_ioc) { - if (H5FD__subfiling_io_helper(file_ptr, (size_t)count, types, addrs, sizes, - (H5_flexible_const_ptr_t *)bufs, IO_TYPE_READ) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "couldn't read data"); - } - else { - if (H5FD_read_vector(_file, count, types, addrs, sizes, bufs) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "couldn't read data"); - } + if (H5FD__subfiling_io_helper(file, (size_t)count, types, addrs, sizes, (H5_flexible_const_ptr_t *)bufs, + IO_TYPE_READ) < 0) + HGOTO_ERROR(H5E_VFL, H5E_READERROR, FAIL, "couldn't read data"); done: - H5_SUBFILING_FUNC_LEAVE_API; + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__subfiling_read_vector() */ /*------------------------------------------------------------------------- @@ -1736,12 +1647,7 @@ H5FD__subfiling_read_vector(H5FD_t *_file, hid_t dxpl_id, uint32_t count, H5FD_m * list dxpl_id (which may be the constant H5P_DEFAULT). * * Return: Success: SUCCEED - * All writes have completed successfully. - * * Failure: FAIL - * An internal error was encountered, e.g the - * input arguments are not valid, or the actual - * subfiling writes have failed for some reason. * *------------------------------------------------------------------------- */ @@ -1749,48 +1655,37 @@ static herr_t H5FD__subfiling_write_vector(H5FD_t *_file, hid_t dxpl_id, uint32_t count, H5FD_mem_t types[], haddr_t addrs[], size_t sizes[], const void *bufs[] /* in */) { - H5FD_subfiling_t *file_ptr = (H5FD_subfiling_t *)_file; + H5FD_subfiling_t *file = (H5FD_subfiling_t *)_file; herr_t ret_value = SUCCEED; - assert(file_ptr); - assert(file_ptr->pub.driver_id == H5FD_SUBFILING); - assert((types) || (count == 0)); - assert((addrs) || (count == 0)); - assert((sizes) || (count == 0)); - assert((bufs) || (count == 0)); + FUNC_ENTER_PACKAGE - /* - * Verify that the first elements of the sizes and - * types arrays are valid. - */ - assert((count == 0) || (sizes[0] != 0)); - assert((count == 0) || (types[0] != H5FD_MEM_NOLIST)); + assert(file); + assert(count == 0 || types); + assert(count == 0 || addrs); + assert(count == 0 || sizes); + assert(count == 0 || bufs); + + /* Verify that the first elements of the sizes and types arrays are valid */ + assert(count == 0 || sizes[0] != 0); + assert(count == 0 || types[0] != H5FD_MEM_NOLIST); /* Get the default dataset transfer property list if the user didn't provide one */ - if (H5P_DEFAULT == dxpl_id) { + if (H5P_DEFAULT == dxpl_id) dxpl_id = H5P_DATASET_XFER_DEFAULT; - } - else { - if (true != H5P_isa_class(dxpl_id, H5P_DATASET_XFER)) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data transfer property list"); - } + else if (true != H5P_isa_class(dxpl_id, H5P_DATASET_XFER)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data transfer property list"); /* Set DXPL for operation */ H5CX_set_dxpl(dxpl_id); - if (file_ptr->fa.require_ioc) { - if (H5FD__subfiling_io_helper(file_ptr, (size_t)count, types, addrs, sizes, - (H5_flexible_const_ptr_t *)bufs, IO_TYPE_WRITE) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "couldn't write data"); - } - else { - if (H5FD_write_vector(_file, count, types, addrs, sizes, bufs) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "couldn't write data"); - } + if (H5FD__subfiling_io_helper(file, (size_t)count, types, addrs, sizes, (H5_flexible_const_ptr_t *)bufs, + IO_TYPE_WRITE) < 0) + HGOTO_ERROR(H5E_VFL, H5E_WRITEERROR, FAIL, "couldn't write data"); done: - H5_SUBFILING_FUNC_LEAVE_API; -} /* end H5FDsubfile__write_vector() */ + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5FD__subfile__write_vector() */ /*------------------------------------------------------------------------- * Function: H5FD__subfiling_truncate @@ -1808,6 +1703,8 @@ H5FD__subfiling_truncate(H5FD_t *_file, hid_t H5_ATTR_UNUSED dxpl_id, bool H5_AT H5FD_subfiling_t *file = (H5FD_subfiling_t *)_file; herr_t ret_value = SUCCEED; /* Return value */ + FUNC_ENTER_PACKAGE + assert(file); /* Extend the file to make sure it's large enough */ @@ -1816,24 +1713,21 @@ H5FD__subfiling_truncate(H5FD_t *_file, hid_t H5_ATTR_UNUSED dxpl_id, bool H5_AT int64_t eoa; int mpi_code; - if (!H5CX_get_mpi_file_flushing()) { + if (!H5CX_get_mpi_file_flushing()) if (file->mpi_size > 1) if (MPI_SUCCESS != (mpi_code = MPI_Barrier(file->comm))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Barrier failed", mpi_code); - } + HMPI_GOTO_ERROR(FAIL, "MPI_Barrier failed", mpi_code); - if (0 == file->mpi_rank) { + if (0 == file->mpi_rank) if (H5FD__subfiling__get_real_eof(file->context_id, &sf_eof) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get EOF"); - } + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get EOF"); - if (file->mpi_size > 1) { + if (file->mpi_size > 1) if (MPI_SUCCESS != (mpi_code = MPI_Bcast(&sf_eof, 1, MPI_INT64_T, 0, file->comm))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Bcast failed", mpi_code); - } + HMPI_GOTO_ERROR(FAIL, "MPI_Bcast failed", mpi_code); if (sf_eof < 0) - H5_SUBFILING_GOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "invalid EOF"); + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "invalid EOF"); H5_CHECKED_ASSIGN(eoa, int64_t, file->eoa, haddr_t); @@ -1844,14 +1738,13 @@ H5FD__subfiling_truncate(H5FD_t *_file, hid_t H5_ATTR_UNUSED dxpl_id, bool H5_AT * JRM -- 12/18/21 */ if (H5FD__subfiling__truncate_sub_files(file->context_id, eoa, file->comm) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTUPDATE, FAIL, "subfile truncate request failed"); + HGOTO_ERROR(H5E_VFL, H5E_CANTUPDATE, FAIL, "subfile truncate request failed"); #if 0 /* TODO: Should be truncated only to size of superblock metadata */ /* Truncate the HDF5 stub file */ - if (file->mpi_rank == 0) { + if (file->mpi_rank == 0) if (H5FD_truncate(file->stub_file, closing) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTUPDATE, FAIL, "stub file truncate request failed"); - } + HGOTO_ERROR(H5E_VFL, H5E_CANTUPDATE, FAIL, "stub file truncate request failed"); #endif /* Reset last file I/O information */ @@ -1863,69 +1756,9 @@ H5FD__subfiling_truncate(H5FD_t *_file, hid_t H5_ATTR_UNUSED dxpl_id, bool H5_AT } done: - H5_SUBFILING_FUNC_LEAVE_API; + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__subfiling_truncate() */ -/*------------------------------------------------------------------------- - * Function: H5FD__subfiling_lock - * - * Purpose: To place an advisory lock on a file. - * The lock type to apply depends on the parameter "rw": - * true--opens for write: an exclusive lock - * false--opens for read: a shared lock - * - * Return: SUCCEED/FAIL - * - *------------------------------------------------------------------------- - */ -#if 0 -static herr_t -H5FD__subfiling_lock(H5FD_t *_file, bool rw) -{ - H5FD_subfiling_t *file = (H5FD_subfiling_t *)_file; /* VFD file struct */ - herr_t ret_value = SUCCEED; /* Return value */ - - assert(file); - - if (file->fa.require_ioc) { -#ifdef VERBOSE - puts("Subfiling driver doesn't support file locking"); -#endif - } - else { - if (H5FD_lock(file->sf_file, rw) < 0) - H5_SUBFILING_SYS_GOTO_ERROR(H5E_FILE, H5E_BADFILE, FAIL, "unable to lock file"); - } /* end if */ - -done: - H5_SUBFILING_FUNC_LEAVE_API; -} /* end H5FD__subfiling_lock() */ - -/*------------------------------------------------------------------------- - * Function: H5FD__subfiling_unlock - * - * Purpose: To remove the existing lock on the file - * - * Return: SUCCEED/FAIL - * - *------------------------------------------------------------------------- - */ -static herr_t -H5FD__subfiling_unlock(H5FD_t *_file) -{ - H5FD_subfiling_t *file = (H5FD_subfiling_t *)_file; /* VFD file struct */ - herr_t ret_value = SUCCEED; /* Return value */ - - assert(file); - - if (H5FD_unlock(file->sf_file) < 0) - H5_SUBFILING_SYS_GOTO_ERROR(H5E_FILE, H5E_BADFILE, FAIL, "unable to lock file"); - -done: - H5_SUBFILING_FUNC_LEAVE_API; -} /* end H5FD__subfiling_unlock() */ -#endif - static herr_t H5FD__subfiling_del(const char *name, hid_t fapl) { @@ -1934,28 +1767,29 @@ H5FD__subfiling_del(const char *name, hid_t fapl) H5P_genplist_t *plist = NULL; herr_t ret_value = SUCCEED; + FUNC_ENTER_PACKAGE + if (NULL == (plist = H5P_object_verify(fapl, H5P_FILE_ACCESS))) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list"); + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list"); if (H5FD_SUBFILING != H5P_peek_driver(plist)) - H5_SUBFILING_GOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "incorrect driver set on FAPL"); + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "incorrect driver set on FAPL"); if (NULL == (subfiling_config = H5P_peek_driver_info(plist))) { if (H5FD__subfiling_get_default_config(fapl, &default_config) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, - "can't get default Subfiling VFD configuration"); + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get default Subfiling VFD configuration"); subfiling_config = &default_config; } if (H5FD_delete(name, subfiling_config->ioc_fapl_id) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_FILE, H5E_CANTDELETE, FAIL, "unable to delete file"); + HGOTO_ERROR(H5E_VFL, H5E_CANTDELETE, FAIL, "unable to delete file"); done: if (subfiling_config == &default_config) if (H5I_dec_ref(subfiling_config->ioc_fapl_id) < 0) - H5_SUBFILING_DONE_ERROR(H5E_PLIST, H5E_CANTCLOSEOBJ, FAIL, "unable to close IOC FAPL"); + HDONE_ERROR(H5E_VFL, H5E_CANTCLOSEOBJ, FAIL, "unable to close IOC FAPL"); - H5_SUBFILING_FUNC_LEAVE_API; + FUNC_LEAVE_NOAPI(ret_value) } /*------------------------------------------------------------------------- @@ -1992,24 +1826,20 @@ H5FD__subfiling_ctl(H5FD_t *_file, uint64_t op_code, uint64_t flags, const void H5FD_subfiling_t *file = (H5FD_subfiling_t *)_file; herr_t ret_value = SUCCEED; /* Return value */ + FUNC_ENTER_PACKAGE + /* Sanity checks */ assert(file); - assert(H5FD_SUBFILING == file->pub.driver_id); switch (op_code) { - case H5FD_CTL_GET_MPI_COMMUNICATOR_OPCODE: assert(output); assert(*output); - /* - * Return a separate MPI communicator to the caller so - * that our own MPI calls won't have a chance to conflict - */ - if (file->ext_comm == MPI_COMM_NULL) { + /* Return a new MPI communicator so that our MPI calls are isolated */ + if (file->ext_comm == MPI_COMM_NULL) if (H5_mpi_comm_dup(file->comm, &file->ext_comm) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't duplicate MPI communicator"); - } + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't duplicate MPI communicator"); **((MPI_Comm **)output) = file->ext_comm; break; @@ -2033,14 +1863,13 @@ H5FD__subfiling_ctl(H5FD_t *_file, uint64_t op_code, uint64_t flags, const void break; default: /* unknown op code */ - if (flags & H5FD_CTL_FAIL_IF_UNKNOWN_FLAG) { - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_FCNTL, FAIL, "unknown op_code and fail if unknown"); - } + if (flags & H5FD_CTL_FAIL_IF_UNKNOWN_FLAG) + HGOTO_ERROR(H5E_VFL, H5E_FCNTL, FAIL, "unknown op_code and fail if unknown"); break; } done: - H5_SUBFILING_FUNC_LEAVE_API; + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__subfiling_ctl() */ /*------------------------------------------------------------------------- @@ -2054,7 +1883,7 @@ H5FD__subfiling_ctl(H5FD_t *_file, uint64_t op_code, uint64_t flags, const void *------------------------------------------------------------------------- */ static herr_t -H5FD__subfiling_io_helper(H5FD_subfiling_t *file_ptr, size_t io_count, H5FD_mem_t types[], haddr_t addrs[], +H5FD__subfiling_io_helper(H5FD_subfiling_t *file, size_t io_count, H5FD_mem_t types[], haddr_t addrs[], size_t sizes[], H5_flexible_const_ptr_t bufs[], H5FD_subfiling_io_type_t io_type) { H5_flexible_const_ptr_t *io_bufs = NULL; @@ -2070,36 +1899,32 @@ H5FD__subfiling_io_helper(H5FD_subfiling_t *file_ptr, size_t io_count, H5FD_mem_ int num_subfiles; herr_t ret_value = SUCCEED; - assert(file_ptr); + FUNC_ENTER_PACKAGE + + assert(file); - if (HADDR_UNDEF == (file_eoa = H5FD__subfiling_get_eoa((const H5FD_t *)file_ptr, H5FD_MEM_DEFAULT))) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get file EOA"); + if (HADDR_UNDEF == (file_eoa = H5FD__subfiling_get_eoa((const H5FD_t *)file, H5FD_MEM_DEFAULT))) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get file EOA"); /* Perform some sanity checking on the given (address, size) pairs */ extend_sizes = false; for (size_t i = 0; i < io_count; i++) { if (!extend_sizes) { - if ((i > 0) && (sizes[i] == 0)) { + if (i > 0 && sizes[i] == 0) extend_sizes = true; - io_size = sizes[i - 1]; - } - else { + else io_size = sizes[i]; - } } if (!H5_addr_defined(addrs[i])) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "addr[%zu] undefined, addr = %" PRIuHADDR, - i, addrs[i]); + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "addr[%zu] undefined, addr = %" PRIuHADDR, i, addrs[i]); if (REGION_OVERFLOW(addrs[i], io_size)) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, - "addr[%zu] overflow, addr = %" PRIuHADDR ", size = %zu", i, addrs[i], - io_size); + HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, "addr[%zu] overflow, addr = %" PRIuHADDR ", size = %zu", + i, addrs[i], io_size); if ((addrs[i] + io_size) > file_eoa) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, - "addr overflow, addrs[%zu] = %" PRIuHADDR - ", sizes[%zu] = %zu, eoa = %" PRIuHADDR, - i, addrs[i], i, io_size, file_eoa); + HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, + "addr overflow, addrs[%zu] = %" PRIuHADDR ", sizes[%zu] = %zu, eoa = %" PRIuHADDR, i, + addrs[i], i, io_size, file_eoa); } /* @@ -2108,15 +1933,15 @@ H5FD__subfiling_io_helper(H5FD_subfiling_t *file_ptr, size_t io_count, H5FD_mem_ * can be properly handled here. */ if (H5CX_get_io_xfer_mode(&xfer_mode) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_CONTEXT, H5E_CANTGET, FAIL, "can't determine I/O collectivity setting"); + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't determine I/O collectivity setting"); if (xfer_mode == H5FD_MPIO_COLLECTIVE) { MPI_Datatype btype, ftype; if (H5CX_get_mpi_coll_datatypes(&btype, &ftype) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_CONTEXT, H5E_CANTGET, FAIL, "can't get MPI-I/O datatypes"); + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get MPI-I/O datatypes"); if (MPI_BYTE != btype || MPI_BYTE != ftype) - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_UNSUPPORTED, FAIL, "collective I/O is currently unsupported"); + HGOTO_ERROR(H5E_VFL, H5E_UNSUPPORTED, FAIL, "collective I/O is currently unsupported"); } /* @@ -2141,14 +1966,12 @@ H5FD__subfiling_io_helper(H5FD_subfiling_t *file_ptr, size_t io_count, H5FD_mem_ * to size the vectors that will be used to invoke the * underlying I/O operations. */ - if (NULL == (sf_context = (subfiling_context_t *)H5_get_subfiling_object(file_ptr->context_id))) - H5_SUBFILING_GOTO_ERROR(H5E_INTERNAL, H5E_BADVALUE, FAIL, - "invalid or missing subfiling context object"); + if (NULL == (sf_context = (subfiling_context_t *)H5FD__subfiling_get_object(file->context_id))) + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "invalid or missing subfiling context object"); assert(sf_context->topology); if ((num_subfiles = sf_context->sf_num_subfiles) <= 0) - H5_SUBFILING_GOTO_ERROR(H5E_INTERNAL, H5E_BADVALUE, FAIL, "invalid number of subfiles (%d)", - num_subfiles); + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "invalid number of subfiles (%d)", num_subfiles); if (num_subfiles == 1) { uint32_t u32_io_count; @@ -2166,24 +1989,21 @@ H5FD__subfiling_io_helper(H5FD_subfiling_t *file_ptr, size_t io_count, H5FD_mem_ if (io_type == IO_TYPE_WRITE) { /* Make vector write call to VFD controlling subfiles */ - if (H5FD_write_vector(file_ptr->sf_file, u32_io_count, types, addrs, sizes, (const void **)bufs) < - 0) - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "write to subfile failed"); + if (H5FD_write_vector(file->sf_file, u32_io_count, types, addrs, sizes, (const void **)bufs) < 0) + HGOTO_ERROR(H5E_VFL, H5E_WRITEERROR, FAIL, "write to subfile failed"); /* - * Mirror superblock writes to the stub file so that - * legacy HDF5 applications can check what type of - * file they are reading + * Mirror superblock writes to the stub file so that legacy HDF5 + * applications can check what type of file they are reading */ - if (H5FD__subfiling_mirror_writes_to_stub(file_ptr, u32_io_count, types, addrs, sizes, + if (H5FD__subfiling_mirror_writes_to_stub(file, u32_io_count, types, addrs, sizes, (const void **)bufs) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "mirrored write to stub file failed"); + HGOTO_ERROR(H5E_VFL, H5E_WRITEERROR, FAIL, "mirrored write to stub file failed"); } - else { + else /* Make vector read call to VFD controlling subfiles */ - if (H5FD_read_vector(file_ptr->sf_file, u32_io_count, types, addrs, sizes, (void **)bufs) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "read from subfile failed"); - } + if (H5FD_read_vector(file->sf_file, u32_io_count, types, addrs, sizes, (void **)bufs) < 0) + HGOTO_ERROR(H5E_VFL, H5E_READERROR, FAIL, "read from subfile failed"); } else { uint32_t iovec_len; @@ -2198,14 +2018,13 @@ H5FD__subfiling_io_helper(H5FD_subfiling_t *file_ptr, size_t io_count, H5FD_mem_ * Generate the types, addrs, sizes and bufs I/O vectors for * this I/O request. */ - status = generate_io_vectors( + status = H5FD__subfiling_generate_io_vectors( sf_context, /* IN: Subfiling context used to look up config info */ io_count, /* IN: Number of entries in `types`, `addrs`, `sizes` and `bufs` */ types, /* IN: Array of memory types */ addrs, /* IN: Array of starting file offsets */ sizes, /* IN: Array of I/O sizes (in terms of elements) */ bufs, /* IN: Array of I/O buffers */ - 1, /* IN: Data extent of the 'type'; byte is assumed currently */ io_type, /* IN: Type of I/O being performed (IO_TYPE_WRITE or IO_TYPE_READ) */ &ioreq_count, /* OUT: Number of I/O requests to be made */ &iovec_len, /* OUT: Number of elements in I/O vector for a single I/O request */ @@ -2215,17 +2034,17 @@ H5FD__subfiling_io_helper(H5FD_subfiling_t *file_ptr, size_t io_count, H5FD_mem_ &io_bufs); /* OUT: I/O vector of buffers for each I/O entry */ if (status < 0) - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_CANTINIT, FAIL, "can't initialize I/O vectors"); + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "can't initialize I/O vectors"); /* Nothing to do * - * TODO: Note that this does not let the sub-filing VFD participate in + * TODO: Note that this does not let the subfiling VFD participate in * collective calls when there is no data to write. This is not an issue * now, as we don't do anything special with collective operations. * However, this needs to be fixed. */ if (ioreq_count == 0) - H5_SUBFILING_GOTO_DONE(SUCCEED); + HGOTO_DONE(SUCCEED); #ifdef H5_SUBFILING_DEBUG H5_subfiling_dump_iovecs(sf_context, ioreq_count, iovec_len, io_type, io_types, io_addrs, io_sizes, @@ -2282,50 +2101,44 @@ H5FD__subfiling_io_helper(H5FD_subfiling_t *file_ptr, size_t io_count, H5FD_mem_ if (io_type == IO_TYPE_WRITE) { /* Make vector write call to VFD controlling subfiles */ - if (H5FD_write_vector(file_ptr->sf_file, final_vec_len, io_types_ptr, io_addrs_ptr, - io_sizes_ptr, (const void **)io_bufs_ptr) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "write to subfile failed"); + if (H5FD_write_vector(file->sf_file, final_vec_len, io_types_ptr, io_addrs_ptr, io_sizes_ptr, + (const void **)io_bufs_ptr) < 0) + HGOTO_ERROR(H5E_VFL, H5E_WRITEERROR, FAIL, "write to subfile failed"); /* - * Mirror superblock writes to the stub file so that - * legacy HDF5 applications can check what type of - * file they are reading + * Mirror superblock writes to the stub file so that legacy HDF5 + * applications can check what type of file they are reading */ - if (H5FD__subfiling_mirror_writes_to_stub(file_ptr, final_vec_len, io_types_ptr, io_addrs_ptr, + if (H5FD__subfiling_mirror_writes_to_stub(file, final_vec_len, io_types_ptr, io_addrs_ptr, io_sizes_ptr, (const void **)io_bufs_ptr) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, - "mirrored write to stub file failed"); + HGOTO_ERROR(H5E_VFL, H5E_WRITEERROR, FAIL, "mirrored write to stub file failed"); } else { - if (!rank0_bcast || (file_ptr->mpi_rank == 0)) { + if (!rank0_bcast || (file->mpi_rank == 0)) /* Make vector read call to VFD controlling subfiles */ - if (H5FD_read_vector(file_ptr->sf_file, final_vec_len, io_types_ptr, io_addrs_ptr, + if (H5FD_read_vector(file->sf_file, final_vec_len, io_types_ptr, io_addrs_ptr, io_sizes_ptr, (void **)io_bufs_ptr) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "read from subfile failed"); - } + HGOTO_ERROR(H5E_VFL, H5E_READERROR, FAIL, "read from subfile failed"); } } - if (rank0_bcast && (file_ptr->mpi_size > 1)) { - size_t size; + if (rank0_bcast && (file->mpi_size > 1)) { + size_t size = 0; assert(io_type == IO_TYPE_READ); extend_sizes = false; for (size_t i = 0; i < io_count; i++) { if (!extend_sizes) { - if ((i > 0) && (sizes[i] == 0)) { + if (i > 0 && sizes[i] == 0) extend_sizes = true; - size = sizes[i - 1]; - } - else { + else size = sizes[i]; - } } H5_CHECK_OVERFLOW(size, size_t, int); - if (MPI_SUCCESS != MPI_Bcast(bufs[i].vp, (int)size, MPI_BYTE, 0, file_ptr->comm)) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_READERROR, FAIL, "can't broadcast data from rank 0"); + if (MPI_SUCCESS != MPI_Bcast(bufs[i].vp, (int)size, MPI_BYTE, 0, file->comm)) + HGOTO_ERROR(H5E_VFL, H5E_READERROR, FAIL, "can't broadcast data from rank 0"); } } } @@ -2334,14 +2147,14 @@ H5FD__subfiling_io_helper(H5FD_subfiling_t *file_ptr, size_t io_count, H5FD_mem_ /* Restore original transfer mode if we changed it */ if (xfer_mode != H5FD_MPIO_INDEPENDENT) if (H5CX_set_io_xfer_mode(xfer_mode) < 0) - H5_SUBFILING_DONE_ERROR(H5E_CONTEXT, H5E_CANTSET, FAIL, "can't set I/O collectivity setting"); + HDONE_ERROR(H5E_VFL, H5E_CANTSET, FAIL, "can't set I/O collectivity setting"); - free(io_bufs); - free(io_sizes); - free(io_addrs); - free(io_types); + H5MM_free(io_bufs); + H5MM_free(io_sizes); + H5MM_free(io_addrs); + H5MM_free(io_types); - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /*------------------------------------------------------------------------- @@ -2362,7 +2175,7 @@ H5FD__subfiling_io_helper(H5FD_subfiling_t *file_ptr, size_t io_count, H5FD_mem_ *------------------------------------------------------------------------- */ static herr_t -H5FD__subfiling_mirror_writes_to_stub(H5FD_subfiling_t *file_ptr, uint32_t count, H5FD_mem_t types[], +H5FD__subfiling_mirror_writes_to_stub(H5FD_subfiling_t *file, uint32_t count, H5FD_mem_t types[], haddr_t addrs[], size_t sizes[], const void *bufs[]) { const void **copied_bufs = NULL; @@ -2373,91 +2186,83 @@ H5FD__subfiling_mirror_writes_to_stub(H5FD_subfiling_t *file_ptr, uint32_t count size_t io_size = 0; bool all_super_writes = true; bool some_super_writes = false; + uint32_t super_count = 0; bool extend_types = false; bool extend_sizes = false; herr_t ret_value = SUCCEED; - assert(file_ptr); + FUNC_ENTER_PACKAGE + + assert(file); /* Only mirror I/O from MPI rank 0 */ - if (file_ptr->mpi_rank != 0) - H5_SUBFILING_GOTO_DONE(SUCCEED); + if (file->mpi_rank != 0) + HGOTO_DONE(SUCCEED); if (count == 0) - H5_SUBFILING_GOTO_DONE(SUCCEED); + HGOTO_DONE(SUCCEED); for (size_t i = 0; i < count; i++) { if (!extend_types) { - if ((i > 0) && (types[i] == H5FD_MEM_NOLIST)) { + if (i > 0 && types[i] == H5FD_MEM_NOLIST) extend_types = true; - type = types[i - 1]; - } - else { + else type = types[i]; - } } - if (type == H5FD_MEM_SUPER) + if (type == H5FD_MEM_SUPER) { some_super_writes = true; + super_count++; + } else all_super_writes = false; - /* - * If we find H5FD_MEM_NOLIST, we don't need to - * keep looking through the array entries - */ - if (extend_types) + /* If we find H5FD_MEM_NOLIST, we can stop looking at array entries */ + if (extend_types) { + if (type == H5FD_MEM_SUPER) + super_count += (count - (uint32_t)i) - 1; /* Account for remaining elements */ break; + } } if (all_super_writes) { - if (H5FD_write_vector(file_ptr->stub_file, count, types, addrs, sizes, bufs) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, - "couldn't write superblock information to stub file"); + if (H5FD_write_vector(file->stub_file, count, types, addrs, sizes, bufs) < 0) + HGOTO_ERROR(H5E_VFL, H5E_WRITEERROR, FAIL, "couldn't write superblock information to stub file"); } else if (some_super_writes) { uint32_t vec_len = 0; /* Copy I/O vectors and strip out non-superblock I/O */ - if (NULL == (copied_types = malloc(count * sizeof(*copied_types)))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, - "can't allocate copy of I/O types array"); - if (NULL == (copied_addrs = malloc(count * sizeof(*copied_addrs)))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, - "can't allocate copy of I/O addresses array"); - if (NULL == (copied_sizes = malloc(count * sizeof(*copied_sizes)))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, - "can't allocate copy of I/O sizes array"); - if (NULL == (copied_bufs = malloc(count * sizeof(*copied_bufs)))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, - "can't allocate copy of I/O buffers array"); + if (NULL == (copied_types = H5MM_malloc(super_count * sizeof(*copied_types)))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "can't allocate copy of I/O types array"); + if (NULL == (copied_addrs = H5MM_malloc(super_count * sizeof(*copied_addrs)))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "can't allocate copy of I/O addresses array"); + if (NULL == (copied_sizes = H5MM_malloc(super_count * sizeof(*copied_sizes)))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "can't allocate copy of I/O sizes array"); + if (NULL == (copied_bufs = H5MM_malloc(super_count * sizeof(*copied_bufs)))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "can't allocate copy of I/O buffers array"); extend_types = false; extend_sizes = false; for (size_t i = 0; i < count; i++) { if (!extend_types) { - if ((i > 0) && (types[i] == H5FD_MEM_NOLIST)) { + if (i > 0 && types[i] == H5FD_MEM_NOLIST) { extend_types = true; - type = types[i - 1]; /* End early if none of the remaining memory types are H5FD_MEM_SUPER */ if (type != H5FD_MEM_SUPER) break; } - else { + else type = types[i]; - } } if (!extend_sizes) { - if ((i > 0) && (sizes[i] == 0)) { + if (i > 0 && sizes[i] == 0) extend_sizes = true; - io_size = sizes[i - 1]; - } - else { + else io_size = sizes[i]; - } } if (type != H5FD_MEM_SUPER) @@ -2470,24 +2275,24 @@ H5FD__subfiling_mirror_writes_to_stub(H5FD_subfiling_t *file_ptr, uint32_t count vec_len++; } + assert(vec_len > 0); - if ((vec_len > 0) && (H5FD_write_vector(file_ptr->stub_file, vec_len, copied_types, copied_addrs, - copied_sizes, copied_bufs) < 0)) - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, - "couldn't write superblock information to stub file"); + if (H5FD_write_vector(file->stub_file, vec_len, copied_types, copied_addrs, copied_sizes, + copied_bufs) < 0) + HGOTO_ERROR(H5E_VFL, H5E_WRITEERROR, FAIL, "couldn't write superblock information to stub file"); } done: - free(copied_bufs); - free(copied_sizes); - free(copied_addrs); - free(copied_types); + H5MM_free(copied_bufs); + H5MM_free(copied_sizes); + H5MM_free(copied_addrs); + H5MM_free(copied_types); - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /*------------------------------------------------------------------------- - * Function: generate_io_vectors + * Function: H5FD__subfiling_generate_io_vectors * * Purpose: Given an array of memory types, an array of file offsets, * an array of the number of I/O elements for each file @@ -2526,12 +2331,6 @@ H5FD__subfiling_mirror_writes_to_stub(H5FD_subfiling_t *file_ptr, uint32_t count * bufs (IN) * - array of the I/O buffers to use for each I/O entry * - * dtype_extent (IN) - * - the extent of the datatype of each data element for - * the I/O operation (currently assumed to be 1, meaning - * entries in `nelemts` are expressed in terms of - * bytes) - * * io_type (IN) * - the type of I/O being performed (IO_TYPE_WRITE or * IO_TYPE_READ) @@ -2568,11 +2367,11 @@ H5FD__subfiling_mirror_writes_to_stub(H5FD_subfiling_t *file_ptr, uint32_t count * */ static herr_t -generate_io_vectors(subfiling_context_t *sf_context, size_t in_count, H5FD_mem_t types[], - haddr_t file_offsets[], size_t nelemts[], H5_flexible_const_ptr_t bufs[], - size_t dtype_extent, H5FD_subfiling_io_type_t io_type, size_t *ioreq_count, - uint32_t *iovec_len, H5FD_mem_t **io_types, haddr_t **io_addrs, size_t **io_sizes, - H5_flexible_const_ptr_t **io_bufs) +H5FD__subfiling_generate_io_vectors(subfiling_context_t *sf_context, size_t in_count, H5FD_mem_t types[], + haddr_t file_offsets[], size_t nelemts[], H5_flexible_const_ptr_t bufs[], + H5FD_subfiling_io_type_t io_type, size_t *ioreq_count, + uint32_t *iovec_len, H5FD_mem_t **io_types, haddr_t **io_addrs, + size_t **io_sizes, H5_flexible_const_ptr_t **io_bufs) { H5_flexible_const_ptr_t *loc_io_bufs = NULL; H5FD_mem_t *loc_io_types = NULL; @@ -2587,16 +2386,17 @@ generate_io_vectors(subfiling_context_t *sf_context, size_t in_count, H5FD_mem_t bool extend_types = false; herr_t ret_value = SUCCEED; + FUNC_ENTER_PACKAGE + assert(sf_context); assert(sf_context->sf_stripe_size > 0); assert(sf_context->sf_blocksize_per_stripe > 0); assert(sf_context->sf_num_subfiles > 0); assert(sf_context->topology); - assert((types) || (in_count == 0)); - assert((file_offsets) || (in_count == 0)); - assert((nelemts) || (in_count == 0)); - assert((bufs) || (in_count == 0)); - assert(dtype_extent == 1); /* For now, assume 'byte'-sized elements */ + assert(types || in_count == 0); + assert(file_offsets || in_count == 0); + assert(nelemts || in_count == 0); + assert(bufs || in_count == 0); assert(ioreq_count); assert(iovec_len); assert(io_types); @@ -2610,36 +2410,33 @@ generate_io_vectors(subfiling_context_t *sf_context, size_t in_count, H5FD_mem_t /* Nothing to do */ if (in_count == 0) - H5_SUBFILING_GOTO_DONE(SUCCEED); + HGOTO_DONE(SUCCEED); /* - * Do some initial pre-processing to determine how large of - * I/O vectors we will need to allocate to satisfy the - * entire I/O request + * Do some initial pre-processing to determine how large of I/O vectors we + * will need to allocate to satisfy the entire I/O request */ - get_iovec_sizes(sf_context, in_count, file_offsets, nelemts, dtype_extent, &max_iovec_depth, - &max_num_subfiles_touched); + H5FD__subfiling_get_iovec_sizes(sf_context, in_count, file_offsets, nelemts, &max_iovec_depth, + &max_num_subfiles_touched); tot_iovec_len = in_count * max_iovec_depth * max_num_subfiles_touched; #ifdef H5_SUBFILING_DEBUG - H5_subfiling_log( + H5FD__subfiling_log( sf_context->sf_context_id, "%s: I/O count: %zu, max_iovec_depth = %zu, max_num_subfiles_touched = %zu, iovec_len = %zu", __func__, in_count, max_iovec_depth, max_num_subfiles_touched, tot_iovec_len); #endif /* Allocate I/O vectors that will be returned to the caller */ - if (NULL == (loc_io_types = calloc(1, tot_iovec_len * sizeof(*loc_io_types)))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't allocate subfile I/O types vector"); - if (NULL == (loc_io_addrs = calloc(1, tot_iovec_len * sizeof(*loc_io_addrs)))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, - "can't allocate subfile I/O addresses vector"); - if (NULL == (loc_io_sizes = calloc(1, tot_iovec_len * sizeof(*loc_io_sizes)))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't allocate subfile I/O sizes vector"); - if (NULL == (loc_io_bufs = calloc(1, tot_iovec_len * sizeof(*loc_io_bufs)))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, - "can't allocate subfile I/O buffers vector"); + if (NULL == (loc_io_types = H5MM_calloc(tot_iovec_len * sizeof(*loc_io_types)))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "can't allocate subfile I/O types vector"); + if (NULL == (loc_io_addrs = H5MM_calloc(tot_iovec_len * sizeof(*loc_io_addrs)))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "can't allocate subfile I/O addresses vector"); + if (NULL == (loc_io_sizes = H5MM_calloc(tot_iovec_len * sizeof(*loc_io_sizes)))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "can't allocate subfile I/O sizes vector"); + if (NULL == (loc_io_bufs = H5MM_calloc(tot_iovec_len * sizeof(*loc_io_bufs)))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "can't allocate subfile I/O buffers vector"); /* * Populate the I/O vectors by looping through each @@ -2652,29 +2449,24 @@ generate_io_vectors(subfiling_context_t *sf_context, size_t in_count, H5FD_mem_t assert(iovec_idx < tot_iovec_len); if (!extend_types) { - if ((io_idx > 0) && (types[io_idx] == H5FD_MEM_NOLIST)) { + if (io_idx > 0 && types[io_idx] == H5FD_MEM_NOLIST) extend_types = true; - mem_type = types[io_idx - 1]; - } - else { + else mem_type = types[io_idx]; - } } if (!extend_sizes) { - if ((io_idx > 0) && (nelemts[io_idx] == 0)) { + if (io_idx > 0 && nelemts[io_idx] == 0) extend_sizes = true; - io_size = nelemts[io_idx - 1] * dtype_extent; - } - else { - io_size = nelemts[io_idx] * dtype_extent; - } + else + io_size = nelemts[io_idx]; } - if (translate_io_req_to_iovec(sf_context, iovec_idx, max_num_subfiles_touched, max_iovec_depth, - mem_type, file_offsets[io_idx], io_size, bufs[io_idx], io_type, - loc_io_types, loc_io_addrs, loc_io_sizes, loc_io_bufs) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_CANTINIT, FAIL, "can't translate I/O request to I/O vectors"); + if (H5FD__subfiling_translate_io_req_to_iovec(sf_context, iovec_idx, max_num_subfiles_touched, + max_iovec_depth, mem_type, file_offsets[io_idx], + io_size, bufs[io_idx], io_type, loc_io_types, + loc_io_addrs, loc_io_sizes, loc_io_bufs) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "can't translate I/O request to I/O vectors"); } *ioreq_count = in_count * max_iovec_depth; @@ -2687,17 +2479,17 @@ generate_io_vectors(subfiling_context_t *sf_context, size_t in_count, H5FD_mem_t done: if (ret_value < 0) { - free(loc_io_bufs); - free(loc_io_sizes); - free(loc_io_addrs); - free(loc_io_types); + H5MM_free(loc_io_bufs); + H5MM_free(loc_io_sizes); + H5MM_free(loc_io_addrs); + H5MM_free(loc_io_types); } - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /*------------------------------------------------------------------------- - * Function: get_iovec_sizes + * Function: H5FD__subfiling_get_iovec_sizes * * Purpose: Helper routine to determine the maximum I/O vector depth * (in terms of array elements) and maximum number of subfiles @@ -2711,8 +2503,8 @@ generate_io_vectors(subfiling_context_t *sf_context, size_t in_count, H5FD_mem_t *------------------------------------------------------------------------- */ static void -get_iovec_sizes(subfiling_context_t *sf_context, size_t in_count, haddr_t file_offsets[], size_t nelemts[], - size_t dtype_extent, size_t *max_iovec_depth, size_t *max_num_subfiles) +H5FD__subfiling_get_iovec_sizes(subfiling_context_t *sf_context, size_t in_count, haddr_t file_offsets[], + size_t nelemts[], size_t *max_iovec_depth, size_t *max_num_subfiles) { int64_t stripe_size = 0; int64_t block_size = 0; @@ -2720,6 +2512,8 @@ get_iovec_sizes(subfiling_context_t *sf_context, size_t in_count, haddr_t file_o size_t loc_max_num_subfiles = 0; int num_subfiles = 0; + FUNC_ENTER_PACKAGE_NOERR + assert(sf_context); assert(file_offsets); assert(nelemts); @@ -2744,7 +2538,7 @@ get_iovec_sizes(subfiling_context_t *sf_context, size_t in_count, haddr_t file_o size_t cur_iovec_depth; H5_CHECKED_ASSIGN(cur_file_offset, int64_t, file_offsets[io_idx], haddr_t); - H5_CHECKED_ASSIGN(data_size, int64_t, (nelemts[io_idx] * dtype_extent), size_t); + H5_CHECKED_ASSIGN(data_size, int64_t, nelemts[io_idx], size_t); /* * Calculate the following from the starting file offset: @@ -2759,8 +2553,7 @@ get_iovec_sizes(subfiling_context_t *sf_context, size_t in_count, haddr_t file_o * (offsets 0-1023) * final_offset * - the last offset in the virtual file covered by this I/O - * operation. Simply the I/O size added to the starting file - * offset. + * operation. Simply the I/O size added to the starting file offset. */ stripe_idx = cur_file_offset / stripe_size; final_offset = cur_file_offset + data_size; @@ -2769,28 +2562,26 @@ get_iovec_sizes(subfiling_context_t *sf_context, size_t in_count, haddr_t file_o first_subfile = stripe_idx % num_subfiles; /* - * Determine the stripe "index" of the last offset in the - * virtual file and, from that, determine the subfile that - * the I/O request ends in. + * Determine the stripe "index" of the last offset in the virtual file + * and the subfile that the I/O request ends in. */ final_stripe_idx = final_offset / stripe_size; last_subfile = final_stripe_idx % num_subfiles; /* - * Determine how "deep" the resulting I/O vectors are at - * most by calculating the maximum number of "rows" spanned - * for any particular subfile; e.g. the maximum number of - * I/O requests for any particular subfile + * Determine how "deep" the resulting I/O vectors are at most by + * calculating the maximum number of "rows" spanned for any particular + * subfile; i.e. the maximum number of I/O requests for any particular + * subfile */ row_stripe_idx_start = stripe_idx - first_subfile; row_stripe_idx_final = final_stripe_idx - last_subfile; cur_iovec_depth = (size_t)((row_stripe_idx_final - row_stripe_idx_start) / num_subfiles) + 1; /* - * If the I/O request "wrapped around" and ends in a subfile - * less than the subfile we started in, subtract one from the - * I/O vector length to account for "empty space". This can be - * visualized as follows: + * If the I/O request "wrapped around" and ends in a subfile less than + * the subfile we started in, subtract one from the I/O vector length to + * account for "empty space". This can be visualized as follows: * * SUBFILE 0 SUBFILE 1 SUBFILE 2 SUBFILE 3 * _______________________________________________ @@ -2803,16 +2594,15 @@ get_iovec_sizes(subfiling_context_t *sf_context, size_t in_count, haddr_t file_o * | | | | | * |___________|___________|___________|___________| * - * Here, `stripe_idx` would be calculated as 2 (I/O begins in - * the 3rd stripe, or subfile index 2), `first_subfile` would be - * calculated as 2 and the starting "row" (row_stripe_idx_start) - * would be calculated as "row" index 0. `final_stripe_idx` would - * be calculated as 9, `last_subfile` would be calculated as - * (9 % 4) = 1 and the ending "row" (row_stripe_idx_final) would - * be calculated as (9 - 1) = 8. Thus, the calculated I/O vector - * length would be ((8 - 0) / 4) + 1 = 3. However, since there is - * no I/O to stripe indices 0 and 1 (residing in "row" 0 of subfile - * index 0 and 1, respectively), it can be seen that the real I/O + * Here, `stripe_idx` would be calculated as 2 (I/O begins in the 3rd + * stripe, or subfile index 2), `first_subfile` would be calculated as 2 + * and the starting "row" (row_stripe_idx_start) would be calculated as + * "row" index 0. `final_stripe_idx` would be calculated as 9, + * `last_subfile` would be calculated as (9 % 4) = 1 and the ending "row" + * (row_stripe_idx_final) would be calculated as (9 - 1) = 8. Thus, the + * calculated I/O vector length would be ((8 - 0) / 4) + 1 = 3. However, + * since there is no I/O to stripe indices 0 and 1 (residing in "row" 0 of + * subfile index 0 and 1, respectively), it can be seen that the real I/O * vector length is 2. */ if (last_subfile < first_subfile) @@ -2854,13 +2644,15 @@ get_iovec_sizes(subfiling_context_t *sf_context, size_t in_count, haddr_t file_o *max_iovec_depth = loc_max_iovec_depth; *max_num_subfiles = loc_max_num_subfiles; + + FUNC_LEAVE_NOAPI_VOID } /*------------------------------------------------------------------------- - * Function: translate_io_req_to_iovec + * Function: H5FD__subfiling_translate_io_req_to_iovec * * Purpose: Helper routine to perform the translation between an I/O - * request (type, addr, size, buf tuple) and a set of I/O + * request [i.e. an (type, addr, size, buf) tuple] and a set of I/O * vectors that spans all the subfiles touched by that I/O * request. Once finished, this function will have generated * at most `iovec_count` sets of I/O vectors, each containing @@ -2880,7 +2672,7 @@ get_iovec_sizes(subfiling_context_t *sf_context, size_t in_count, haddr_t file_o * * iovec_count (IN) * - the maximum number of I/O vectors to be generated, as - * calculated in generate_io_vectors() + * calculated in H5FD__subfiling_generate_io_vectors() * * type (IN) * - the memory type to use for each component of the I/O @@ -2919,11 +2711,11 @@ get_iovec_sizes(subfiling_context_t *sf_context, size_t in_count, haddr_t file_o *------------------------------------------------------------------------- */ static herr_t -translate_io_req_to_iovec(subfiling_context_t *sf_context, size_t iovec_idx, size_t iovec_len, - size_t iovec_count, H5FD_mem_t type, haddr_t addr, size_t io_size, - H5_flexible_const_ptr_t io_buf, H5FD_subfiling_io_type_t io_type, - H5FD_mem_t *io_types, haddr_t *io_addrs, size_t *io_sizes, - H5_flexible_const_ptr_t *io_bufs) +H5FD__subfiling_translate_io_req_to_iovec(subfiling_context_t *sf_context, size_t iovec_idx, size_t iovec_len, + size_t iovec_count, H5FD_mem_t type, haddr_t addr, size_t io_size, + H5_flexible_const_ptr_t io_buf, H5FD_subfiling_io_type_t io_type, + H5FD_mem_t *io_types, haddr_t *io_addrs, size_t *io_sizes, + H5_flexible_const_ptr_t *io_bufs) { int64_t stripe_idx = 0; int64_t final_stripe_idx = 0; @@ -2947,6 +2739,8 @@ translate_io_req_to_iovec(subfiling_context_t *sf_context, size_t iovec_idx, siz int num_subfiles = 0; herr_t ret_value = SUCCEED; + FUNC_ENTER_PACKAGE + assert(sf_context); assert(io_types); assert(io_addrs); @@ -2960,11 +2754,9 @@ translate_io_req_to_iovec(subfiling_context_t *sf_context, size_t iovec_idx, siz * - the size of the data striping across the file's subfiles * block_size * - the size of a "block" across the IOCs, as calculated - * by the stripe size multiplied by the number of - * subfiles + * by the stripe size multiplied by the number of subfiles * num_subfiles - * - the total number of subfiles for the logical - * HDF5 file + * - the total number of subfiles for the logical HDF5 file */ stripe_size = sf_context->sf_stripe_size; block_size = sf_context->sf_blocksize_per_stripe; @@ -2988,8 +2780,7 @@ translate_io_req_to_iovec(subfiling_context_t *sf_context, size_t iovec_idx, siz * - the relative offset in the stripe that the starting file * offset resides in * offset_in_block - * - the relative offset in the "block" of stripes across the - * subfiles + * - the relative offset in the "block" of stripes across the subfiles * final_offset * - the last offset in the virtual file covered by this I/O * request. Simply the I/O size minus one byte added to the @@ -3012,14 +2803,12 @@ translate_io_req_to_iovec(subfiling_context_t *sf_context, size_t iovec_idx, siz assert(final_length <= stripe_size); /* - * Determine which subfile the I/O request begins in and which - * "row" the I/O request begins in within the "block" of stripes - * across the subfiles. Note that "row" here is just a conceptual - * way to think of how a block of data stripes is laid out across - * the subfiles. A block's "column" size in bytes is equal to the - * stripe size multiplied by the number of subfiles. Therefore, - * file offsets that are multiples of the block size begin a new - * "row". + * Determine which subfile the I/O request begins in and which "row" the I/O + * request begins in within the "block" of stripes across the subfiles. Note + * that "row" here is just a conceptual way to think of how a block of data + * stripes is laid out across the subfiles. A block's "column" size in bytes + * is equal to the stripe size multiplied by the number of subfiles. Therefore, + * file offsets that are multiples of the block size begin a new "row". */ start_row = stripe_idx / num_subfiles; first_subfile_idx = stripe_idx % num_subfiles; @@ -3050,10 +2839,9 @@ translate_io_req_to_iovec(subfiling_context_t *sf_context, size_t iovec_idx, siz max_iovec_depth = ((row_stripe_idx_final - row_stripe_idx_start) / num_subfiles) + 1; /* - * If the I/O request "wrapped around" and ends in a subfile - * less than the subfile we started in, subtract one from the - * I/O vector length to account for "empty space". This can be - * visualized as follows: + * If the I/O request "wrapped around" and ends in a subfile less than the + * subfile we started in, subtract one from the I/O vector length to account + * for "empty space". This can be visualized as follows: * * SUBFILE 0 SUBFILE 1 SUBFILE 2 SUBFILE 3 * _______________________________________________ @@ -3066,23 +2854,21 @@ translate_io_req_to_iovec(subfiling_context_t *sf_context, size_t iovec_idx, siz * | | | | | * |___________|___________|___________|___________| * - * Here, `stripe_idx` would be calculated as 2 (I/O begins in - * the 3rd stripe, or subfile index 2), `first_subfile` would be - * calculated as 2 and the starting "row" (row_stripe_idx_start) - * would be calculated as "row" index 0. `final_stripe_idx` would - * be calculated as 9, `last_subfile` would be calculated as - * (9 % 4) = 1 and the ending "row" (row_stripe_idx_final) would - * be calculated as (9 - 1) = 8. Thus, the calculated I/O vector - * length would be ((8 - 0) / 4) + 1 = 3. However, since there is - * no I/O to stripe indices 0 and 1 (residing in "row" 0 of subfile - * index 0 and 1, respectively), it can be seen that the real I/O - * vector length is 2. + * Here, `stripe_idx` would be calculated as 2 (I/O begins in the 3rd stripe, + * or subfile index 2), `first_subfile` would be calculated as 2 and the + * starting "row" (row_stripe_idx_start) would be calculated as "row" index 0. + * `final_stripe_idx` would be calculated as 9, `last_subfile` would be + * calculated as (9 % 4) = 1 and the ending "row" (row_stripe_idx_final) would + * be calculated as (9 - 1) = 8. Thus, the calculated I/O vector length would + * be ((8 - 0) / 4) + 1 = 3. However, since there is no I/O to stripe indices + * 0 and 1 (residing in "row" 0 of subfile index 0 and 1, respectively), it + * can be seen that the real I/O vector length is 2. */ if (last_subfile_idx < first_subfile_idx) max_iovec_depth--; #ifdef H5_SUBFILING_DEBUG - H5_subfiling_log( + H5FD__subfiling_log( sf_context->sf_context_id, "%s: TRANSLATING I/O REQUEST (MEMORY TYPE: %d, ADDR: %" PRIuHADDR ", I/O SIZE: %zu, BUF: %p)\n" "STRIPE SIZE: %" PRId64 ", BLOCK SIZE: %" PRId64 ", NUM SUBFILES: %d\n" @@ -3096,9 +2882,9 @@ translate_io_req_to_iovec(subfiling_context_t *sf_context, size_t iovec_idx, siz #endif /* - * Loop through the set of subfiles to determine the various - * vector components for each. Subfiles whose data size is - * zero will not have I/O requests passed to them. + * Loop through the set of subfiles to determine the various vector components + * for each. Subfiles whose data size is zero will not have I/O requests + * passed to them. */ for (int i = 0, subfile_idx = (int)first_subfile_idx; i < num_subfiles; i++) { H5_flexible_const_ptr_t *_io_bufs_ptr; @@ -3120,10 +2906,7 @@ translate_io_req_to_iovec(subfiling_context_t *sf_context, size_t iovec_idx, siz if (subfile_idx == first_subfile_idx) { is_first = true; - /* - * Add partial segment length if not - * starting on a stripe boundary - */ + /* Add partial segment length if not starting on a stripe boundary */ if (start_length < stripe_size) { subfile_bytes += start_length; num_full_stripes--; @@ -3133,10 +2916,7 @@ translate_io_req_to_iovec(subfiling_context_t *sf_context, size_t iovec_idx, siz if (subfile_idx == last_subfile_idx) { is_last = true; - /* - * Add partial segment length if not - * ending on a stripe boundary - */ + /* Add partial segment length if not ending on a stripe boundary */ if (final_length < stripe_size) { subfile_bytes += final_length; if (num_full_stripes) @@ -3150,15 +2930,13 @@ translate_io_req_to_iovec(subfiling_context_t *sf_context, size_t iovec_idx, siz if (last_subfile_idx >= first_subfile_idx) { /* - * In the case where the subfile with the final data - * segment has an index value greater than or equal - * to the subfile with the first data segment, I/O - * vectors directed to a subfile with an index value - * that is greater than the last subfile or less than - * the first subfile will be "thin", or rather will - * have a vector depth of 1 less than normal, which - * will be accounted for below. This can be visualized - * with the following I/O pattern: + * In the case where the subfile with the final data segment has + * an index value greater than or equal to the subfile with the + * first data segment, I/O vectors directed to a subfile with an + * index value that is greater than the last subfile or less than + * the first subfile will be "thin", or rather will have a vector + * depth of 1 less than normal, which will be accounted for below. + * This can be visualized with the following I/O pattern: * * SUBFILE 0 SUBFILE 1 SUBFILE 2 SUBFILE 3 * _______________________________________________ @@ -3176,10 +2954,10 @@ translate_io_req_to_iovec(subfiling_context_t *sf_context, size_t iovec_idx, siz } else { /* last_subfile_idx < first_subfile_idx */ /* - * This can also happen when the subfile with the final - * data segment has a smaller subfile index than the - * subfile with the first data segment and the current - * subfile index falls between the two. + * This can also happen when the subfile with the final data + * segment has a smaller subfile index than the subfile with the + * first data segment and the current subfile index falls between + * the two. */ thin_uniform_section = ((last_subfile_idx < subfile_idx) && (subfile_idx < first_subfile_idx)); @@ -3203,10 +2981,7 @@ translate_io_req_to_iovec(subfiling_context_t *sf_context, size_t iovec_idx, siz subfile_bytes += num_full_stripes * stripe_size; total_bytes += (size_t)subfile_bytes; - /* - * Setup the pointers to the next set of I/O vectors - * in the output arrays - */ + /* Set up the pointers to the next I/O vector in the output arrays */ _io_types_ptr = &io_types[iovec_idx + (size_t)i]; _io_addrs_ptr = &io_addrs[iovec_idx + (size_t)i]; _io_sizes_ptr = &io_sizes[iovec_idx + (size_t)i]; @@ -3240,23 +3015,24 @@ translate_io_req_to_iovec(subfiling_context_t *sf_context, size_t iovec_idx, siz * I/O. In this case, we may have to deal with partial * stripe I/O in the first and last I/O segments. */ - if (iovec_fill_first_last(sf_context, iovec_len, iovec_depth, subfile_bytes, mem_offset, - cur_file_offset, start_length, final_length, io_buf, io_type, - _io_addrs_ptr, _io_sizes_ptr, _io_bufs_ptr) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_CANTINIT, FAIL, "can't fill I/O vectors"); + if (H5FD__subfiling_iovec_fill_first_last(sf_context, iovec_len, iovec_depth, + subfile_bytes, mem_offset, cur_file_offset, + start_length, final_length, io_buf, io_type, + _io_addrs_ptr, _io_sizes_ptr, _io_bufs_ptr) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "can't fill I/O vectors"); } else { /* - * The current subfile being processed is the first - * subfile touched by I/O. In this case, we may have - * to deal with partial stripe I/O in the first I/O - * segment. + * The current subfile being processed is the first subfile + * touched by I/O. In this case, we may have to deal with + * partial stripe I/O in the first I/O segment. */ - if (iovec_fill_first(sf_context, iovec_len, iovec_depth, subfile_bytes, mem_offset, - cur_file_offset, start_length, io_buf, io_type, _io_addrs_ptr, - _io_sizes_ptr, _io_bufs_ptr) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_CANTINIT, FAIL, "can't fill I/O vectors"); + if (H5FD__subfiling_iovec_fill_first( + sf_context, iovec_len, iovec_depth, subfile_bytes, mem_offset, cur_file_offset, + start_length, io_buf, io_type, _io_addrs_ptr, _io_sizes_ptr, _io_bufs_ptr) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "can't fill I/O vectors"); } + /* Move the memory pointer to the starting location * for next subfile I/O request. */ @@ -3268,10 +3044,10 @@ translate_io_req_to_iovec(subfiling_context_t *sf_context, size_t iovec_idx, siz * touched by I/O. In this case, we may have to deal with * partial stripe I/O in the last I/O segment. */ - if (iovec_fill_last(sf_context, iovec_len, iovec_depth, subfile_bytes, mem_offset, - cur_file_offset, final_length, io_buf, io_type, _io_addrs_ptr, - _io_sizes_ptr, _io_bufs_ptr) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_CANTINIT, FAIL, "can't fill I/O vectors"); + if (H5FD__subfiling_iovec_fill_last(sf_context, iovec_len, iovec_depth, subfile_bytes, + mem_offset, cur_file_offset, final_length, io_buf, + io_type, _io_addrs_ptr, _io_sizes_ptr, _io_bufs_ptr) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "can't fill I/O vectors"); mem_offset += stripe_size; } @@ -3282,10 +3058,10 @@ translate_io_req_to_iovec(subfiling_context_t *sf_context, size_t iovec_idx, siz * partial stripe I/O will need to be dealt with; all I/O * segments will cover a full I/O stripe. */ - if (iovec_fill_uniform(sf_context, iovec_len, iovec_depth, subfile_bytes, mem_offset, - cur_file_offset, io_buf, io_type, _io_addrs_ptr, _io_sizes_ptr, - _io_bufs_ptr) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_CANTINIT, FAIL, "can't fill I/O vectors"); + if (H5FD__subfiling_iovec_fill_uniform(sf_context, iovec_len, iovec_depth, subfile_bytes, + mem_offset, cur_file_offset, io_buf, io_type, + _io_addrs_ptr, _io_sizes_ptr, _io_bufs_ptr) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "can't fill I/O vectors"); mem_offset += stripe_size; } @@ -3306,15 +3082,15 @@ translate_io_req_to_iovec(subfiling_context_t *sf_context, size_t iovec_idx, siz } if (total_bytes != io_size) - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_CANTINIT, FAIL, "total bytes (%zu) didn't match data size (%zu)!", - total_bytes, io_size); + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "total bytes (%zu) didn't match data size (%zu)!", + total_bytes, io_size); done: - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /*------------------------------------------------------------------------- - * Function: iovec_fill_first + * Function: H5FD__subfiling_iovec_fill_first * * Purpose: Fills I/O vectors for the case where the IOC has the first * data segment of the I/O operation. @@ -3333,16 +3109,19 @@ translate_io_req_to_iovec(subfiling_context_t *sf_context, size_t iovec_idx, siz *------------------------------------------------------------------------- */ static herr_t -iovec_fill_first(subfiling_context_t *sf_context, size_t iovec_len, int64_t cur_iovec_depth, - int64_t target_datasize, int64_t start_mem_offset, int64_t start_file_offset, - int64_t first_io_len, H5_flexible_const_ptr_t buf, H5FD_subfiling_io_type_t io_type, - haddr_t *io_addrs_ptr, size_t *io_sizes_ptr, H5_flexible_const_ptr_t *io_bufs_ptr) +H5FD__subfiling_iovec_fill_first(subfiling_context_t *sf_context, size_t iovec_len, int64_t cur_iovec_depth, + int64_t target_datasize, int64_t start_mem_offset, int64_t start_file_offset, + int64_t first_io_len, H5_flexible_const_ptr_t buf, + H5FD_subfiling_io_type_t io_type, haddr_t *io_addrs_ptr, + size_t *io_sizes_ptr, H5_flexible_const_ptr_t *io_bufs_ptr) { int64_t stripe_size; int64_t block_size; int64_t total_bytes = 0; herr_t ret_value = SUCCEED; + FUNC_ENTER_PACKAGE + assert(sf_context); assert(cur_iovec_depth > 0); assert(io_addrs_ptr); @@ -3353,10 +3132,10 @@ iovec_fill_first(subfiling_context_t *sf_context, size_t iovec_len, int64_t cur_ block_size = sf_context->sf_blocksize_per_stripe; #ifdef H5_SUBFILING_DEBUG - H5_subfiling_log(sf_context->sf_context_id, - "%s: start_mem_offset = %" PRId64 ", start_file_offset = %" PRId64 - ", first_io_len = %" PRId64, - __func__, start_mem_offset, start_file_offset, first_io_len); + H5FD__subfiling_log(sf_context->sf_context_id, + "%s: start_mem_offset = %" PRId64 ", start_file_offset = %" PRId64 + ", first_io_len = %" PRId64, + __func__, start_mem_offset, start_file_offset, first_io_len); #endif *io_addrs_ptr = (haddr_t)start_file_offset; @@ -3368,7 +3147,7 @@ iovec_fill_first(subfiling_context_t *sf_context, size_t iovec_len, int64_t cur_ io_bufs_ptr->vp = (char *)(buf.vp) + start_mem_offset; if (first_io_len == target_datasize) - H5_SUBFILING_GOTO_DONE(SUCCEED); + HGOTO_DONE(SUCCEED); if (first_io_len > 0) { int64_t offset_in_stripe = start_file_offset % stripe_size; @@ -3387,10 +3166,10 @@ iovec_fill_first(subfiling_context_t *sf_context, size_t iovec_len, int64_t cur_ (io_bufs_ptr + (i * iovec_len))->vp = (char *)(buf.vp) + next_mem_offset; #ifdef H5_SUBFILING_DEBUG - H5_subfiling_log(sf_context->sf_context_id, - "%s: mem_offset[%zu] = %" PRId64 ", file_offset[%zu] = %" PRId64 - ", io_block_len[%zu] = %" PRId64, - __func__, i, next_mem_offset, i, next_file_offset, i, stripe_size); + H5FD__subfiling_log(sf_context->sf_context_id, + "%s: mem_offset[%zu] = %" PRId64 ", file_offset[%zu] = %" PRId64 + ", io_block_len[%zu] = %" PRId64, + __func__, i, next_mem_offset, i, next_file_offset, i, stripe_size); #endif next_mem_offset += block_size; @@ -3399,17 +3178,17 @@ iovec_fill_first(subfiling_context_t *sf_context, size_t iovec_len, int64_t cur_ } if (total_bytes != target_datasize) - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_CANTINIT, FAIL, - "total bytes (%" PRId64 ") didn't match target data size (%" PRId64 ")!", - total_bytes, target_datasize); + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, + "total bytes (%" PRId64 ") didn't match target data size (%" PRId64 ")!", total_bytes, + target_datasize); } done: - return ret_value; + FUNC_LEAVE_NOAPI(ret_value) } /*------------------------------------------------------------------------- - * Function: iovec_fill_last + * Function: H5FD__subfiling_iovec_fill_last * * Purpose: Fills I/O vectors for the case where the IOC has the last * data segment of the I/O operation. @@ -3430,15 +3209,21 @@ iovec_fill_first(subfiling_context_t *sf_context, size_t iovec_len, int64_t cur_ *------------------------------------------------------------------------- */ static herr_t -iovec_fill_last(subfiling_context_t *sf_context, size_t iovec_len, int64_t cur_iovec_depth, - int64_t target_datasize, int64_t start_mem_offset, int64_t start_file_offset, - int64_t last_io_len, H5_flexible_const_ptr_t buf, H5FD_subfiling_io_type_t io_type, - haddr_t *io_addrs_ptr, size_t *io_sizes_ptr, H5_flexible_const_ptr_t *io_bufs_ptr) +H5FD__subfiling_iovec_fill_last(subfiling_context_t *sf_context, size_t iovec_len, int64_t cur_iovec_depth, + int64_t target_datasize, int64_t start_mem_offset, int64_t start_file_offset, + int64_t last_io_len, H5_flexible_const_ptr_t buf, + H5FD_subfiling_io_type_t io_type, haddr_t *io_addrs_ptr, size_t *io_sizes_ptr, + H5_flexible_const_ptr_t *io_bufs_ptr) { int64_t stripe_size; int64_t block_size; int64_t total_bytes = 0; - herr_t ret_value = SUCCEED; + int64_t next_mem_offset; + int64_t next_file_offset; + size_t i; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_PACKAGE assert(sf_context); assert(cur_iovec_depth > 0); @@ -3450,10 +3235,10 @@ iovec_fill_last(subfiling_context_t *sf_context, size_t iovec_len, int64_t cur_i block_size = sf_context->sf_blocksize_per_stripe; #ifdef H5_SUBFILING_DEBUG - H5_subfiling_log(sf_context->sf_context_id, - "%s: start_mem_offset = %" PRId64 ", start_file_offset = %" PRId64 - ", last_io_len = %" PRId64, - __func__, start_mem_offset, start_file_offset, last_io_len); + H5FD__subfiling_log(sf_context->sf_context_id, + "%s: start_mem_offset = %" PRId64 ", start_file_offset = %" PRId64 + ", last_io_len = %" PRId64, + __func__, start_mem_offset, start_file_offset, last_io_len); #endif *io_addrs_ptr = (haddr_t)start_file_offset; @@ -3465,79 +3250,72 @@ iovec_fill_last(subfiling_context_t *sf_context, size_t iovec_len, int64_t cur_i io_bufs_ptr->vp = (char *)(buf.vp) + start_mem_offset; if (last_io_len == target_datasize) - H5_SUBFILING_GOTO_DONE(SUCCEED); - - { - int64_t next_mem_offset = start_mem_offset + block_size; - int64_t next_file_offset = start_file_offset + block_size; - size_t i; - - /* - * If the last I/O size doesn't cover the target data - * size, there is at least one full stripe preceding - * the last I/O block - */ - *io_sizes_ptr = (size_t)stripe_size; + HGOTO_DONE(SUCCEED); - total_bytes = stripe_size; + /* + * If the last I/O size doesn't cover the target data + * size, there is at least one full stripe preceding + * the last I/O block + */ + *io_sizes_ptr = (size_t)stripe_size; - for (i = 1; i < (size_t)cur_iovec_depth - 1;) { - *(io_addrs_ptr + (i * iovec_len)) = (haddr_t)next_file_offset; - *(io_sizes_ptr + (i * iovec_len)) = (size_t)stripe_size; + next_mem_offset = start_mem_offset + block_size; + next_file_offset = start_file_offset + block_size; + total_bytes = stripe_size; + for (i = 1; i < (size_t)cur_iovec_depth - 1; i++) { + *(io_addrs_ptr + (i * iovec_len)) = (haddr_t)next_file_offset; + *(io_sizes_ptr + (i * iovec_len)) = (size_t)stripe_size; - if (io_type == IO_TYPE_WRITE) - (io_bufs_ptr + (i * iovec_len))->cvp = (const char *)(buf.cvp) + next_mem_offset; - else - (io_bufs_ptr + (i * iovec_len))->vp = (char *)(buf.vp) + next_mem_offset; + if (io_type == IO_TYPE_WRITE) + (io_bufs_ptr + (i * iovec_len))->cvp = (const char *)(buf.cvp) + next_mem_offset; + else + (io_bufs_ptr + (i * iovec_len))->vp = (char *)(buf.vp) + next_mem_offset; #ifdef H5_SUBFILING_DEBUG - H5_subfiling_log(sf_context->sf_context_id, - "%s: mem_offset[%zu] = %" PRId64 ", file_offset[%zu] = %" PRId64 - ", io_block_len[%zu] = %" PRId64, - __func__, i, next_mem_offset, i, next_file_offset, i, stripe_size); + H5FD__subfiling_log(sf_context->sf_context_id, + "%s: mem_offset[%zu] = %" PRId64 ", file_offset[%zu] = %" PRId64 + ", io_block_len[%zu] = %" PRId64, + __func__, i, next_mem_offset, i, next_file_offset, i, stripe_size); #endif - next_mem_offset += block_size; - next_file_offset += block_size; - total_bytes += stripe_size; - - i++; - } + next_mem_offset += block_size; + next_file_offset += block_size; + total_bytes += stripe_size; + } - *(io_addrs_ptr + (i * iovec_len)) = (haddr_t)next_file_offset; - *(io_sizes_ptr + (i * iovec_len)) = (size_t)last_io_len; + *(io_addrs_ptr + (i * iovec_len)) = (haddr_t)next_file_offset; + *(io_sizes_ptr + (i * iovec_len)) = (size_t)last_io_len; - if (io_type == IO_TYPE_WRITE) - (io_bufs_ptr + (i * iovec_len))->cvp = (const char *)(buf.cvp) + next_mem_offset; - else - (io_bufs_ptr + (i * iovec_len))->vp = (char *)(buf.vp) + next_mem_offset; + if (io_type == IO_TYPE_WRITE) + (io_bufs_ptr + (i * iovec_len))->cvp = (const char *)(buf.cvp) + next_mem_offset; + else + (io_bufs_ptr + (i * iovec_len))->vp = (char *)(buf.vp) + next_mem_offset; #ifdef H5_SUBFILING_DEBUG - H5_subfiling_log(sf_context->sf_context_id, - "%s: mem_offset[%zu] = %" PRId64 ", file_offset[%zu] = %" PRId64 - ", io_block_len[%zu] = %" PRId64, - __func__, i, next_mem_offset, i, next_file_offset, i, last_io_len); + H5FD__subfiling_log(sf_context->sf_context_id, + "%s: mem_offset[%zu] = %" PRId64 ", file_offset[%zu] = %" PRId64 + ", io_block_len[%zu] = %" PRId64, + __func__, i, next_mem_offset, i, next_file_offset, i, last_io_len); #endif - total_bytes += last_io_len; + total_bytes += last_io_len; - if (total_bytes != target_datasize) - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_CANTINIT, FAIL, - "total bytes (%" PRId64 ") didn't match target data size (%" PRId64 ")!", - total_bytes, target_datasize); - } + if (total_bytes != target_datasize) + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, + "total bytes (%" PRId64 ") didn't match target data size (%" PRId64 ")!", total_bytes, + target_datasize); done: - return ret_value; + FUNC_LEAVE_NOAPI(ret_value) } /*------------------------------------------------------------------------- - * Function: iovec_fill_first_last + * Function: H5FD__subfiling_iovec_fill_first_last * * Purpose: Fills I/O vectors for the case where the IOC has the first * and last data segments of the I/O operation. This function - * is essentially a merge of the iovec_fill_first and - * iovec_fill_last functions. + * is essentially a merge of the H5FD__subfiling_iovec_fill_first and + * H5FD__subfiling_iovec_fill_last functions. * * If the 'first_io_len' is sufficient to complete the I/O to * the IOC, then the first entry in the I/O vectors is simply @@ -3555,17 +3333,20 @@ iovec_fill_last(subfiling_context_t *sf_context, size_t iovec_len, int64_t cur_i *------------------------------------------------------------------------- */ static herr_t -iovec_fill_first_last(subfiling_context_t *sf_context, size_t iovec_len, int64_t cur_iovec_depth, - int64_t target_datasize, int64_t start_mem_offset, int64_t start_file_offset, - int64_t first_io_len, int64_t last_io_len, H5_flexible_const_ptr_t buf, - H5FD_subfiling_io_type_t io_type, haddr_t *io_addrs_ptr, size_t *io_sizes_ptr, - H5_flexible_const_ptr_t *io_bufs_ptr) +H5FD__subfiling_iovec_fill_first_last(subfiling_context_t *sf_context, size_t iovec_len, + int64_t cur_iovec_depth, int64_t target_datasize, + int64_t start_mem_offset, int64_t start_file_offset, + int64_t first_io_len, int64_t last_io_len, H5_flexible_const_ptr_t buf, + H5FD_subfiling_io_type_t io_type, haddr_t *io_addrs_ptr, + size_t *io_sizes_ptr, H5_flexible_const_ptr_t *io_bufs_ptr) { int64_t stripe_size; int64_t block_size; int64_t total_bytes = 0; herr_t ret_value = SUCCEED; + FUNC_ENTER_PACKAGE + assert(sf_context); assert(cur_iovec_depth > 0); assert(io_addrs_ptr); @@ -3576,10 +3357,10 @@ iovec_fill_first_last(subfiling_context_t *sf_context, size_t iovec_len, int64_t block_size = sf_context->sf_blocksize_per_stripe; #ifdef H5_SUBFILING_DEBUG - H5_subfiling_log(sf_context->sf_context_id, - "%s: start_mem_offset = %" PRId64 ", start_file_offset = %" PRId64 - ", first_io_len = %" PRId64 ", last_io_len = %" PRId64, - __func__, start_mem_offset, start_file_offset, first_io_len, last_io_len); + H5FD__subfiling_log(sf_context->sf_context_id, + "%s: start_mem_offset = %" PRId64 ", start_file_offset = %" PRId64 + ", first_io_len = %" PRId64 ", last_io_len = %" PRId64, + __func__, start_mem_offset, start_file_offset, first_io_len, last_io_len); #endif *io_addrs_ptr = (haddr_t)start_file_offset; @@ -3591,7 +3372,7 @@ iovec_fill_first_last(subfiling_context_t *sf_context, size_t iovec_len, int64_t io_bufs_ptr->vp = (char *)(buf.vp) + start_mem_offset; if (first_io_len == target_datasize) - H5_SUBFILING_GOTO_DONE(SUCCEED); + HGOTO_DONE(SUCCEED); if (first_io_len > 0) { int64_t offset_in_stripe = start_file_offset % stripe_size; @@ -3601,7 +3382,7 @@ iovec_fill_first_last(subfiling_context_t *sf_context, size_t iovec_len, int64_t total_bytes = first_io_len; - for (i = 1; i < (size_t)cur_iovec_depth - 1;) { + for (i = 1; i < (size_t)cur_iovec_depth - 1; i++) { *(io_addrs_ptr + (i * iovec_len)) = (haddr_t)next_file_offset; *(io_sizes_ptr + (i * iovec_len)) = (size_t)stripe_size; @@ -3611,17 +3392,15 @@ iovec_fill_first_last(subfiling_context_t *sf_context, size_t iovec_len, int64_t (io_bufs_ptr + (i * iovec_len))->vp = (char *)(buf.vp) + next_mem_offset; #ifdef H5_SUBFILING_DEBUG - H5_subfiling_log(sf_context->sf_context_id, - "%s: mem_offset[%zu] = %" PRId64 ", file_offset[%zu] = %" PRId64 - ", io_block_len[%zu] = %" PRId64, - __func__, i, next_mem_offset, i, next_file_offset, i, stripe_size); + H5FD__subfiling_log(sf_context->sf_context_id, + "%s: mem_offset[%zu] = %" PRId64 ", file_offset[%zu] = %" PRId64 + ", io_block_len[%zu] = %" PRId64, + __func__, i, next_mem_offset, i, next_file_offset, i, stripe_size); #endif next_mem_offset += block_size; next_file_offset += block_size; total_bytes += stripe_size; - - i++; } *(io_addrs_ptr + (i * iovec_len)) = (haddr_t)next_file_offset; @@ -3633,26 +3412,26 @@ iovec_fill_first_last(subfiling_context_t *sf_context, size_t iovec_len, int64_t (io_bufs_ptr + (i * iovec_len))->vp = (char *)(buf.vp) + next_mem_offset; #ifdef H5_SUBFILING_DEBUG - H5_subfiling_log(sf_context->sf_context_id, - "%s: mem_offset[%zu] = %" PRId64 ", file_offset[%zu] = %" PRId64 - ", io_block_len[%zu] = %" PRId64, - __func__, i, next_mem_offset, i, next_file_offset, i, last_io_len); + H5FD__subfiling_log(sf_context->sf_context_id, + "%s: mem_offset[%zu] = %" PRId64 ", file_offset[%zu] = %" PRId64 + ", io_block_len[%zu] = %" PRId64, + __func__, i, next_mem_offset, i, next_file_offset, i, last_io_len); #endif total_bytes += last_io_len; if (total_bytes != target_datasize) - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_CANTINIT, FAIL, - "total bytes (%" PRId64 ") didn't match target data size (%" PRId64 ")!", - total_bytes, target_datasize); + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, + "total bytes (%" PRId64 ") didn't match target data size (%" PRId64 ")!", total_bytes, + target_datasize); } done: - return ret_value; + FUNC_LEAVE_NOAPI(ret_value) } /*------------------------------------------------------------------------- - * Function: iovec_fill_uniform + * Function: H5FD__subfiling_iovec_fill_uniform * * Purpose: Fills I/O vectors for the typical I/O operation when * reading data from or writing data to an I/O Concentrator @@ -3667,18 +3446,21 @@ iovec_fill_first_last(subfiling_context_t *sf_context, size_t iovec_len, int64_t *------------------------------------------------------------------------- */ static herr_t -iovec_fill_uniform(subfiling_context_t *sf_context, size_t iovec_len, int64_t cur_iovec_depth, - int64_t target_datasize, int64_t start_mem_offset, int64_t start_file_offset, - H5_flexible_const_ptr_t buf, H5FD_subfiling_io_type_t io_type, haddr_t *io_addrs_ptr, - size_t *io_sizes_ptr, H5_flexible_const_ptr_t *io_bufs_ptr) +H5FD__subfiling_iovec_fill_uniform(subfiling_context_t *sf_context, size_t iovec_len, int64_t cur_iovec_depth, + int64_t target_datasize, int64_t start_mem_offset, + int64_t start_file_offset, H5_flexible_const_ptr_t buf, + H5FD_subfiling_io_type_t io_type, haddr_t *io_addrs_ptr, + size_t *io_sizes_ptr, H5_flexible_const_ptr_t *io_bufs_ptr) { int64_t stripe_size; int64_t block_size; int64_t total_bytes = 0; herr_t ret_value = SUCCEED; + FUNC_ENTER_PACKAGE + assert(sf_context); - assert((cur_iovec_depth > 0) || (target_datasize == 0)); + assert(cur_iovec_depth > 0 || target_datasize == 0); assert(io_addrs_ptr); assert(io_sizes_ptr); assert(io_bufs_ptr); @@ -3687,10 +3469,10 @@ iovec_fill_uniform(subfiling_context_t *sf_context, size_t iovec_len, int64_t cu block_size = sf_context->sf_blocksize_per_stripe; #ifdef H5_SUBFILING_DEBUG - H5_subfiling_log(sf_context->sf_context_id, - "%s: start_mem_offset = %" PRId64 ", start_file_offset = %" PRId64 - ", segment size = %" PRId64, - __func__, start_mem_offset, start_file_offset, stripe_size); + H5FD__subfiling_log(sf_context->sf_context_id, + "%s: start_mem_offset = %" PRId64 ", start_file_offset = %" PRId64 + ", segment size = %" PRId64, + __func__, start_mem_offset, start_file_offset, stripe_size); #endif *io_addrs_ptr = (haddr_t)start_file_offset; @@ -3703,11 +3485,11 @@ iovec_fill_uniform(subfiling_context_t *sf_context, size_t iovec_len, int64_t cu if (target_datasize == 0) { #ifdef H5_SUBFILING_DEBUG - H5_subfiling_log(sf_context->sf_context_id, "%s: target_datasize = 0", __func__); + H5FD__subfiling_log(sf_context->sf_context_id, "%s: target_datasize = 0", __func__); #endif *io_sizes_ptr = (size_t)0; - H5_SUBFILING_GOTO_DONE(SUCCEED); + HGOTO_DONE(SUCCEED); } if (target_datasize > stripe_size) { @@ -3726,10 +3508,10 @@ iovec_fill_uniform(subfiling_context_t *sf_context, size_t iovec_len, int64_t cu (io_bufs_ptr + (i * iovec_len))->vp = (char *)(buf.vp) + next_mem_offset; #ifdef H5_SUBFILING_DEBUG - H5_subfiling_log(sf_context->sf_context_id, - "%s: mem_offset[%zu] = %" PRId64 ", file_offset[%zu] = %" PRId64 - ", io_block_len[%zu] = %" PRId64, - __func__, i, next_mem_offset, i, next_file_offset, i, stripe_size); + H5FD__subfiling_log(sf_context->sf_context_id, + "%s: mem_offset[%zu] = %" PRId64 ", file_offset[%zu] = %" PRId64 + ", io_block_len[%zu] = %" PRId64, + __func__, i, next_mem_offset, i, next_file_offset, i, stripe_size); #endif next_mem_offset += block_size; @@ -3738,46 +3520,50 @@ iovec_fill_uniform(subfiling_context_t *sf_context, size_t iovec_len, int64_t cu } if (total_bytes != target_datasize) - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_CANTINIT, FAIL, - "total bytes (%" PRId64 ") didn't match target data size (%" PRId64 ")!", - total_bytes, target_datasize); + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, + "total bytes (%" PRId64 ") didn't match target data size (%" PRId64 ")!", total_bytes, + target_datasize); } done: - return ret_value; + FUNC_LEAVE_NOAPI(ret_value) } #ifdef H5_SUBFILING_DEBUG -void +static void H5_subfiling_dump_iovecs(subfiling_context_t *sf_context, size_t ioreq_count, size_t iovec_len, H5FD_subfiling_io_type_t io_type, H5FD_mem_t *io_types, haddr_t *io_addrs, size_t *io_sizes, H5_flexible_const_ptr_t *io_bufs) { + FUNC_ENTER_PACKAGE_NOERR + assert(sf_context); assert(io_types); assert(io_addrs); assert(io_sizes); assert(io_bufs); - H5_subfiling_log(sf_context->sf_context_id, - "%s: I/O REQUEST VECTORS (mem type, addr, size, buf):", __func__); + H5FD__subfiling_log(sf_context->sf_context_id, + "%s: I/O REQUEST VECTORS (mem type, addr, size, buf):", __func__); for (size_t ioreq_idx = 0; ioreq_idx < ioreq_count; ioreq_idx++) { - H5_subfiling_log_nonewline(sf_context->sf_context_id, " -> I/O REQUEST %zu: ", ioreq_idx); + H5FD__subfiling_log_nonewline(sf_context->sf_context_id, " -> I/O REQUEST %zu: ", ioreq_idx); - H5_subfiling_log_nonewline(sf_context->sf_context_id, "["); + H5FD__subfiling_log_nonewline(sf_context->sf_context_id, "["); for (size_t i = 0; i < iovec_len; i++) { if (i > 0) - H5_subfiling_log_nonewline(sf_context->sf_context_id, ", "); + H5FD__subfiling_log_nonewline(sf_context->sf_context_id, ", "); - H5_subfiling_log_nonewline( + H5FD__subfiling_log_nonewline( sf_context->sf_context_id, "(%d, %" PRIuHADDR ", %zu, %p)", *(io_types + (ioreq_idx * iovec_len) + i), *(io_addrs + (ioreq_idx * iovec_len) + i), *(io_sizes + (ioreq_idx * iovec_len) + i), (io_type == IO_TYPE_WRITE) ? (const void *)(io_bufs + (ioreq_idx * iovec_len) + i)->cvp : (void *)(io_bufs + (ioreq_idx * iovec_len) + i)->vp); } - H5_subfiling_log_nonewline(sf_context->sf_context_id, "]\n"); + H5FD__subfiling_log_nonewline(sf_context->sf_context_id, "]\n"); } + + FUNC_LEAVE_NOAPI_VOID } #endif diff --git a/src/H5FDsubfiling/H5FDsubfiling_priv.h b/src/H5FDsubfiling/H5FDsubfiling_priv.h index 08fef7d1a01..cef71e15b84 100644 --- a/src/H5FDsubfiling/H5FDsubfiling_priv.h +++ b/src/H5FDsubfiling/H5FDsubfiling_priv.h @@ -38,7 +38,6 @@ #include "H5Pprivate.h" /* Property lists */ #include "H5subfiling_common.h" -#include "H5subfiling_err.h" #define DRIVER_INFO_MESSAGE_MAX_INFO 65536 #define DRIVER_INFO_MESSAGE_MAX_LENGTH 65552 /* MAX_INFO + sizeof(info_header_t) */ diff --git a/src/H5FDsubfiling/H5subfiling_common.c b/src/H5FDsubfiling/H5subfiling_common.c index 53fb0ce3c4c..0b7dea833a4 100644 --- a/src/H5FDsubfiling/H5subfiling_common.c +++ b/src/H5FDsubfiling/H5subfiling_common.c @@ -15,8 +15,8 @@ */ #include "H5subfiling_common.h" -#include "H5subfiling_err.h" +#include "H5Eprivate.h" #include "H5MMprivate.h" typedef struct { /* Format of a context map entry */ @@ -24,12 +24,6 @@ typedef struct { /* Format of a context map entry */ int64_t sf_context_id; /* The return value if matching file_handle */ } file_map_to_context_t; -/* Identifiers for HDF5's error API */ -hid_t H5subfiling_err_stack_g = H5I_INVALID_HID; -hid_t H5subfiling_err_class_g = H5I_INVALID_HID; -char H5subfiling_mpi_error_str[MPI_MAX_ERROR_STRING]; -int H5subfiling_mpi_error_str_len; - /* MPI Datatype used to send/receive an RPC message */ MPI_Datatype H5_subfiling_rpc_msg_type = MPI_DATATYPE_NULL; @@ -48,36 +42,45 @@ static int sf_file_map_size = 0; #define DEFAULT_TOPOLOGY_CACHE_SIZE 4 #define DEFAULT_FILE_MAP_ENTRIES 8 -static herr_t H5_free_subfiling_object_int(subfiling_context_t *sf_context); -static herr_t H5_free_subfiling_topology(sf_topology_t *topology); - -static herr_t init_subfiling(const char *base_filename, uint64_t file_id, - H5FD_subfiling_params_t *subfiling_config, int file_acc_flags, MPI_Comm comm, - int64_t *context_id_out); -static herr_t init_app_topology(int64_t sf_context_id, H5FD_subfiling_params_t *subfiling_config, - MPI_Comm comm, MPI_Comm node_comm, sf_topology_t **app_topology_out); -static herr_t get_ioc_selection_criteria_from_env(H5FD_subfiling_ioc_select_t *ioc_selection_type, - char **ioc_sel_info_str); -static herr_t find_cached_topology_info(MPI_Comm comm, H5FD_subfiling_params_t *subf_config, - long iocs_per_node, sf_topology_t **app_topology); -static herr_t init_app_layout(sf_topology_t *app_topology, MPI_Comm comm, MPI_Comm node_comm); -static herr_t gather_topology_info(app_layout_t *app_layout, MPI_Comm comm, MPI_Comm intra_comm); -static int compare_layout_nodelocal(const void *layout1, const void *layout2); -static herr_t identify_ioc_ranks(int64_t sf_context_id, sf_topology_t *app_topology, int rank_stride); -static herr_t init_subfiling_context(subfiling_context_t *sf_context, const char *base_filename, - uint64_t file_id, H5FD_subfiling_params_t *subfiling_config, - sf_topology_t *app_topology, MPI_Comm file_comm); -static herr_t init_open_file_map(void); -static herr_t record_fid_map_entry(uint64_t file_id, int64_t subfile_context_id, int *next_index); -static herr_t clear_fid_map_entry(uint64_t file_id, int64_t sf_context_id); -static herr_t ioc_open_files(int64_t file_context_id, int file_acc_flags); -static herr_t create_config_file(subfiling_context_t *sf_context, const char *base_filename, - const char *config_dir, const char *subfile_dir, bool truncate_if_exists); -static herr_t open_config_file(const char *base_filename, const char *config_dir, uint64_t file_id, - const char *mode, FILE **config_file_out); +static int64_t H5FD__subfiling_new_object_id(sf_obj_type_t obj_type); +static herr_t H5FD__subfiling_free_context(subfiling_context_t *sf_context); +static herr_t H5FD__subfiling_free_topology(sf_topology_t *topology); + +static herr_t H5FD__subfiling_setup_context(const char *base_filename, uint64_t file_id, + H5FD_subfiling_params_t *subfiling_config, int file_acc_flags, + MPI_Comm comm, int64_t *context_id_out); +static herr_t H5FD__subfiling_init_app_topology(int64_t sf_context_id, + H5FD_subfiling_params_t *subfiling_config, MPI_Comm comm, + MPI_Comm node_comm, sf_topology_t **app_topology_out); +static herr_t H5FD__subfiling_init_context(int64_t context_id, const char *prefix_env, + const char *base_filename, uint64_t file_id, + H5FD_subfiling_params_t *subfiling_config, + sf_topology_t *app_topology, MPI_Comm file_comm, + MPI_Comm node_comm, subfiling_context_t **context); +static herr_t +H5FD__subfiling_get_ioc_selection_criteria_from_env(H5FD_subfiling_ioc_select_t *ioc_selection_type, + char **ioc_sel_info_str); +static herr_t H5FD__subfiling_find_cached_topology_info(MPI_Comm comm, H5FD_subfiling_params_t *subf_config, + long iocs_per_node, sf_topology_t **app_topology); +static herr_t H5FD__subfiling_init_app_layout(sf_topology_t *app_topology, MPI_Comm comm, MPI_Comm node_comm); +static herr_t H5FD__subfiling_gather_topology_info(app_layout_t *app_layout, MPI_Comm comm, + MPI_Comm intra_comm); +static int H5FD__subfiling_compare_layout_nodelocal(const void *layout1, const void *layout2); +static herr_t H5FD__subfiling_identify_ioc_ranks(int64_t sf_context_id, sf_topology_t *app_topology, + int rank_stride); +static herr_t H5FD__subfiling_init_open_file_map(void); +static herr_t H5FD__subfiling_record_fid_map_entry(uint64_t file_id, int64_t subfile_context_id, + int *next_index); +static herr_t H5FD__subfiling_clear_fid_map_entry(uint64_t file_id, int64_t sf_context_id); +static herr_t H5FD__subfiling_ioc_open_files(int64_t file_context_id, int file_acc_flags); +static herr_t H5FD__subfiling_create_config_file(subfiling_context_t *sf_context, const char *base_filename, + const char *config_dir, const char *subfile_dir, + bool truncate_if_exists); +static herr_t H5FD__subfiling_open_config_file(const char *base_filename, const char *config_dir, + uint64_t file_id, const char *mode, FILE **config_file_out); /*------------------------------------------------------------------------- - * Function: H5_new_subfiling_object_id + * Function: H5FD__subfiling_new_object_id * * Purpose: Given a subfiling object type and an index value, generates * a new subfiling object ID. @@ -86,28 +89,32 @@ static herr_t open_config_file(const char *base_filename, const char *config_dir * *------------------------------------------------------------------------- */ -int64_t -H5_new_subfiling_object_id(sf_obj_type_t obj_type) +static int64_t +H5FD__subfiling_new_object_id(sf_obj_type_t obj_type) { int64_t index_val = 0; + int64_t ret_value; - if (obj_type == SF_CONTEXT) { + FUNC_ENTER_PACKAGE + + if (obj_type == SF_CONTEXT) index_val = (int64_t)sf_context_cache_next_index; - } - else if (obj_type == SF_TOPOLOGY) { + else if (obj_type == SF_TOPOLOGY) index_val = (int64_t)sf_topology_cache_num_entries; - } else - return -1; + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "invalid object type"); if (index_val < 0) - return -1; + HGOTO_ERROR(H5E_VFL, H5E_CANTREGISTER, FAIL, "invalid object index"); + + ret_value = ((int64_t)obj_type << 32) | index_val; - return (((int64_t)obj_type << 32) | index_val); +done: + FUNC_LEAVE_NOAPI(ret_value) } /*------------------------------------------------------------------------- - * Function: H5_get_subfiling_object + * Function: H5FD__subfiling_get_object * * Purpose: Given a subfiling object ID, returns a pointer to the * underlying object, which can be either a subfiling context @@ -130,32 +137,33 @@ H5_new_subfiling_object_id(sf_obj_type_t obj_type) *------------------------------------------------------------------------- */ void * -H5_get_subfiling_object(int64_t object_id) +H5FD__subfiling_get_object(int64_t object_id) { int64_t obj_type = (object_id >> 32) & 0x0FFFF; int64_t obj_index = object_id & 0x0FFFF; void *ret_value = NULL; + FUNC_ENTER_PACKAGE + if (obj_index < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_BADVALUE, NULL, - "invalid object index for subfiling object ID %" PRId64, object_id); + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, NULL, "invalid object index for subfiling object ID %" PRId64, + object_id); if (obj_type == SF_CONTEXT) { - /* Contexts provide information principally about - * the application and how the data layout is managed - * over some number of subfiles. The important - * parameters are the number of subfiles (or in the - * context of IOCs, the MPI ranks and counts of the - * processes which host an I/O Concentrator. We - * also provide a map of IOC rank to MPI rank - * to facilitate the communication of I/O requests. + /* Contexts provide information principally about the application and how + * the data layout is managed over some number of subfiles. The important + * parameters are the number of subfiles (or in the context of IOCs, the + * MPI ranks and counts of the processes which host an I/O Concentrator. + * We also provide a map of IOC rank to MPI rank to facilitate the + * communication of I/O requests. */ /* Create subfiling context cache if it doesn't exist */ if (!sf_context_cache) { - if (NULL == (sf_context_cache = calloc(DEFAULT_CONTEXT_CACHE_SIZE, sizeof(*sf_context_cache)))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, NULL, - "couldn't allocate space for subfiling context cache"); + if (NULL == + (sf_context_cache = H5MM_calloc(DEFAULT_CONTEXT_CACHE_SIZE * sizeof(*sf_context_cache)))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, NULL, + "couldn't allocate space for subfiling context cache"); sf_context_cache_size = DEFAULT_CONTEXT_CACHE_SIZE; sf_context_cache_next_index = 0; } @@ -170,9 +178,9 @@ H5_get_subfiling_object(int64_t object_id) new_size = (sf_context_cache_size * 3) / 2; - if (NULL == (tmp_realloc = realloc(sf_context_cache, new_size * sizeof(*sf_context_cache)))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, NULL, - "couldn't allocate space for subfiling context cache"); + if (NULL == (tmp_realloc = H5MM_realloc(sf_context_cache, new_size * sizeof(*sf_context_cache)))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, NULL, + "couldn't allocate space for subfiling context cache"); sf_context_cache = tmp_realloc; sf_context_cache_size = new_size; @@ -193,9 +201,8 @@ H5_get_subfiling_object(int64_t object_id) size_t next_idx; /* Allocate a new subfiling context object */ - if (NULL == (sf_context_cache[obj_index] = calloc(1, sizeof(subfiling_context_t)))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, NULL, - "couldn't allocate subfiling context object"); + if (NULL == (sf_context_cache[obj_index] = H5MM_calloc(sizeof(subfiling_context_t)))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, NULL, "couldn't allocate subfiling context object"); ret_value = sf_context_cache[obj_index]; @@ -214,9 +221,10 @@ H5_get_subfiling_object(int64_t object_id) else if (obj_type == SF_TOPOLOGY) { /* Create subfiling topology cache if it doesn't exist */ if (!sf_topology_cache) { - if (NULL == (sf_topology_cache = calloc(DEFAULT_TOPOLOGY_CACHE_SIZE, sizeof(*sf_topology_cache)))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, NULL, - "couldn't allocate space for subfiling topology cache"); + if (NULL == + (sf_topology_cache = H5MM_calloc(DEFAULT_TOPOLOGY_CACHE_SIZE * sizeof(*sf_topology_cache)))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, NULL, + "couldn't allocate space for subfiling topology cache"); sf_topology_cache_size = DEFAULT_TOPOLOGY_CACHE_SIZE; sf_topology_cache_num_entries = 0; } @@ -231,9 +239,10 @@ H5_get_subfiling_object(int64_t object_id) new_size = (sf_topology_cache_size * 3) / 2; - if (NULL == (tmp_realloc = realloc(sf_topology_cache, new_size * sizeof(*sf_topology_cache)))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, NULL, - "couldn't allocate space for subfiling topology cache"); + if (NULL == + (tmp_realloc = H5MM_realloc(sf_topology_cache, new_size * sizeof(*sf_topology_cache)))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, NULL, + "couldn't allocate space for subfiling topology cache"); sf_topology_cache = tmp_realloc; sf_topology_cache_size = new_size; @@ -261,24 +270,21 @@ H5_get_subfiling_object(int64_t object_id) assert(!sf_topology_cache[sf_topology_cache_num_entries]); /* Allocate a new subfiling topology object */ - if (NULL == (ret_value = malloc(sizeof(sf_topology_t)))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, NULL, - "couldn't allocate subfiling topology object"); + if (NULL == (ret_value = H5MM_malloc(sizeof(sf_topology_t)))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, NULL, "couldn't allocate subfiling topology object"); sf_topology_cache[sf_topology_cache_num_entries++] = ret_value; } } -#ifdef H5_SUBFILING_DEBUG else - printf("%s: Unknown subfiling object type for ID %" PRId64 "\n", __func__, object_id); -#endif + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, NULL, "unknown subfiling object type for ID %" PRId64, object_id); done: - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /*------------------------------------------------------------------------- - * Function: H5_free_subfiling_object + * Function: H5FD__subfiling_free_object * * Purpose: Frees the underlying subfiling object for a given subfiling * object ID. @@ -302,22 +308,22 @@ H5_get_subfiling_object(int64_t object_id) *------------------------------------------------------------------------- */ herr_t -H5_free_subfiling_object(int64_t object_id) +H5FD__subfiling_free_object(int64_t object_id) { int64_t obj_type = (object_id >> 32) & 0x0FFFF; herr_t ret_value = SUCCEED; + FUNC_ENTER_PACKAGE + if (obj_type == SF_CONTEXT) { subfiling_context_t *sf_context; - if (NULL == (sf_context = H5_get_subfiling_object(object_id))) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, - "couldn't get subfiling context for subfiling object ID"); + if (NULL == (sf_context = H5FD__subfiling_get_object(object_id))) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "couldn't get subfiling context for subfiling object ID"); if (sf_context->file_ref == 0 || --sf_context->file_ref == 0) { - if (H5_free_subfiling_object_int(sf_context) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, - "couldn't free subfiling context object"); + if (H5FD__subfiling_free_context(sf_context) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "couldn't free subfiling context object"); for (size_t idx = 0; idx < sf_context_cache_size; idx++) { if (sf_context != sf_context_cache[idx]) @@ -333,12 +339,11 @@ H5_free_subfiling_object(int64_t object_id) else if (obj_type == SF_TOPOLOGY) { sf_topology_t *sf_topology; - if (NULL == (sf_topology = H5_get_subfiling_object(object_id))) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, - "couldn't get subfiling context for subfiling object ID"); + if (NULL == (sf_topology = H5FD__subfiling_get_object(object_id))) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "couldn't get subfiling context for subfiling object ID"); - if (H5_free_subfiling_topology(sf_topology) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "couldn't free subfiling topology object"); + if (H5FD__subfiling_free_topology(sf_topology) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "couldn't free subfiling topology object"); assert(sf_topology_cache_num_entries > 0); assert(sf_topology == sf_topology_cache[sf_topology_cache_num_entries - 1]); @@ -346,91 +351,46 @@ H5_free_subfiling_object(int64_t object_id) sf_topology_cache_num_entries--; } else - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, - "couldn't free subfiling object - invalid object type"); + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "couldn't free subfiling object - invalid object type"); done: - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } static herr_t -H5_free_subfiling_object_int(subfiling_context_t *sf_context) +H5FD__subfiling_free_context(subfiling_context_t *sf_context) { int mpi_finalized; int mpi_code; herr_t ret_value = SUCCEED; + FUNC_ENTER_PACKAGE + assert(sf_context); if (MPI_SUCCESS != (mpi_code = MPI_Finalized(&mpi_finalized))) { - /* Assume MPI is finalized or worse, and try to clean up what we can */ - H5_SUBFILING_MPI_DONE_ERROR(FAIL, "MPI_Finalized failed", mpi_code); + /* Assume MPI is finalized and try to clean up what we can */ + HMPI_DONE_ERROR(FAIL, "MPI_Finalized failed", mpi_code); mpi_finalized = 1; } - sf_context->sf_context_id = -1; - sf_context->h5_file_id = UINT64_MAX; - sf_context->threads_inited = false; - sf_context->file_ref = 0; - sf_context->sf_num_fids = 0; - sf_context->sf_num_subfiles = -1; - sf_context->sf_write_count = 0; - sf_context->sf_read_count = 0; - sf_context->sf_eof = HADDR_UNDEF; - sf_context->sf_stripe_size = -1; - sf_context->sf_blocksize_per_stripe = -1; - sf_context->sf_base_addr = -1; - - if (sf_context->sf_msg_comm != MPI_COMM_NULL) { - if (!mpi_finalized) { - if (H5_mpi_comm_free(&sf_context->sf_msg_comm) < 0) - return FAIL; - } - sf_context->sf_msg_comm = MPI_COMM_NULL; - } - if (sf_context->sf_data_comm != MPI_COMM_NULL) { - if (!mpi_finalized) { - if (H5_mpi_comm_free(&sf_context->sf_data_comm) < 0) - return FAIL; - } - sf_context->sf_data_comm = MPI_COMM_NULL; - } - if (sf_context->sf_eof_comm != MPI_COMM_NULL) { - if (!mpi_finalized) { - if (H5_mpi_comm_free(&sf_context->sf_eof_comm) < 0) - return FAIL; - } - sf_context->sf_eof_comm = MPI_COMM_NULL; - } - if (sf_context->sf_node_comm != MPI_COMM_NULL) { - if (!mpi_finalized) { - if (H5_mpi_comm_free(&sf_context->sf_node_comm) < 0) - return FAIL; - } - sf_context->sf_node_comm = MPI_COMM_NULL; + if (!mpi_finalized) { + if (H5_mpi_comm_free(&sf_context->sf_msg_comm) < 0) + HDONE_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "can't free MPI communicator"); + if (H5_mpi_comm_free(&sf_context->sf_data_comm) < 0) + HDONE_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "can't free MPI communicator"); + if (H5_mpi_comm_free(&sf_context->sf_eof_comm) < 0) + HDONE_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "can't free MPI communicator"); + if (H5_mpi_comm_free(&sf_context->sf_node_comm) < 0) + HDONE_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "can't free MPI communicator"); + if (H5_mpi_comm_free(&sf_context->sf_group_comm) < 0) + HDONE_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "can't free MPI communicator"); } - if (sf_context->sf_group_comm != MPI_COMM_NULL) { - if (!mpi_finalized) { - if (H5_mpi_comm_free(&sf_context->sf_group_comm) < 0) - return FAIL; - } - sf_context->sf_group_comm = MPI_COMM_NULL; - } - - sf_context->sf_group_size = -1; - sf_context->sf_group_rank = -1; - - free(sf_context->subfile_prefix); - sf_context->subfile_prefix = NULL; - free(sf_context->config_file_prefix); - sf_context->config_file_prefix = NULL; - - free(sf_context->h5_filename); - sf_context->h5_filename = NULL; - - free(sf_context->sf_fids); - sf_context->sf_fids = NULL; + H5MM_free(sf_context->subfile_prefix); + H5MM_free(sf_context->config_file_prefix); + H5MM_free(sf_context->h5_filename); + H5MM_free(sf_context->sf_fids); /* * Currently we assume that all created application topology @@ -438,25 +398,27 @@ H5_free_subfiling_object_int(subfiling_context_t *sf_context) * among multiple subfiling contexts, so we free them separately * from here to avoid issues with stale pointers. */ - sf_context->topology = NULL; + /* sf_context->topology = NULL; */ - free(sf_context); + H5MM_free(sf_context); - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } static herr_t -H5_free_subfiling_topology(sf_topology_t *topology) +H5FD__subfiling_free_topology(sf_topology_t *topology) { int mpi_finalized; int mpi_code; herr_t ret_value = SUCCEED; + FUNC_ENTER_PACKAGE + assert(topology); if (MPI_SUCCESS != (mpi_code = MPI_Finalized(&mpi_finalized))) { - /* Assume MPI is finalized or worse, but clean up what we can */ - H5_SUBFILING_MPI_DONE_ERROR(FAIL, "MPI_Finalized failed", mpi_code); + /* Assume MPI is finalized, but clean up what we can */ + HMPI_DONE_ERROR(FAIL, "MPI_Finalized failed", mpi_code); mpi_finalized = 1; } @@ -472,41 +434,30 @@ H5_free_subfiling_topology(sf_topology_t *topology) } #endif - topology->ioc_idx = -1; - topology->n_io_concentrators = 0; - if (topology->app_layout) { - free(topology->app_layout->layout); - topology->app_layout->layout = NULL; - - free(topology->app_layout->node_ranks); - topology->app_layout->node_ranks = NULL; - - free(topology->app_layout); + H5MM_free(topology->app_layout->layout); + H5MM_free(topology->app_layout->node_ranks); + H5MM_free(topology->app_layout); } - topology->app_layout = NULL; - - free(topology->io_concentrators); - topology->io_concentrators = NULL; + H5MM_free(topology->io_concentrators); if (!mpi_finalized) if (H5_mpi_comm_free(&topology->app_comm) < 0) - H5_SUBFILING_DONE_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "can't free MPI communicator"); + HDONE_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "can't free MPI communicator"); - free(topology); + H5MM_free(topology); - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /*------------------------------------------------------------------------- - * Function: H5_open_subfiling_stub_file + * Function: H5FD__subfiling_open_stub_file * - * Purpose: Opens the stub file for an HDF5 file created with the - * Subfiling VFD. This stub file only contains some superblock - * metadata that can allow HDF5 applications to determine that - * the file is an HDF5 file and was created with the Subfiling - * VFD. + * Purpose: Opens the stub file for an HDF5 file created with the subfiling + * VFD. This stub file only contains some superblock metadata that + * can allow HDF5 applications to determine that the file is an HDF5 + * file and was created with the subfiling VFD. * * This routine is collective across `file_comm`; once the * stub file has been opened, the inode value for the file is @@ -517,17 +468,16 @@ H5_free_subfiling_topology(sf_topology_t *topology) * this stub file is currently only opened on MPI rank 0. Note * that this assumes that all the relevant metadata will be * written from MPI rank 0. This should be fine for now since - * the HDF file signature and Subfiling driver info is really + * the HDF file signature and subfiling driver info is really * all that's needed, but this should be revisited since the - * file metadata can and will come from other MPI ranks as - * well. + * file metadata can and will come from other MPI ranks as well. * * Return: Non-negative on success/Negative on failure *------------------------------------------------------------------------- */ herr_t -H5_open_subfiling_stub_file(const char *name, unsigned flags, MPI_Comm file_comm, H5FD_t **file_ptr, - uint64_t *file_id) +H5FD__subfiling_open_stub_file(const char *name, unsigned flags, MPI_Comm file_comm, H5FD_t **file_ptr, + uint64_t *file_id) { H5P_genplist_t *plist = NULL; uint64_t stub_file_id = UINT64_MAX; @@ -539,20 +489,22 @@ H5_open_subfiling_stub_file(const char *name, unsigned flags, MPI_Comm file_comm int mpi_code; herr_t ret_value = SUCCEED; + FUNC_ENTER_PACKAGE + if (!name) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid subfiling stub file name"); + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid subfiling stub file name"); if (file_comm == MPI_COMM_NULL) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid MPI communicator"); + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid MPI communicator"); if (!file_id) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL file ID pointer"); + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL file ID pointer"); if (MPI_SUCCESS != (mpi_code = MPI_Comm_rank(file_comm, &mpi_rank))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Comm_rank failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Comm_rank failed", mpi_code); if (MPI_SUCCESS != (mpi_code = MPI_Comm_size(file_comm, &mpi_size))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Comm_size failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Comm_size failed", mpi_code); - if (!file_ptr && (mpi_rank == 0)) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL stub file pointer"); + if (!file_ptr && mpi_rank == 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL stub file pointer"); /* Open stub file on MPI rank 0 only */ if (mpi_rank == 0) { @@ -561,44 +513,39 @@ H5_open_subfiling_stub_file(const char *name, unsigned flags, MPI_Comm file_comm MPI_Info stub_info = MPI_INFO_NULL; if ((fapl_id = H5P_create_id(H5P_CLS_FILE_ACCESS_g, false)) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "can't create FAPL for stub file"); + HGOTO_ERROR(H5E_VFL, H5E_CANTREGISTER, FAIL, "can't create FAPL for stub file"); if (NULL == (plist = H5P_object_verify(fapl_id, H5P_FILE_ACCESS))) - H5_SUBFILING_GOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "not a file access property list"); + HGOTO_ERROR(H5E_VFL, H5E_BADTYPE, FAIL, "not a file access property list"); /* Use MPI I/O driver for stub file to allow access to vector I/O */ if (H5P_set(plist, H5F_ACS_MPI_PARAMS_COMM_NAME, &stub_comm) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set MPI communicator"); + HGOTO_ERROR(H5E_VFL, H5E_CANTSET, FAIL, "can't set MPI communicator"); if (H5P_set(plist, H5F_ACS_MPI_PARAMS_INFO_NAME, &stub_info) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set MPI info object"); + HGOTO_ERROR(H5E_VFL, H5E_CANTSET, FAIL, "can't set MPI info object"); if (H5P_set_driver(plist, H5FD_MPIO, NULL, NULL) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set MPI I/O driver on FAPL"); + HGOTO_ERROR(H5E_VFL, H5E_CANTSET, FAIL, "can't set MPI I/O driver on FAPL"); if (H5FD_open(false, &stub_file, name, flags, fapl_id, HADDR_UNDEF) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "couldn't open HDF5 stub file"); + HGOTO_ERROR(H5E_VFL, H5E_CANTOPENFILE, FAIL, "couldn't open HDF5 stub file"); HDcompile_assert(sizeof(uint64_t) >= sizeof(ino_t)); /* Retrieve Inode value for stub file */ memset(&st, 0, sizeof(h5_stat_t)); - if (HDstat(name, &st) < 0) { - stub_file_id = UINT64_MAX; - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, - "couldn't stat HDF5 stub file, errno = %d, error message = '%s'", errno, - strerror(errno)); - } - else - stub_file_id = (uint64_t)st.st_ino; + if (HDstat(name, &st) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, + "couldn't stat HDF5 stub file, errno = %d, error message = '%s'", errno, + strerror(errno)); + stub_file_id = (uint64_t)st.st_ino; } - bcasted_inode = true; - - if (mpi_size > 1) { + if (mpi_size > 1) if (MPI_SUCCESS != (mpi_code = MPI_Bcast(&stub_file_id, 1, MPI_UINT64_T, 0, file_comm))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Bcast failed", mpi_code); - } + HMPI_GOTO_ERROR(FAIL, "MPI_Bcast failed", mpi_code); + bcasted_inode = true; if (stub_file_id == UINT64_MAX) - H5_SUBFILING_GOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "couldn't get inode value for HDF5 stub file"); + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "couldn't get inode value for HDF5 stub file"); if (file_ptr) *file_ptr = stub_file; @@ -606,24 +553,22 @@ H5_open_subfiling_stub_file(const char *name, unsigned flags, MPI_Comm file_comm done: if (fapl_id >= 0 && H5I_dec_ref(fapl_id) < 0) - H5_SUBFILING_DONE_ERROR(H5E_ID, H5E_CANTDEC, FAIL, "can't close FAPL ID"); + HDONE_ERROR(H5E_VFL, H5E_CANTDEC, FAIL, "can't close FAPL ID"); if (ret_value < 0) { - if (!bcasted_inode && (mpi_size > 1)) { + if (!bcasted_inode && (mpi_size > 1)) if (MPI_SUCCESS != (mpi_code = MPI_Bcast(&stub_file_id, 1, MPI_UINT64_T, 0, file_comm))) - H5_SUBFILING_MPI_DONE_ERROR(FAIL, "MPI_Bcast failed", mpi_code); - } - if (stub_file) { + HMPI_DONE_ERROR(FAIL, "MPI_Bcast failed", mpi_code); + if (stub_file) if (H5FD_close(stub_file) < 0) - H5_SUBFILING_DONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "couldn't close HDF5 stub file"); - } + HDONE_ERROR(H5E_VFL, H5E_CANTCLOSEFILE, FAIL, "couldn't close HDF5 stub file"); } - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /*------------------------------------------------------------------------- - * Function: H5_open_subfiles + * Function: H5FD__subfiling_open_subfiles * * Purpose: Initializes a subfiling context object for a file with the * given filename and file ID (inode) and opens the associated @@ -641,61 +586,59 @@ H5_open_subfiling_stub_file(const char *name, unsigned flags, MPI_Comm file_comm *------------------------------------------------------------------------- */ herr_t -H5_open_subfiles(const char *base_filename, uint64_t file_id, H5FD_subfiling_params_t *subfiling_config, - int file_acc_flags, MPI_Comm file_comm, int64_t *context_id_out) +H5FD__subfiling_open_subfiles(const char *base_filename, uint64_t file_id, + H5FD_subfiling_params_t *subfiling_config, int file_acc_flags, + MPI_Comm file_comm, int64_t *context_id_out) { - subfiling_context_t *sf_context = NULL; - int64_t context_id = -1; + subfiling_context_t *sf_context = NULL; + int64_t context_id = -1; + int mpi_size; + int err_result; bool recorded_fid = false; int mpi_code; herr_t ret_value = SUCCEED; - if (!base_filename) - H5_SUBFILING_GOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "invalid subfiling base filename"); + FUNC_ENTER_PACKAGE + if (!base_filename) + HGOTO_ERROR(H5E_VFL, H5E_CANTOPENFILE, FAIL, "invalid subfiling base filename"); if (!subfiling_config) - H5_SUBFILING_GOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "invalid subfiling configuration"); - + HGOTO_ERROR(H5E_VFL, H5E_CANTOPENFILE, FAIL, "invalid subfiling configuration"); if (!context_id_out) - H5_SUBFILING_GOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "invalid subfiling context ID pointer"); + HGOTO_ERROR(H5E_VFL, H5E_CANTOPENFILE, FAIL, "invalid subfiling context ID pointer"); /* Make sure open file mapping is initialized in case this * is the first file open call with the VFD */ - if (init_open_file_map() < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "couldn't initialize open file mapping"); + if (H5FD__subfiling_init_open_file_map() < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "couldn't initialize open file mapping"); /* Check if this file is already open */ - if (H5_subfile_fid_to_context(file_id, &context_id) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, - "couldn't retrieve context ID from open file mapping"); + if (H5FD__subfile_fid_to_context(file_id, &context_id) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "couldn't retrieve context ID from open file mapping"); if (context_id >= 0) { /* Retrieve the subfiling object for the cached context ID */ - if (NULL == (sf_context = H5_get_subfiling_object(context_id))) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, - "couldn't get subfiling object from context ID"); + if (NULL == (sf_context = H5FD__subfiling_get_object(context_id))) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "couldn't get subfiling object from context ID"); } else { - /* Initialize new subfiling context ID based on configuration information */ - if (init_subfiling(base_filename, file_id, subfiling_config, file_acc_flags, file_comm, &context_id) < - 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "couldn't initialize subfiling context"); + /* Set up new subfiling context based on configuration information */ + if (H5FD__subfiling_setup_context(base_filename, file_id, subfiling_config, file_acc_flags, file_comm, + &context_id) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "couldn't initialize subfiling context"); /* Retrieve the subfiling object for the newly-created context ID */ - if (NULL == (sf_context = H5_get_subfiling_object(context_id))) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, - "couldn't get subfiling object from context ID"); + if (NULL == (sf_context = H5FD__subfiling_get_object(context_id))) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "couldn't get subfiling object from context ID"); /* - * If this rank is an I/O concentrator, actually open - * the subfiles belonging to this IOC rank and start - * the I/O service threads + * If this rank is an I/O concentrator, actually open the subfiles + * belonging to this IOC rank and start the I/O service threads */ - if (sf_context->topology->rank_is_ioc) { - if (ioc_open_files(sf_context->sf_context_id, file_acc_flags) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTOPENFILE, FAIL, "IOC couldn't open subfile"); - } + if (sf_context->topology->rank_is_ioc) + if (H5FD__subfiling_ioc_open_files(sf_context->sf_context_id, file_acc_flags) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTOPENFILE, FAIL, "IOC couldn't open subfile"); } #ifdef H5_SUBFILING_DEBUG @@ -707,18 +650,17 @@ H5_open_subfiles(const char *base_filename, uint64_t file_id, H5FD_subfiling_par /* Open debugging logfile */ if (MPI_SUCCESS != (mpi_code = MPI_Comm_rank(file_comm, &mpi_rank))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Comm_rank failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Comm_rank failed", mpi_code); snprintf(sf_context->sf_logfile_name, PATH_MAX, "%s.log.%d", sf_context->h5_filename, mpi_rank); if (NULL == (sf_context->sf_logfile = fopen(sf_context->sf_logfile_name, "a"))) - H5_SUBFILING_SYS_GOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, - "couldn't open subfiling debug logfile"); + HSYS_GOTO_ERROR(H5E_VFL, H5E_CANTOPENFILE, FAIL, "couldn't open subfiling debug logfile"); cur_time = time(NULL); tm = localtime(&cur_time); - H5_subfiling_log(context_id, "-- LOGGING BEGIN - %s", asctime(tm)); + H5FD__subfiling_log(context_id, "-- LOGGING BEGIN - %s", asctime(tm)); } #endif @@ -727,48 +669,35 @@ H5_open_subfiles(const char *base_filename, uint64_t file_id, H5FD_subfiling_par * There shouldn't be any issue, but check the status and * return if there was a problem. */ - if (record_fid_map_entry(sf_context->h5_file_id, sf_context->sf_context_id, NULL) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, - "couldn't record HDF5 file ID to subfile context mapping"); + if (H5FD__subfiling_record_fid_map_entry(sf_context->h5_file_id, sf_context->sf_context_id, NULL) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "couldn't record HDF5 file ID to subfile context mapping"); recorded_fid = true; *context_id_out = context_id; done: - /* - * Form consensus on whether opening subfiles was - * successful - */ - { - int mpi_size = -1; - int err_result = (ret_value < 0); - - if (MPI_SUCCESS != (mpi_code = MPI_Comm_size(file_comm, &mpi_size))) - H5_SUBFILING_MPI_DONE_ERROR(FAIL, "MPI_Comm_size failed", mpi_code); - - if (mpi_size > 1) { - if (MPI_SUCCESS != - (mpi_code = MPI_Allreduce(MPI_IN_PLACE, &err_result, 1, MPI_INT, MPI_MAX, file_comm))) - H5_SUBFILING_MPI_DONE_ERROR(FAIL, "MPI_Allreduce failed", mpi_code); - } - - if (err_result) - H5_SUBFILING_DONE_ERROR(H5E_VFL, H5E_CANTOPENFILE, FAIL, - "one or more IOC ranks couldn't open subfiles"); - } + /* Form consensus on whether opening subfiles was successful */ + if (MPI_SUCCESS != (mpi_code = MPI_Comm_size(file_comm, &mpi_size))) + HMPI_DONE_ERROR(FAIL, "MPI_Comm_size failed", mpi_code); + err_result = (ret_value < 0); + if (mpi_size > 1) + if (MPI_SUCCESS != + (mpi_code = MPI_Allreduce(MPI_IN_PLACE, &err_result, 1, MPI_INT, MPI_MAX, file_comm))) + HMPI_DONE_ERROR(FAIL, "MPI_Allreduce failed", mpi_code); + if (err_result) + HDONE_ERROR(H5E_VFL, H5E_CANTOPENFILE, FAIL, "one or more IOC ranks couldn't open subfiles"); if (ret_value < 0) { - if (recorded_fid && clear_fid_map_entry(file_id, context_id) < 0) - H5_SUBFILING_DONE_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, - "unable to clear entry from file ID to context mapping"); + if (recorded_fid && H5FD__subfiling_clear_fid_map_entry(file_id, context_id) < 0) + HDONE_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "unable to clear entry from file ID to context mapping"); - if (context_id >= 0 && H5_free_subfiling_object(context_id) < 0) - H5_SUBFILING_DONE_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "couldn't free subfiling object"); + if (context_id >= 0 && H5FD__subfiling_free_object(context_id) < 0) + HDONE_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "couldn't free subfiling object"); *context_id_out = -1; } - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /* @@ -786,14 +715,14 @@ H5_open_subfiles(const char *base_filename, uint64_t file_id, H5FD_subfiling_par including malloc failures or any resource allocation problems. - Revision History -- Initial implementation ------------------------------------------------------------------------- */ static herr_t -init_subfiling(const char *base_filename, uint64_t file_id, H5FD_subfiling_params_t *subfiling_config, - int file_acc_flags, MPI_Comm comm, int64_t *context_id_out) +H5FD__subfiling_setup_context(const char *base_filename, uint64_t file_id, + H5FD_subfiling_params_t *subfiling_config, int file_acc_flags, MPI_Comm comm, + int64_t *context_id_out) { - subfiling_context_t *new_context = NULL; + subfiling_context_t *context = NULL; sf_topology_t *app_topology = NULL; MPI_Comm node_comm = MPI_COMM_NULL; int64_t context_id = -1; @@ -801,44 +730,27 @@ init_subfiling(const char *base_filename, uint64_t file_id, H5FD_subfiling_param char *file_basename = NULL; char *subfile_dir = NULL; char *prefix_env = NULL; + char *env_value = NULL; int mpi_rank; int mpi_size; int mpi_code; herr_t ret_value = SUCCEED; + FUNC_ENTER_PACKAGE + assert(context_id_out); if (MPI_SUCCESS != (mpi_code = MPI_Comm_rank(comm, &mpi_rank))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Comm_rank failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Comm_rank failed", mpi_code); if (MPI_SUCCESS != (mpi_code = MPI_Comm_size(comm, &mpi_size))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Comm_size failed", mpi_code); - - /* Use the file's index to create a new subfiling context ID */ - if ((context_id = H5_new_subfiling_object_id(SF_CONTEXT)) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "couldn't create new subfiling context ID"); - - /* Create a new subfiling context object with the created context ID */ - if (NULL == (new_context = H5_get_subfiling_object(context_id))) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "couldn't create new subfiling object"); - new_context->sf_context_id = -1; - new_context->topology = NULL; - new_context->sf_msg_comm = MPI_COMM_NULL; - new_context->sf_data_comm = MPI_COMM_NULL; - new_context->sf_eof_comm = MPI_COMM_NULL; - new_context->sf_node_comm = MPI_COMM_NULL; - new_context->sf_group_comm = MPI_COMM_NULL; + HMPI_GOTO_ERROR(FAIL, "MPI_Comm_size failed", mpi_code); /* Check if a prefix has been set for the configuration file name */ prefix_env = getenv(H5FD_SUBFILING_CONFIG_FILE_PREFIX); - if (prefix_env && (strlen(prefix_env) > 0)) { - if (NULL == (new_context->config_file_prefix = strdup(prefix_env))) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTCOPY, FAIL, "couldn't copy config file prefix string"); - } /* - * If there's an existing subfiling configuration file for - * this file, read the stripe size and number of subfiles - * from it + * If there's an existing subfiling configuration file for this file, read the + * stripe size and number of subfiles from it */ if (0 == (file_acc_flags & O_CREAT)) { int64_t config[2] = {0, 0}; /* {stripe size, num subfiles} */ @@ -848,20 +760,18 @@ init_subfiling(const char *base_filename, uint64_t file_id, H5FD_subfiling_param if (H5_dirname(base_filename, &subfile_dir) < 0) config[0] = -1; - if (config[0] >= 0) { + if (config[0] >= 0) if (H5_basename(base_filename, &file_basename) < 0) config[0] = -1; - } - if (config[0] >= 0) { + if (config[0] >= 0) /* * If a prefix has been specified, try to read the config file * from there, otherwise look for it next to the generated subfiles. */ - if (open_config_file(file_basename, prefix_env ? prefix_env : subfile_dir, file_id, "r", - &config_file) < 0) + if (H5FD__subfiling_open_config_file(file_basename, prefix_env ? prefix_env : subfile_dir, + file_id, "r", &config_file) < 0) config[0] = -1; - } if (config[0] >= 0) { if (!config_file) @@ -871,25 +781,24 @@ init_subfiling(const char *base_filename, uint64_t file_id, H5FD_subfiling_param * If a subfiling configuration file exists and we aren't truncating * it, read the number of subfiles used at file creation time. */ - if (H5_get_subfiling_config_from_file(config_file, &config[0], &config[1]) < 0) + if (H5FD__subfiling_get_config_from_file(config_file, &config[0], &config[1]) < 0) config[0] = -1; } } } - if (mpi_size > 1) { + if (mpi_size > 1) if (MPI_SUCCESS != (mpi_code = MPI_Bcast(config, 2, MPI_INT64_T, 0, comm))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Bcast failed", mpi_code); - } + HMPI_GOTO_ERROR(FAIL, "MPI_Bcast failed", mpi_code); /* - * Override the stripe size and stripe count settings in the - * application's subfiling configuration if we read values - * from an existing subfiling configuration file + * Override the stripe size and stripe count settings in the application's + * subfiling configuration if we read values from an existing subfiling + * configuration file */ if (config[0] == -1) - H5_SUBFILING_GOTO_ERROR( - H5E_FILE, H5E_CANTOPENFILE, FAIL, + HGOTO_ERROR( + H5E_VFL, H5E_CANTOPENFILE, FAIL, "lead process couldn't read the number of subfiles from subfiling configuration file"); else { if (config[0] > 0) @@ -901,85 +810,83 @@ init_subfiling(const char *base_filename, uint64_t file_id, H5FD_subfiling_param } } else { - char *env_value = NULL; - /* Check for a subfiling stripe size setting from the environment */ env_value = getenv(H5FD_SUBFILING_STRIPE_SIZE); if (env_value && (strlen(env_value) > 0)) { long long stripe_size = -1; - errno = 0; - + errno = 0; stripe_size = strtoll(env_value, NULL, 0); if (ERANGE == errno) - H5_SUBFILING_SYS_GOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, - "invalid stripe size setting for " H5FD_SUBFILING_STRIPE_SIZE); + HSYS_GOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, + "invalid stripe size setting for " H5FD_SUBFILING_STRIPE_SIZE); - if (stripe_size > 0) { + if (stripe_size > 0) subfiling_config->stripe_size = (int64_t)stripe_size; - } } } #if H5_CHECK_MPI_VERSION(3, 0) if (MPI_SUCCESS != (mpi_code = MPI_Comm_rank(comm, &mpi_rank))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Comm_rank failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Comm_rank failed", mpi_code); /* Create an MPI sub-communicator for intra-node communications */ if (MPI_SUCCESS != (mpi_code = MPI_Comm_split_type(comm, MPI_COMM_TYPE_SHARED, mpi_rank, MPI_INFO_NULL, &node_comm))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Comm_split_type failed", mpi_code); - + HMPI_GOTO_ERROR(FAIL, "MPI_Comm_split_type failed", mpi_code); if (MPI_SUCCESS != (mpi_code = MPI_Comm_set_errhandler(node_comm, MPI_ERRORS_RETURN))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Comm_set_errhandler failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Comm_set_errhandler failed", mpi_code); #else #error "MPI-3 required for MPI_Comm_split_type" #endif + /* Use the file's index to create a new subfiling context ID */ + if ((context_id = H5FD__subfiling_new_object_id(SF_CONTEXT)) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "couldn't create new subfiling context ID"); + /* - * Setup the application topology information, including the computed + * Initialize the application topology information, including the computed * number and distribution map of the set of I/O concentrators */ - if (init_app_topology(context_id, subfiling_config, comm, node_comm, &app_topology) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "couldn't initialize application topology"); - - new_context->sf_context_id = context_id; + if (H5FD__subfiling_init_app_topology(context_id, subfiling_config, comm, node_comm, &app_topology) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "couldn't initialize application topology"); - if (init_subfiling_context(new_context, base_filename, file_id, subfiling_config, app_topology, comm) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, - "couldn't initialize subfiling application topology object"); - new_context->sf_node_comm = node_comm; + /* Initialize the subfiling context */ + if (H5FD__subfiling_init_context(context_id, prefix_env, base_filename, file_id, subfiling_config, + app_topology, comm, node_comm, &context) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "couldn't initialize subfiling context"); + assert(context); + node_comm = MPI_COMM_NULL; /* New context takes ownership of node_comm */ *context_id_out = context_id; done: - if (config_file && (EOF == fclose(config_file))) - H5_SUBFILING_DONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, - "couldn't close subfiling configuration file"); + if (config_file && EOF == fclose(config_file)) + HDONE_ERROR(H5E_VFL, H5E_CANTCLOSEFILE, FAIL, "couldn't close subfiling configuration file"); H5MM_free(file_basename); H5MM_free(subfile_dir); if (ret_value < 0) { - if (app_topology) { - if (H5_free_subfiling_topology(app_topology) < 0) - H5_SUBFILING_DONE_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "couldn't free subfiling topology"); - } + if (app_topology) + if (H5FD__subfiling_free_topology(app_topology) < 0) + HDONE_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "couldn't free subfiling topology"); if (H5_mpi_comm_free(&node_comm) < 0) - H5_SUBFILING_DONE_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "couldn't free MPI communicator"); + HDONE_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "couldn't free MPI communicator"); - if (context_id >= 0 && H5_free_subfiling_object(context_id) < 0) - H5_SUBFILING_DONE_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "couldn't free subfiling object"); + if (context_id >= 0 && context) + if (H5FD__subfiling_free_object(context_id) < 0) + HDONE_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "couldn't free subfiling object"); *context_id_out = -1; } - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /*------------------------------------------------------------------------- - * Function: init_app_topology + * Function: H5FD__subfiling_init_app_topology * * Purpose: Determine the topology of the application so that MPI ranks * can be assigned as I/O concentrators. The default is to use @@ -992,8 +899,8 @@ init_subfiling(const char *base_filename, uint64_t file_id, H5FD_subfiling_param *------------------------------------------------------------------------- */ static herr_t -init_app_topology(int64_t sf_context_id, H5FD_subfiling_params_t *subfiling_config, MPI_Comm comm, - MPI_Comm node_comm, sf_topology_t **app_topology_out) +H5FD__subfiling_init_app_topology(int64_t sf_context_id, H5FD_subfiling_params_t *subfiling_config, + MPI_Comm comm, MPI_Comm node_comm, sf_topology_t **app_topology_out) { H5FD_subfiling_ioc_select_t ioc_selection_type; sf_topology_t *app_topology = NULL; @@ -1009,6 +916,8 @@ init_app_topology(int64_t sf_context_id, H5FD_subfiling_params_t *subfiling_conf int mpi_code; herr_t ret_value = SUCCEED; + FUNC_ENTER_PACKAGE + assert(subfiling_config); assert(MPI_COMM_NULL != comm); assert(MPI_COMM_NULL != node_comm); @@ -1016,16 +925,15 @@ init_app_topology(int64_t sf_context_id, H5FD_subfiling_params_t *subfiling_conf assert(!*app_topology_out); if (MPI_SUCCESS != (mpi_code = MPI_Comm_rank(comm, &comm_rank))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Comm_rank failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Comm_rank failed", mpi_code); if (MPI_SUCCESS != (mpi_code = MPI_Comm_size(comm, &comm_size))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Comm_size failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Comm_size failed", mpi_code); ioc_selection_type = subfiling_config->ioc_selection; /* Check if an IOC selection type was specified by environment variable */ - if (get_ioc_selection_criteria_from_env(&ioc_selection_type, &ioc_sel_str) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, - "couldn't get IOC selection type from environment"); + if (H5FD__subfiling_get_ioc_selection_criteria_from_env(&ioc_selection_type, &ioc_sel_str) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "couldn't get IOC selection type from environment"); /* * Check parameters for the specified IOC selection strategy @@ -1039,10 +947,8 @@ init_app_topology(int64_t sf_context_id, H5FD_subfiling_params_t *subfiling_conf if (env_value && (strlen(env_value) > 0)) { errno = 0; ioc_select_val = strtol(env_value, NULL, 0); - if ((ERANGE == errno)) { - printf("invalid value '%s' for " H5FD_SUBFILING_IOC_PER_NODE "\n", env_value); + if (ERANGE == errno) ioc_select_val = 1; - } if (ioc_select_val > 0) iocs_per_node = ioc_select_val; @@ -1066,11 +972,7 @@ init_app_topology(int64_t sf_context_id, H5FD_subfiling_params_t *subfiling_conf if (ioc_sel_str) { errno = 0; ioc_select_val = strtol(ioc_sel_str, NULL, 0); - if ((ERANGE == errno) || (ioc_select_val <= 0)) { - printf("invalid IOC selection strategy string '%s' for strategy " - "SELECT_IOC_EVERY_NTH_RANK; defaulting to SELECT_IOC_ONE_PER_NODE\n", - ioc_sel_str); - + if (ERANGE == errno || ioc_select_val <= 0) { ioc_select_val = 1; ioc_selection_type = SELECT_IOC_ONE_PER_NODE; @@ -1102,11 +1004,7 @@ init_app_topology(int64_t sf_context_id, H5FD_subfiling_params_t *subfiling_conf if (ioc_sel_str) { errno = 0; ioc_select_val = strtol(ioc_sel_str, NULL, 0); - if ((ERANGE == errno) || (ioc_select_val <= 0)) { - printf("invalid IOC selection strategy string '%s' for strategy SELECT_IOC_TOTAL; " - "defaulting to SELECT_IOC_ONE_PER_NODE\n", - ioc_sel_str); - + if (ERANGE == errno || ioc_select_val <= 0) { ioc_select_val = 1; ioc_selection_type = SELECT_IOC_ONE_PER_NODE; @@ -1134,7 +1032,7 @@ init_app_topology(int64_t sf_context_id, H5FD_subfiling_params_t *subfiling_conf case SELECT_IOC_WITH_CONFIG: case ioc_selection_options: default: - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "invalid IOC selection strategy"); + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "invalid IOC selection strategy"); break; } @@ -1146,19 +1044,18 @@ init_app_topology(int64_t sf_context_id, H5FD_subfiling_params_t *subfiling_conf * eventually. */ /* Check the subfiling topology cache to see if there's a matching object */ - if (find_cached_topology_info(comm, subfiling_config, iocs_per_node, &app_topology) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, - "can't check for cached subfiling topology object"); + if (H5FD__subfiling_find_cached_topology_info(comm, subfiling_config, iocs_per_node, &app_topology) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't check for cached subfiling topology object"); assert(!app_topology || (app_topology->selection_type == ioc_selection_type)); - if (!app_topology) { + if (NULL == app_topology) { /* Generate an ID for the application topology object */ - if ((topology_id = H5_new_subfiling_object_id(SF_TOPOLOGY)) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get ID for subfiling topology object"); + if ((topology_id = H5FD__subfiling_new_object_id(SF_TOPOLOGY)) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get ID for subfiling topology object"); /* Get a new application topology object from the cache */ - if (NULL == (app_topology = H5_get_subfiling_object(topology_id))) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get subfiling topology object"); + if (NULL == (app_topology = H5FD__subfiling_get_object(topology_id))) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get subfiling topology object"); app_topology->app_layout = NULL; app_topology->app_comm = MPI_COMM_NULL; app_topology->rank_is_ioc = false; @@ -1168,10 +1065,10 @@ init_app_topology(int64_t sf_context_id, H5FD_subfiling_params_t *subfiling_conf app_topology->selection_type = ioc_selection_type; if (H5_mpi_comm_dup(comm, &app_topology->app_comm) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTCOPY, FAIL, "can't duplicate MPI communicator"); + HGOTO_ERROR(H5E_VFL, H5E_CANTCOPY, FAIL, "can't duplicate MPI communicator"); - if (init_app_layout(app_topology, comm, node_comm) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "couldn't initialize application layout"); + if (H5FD__subfiling_init_app_layout(app_topology, comm, node_comm) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "couldn't initialize application layout"); assert(app_topology->app_layout); assert(app_topology->app_layout->layout); assert(app_topology->app_layout->node_ranks); @@ -1188,31 +1085,28 @@ init_app_topology(int64_t sf_context_id, H5FD_subfiling_params_t *subfiling_conf * Make sure the number of I/O concentrators doesn't * exceed the specified number of subfiles */ - if (subfiling_config->stripe_count != H5FD_SUBFILING_DEFAULT_STRIPE_COUNT) { + if (subfiling_config->stripe_count != H5FD_SUBFILING_DEFAULT_STRIPE_COUNT) if (app_topology->n_io_concentrators > subfiling_config->stripe_count) app_topology->n_io_concentrators = subfiling_config->stripe_count; - } /* * Determine which ranks are I/O concentrator ranks, based on the * given IOC selection strategy and MPI information. */ - if (identify_ioc_ranks(sf_context_id, app_topology, rank_multiple) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, - "couldn't determine which MPI ranks are I/O concentrators"); + if (H5FD__subfiling_identify_ioc_ranks(sf_context_id, app_topology, rank_multiple) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, + "couldn't determine which MPI ranks are I/O concentrators"); } *app_topology_out = app_topology; done: - if (ret_value < 0) { - if (app_topology && (topology_id >= 0)) { - if (H5_free_subfiling_object(topology_id) < 0) - H5_SUBFILING_DONE_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "can't free subfiling topology object"); - } - } + if (ret_value < 0) + if (app_topology && (topology_id >= 0)) + if (H5FD__subfiling_free_object(topology_id) < 0) + HDONE_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "can't free subfiling topology object"); - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /* @@ -1230,32 +1124,34 @@ init_app_topology(int64_t sf_context_id, H5FD_subfiling_params_t *subfiling_conf ------------------------------------------------------------------------- */ static herr_t -get_ioc_selection_criteria_from_env(H5FD_subfiling_ioc_select_t *ioc_selection_type, char **ioc_sel_info_str) +H5FD__subfiling_get_ioc_selection_criteria_from_env(H5FD_subfiling_ioc_select_t *ioc_selection_type, + char **ioc_sel_info_str) { char *opt_value = NULL; - char *env_value = getenv(H5FD_SUBFILING_IOC_SELECTION_CRITERIA); + char *env_value; herr_t ret_value = SUCCEED; + FUNC_ENTER_PACKAGE + assert(ioc_selection_type); assert(ioc_sel_info_str); *ioc_sel_info_str = NULL; + env_value = getenv(H5FD_SUBFILING_IOC_SELECTION_CRITERIA); if (env_value && (strlen(env_value) > 0)) { /* - * Parse I/O Concentrator selection strategy criteria as - * either a single value or two colon-separated values of - * the form 'integer:[integer|string]'. If two values are - * given, the first value specifies the I/O Concentrator - * selection strategy to use (given as the integer value - * corresponding to the H5FD_subfiling_ioc_select_t enum - * value for that strategy) and the second value specifies - * the criteria for that strategy. + * Parse I/O Concentrator selection strategy criteria as either a single + * value or two colon-separated values of the form + * 'integer:[integer|string]'. If two values are given, the first value + * specifies the I/O Concentrator selection strategy to use (given as the + * integer value corresponding to the H5FD_subfiling_ioc_select_t enum + * value for that strategy) and the second value specifies the criteria + * for that strategy. * - * For example, to assign every 64th MPI rank as an I/O - * Concentrator, the criteria string should have the format - * '1:64' to specify the "every Nth rank" strategy with a - * criteria of '64'. + * For example, to assign every 64th MPI rank as an I/O Concentrator, the + * criteria string should have the format '1:64' to specify the "every + * Nth rank" strategy with a criteria of '64'. */ opt_value = strchr(env_value, ':'); if (opt_value) { @@ -1265,36 +1161,32 @@ get_ioc_selection_criteria_from_env(H5FD_subfiling_ioc_select_t *ioc_selection_t errno = 0; check_value = strtol(env_value, NULL, 0); - if (errno == ERANGE) - H5_SUBFILING_SYS_GOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, - "couldn't parse value from " H5FD_SUBFILING_IOC_SELECTION_CRITERIA - " environment variable"); - - if ((check_value < 0) || (check_value >= ioc_selection_options)) - H5_SUBFILING_GOTO_ERROR( - H5E_VFL, H5E_BADVALUE, FAIL, - "invalid IOC selection type value %ld from " H5FD_SUBFILING_IOC_SELECTION_CRITERIA - " environment variable", - check_value); + HSYS_GOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, + "couldn't parse value from " H5FD_SUBFILING_IOC_SELECTION_CRITERIA + " environment variable"); + if (check_value < 0 || check_value >= ioc_selection_options) + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, + "invalid IOC selection type value %ld from " H5FD_SUBFILING_IOC_SELECTION_CRITERIA + " environment variable", + check_value); *ioc_selection_type = (H5FD_subfiling_ioc_select_t)check_value; *ioc_sel_info_str = opt_value; } - else { + else *ioc_sel_info_str = env_value; - } } done: - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /*------------------------------------------------------------------------- - * Function: find_cached_topology_info + * Function: H5FD__subfiling_find_cached_topology_info * * Purpose: Given an MPI communicator and IOC selection strategy, - * checks the subfiling topology cached to see if any matching + * checks the subfiling topology cache to see if any matching * topology objects have been cached. * * Return: Non-negative on success/Negative on failure @@ -1302,13 +1194,15 @@ get_ioc_selection_criteria_from_env(H5FD_subfiling_ioc_select_t *ioc_selection_t *------------------------------------------------------------------------- */ static herr_t -find_cached_topology_info(MPI_Comm comm, H5FD_subfiling_params_t *subf_config, long iocs_per_node, - sf_topology_t **app_topology) +H5FD__subfiling_find_cached_topology_info(MPI_Comm comm, H5FD_subfiling_params_t *subf_config, + long iocs_per_node, sf_topology_t **app_topology) { H5FD_subfiling_ioc_select_t ioc_selection_type; int32_t stripe_count; herr_t ret_value = SUCCEED; + FUNC_ENTER_PACKAGE + assert(subf_config); ioc_selection_type = subf_config->ioc_selection; @@ -1333,10 +1227,9 @@ find_cached_topology_info(MPI_Comm comm, H5FD_subfiling_params_t *subf_config, l * is greater than the specified target number of subfiles, * reject the cached topology */ - if (stripe_count != H5FD_SUBFILING_DEFAULT_STRIPE_COUNT) { + if (stripe_count != H5FD_SUBFILING_DEFAULT_STRIPE_COUNT) if (stripe_count < cached_topology->n_io_concentrators) continue; - } if (cached_topology->selection_type == SELECT_IOC_ONE_PER_NODE) { assert(iocs_per_node >= 1); @@ -1353,7 +1246,7 @@ find_cached_topology_info(MPI_Comm comm, H5FD_subfiling_params_t *subf_config, l } if (MPI_SUCCESS != (mpi_code = MPI_Comm_compare(comm, cached_topology->app_comm, &result))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Comm_compare failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Comm_compare failed", mpi_code); if (MPI_IDENT == result || MPI_CONGRUENT == result) { *app_topology = cached_topology; @@ -1362,11 +1255,11 @@ find_cached_topology_info(MPI_Comm comm, H5FD_subfiling_params_t *subf_config, l } done: - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /*------------------------------------------------------------------------- - * Function: init_app_layout + * Function: H5FD__subfiling_init_app_layout * * Purpose: Determines the layout of MPI ranks across nodes in order to * figure out the final application topology @@ -1376,40 +1269,42 @@ find_cached_topology_info(MPI_Comm comm, H5FD_subfiling_params_t *subf_config, l *------------------------------------------------------------------------- */ static herr_t -init_app_layout(sf_topology_t *app_topology, MPI_Comm comm, MPI_Comm node_comm) +H5FD__subfiling_init_app_layout(sf_topology_t *app_topology, MPI_Comm comm, MPI_Comm node_comm) { app_layout_t *app_layout = NULL; int mpi_code; herr_t ret_value = SUCCEED; + FUNC_ENTER_PACKAGE + assert(app_topology); assert(!app_topology->app_layout); assert(MPI_COMM_NULL != comm); assert(MPI_COMM_NULL != node_comm); - if (NULL == (app_layout = calloc(1, sizeof(*app_layout)))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, - "couldn't allocate application layout structure"); + if (NULL == (app_layout = H5MM_calloc(sizeof(*app_layout)))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "couldn't allocate application layout structure"); if (MPI_SUCCESS != (mpi_code = MPI_Comm_rank(comm, &app_layout->world_rank))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Comm_rank failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Comm_rank failed", mpi_code); if (MPI_SUCCESS != (mpi_code = MPI_Comm_size(comm, &app_layout->world_size))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Comm_size failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Comm_size failed", mpi_code); if (MPI_SUCCESS != (mpi_code = MPI_Comm_rank(node_comm, &app_layout->node_local_rank))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Comm_rank failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Comm_rank failed", mpi_code); if (MPI_SUCCESS != (mpi_code = MPI_Comm_size(node_comm, &app_layout->node_local_size))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Comm_size failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Comm_size failed", mpi_code); - if (NULL == (app_layout->layout = malloc((size_t)app_layout->world_size * sizeof(*app_layout->layout)))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, - "couldn't allocate application layout array"); + if (NULL == + (app_layout->layout = H5MM_malloc((size_t)app_layout->world_size * sizeof(*app_layout->layout)))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "couldn't allocate application layout array"); /* Gather the list of layout_t pairs to all ranks */ - if (gather_topology_info(app_layout, comm, node_comm) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "can't gather application topology info"); + if (H5FD__subfiling_gather_topology_info(app_layout, comm, node_comm) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "can't gather application topology info"); /* Sort the list according to the node local lead rank values */ - qsort(app_layout->layout, (size_t)app_layout->world_size, sizeof(layout_t), compare_layout_nodelocal); + qsort(app_layout->layout, (size_t)app_layout->world_size, sizeof(layout_t), + H5FD__subfiling_compare_layout_nodelocal); /* * Count the number of nodes by checking how many @@ -1421,40 +1316,32 @@ init_app_layout(sf_topology_t *app_topology, MPI_Comm comm, MPI_Comm node_comm) app_layout->node_count++; if (app_layout->node_count <= 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "node count less than or equal to zero"); + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "node count less than or equal to zero"); - if (NULL == - (app_layout->node_ranks = malloc((size_t)app_layout->node_count * sizeof(*app_layout->node_ranks)))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, - "couldn't allocate application layout node rank array"); + if (NULL == (app_layout->node_ranks = + H5MM_malloc((size_t)app_layout->node_count * sizeof(*app_layout->node_ranks)))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "couldn't allocate application layout node rank array"); - /* - * Record the rank value of the "lead" - * MPI rank on each node for later use - */ - for (size_t i = 0, node_rank_index = 0; i < (size_t)app_layout->world_size; i++) { - if (app_layout->layout[i].node_local_rank == 0) { - assert(node_rank_index < (size_t)app_layout->node_count); + /* Record the rank value of the "lead" MPI rank on each node for later use */ + for (size_t i = 0, node_rank_index = 0; i < (size_t)app_layout->world_size; i++) + if (app_layout->layout[i].node_local_rank == 0) app_layout->node_ranks[node_rank_index++] = app_layout->layout[i].rank; - } - } app_topology->app_layout = app_layout; done: - if (ret_value < 0) { + if (ret_value < 0) if (app_layout) { - free(app_layout->layout); - free(app_layout->node_ranks); - free(app_layout); + H5MM_free(app_layout->layout); + H5MM_free(app_layout->node_ranks); + H5MM_free(app_layout); } - } - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /*------------------------------------------------------------------------- - * Function: gather_topology_info + * Function: H5FD__subfiling_gather_topology_info * * Purpose: Collectively generate a list of layout_t structures * @@ -1463,7 +1350,7 @@ init_app_layout(sf_topology_t *app_topology, MPI_Comm comm, MPI_Comm node_comm) *------------------------------------------------------------------------- */ static herr_t -gather_topology_info(app_layout_t *app_layout, MPI_Comm comm, MPI_Comm intra_comm) +H5FD__subfiling_gather_topology_info(app_layout_t *app_layout, MPI_Comm comm, MPI_Comm intra_comm) { MPI_Group file_group = MPI_GROUP_NULL; MPI_Group node_group = MPI_GROUP_NULL; @@ -1476,9 +1363,13 @@ gather_topology_info(app_layout_t *app_layout, MPI_Comm comm, MPI_Comm intra_com int sf_world_rank; int node_local_rank; int node_local_size; + const int local_lead = 0; + int lead_rank; int mpi_code; herr_t ret_value = SUCCEED; + FUNC_ENTER_PACKAGE + assert(app_layout); assert(app_layout->layout); assert(MPI_COMM_NULL != comm); @@ -1493,32 +1384,25 @@ gather_topology_info(app_layout_t *app_layout, MPI_Comm comm, MPI_Comm intra_com my_layout_info.node_local_size = node_local_size; /* - * Get the rank value for the "lead" rank on this - * rank's node so that we can group the layout_t - * information for all node-local ranks together + * Get the rank value for the "lead" rank on this rank's node so that we can + * group the layout_t information for all node-local ranks together */ - { - const int local_lead = 0; - int lead_rank; - - if (MPI_SUCCESS != (mpi_code = MPI_Comm_group(comm, &file_group))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Comm_group failed", mpi_code); - if (MPI_SUCCESS != (mpi_code = MPI_Comm_group(intra_comm, &node_group))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Comm_group failed", mpi_code); - if (MPI_SUCCESS != - (mpi_code = MPI_Group_translate_ranks(node_group, 1, &local_lead, file_group, &lead_rank))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Group_translate_ranks failed", mpi_code); + if (MPI_SUCCESS != (mpi_code = MPI_Comm_group(comm, &file_group))) + HMPI_GOTO_ERROR(FAIL, "MPI_Comm_group failed", mpi_code); + if (MPI_SUCCESS != (mpi_code = MPI_Comm_group(intra_comm, &node_group))) + HMPI_GOTO_ERROR(FAIL, "MPI_Comm_group failed", mpi_code); + if (MPI_SUCCESS != + (mpi_code = MPI_Group_translate_ranks(node_group, 1, &local_lead, file_group, &lead_rank))) + HMPI_GOTO_ERROR(FAIL, "MPI_Group_translate_ranks failed", mpi_code); + if (MPI_UNDEFINED == lead_rank) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't determine lead rank on node"); - if (MPI_UNDEFINED == lead_rank) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't determine lead rank on node"); + my_layout_info.node_lead_rank = lead_rank; - my_layout_info.node_lead_rank = lead_rank; - - if (MPI_SUCCESS != (mpi_code = MPI_Group_free(&node_group))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Group_free failed", mpi_code); - if (MPI_SUCCESS != (mpi_code = MPI_Group_free(&file_group))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Group_free failed", mpi_code); - } + if (MPI_SUCCESS != (mpi_code = MPI_Group_free(&node_group))) + HMPI_GOTO_ERROR(FAIL, "MPI_Group_free failed", mpi_code); + if (MPI_SUCCESS != (mpi_code = MPI_Group_free(&file_group))) + HMPI_GOTO_ERROR(FAIL, "MPI_Group_free failed", mpi_code); app_layout->layout[sf_world_rank] = my_layout_info; @@ -1528,47 +1412,42 @@ gather_topology_info(app_layout_t *app_layout, MPI_Comm comm, MPI_Comm intra_com if (MPI_SUCCESS != (mpi_code = MPI_Allgather(&my_layout_info, 4, MPI_INT, app_layout->layout, 4, MPI_INT, comm))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Allgather failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Allgather failed", mpi_code); #else - int aggr_comm_size = 0; - assert(MPI_COMM_NULL != intra_comm); /* Split the file communicator into a sub-group of one rank per node */ if (MPI_SUCCESS != (mpi_code = MPI_Comm_split(comm, node_local_rank, sf_world_rank, &aggr_comm))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Comm_split failed", mpi_code); - - if (MPI_SUCCESS != (mpi_code = MPI_Comm_size(aggr_comm, &aggr_comm_size))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Comm_size failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Comm_split failed", mpi_code); /* Allocate a partial layout info array to aggregate into from node-local ranks */ - if (node_local_rank == 0) { + if (node_local_rank == 0) if (NULL == - (layout_info_partial = malloc((size_t)node_local_size * sizeof(*layout_info_partial)))) + (layout_info_partial = H5MM_malloc((size_t)node_local_size * sizeof(*layout_info_partial)))) /* Push error, but participate in gather operation */ - H5_SUBFILING_DONE_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, - "can't allocate layout info array"); - } + HDONE_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "can't allocate layout info array"); - /* Gather node-local layout info to single master rank on each node */ + /* Gather node-local layout info to single leader rank on each node */ if (MPI_SUCCESS != (mpi_code = MPI_Gather(&my_layout_info, 4, MPI_INT, layout_info_partial, 4, MPI_INT, 0, intra_comm))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Gather failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Gather failed", mpi_code); - /* Gather total layout info from/to each master rank on each node */ + /* Gather total layout info from/to each leader rank on each node */ if (node_local_rank == 0) { - int send_size = 4 * node_local_size; + int aggr_comm_size = 0; + int send_size = 4 * node_local_size; + + if (MPI_SUCCESS != (mpi_code = MPI_Comm_size(aggr_comm, &aggr_comm_size))) + HMPI_DONE_ERROR(FAIL, "MPI_Comm_size failed", mpi_code); - if (NULL == (recv_counts = malloc((size_t)aggr_comm_size * sizeof(*recv_counts)))) - H5_SUBFILING_DONE_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, - "can't allocate receive counts array"); - if (NULL == (recv_displs = malloc((size_t)aggr_comm_size * sizeof(*recv_displs)))) - H5_SUBFILING_DONE_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, - "can't allocate receive displacements array"); + if (NULL == (recv_counts = H5MM_malloc((size_t)aggr_comm_size * sizeof(*recv_counts)))) + HDONE_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "can't allocate receive counts array"); + if (NULL == (recv_displs = H5MM_malloc((size_t)aggr_comm_size * sizeof(*recv_displs)))) + HDONE_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "can't allocate receive displacements array"); if (MPI_SUCCESS != (mpi_code = MPI_Allgather(&send_size, 1, MPI_INT, recv_counts, 1, MPI_INT, aggr_comm))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Allgather failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Allgather failed", mpi_code); recv_displs[0] = 0; for (int i = 1; i < aggr_comm_size; i++) @@ -1577,44 +1456,39 @@ gather_topology_info(app_layout_t *app_layout, MPI_Comm comm, MPI_Comm intra_com if (MPI_SUCCESS != (mpi_code = MPI_Allgatherv(layout_info_partial, send_size, MPI_INT, app_layout->layout, recv_counts, recv_displs, MPI_INT, aggr_comm))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Allgatherv failed", mpi_code); - - free(recv_displs); - free(recv_counts); - recv_displs = NULL; - recv_counts = NULL; + HMPI_GOTO_ERROR(FAIL, "MPI_Allgatherv failed", mpi_code); } /* - * Each master rank on each node distributes the total + * Each leader rank on each node distributes the total * layout info back to other node-local ranks */ if (MPI_SUCCESS != (mpi_code = MPI_Bcast(app_layout->layout, 4 * sf_world_size, MPI_INT, 0, intra_comm))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Bcast failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Bcast failed", mpi_code); #endif } done: - free(recv_displs); - free(recv_counts); - free(layout_info_partial); + H5MM_free(recv_displs); + H5MM_free(recv_counts); + H5MM_free(layout_info_partial); if (H5_mpi_comm_free(&aggr_comm) < 0) - H5_SUBFILING_DONE_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "can't free MPI communicator"); + HDONE_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "can't free MPI communicator"); if (node_group != MPI_GROUP_NULL) if (MPI_SUCCESS != (mpi_code = MPI_Group_free(&node_group))) - H5_SUBFILING_MPI_DONE_ERROR(FAIL, "MPI_Group_free failed", mpi_code); + HMPI_DONE_ERROR(FAIL, "MPI_Group_free failed", mpi_code); if (file_group != MPI_GROUP_NULL) if (MPI_SUCCESS != (mpi_code = MPI_Group_free(&file_group))) - H5_SUBFILING_MPI_DONE_ERROR(FAIL, "MPI_Group_free failed", mpi_code); + HMPI_DONE_ERROR(FAIL, "MPI_Group_free failed", mpi_code); - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /*------------------------------------------------------------------------- - * Function: compare_layout_nodelocal + * Function: H5FD__subfiling_compare_layout_nodelocal * * Purpose: Qsort sorting callback that sorts layout_t structures * according to their node local lead MPI rank values. Ties @@ -1624,30 +1498,28 @@ gather_topology_info(app_layout_t *app_layout, MPI_Comm comm, MPI_Comm intra_com *------------------------------------------------------------------------- */ static int -compare_layout_nodelocal(const void *layout1, const void *layout2) +H5FD__subfiling_compare_layout_nodelocal(const void *layout1, const void *layout2) { const layout_t *l1 = (const layout_t *)layout1; const layout_t *l2 = (const layout_t *)layout2; - if (l1->node_lead_rank == l2->node_lead_rank) { + if (l1->node_lead_rank == l2->node_lead_rank) return (l1->node_local_rank > l2->node_local_rank) - (l1->node_local_rank < l2->node_local_rank); - } else return (l1->node_lead_rank > l2->node_lead_rank) - (l1->node_lead_rank < l2->node_lead_rank); } /*------------------------------------------------------------------------- - * Function: identify_ioc_ranks - * - * Purpose: We've already identified the number of unique nodes and - * have a sorted list of layout_t structures. Under normal - * conditions, we only utilize a single IOC per node. Under - * that circumstance, we only need to fill the - * io_concentrators vector from the node_ranks array (which - * contains the index into the layout array of lowest MPI rank - * on each node) into the io_concentrators vector; Otherwise, - * while determining the number of local ranks per node, we - * can also select one or more additional IOCs. + * Function: H5FD__subfiling_identify_ioc_ranks + * + * Purpose: We've already identified the number of unique nodes and have a + * sorted list of layout_t structures. Under normal conditions, we + * only utilize a single IOC per node. Under that circumstance, we + * only need to fill the io_concentrators vector from the node_ranks + * array (which contains the index into the layout array of lowest + * MPI rank on each node) into the io_concentrators vector; Otherwise, + * while determining the number of local ranks per node, we can also + * select one or more additional IOCs. * * As a side effect, we fill the 'io_concentrators' vector * and set the 'rank_is_ioc' flag to true if our rank is @@ -1656,13 +1528,15 @@ compare_layout_nodelocal(const void *layout1, const void *layout2) *------------------------------------------------------------------------- */ static herr_t -identify_ioc_ranks(int64_t sf_context_id, sf_topology_t *app_topology, int rank_stride) +H5FD__subfiling_identify_ioc_ranks(int64_t sf_context_id, sf_topology_t *app_topology, int rank_stride) { app_layout_t *app_layout = NULL; int *io_concentrators = NULL; int max_iocs = 0; herr_t ret_value = SUCCEED; + FUNC_ENTER_PACKAGE + assert(app_topology); assert(!app_topology->io_concentrators); assert(app_topology->n_io_concentrators > 0); @@ -1678,11 +1552,9 @@ identify_ioc_ranks(int64_t sf_context_id, sf_topology_t *app_topology, int rank_ app_layout = app_topology->app_layout; max_iocs = app_topology->n_io_concentrators; - - if (NULL == - (app_topology->io_concentrators = malloc((size_t)max_iocs * sizeof(*app_topology->io_concentrators)))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, - "couldn't allocate array of I/O concentrator ranks"); + if (NULL == (app_topology->io_concentrators = + H5MM_malloc((size_t)max_iocs * sizeof(*app_topology->io_concentrators)))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "couldn't allocate array of I/O concentrator ranks"); io_concentrators = app_topology->io_concentrators; @@ -1759,9 +1631,9 @@ identify_ioc_ranks(int64_t sf_context_id, sf_topology_t *app_topology, int rank_ #ifdef H5_SUBFILING_DEBUG if (app_topology->n_io_concentrators != total_ioc_count) - H5_subfiling_log(sf_context_id, - "%s: **WARN** Number of I/O concentrators adjusted from %d to %d", __func__, - app_topology->n_io_concentrators, total_ioc_count); + H5FD__subfiling_log(sf_context_id, + "%s: **WARN** Number of I/O concentrators adjusted from %d to %d", + __func__, app_topology->n_io_concentrators, total_ioc_count); #endif /* Set final number of I/O concentrators after adjustments */ @@ -1802,21 +1674,20 @@ identify_ioc_ranks(int64_t sf_context_id, sf_topology_t *app_topology, int rank_ case SELECT_IOC_WITH_CONFIG: case ioc_selection_options: default: - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "invalid IOC selection strategy"); + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "invalid IOC selection strategy"); break; } done: - if (ret_value < 0) { + if (ret_value < 0) if (app_topology) - free(app_topology->io_concentrators); - } + H5MM_free(app_topology->io_concentrators); - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /*------------------------------------------------------------------------- - * Function: init_subfile_context + * Function: H5FD__subfiling_init_context * * Purpose: Called as part of the HDF5 file + subfiling opening. * This initializes the subfiling context and associates @@ -1827,81 +1698,64 @@ identify_ioc_ranks(int64_t sf_context_id, sf_topology_t *app_topology, int rank_ *------------------------------------------------------------------------- */ static herr_t -init_subfiling_context(subfiling_context_t *sf_context, const char *base_filename, uint64_t file_id, - H5FD_subfiling_params_t *subfiling_config, sf_topology_t *app_topology, - MPI_Comm file_comm) +H5FD__subfiling_init_context(int64_t context_id, const char *prefix_env, const char *base_filename, + uint64_t file_id, H5FD_subfiling_params_t *subfiling_config, + sf_topology_t *app_topology, MPI_Comm file_comm, MPI_Comm node_comm, + subfiling_context_t **context) { - char *env_value = NULL; - int mpi_rank; - int mpi_code; - herr_t ret_value = SUCCEED; + subfiling_context_t *sf_context = NULL; + char *env_value = NULL; + int mpi_code; + herr_t ret_value = SUCCEED; - assert(sf_context); - assert(sf_context->topology == NULL); - assert(sf_context->sf_context_id >= 0); - assert(base_filename); - assert(file_id != UINT64_MAX); - assert(subfiling_config); - assert(app_topology); - assert(app_topology->n_io_concentrators > 0); - assert(MPI_COMM_NULL != file_comm); + FUNC_ENTER_PACKAGE + + /* Create a new subfiling context object with the created context ID */ + if (NULL == (sf_context = H5FD__subfiling_get_object(context_id))) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "couldn't create new subfiling object"); + /* Set non-zero fields */ sf_context->h5_file_id = file_id; - sf_context->threads_inited = false; - sf_context->file_ref = 0; - sf_context->sf_fids = NULL; - sf_context->sf_num_fids = 0; + sf_context->sf_context_id = context_id; sf_context->sf_num_subfiles = subfiling_config->stripe_count; - sf_context->sf_write_count = 0; - sf_context->sf_read_count = 0; sf_context->sf_eof = HADDR_UNDEF; sf_context->sf_stripe_size = H5FD_SUBFILING_DEFAULT_STRIPE_SIZE; - sf_context->sf_base_addr = 0; sf_context->sf_msg_comm = MPI_COMM_NULL; sf_context->sf_data_comm = MPI_COMM_NULL; sf_context->sf_eof_comm = MPI_COMM_NULL; - sf_context->sf_node_comm = MPI_COMM_NULL; + sf_context->sf_node_comm = node_comm; sf_context->sf_group_comm = MPI_COMM_NULL; sf_context->sf_group_size = 1; - sf_context->sf_group_rank = 0; - sf_context->subfile_prefix = NULL; - sf_context->h5_filename = NULL; - sf_context->ioc_data = NULL; sf_context->topology = app_topology; -#ifdef H5_SUBFILING_DEBUG - sf_context->sf_logfile = NULL; -#endif + /* Check if a prefix has been set for the configuration file name */ + if (prefix_env && (strlen(prefix_env) > 0)) + if (NULL == (sf_context->config_file_prefix = strdup(prefix_env))) + HGOTO_ERROR(H5E_VFL, H5E_CANTCOPY, FAIL, "couldn't copy config file prefix string"); if (NULL == (sf_context->h5_filename = strdup(base_filename))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, - "couldn't allocate space for subfiling filename"); + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "couldn't allocate space for subfiling filename"); /* Check for a subfile name prefix setting in the environment */ env_value = getenv(H5FD_SUBFILING_SUBFILE_PREFIX); - if (env_value && (strlen(env_value) > 0)) { + if (env_value && (strlen(env_value) > 0)) if (NULL == (sf_context->subfile_prefix = strdup(env_value))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "couldn't copy subfile prefix value"); - } + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "couldn't copy subfile prefix value"); - /* - * Set IOC stripe size from subfiling configuration - */ + /* Set IOC stripe size from subfiling configuration */ if (subfiling_config->stripe_size > 0) sf_context->sf_stripe_size = subfiling_config->stripe_size; /* - * If still set to the default, set the number of subfiles - * according to the default mapping of 1 I/O concentrator - * -> 1 subfile + * If still set to the default, set the number of subfiles according to the + * default mapping of 1 I/O concentrator -> 1 subfile */ if (sf_context->sf_num_subfiles == H5FD_SUBFILING_DEFAULT_STRIPE_COUNT) sf_context->sf_num_subfiles = app_topology->n_io_concentrators; /* - * Set blocksize per stripe value after possibly adjusting - * for user-specified subfile stripe size and number of - * subfiles + * Set blocksize per stripe value after possibly adjusting for user-specified + * subfile stripe size and number of subfiles */ sf_context->sf_blocksize_per_stripe = sf_context->sf_stripe_size * sf_context->sf_num_subfiles; @@ -1912,9 +1766,8 @@ init_subfiling_context(subfiling_context_t *sf_context, const char *base_filenam sf_context->sf_base_addr = (int64_t)(app_topology->ioc_idx * sf_context->sf_stripe_size); /* - * Calculate the number of subfiles this rank owns by - * round-robining them across the available IOCs and - * then allocate an array for the subfile IDs + * Calculate the number of subfiles this rank owns by round-robining them + * across the available IOCs and then allocate an array for the subfile IDs */ sf_context->sf_num_fids = sf_context->sf_num_subfiles / app_topology->n_io_concentrators; @@ -1922,70 +1775,70 @@ init_subfiling_context(subfiling_context_t *sf_context, const char *base_filenam if (leftover_subfiles && (leftover_subfiles > app_topology->ioc_idx)) sf_context->sf_num_fids++; - if (NULL == - (sf_context->sf_fids = malloc((size_t)sf_context->sf_num_fids * sizeof(*sf_context->sf_fids)))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "couldn't allocate subfile IDs array"); + if (NULL == (sf_context->sf_fids = + H5MM_malloc((size_t)sf_context->sf_num_fids * sizeof(*sf_context->sf_fids)))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "couldn't allocate subfile IDs array"); for (int i = 0; i < sf_context->sf_num_fids; i++) sf_context->sf_fids[i] = -1; } - /* - * Set up various MPI sub-communicators for MPI operations - * to/from IOC ranks - */ - - if (MPI_SUCCESS != (mpi_code = MPI_Comm_rank(file_comm, &mpi_rank))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Comm_rank failed", mpi_code); + /* Set up various MPI sub-communicators for MPI operations to/from IOC ranks */ if (MPI_SUCCESS != (mpi_code = MPI_Comm_dup(file_comm, &sf_context->sf_msg_comm))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Comm_dup failed", mpi_code); - + HMPI_GOTO_ERROR(FAIL, "MPI_Comm_dup failed", mpi_code); if (MPI_SUCCESS != (mpi_code = MPI_Comm_set_errhandler(sf_context->sf_msg_comm, MPI_ERRORS_RETURN))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Comm_set_errhandler failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Comm_set_errhandler failed", mpi_code); if (MPI_SUCCESS != (mpi_code = MPI_Comm_dup(file_comm, &sf_context->sf_data_comm))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Comm_dup failed", mpi_code); - + HMPI_GOTO_ERROR(FAIL, "MPI_Comm_dup failed", mpi_code); if (MPI_SUCCESS != (mpi_code = MPI_Comm_set_errhandler(sf_context->sf_data_comm, MPI_ERRORS_RETURN))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Comm_set_errhandler failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Comm_set_errhandler failed", mpi_code); if (MPI_SUCCESS != (mpi_code = MPI_Comm_dup(file_comm, &sf_context->sf_eof_comm))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Comm_dup failed", mpi_code); - + HMPI_GOTO_ERROR(FAIL, "MPI_Comm_dup failed", mpi_code); if (MPI_SUCCESS != (mpi_code = MPI_Comm_set_errhandler(sf_context->sf_eof_comm, MPI_ERRORS_RETURN))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Comm_set_errhandler failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Comm_set_errhandler failed", mpi_code); /* Create an MPI sub-communicator for IOC ranks */ if (app_topology->n_io_concentrators > 1) { + int mpi_rank; + + if (MPI_SUCCESS != (mpi_code = MPI_Comm_rank(file_comm, &mpi_rank))) + HMPI_GOTO_ERROR(FAIL, "MPI_Comm_rank failed", mpi_code); if (MPI_SUCCESS != (mpi_code = MPI_Comm_split(file_comm, app_topology->rank_is_ioc, mpi_rank, &sf_context->sf_group_comm))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Comm_split failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Comm_split failed", mpi_code); if (MPI_SUCCESS != (mpi_code = MPI_Comm_rank(sf_context->sf_group_comm, &sf_context->sf_group_rank))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Comm_rank failed", mpi_code); - + HMPI_GOTO_ERROR(FAIL, "MPI_Comm_rank failed", mpi_code); if (MPI_SUCCESS != (mpi_code = MPI_Comm_size(sf_context->sf_group_comm, &sf_context->sf_group_size))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Comm_size failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Comm_size failed", mpi_code); } /* Perform some final validation of subfiling configuration */ if (sf_context->sf_stripe_size <= 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "invalid subfiling stripe size (%" PRId64 ")", - sf_context->sf_stripe_size); - + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "invalid subfiling stripe size (%" PRId64 ")", + sf_context->sf_stripe_size); if (sf_context->sf_num_subfiles <= 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "invalid subfiling stripe count (%d)", - sf_context->sf_num_subfiles); - + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "invalid subfiling stripe count (%d)", + sf_context->sf_num_subfiles); assert(sf_context->sf_num_subfiles >= app_topology->n_io_concentrators); + *context = sf_context; + done: - H5_SUBFILING_FUNC_LEAVE; + if (ret_value < 0) { + if (context_id >= 0 && H5FD__subfiling_free_object(context_id) < 0) + HDONE_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "couldn't free subfiling object"); + *context = NULL; + } + + FUNC_LEAVE_NOAPI(ret_value) } /*------------------------------------------------------------------------- - * Function: init_open_file_map + * Function: H5FD__subfiling_init_open_file_map * * Purpose: Allocates and initializes an array that keeps a mapping * between a file's inode value (__ino_t st_ino) and the ID @@ -1996,13 +1849,16 @@ init_subfiling_context(subfiling_context_t *sf_context, const char *base_filenam *------------------------------------------------------------------------- */ static herr_t -init_open_file_map(void) +H5FD__subfiling_init_open_file_map(void) { herr_t ret_value = SUCCEED; + FUNC_ENTER_PACKAGE + if (!sf_open_file_map) { - if (NULL == (sf_open_file_map = malloc((size_t)DEFAULT_FILE_MAP_ENTRIES * sizeof(*sf_open_file_map)))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "couldn't allocate open file mapping"); + if (NULL == + (sf_open_file_map = H5MM_malloc((size_t)DEFAULT_FILE_MAP_ENTRIES * sizeof(*sf_open_file_map)))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "couldn't allocate open file mapping"); sf_file_map_size = DEFAULT_FILE_MAP_ENTRIES; for (int i = 0; i < sf_file_map_size; i++) { @@ -2012,24 +1868,23 @@ init_open_file_map(void) } done: - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /*------------------------------------------------------------------------- - * Function: record_fid_map_entry + * Function: H5FD__subfiling_record_fid_map_entry * - * Purpose: Every opened HDF5 file will have (if utilizing subfiling) - * a subfiling context associated with it. It is important that - * the HDF5 file index is a constant rather than utilizing a - * posix file handle since files can be opened multiple times - * and with each file open, a new file handle will be assigned. - * Note that in such a case, the actual filesystem id will be - * retained. + * Purpose: Every opened HDF5 file that uses subfiling will have a subfiling + * context associated with it. It is important that the HDF5 file + * index is a constant rather than utilizing a POSIX file handle + * since files can be opened multiple times and with each file open, + * a new file handle will be assigned. Note that in such a case, the + * actual filesystem id will be retained. * - * We utilize that filesystem id (ino_t inode) so that - * irrespective of what process opens a common file, the - * subfiling system will generate a consistent context for this - * file across all parallel ranks. + * We use the filesystem id (ino_t inode) so that irrespective of + * what process opens a common file, the subfiling system will + * generate a consistent context for this file across all parallel + * ranks. * * This function simply records the filesystem handle to * subfiling context mapping. @@ -2039,19 +1894,21 @@ init_open_file_map(void) *------------------------------------------------------------------------- */ static herr_t -record_fid_map_entry(uint64_t file_id, int64_t subfile_context_id, int *next_index) +H5FD__subfiling_record_fid_map_entry(uint64_t file_id, int64_t subfile_context_id, int *next_index) { subfiling_context_t *sf_context = NULL; int index; herr_t ret_value = SUCCEED; + FUNC_ENTER_PACKAGE + for (index = 0; index < sf_file_map_size; index++) { if (sf_open_file_map[index].file_id == file_id) { /* Increment file ref. count for this context */ - if (NULL == (sf_context = H5_get_subfiling_object(sf_open_file_map[index].sf_context_id))) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "couldn't get subfiling context"); + if (NULL == (sf_context = H5FD__subfiling_get_object(sf_open_file_map[index].sf_context_id))) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "couldn't get subfiling context"); sf_context->file_ref++; - goto done; + HGOTO_DONE(SUCCEED); } if (sf_open_file_map[index].file_id == UINT64_MAX) { @@ -2059,52 +1916,48 @@ record_fid_map_entry(uint64_t file_id, int64_t subfile_context_id, int *next_ind sf_open_file_map[index].sf_context_id = subfile_context_id; /* First open of this file - set file ref. count to 1 for this context */ - if (NULL == (sf_context = H5_get_subfiling_object(subfile_context_id))) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "couldn't get subfiling context"); + if (NULL == (sf_context = H5FD__subfiling_get_object(subfile_context_id))) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "couldn't get subfiling context"); sf_context->file_ref = 1; - if (next_index) { + if (next_index) *next_index = index; - } - goto done; + HGOTO_DONE(SUCCEED); } } if (index == sf_file_map_size) { void *tmp_realloc; - if (NULL == (tmp_realloc = realloc(sf_open_file_map, - ((size_t)(sf_file_map_size * 2) * sizeof(*sf_open_file_map))))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, - "couldn't reallocate open file mapping"); + if (NULL == (tmp_realloc = H5MM_realloc( + sf_open_file_map, ((size_t)(sf_file_map_size * 2) * sizeof(*sf_open_file_map))))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "couldn't reallocate open file mapping"); sf_open_file_map = tmp_realloc; sf_file_map_size *= 2; - for (int i = index; i < sf_file_map_size; i++) { + for (int i = index; i < sf_file_map_size; i++) sf_open_file_map[i].file_id = UINT64_MAX; - } - if (next_index) { + if (next_index) *next_index = index; - } sf_open_file_map[index].file_id = file_id; sf_open_file_map[index].sf_context_id = subfile_context_id; /* First open of this file - set file ref. count to 1 for this context */ - if (NULL == (sf_context = H5_get_subfiling_object(subfile_context_id))) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "couldn't get subfiling context"); + if (NULL == (sf_context = H5FD__subfiling_get_object(subfile_context_id))) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "couldn't get subfiling context"); sf_context->file_ref = 1; } done: - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /*------------------------------------------------------------------------- - * Function: clear_fid_map_entry + * Function: H5FD__subfiling_clear_fid_map_entry * * Purpose: Remove the map entry associated with the file->inode. * This is done at file close. @@ -2114,39 +1967,66 @@ record_fid_map_entry(uint64_t file_id, int64_t subfile_context_id, int *next_ind *------------------------------------------------------------------------- */ static herr_t -clear_fid_map_entry(uint64_t file_id, int64_t sf_context_id) +H5FD__subfiling_clear_fid_map_entry(uint64_t file_id, int64_t sf_context_id) { herr_t ret_value = SUCCEED; + FUNC_ENTER_PACKAGE + if (!sf_open_file_map) - H5_SUBFILING_GOTO_DONE(SUCCEED); + HGOTO_DONE(SUCCEED); for (int i = 0; i < sf_file_map_size; i++) { - subfiling_context_t *sf_context = NULL; + if (sf_open_file_map[i].file_id == file_id && sf_open_file_map[i].sf_context_id == sf_context_id) { + subfiling_context_t *sf_context; - if ((sf_open_file_map[i].file_id != file_id) || (sf_open_file_map[i].sf_context_id != sf_context_id)) - continue; + /* Only clear map entry if this is the last file + * holding a reference to the context + */ + if (NULL == (sf_context = H5FD__subfiling_get_object(sf_context_id))) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "couldn't get subfiling context object"); - /* Only clear map entry if this is the last file - * holding a reference to the context - */ - if (NULL == (sf_context = H5_get_subfiling_object(sf_context_id))) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "couldn't get subfiling context object"); + if (sf_context->file_ref == 0 || sf_context->file_ref == 1) { + sf_open_file_map[i].file_id = UINT64_MAX; + sf_open_file_map[i].sf_context_id = -1; + } - if (sf_context->file_ref == 0 || sf_context->file_ref == 1) { - sf_open_file_map[i].file_id = UINT64_MAX; - sf_open_file_map[i].sf_context_id = -1; + break; } - - break; } done: - return ret_value; -} /* end clear_fid_map_entry() */ + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5FD__subfiling_clear_fid_map_entry() */ /*------------------------------------------------------------------------- - * Function: ioc_open_files + * Function: H5FD__subfiling_get_default_ioc_config + * + * Purpose: This simply fills in + * the basics. This avoids the necessity of having the + * user write code to initialize the config structure. + * + * Return: SUCCEED/FAIL + *------------------------------------------------------------------------- + */ +herr_t +H5FD__subfiling_get_default_ioc_config(H5FD_ioc_config_t *config) +{ + FUNC_ENTER_PACKAGE_NOERR + + assert(config); + + memset(config, 0, sizeof(*config)); + + config->magic = H5FD_IOC_FAPL_MAGIC; + config->version = H5FD_IOC_CURR_FAPL_VERSION; + config->thread_pool_size = H5FD_IOC_DEFAULT_THREAD_POOL_SIZE; + + FUNC_LEAVE_NOAPI(SUCCEED) +} + +/*------------------------------------------------------------------------- + * Function: H5FD__subfiling_ioc_open_files * * Purpose: This function is called by an I/O concentrator in order to * open the subfiles it is responsible for. @@ -2179,7 +2059,7 @@ clear_fid_map_entry(uint64_t file_id, int64_t sf_context_id) *------------------------------------------------------------------------- */ static herr_t -ioc_open_files(int64_t file_context_id, int file_acc_flags) +H5FD__subfiling_ioc_open_files(int64_t file_context_id, int file_acc_flags) { subfiling_context_t *sf_context = NULL; mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; @@ -2190,9 +2070,10 @@ ioc_open_files(int64_t file_context_id, int file_acc_flags) int num_digits = 0; herr_t ret_value = SUCCEED; - if (NULL == (sf_context = H5_get_subfiling_object(file_context_id))) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTOPENFILE, FAIL, - "couldn't get subfiling object from context ID"); + FUNC_ENTER_PACKAGE + + if (NULL == (sf_context = H5FD__subfiling_get_object(file_context_id))) + HGOTO_ERROR(H5E_VFL, H5E_CANTOPENFILE, FAIL, "couldn't get subfiling object from context ID"); assert(sf_context->h5_file_id != UINT64_MAX); assert(sf_context->h5_filename); @@ -2204,7 +2085,7 @@ ioc_open_files(int64_t file_context_id, int file_acc_flags) /* Get the basename of the full HDF5 filename */ if (H5_basename(sf_context->h5_filename, &base) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't get HDF5 file basename"); + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "can't get HDF5 file basename"); /* * Get the directory prefix where subfiles will be placed. @@ -2214,16 +2095,13 @@ ioc_open_files(int64_t file_context_id, int file_acc_flags) */ if (sf_context->subfile_prefix) { if (NULL == (subfile_dir = H5MM_strdup(sf_context->subfile_prefix))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "couldn't copy subfile prefix"); - } - else { - if (H5_dirname(sf_context->h5_filename, &subfile_dir) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "couldn't get HDF5 file dirname"); + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "couldn't copy subfile prefix"); } + else if (H5_dirname(sf_context->h5_filename, &subfile_dir) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "couldn't get HDF5 file dirname"); - if (NULL == (filepath = malloc(PATH_MAX))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, - "couldn't allocate space for subfile filename"); + if (NULL == (filepath = H5MM_malloc(PATH_MAX))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "couldn't allocate space for subfile filename"); num_subfiles = sf_context->sf_num_subfiles; num_digits = (int)(log10(num_subfiles) + 1); @@ -2253,7 +2131,7 @@ ioc_open_files(int64_t file_context_id, int file_acc_flags) sf_context->h5_file_id, num_digits, subfile_idx, num_subfiles); if ((sf_context->sf_fids[i] = HDopen(filepath, file_acc_flags, mode)) < 0) - H5_SUBFILING_SYS_GOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "failed to open subfile"); + HSYS_GOTO_ERROR(H5E_VFL, H5E_CANTOPENFILE, FAIL, "failed to open subfile"); } if (file_acc_flags & O_CREAT) @@ -2276,31 +2154,29 @@ ioc_open_files(int64_t file_context_id, int file_acc_flags) else config_dir = subfile_dir; - if (create_config_file(sf_context, base, config_dir, subfile_dir, (file_acc_flags & O_TRUNC)) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_FILE, H5E_CANTCREATE, FAIL, - "couldn't create subfiling configuration file"); + if (H5FD__subfiling_create_config_file(sf_context, base, config_dir, subfile_dir, + (file_acc_flags & O_TRUNC)) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTCREATE, FAIL, "couldn't create subfiling configuration file"); } done: - if (ret_value < 0) { - if (sf_context) { + if (ret_value < 0) + if (sf_context) for (int i = 0; i < sf_context->sf_num_fids; i++) { if (sf_context->sf_fids[i] >= 0 && HDclose(sf_context->sf_fids[i]) < 0) - H5_SUBFILING_DONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "failed to close subfile"); + HDONE_ERROR(H5E_VFL, H5E_CANTCLOSEFILE, FAIL, "failed to close subfile"); sf_context->sf_fids[i] = -1; } - } - } H5MM_free(base); H5MM_free(subfile_dir); - free(filepath); + H5MM_free(filepath); - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /*------------------------------------------------------------------------- - * Function: create_config_file + * Function: H5FD__subfiling_create_config_file * * Purpose: Creates a configuration file that contains * subfiling-related information for a file. This file @@ -2317,8 +2193,8 @@ ioc_open_files(int64_t file_context_id, int file_acc_flags) *------------------------------------------------------------------------- */ static herr_t -create_config_file(subfiling_context_t *sf_context, const char *base_filename, const char *config_dir, - const char *subfile_dir, bool truncate_if_exists) +H5FD__subfiling_create_config_file(subfiling_context_t *sf_context, const char *base_filename, + const char *config_dir, const char *subfile_dir, bool truncate_if_exists) { bool config_file_exists = false; FILE *config_file = NULL; @@ -2327,25 +2203,25 @@ create_config_file(subfiling_context_t *sf_context, const char *base_filename, c int ret = 0; herr_t ret_value = SUCCEED; + FUNC_ENTER_PACKAGE + assert(sf_context); assert(base_filename); assert(config_dir); assert(subfile_dir); if (sf_context->h5_file_id == UINT64_MAX) - H5_SUBFILING_GOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "invalid HDF5 file ID %" PRIu64, - sf_context->h5_file_id); + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "invalid HDF5 file ID %" PRIu64, sf_context->h5_file_id); if (*base_filename == '\0') - H5_SUBFILING_GOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "invalid base HDF5 filename '%s'", - base_filename); + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "invalid base HDF5 filename '%s'", base_filename); if (*config_dir == '\0') config_dir = "."; if (*subfile_dir == '\0') subfile_dir = "."; - if (NULL == (config_filename = malloc(PATH_MAX))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, - "couldn't allocate space for subfiling configuration filename"); + if (NULL == (config_filename = H5MM_malloc(PATH_MAX))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, + "couldn't allocate space for subfiling configuration filename"); snprintf(config_filename, PATH_MAX, "%s/" H5FD_SUBFILING_CONFIG_FILENAME_TEMPLATE, config_dir, base_filename, sf_context->h5_file_id); @@ -2356,57 +2232,51 @@ create_config_file(subfiling_context_t *sf_context, const char *base_filename, c config_file_exists = (ret == 0) || ((ret < 0) && (ENOENT != errno)); - if (config_file_exists && (ret != 0)) - H5_SUBFILING_SYS_GOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, - "couldn't check existence of subfiling configuration file"); + if (config_file_exists && ret != 0) + HSYS_GOTO_ERROR(H5E_VFL, H5E_CANTOPENFILE, FAIL, + "couldn't check existence of subfiling configuration file"); /* - * If a config file doesn't exist, create one. If a - * config file does exist, don't touch it unless the - * O_TRUNC flag was specified. In this case, truncate - * the existing config file and create a new one. + * If a config file doesn't exist, create one. If a config file does exist, + * don't touch it unless the O_TRUNC flag was specified. In this case, + * truncate the existing config file and create a new one. */ if (!config_file_exists || truncate_if_exists) { int n_subfiles = sf_context->sf_num_subfiles; int num_digits; if (NULL == (config_file = fopen(config_filename, "w+"))) - H5_SUBFILING_SYS_GOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, - "couldn't create/truncate subfiling configuration file"); + HSYS_GOTO_ERROR(H5E_VFL, H5E_CANTOPENFILE, FAIL, + "couldn't create/truncate subfiling configuration file"); - if (NULL == (line_buf = malloc(PATH_MAX))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, - "couldn't allocate buffer for writing to subfiling configuration file"); + if (NULL == (line_buf = H5MM_malloc(PATH_MAX))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, + "couldn't allocate buffer for writing to subfiling configuration file"); /* Write the subfiling stripe size to the configuration file */ snprintf(line_buf, PATH_MAX, "stripe_size=%" PRId64 "\n", sf_context->sf_stripe_size); if (fwrite(line_buf, strlen(line_buf), 1, config_file) != 1) - H5_SUBFILING_SYS_GOTO_ERROR(H5E_FILE, H5E_WRITEERROR, FAIL, - "failed to write to subfiling configuration file"); + HSYS_GOTO_ERROR(H5E_VFL, H5E_WRITEERROR, FAIL, "failed to write to subfiling configuration file"); /* Write the number of I/O concentrators to the configuration file */ snprintf(line_buf, PATH_MAX, "aggregator_count=%d\n", sf_context->topology->n_io_concentrators); if (fwrite(line_buf, strlen(line_buf), 1, config_file) != 1) - H5_SUBFILING_SYS_GOTO_ERROR(H5E_FILE, H5E_WRITEERROR, FAIL, - "failed to write to subfiling configuration file"); + HSYS_GOTO_ERROR(H5E_VFL, H5E_WRITEERROR, FAIL, "failed to write to subfiling configuration file"); /* Write the number of subfiles to the configuration file */ snprintf(line_buf, PATH_MAX, "subfile_count=%d\n", n_subfiles); if (fwrite(line_buf, strlen(line_buf), 1, config_file) != 1) - H5_SUBFILING_SYS_GOTO_ERROR(H5E_FILE, H5E_WRITEERROR, FAIL, - "failed to write to subfiling configuration file"); + HSYS_GOTO_ERROR(H5E_VFL, H5E_WRITEERROR, FAIL, "failed to write to subfiling configuration file"); /* Write the base HDF5 filename to the configuration file */ snprintf(line_buf, PATH_MAX, "hdf5_file=%s\n", sf_context->h5_filename); if (fwrite(line_buf, strlen(line_buf), 1, config_file) != 1) - H5_SUBFILING_SYS_GOTO_ERROR(H5E_FILE, H5E_WRITEERROR, FAIL, - "failed to write to subfiling configuration file"); + HSYS_GOTO_ERROR(H5E_VFL, H5E_WRITEERROR, FAIL, "failed to write to subfiling configuration file"); /* Write the optional subfile directory prefix to the configuration file */ snprintf(line_buf, PATH_MAX, "subfile_dir=%s\n", subfile_dir); if (fwrite(line_buf, strlen(line_buf), 1, config_file) != 1) - H5_SUBFILING_SYS_GOTO_ERROR(H5E_FILE, H5E_WRITEERROR, FAIL, - "failed to write to subfiling configuration file"); + HSYS_GOTO_ERROR(H5E_VFL, H5E_WRITEERROR, FAIL, "failed to write to subfiling configuration file"); /* Write out each subfile name to the configuration file */ num_digits = (int)(log10(n_subfiles) + 1); @@ -2415,41 +2285,38 @@ create_config_file(subfiling_context_t *sf_context, const char *base_filename, c sf_context->h5_file_id, num_digits, k + 1, n_subfiles); if (fwrite(line_buf, strlen(line_buf), 1, config_file) != 1) - H5_SUBFILING_SYS_GOTO_ERROR(H5E_FILE, H5E_WRITEERROR, FAIL, - "failed to write to subfiling configuration file"); + HSYS_GOTO_ERROR(H5E_VFL, H5E_WRITEERROR, FAIL, + "failed to write to subfiling configuration file"); } } done: - if (config_file) { + if (config_file) if (EOF == fclose(config_file)) - H5_SUBFILING_DONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, - "couldn't close subfiling configuration file"); - } + HDONE_ERROR(H5E_VFL, H5E_CANTCLOSEFILE, FAIL, "couldn't close subfiling configuration file"); - free(line_buf); - free(config_filename); + H5MM_free(line_buf); + H5MM_free(config_filename); - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /*------------------------------------------------------------------------- - * Function: open_config_file + * Function: H5FD__subfiling_open_config_file * * Purpose: Opens the subfiling configuration file for a given HDF5 * file and sets `config_file_out`, if a configuration file * exists. Otherwise, `config_file_out` is set to NULL. * - * It is the caller's responsibility to check - * `config_file_out` on success and close an opened file as - * necessary. + * It is the caller's responsibility to check `config_file_out` + * on success and close an opened file as necessary. * * Return: Non-negative on success/Negative on failure *------------------------------------------------------------------------- */ static herr_t -open_config_file(const char *base_filename, const char *config_dir, uint64_t file_id, const char *mode, - FILE **config_file_out) +H5FD__subfiling_open_config_file(const char *base_filename, const char *config_dir, uint64_t file_id, + const char *mode, FILE **config_file_out) { bool config_file_exists = false; FILE *config_file = NULL; @@ -2457,6 +2324,8 @@ open_config_file(const char *base_filename, const char *config_dir, uint64_t fil int ret = 0; herr_t ret_value = SUCCEED; + FUNC_ENTER_PACKAGE + assert(base_filename); assert(config_dir); assert(file_id != UINT64_MAX); @@ -2466,14 +2335,13 @@ open_config_file(const char *base_filename, const char *config_dir, uint64_t fil *config_file_out = NULL; if (*base_filename == '\0') - H5_SUBFILING_GOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "invalid base HDF5 filename '%s'", - base_filename); + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "invalid base HDF5 filename '%s'", base_filename); if (*config_dir == '\0') config_dir = "."; - if (NULL == (config_filename = malloc(PATH_MAX))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, - "couldn't allocate space for subfiling configuration filename"); + if (NULL == (config_filename = H5MM_malloc(PATH_MAX))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, + "couldn't allocate space for subfiling configuration filename"); snprintf(config_filename, PATH_MAX, "%s/" H5FD_SUBFILING_CONFIG_FILENAME_TEMPLATE, config_dir, base_filename, file_id); @@ -2485,32 +2353,29 @@ open_config_file(const char *base_filename, const char *config_dir, uint64_t fil config_file_exists = (ret == 0) || ((ret < 0) && (ENOENT != errno)); if (!config_file_exists) - goto done; + HGOTO_DONE(SUCCEED); - if (config_file_exists && (ret != 0)) - H5_SUBFILING_SYS_GOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, - "couldn't check existence of subfiling configuration file"); + if (config_file_exists && ret != 0) + HSYS_GOTO_ERROR(H5E_VFL, H5E_CANTOPENFILE, FAIL, + "couldn't check existence of subfiling configuration file"); if (NULL == (config_file = fopen(config_filename, mode))) - H5_SUBFILING_SYS_GOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, - "couldn't open subfiling configuration file"); + HSYS_GOTO_ERROR(H5E_VFL, H5E_CANTOPENFILE, FAIL, "couldn't open subfiling configuration file"); *config_file_out = config_file; done: - if (ret_value < 0) { + if (ret_value < 0) if (config_file && (EOF == fclose(config_file))) - H5_SUBFILING_DONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, - "couldn't close subfiling configuration file"); - } + HDONE_ERROR(H5E_VFL, H5E_CANTCLOSEFILE, FAIL, "couldn't close subfiling configuration file"); - free(config_filename); + H5MM_free(config_filename); - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /*------------------------------------------------------------------------- - * Function: H5_get_subfiling_config_from_file + * Function: H5FD__subfiling_get_config_from_file * * Purpose: Reads a Subfiling configuration file to get the stripe size * and number of subfiles used for the logical HDF5 file. @@ -2520,7 +2385,7 @@ open_config_file(const char *base_filename, const char *config_dir, uint64_t fil *------------------------------------------------------------------------- */ herr_t -H5_get_subfiling_config_from_file(FILE *config_file, int64_t *stripe_size, int64_t *num_subfiles) +H5FD__subfiling_get_config_from_file(FILE *config_file, int64_t *stripe_size, int64_t *num_subfiles) { int64_t read_stripe_size = 0; int64_t read_num_subfiles = 0; @@ -2529,73 +2394,71 @@ H5_get_subfiling_config_from_file(FILE *config_file, int64_t *stripe_size, int64 long config_file_len = 0; herr_t ret_value = SUCCEED; + FUNC_ENTER_PACKAGE + assert(config_file); if (HDfseek(config_file, 0, SEEK_END) < 0) - H5_SUBFILING_SYS_GOTO_ERROR(H5E_FILE, H5E_SEEKERROR, FAIL, - "couldn't seek to end of subfiling configuration file"); + HSYS_GOTO_ERROR(H5E_VFL, H5E_SEEKERROR, FAIL, "couldn't seek to end of subfiling configuration file"); if ((config_file_len = HDftell(config_file)) < 0) - H5_SUBFILING_SYS_GOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, - "couldn't get size of subfiling configuration file"); + HSYS_GOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "couldn't get size of subfiling configuration file"); if (HDfseek(config_file, 0, SEEK_SET) < 0) - H5_SUBFILING_SYS_GOTO_ERROR(H5E_FILE, H5E_SEEKERROR, FAIL, - "couldn't seek to beginning of subfiling configuration file"); + HSYS_GOTO_ERROR(H5E_VFL, H5E_SEEKERROR, FAIL, + "couldn't seek to beginning of subfiling configuration file"); - if (NULL == (config_buf = malloc((size_t)config_file_len + 1))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, - "couldn't allocate space for reading from subfiling configuration file"); + if (NULL == (config_buf = H5MM_malloc((size_t)config_file_len + 1))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, + "couldn't allocate space for reading from subfiling configuration file"); if (fread(config_buf, (size_t)config_file_len, 1, config_file) != 1) - H5_SUBFILING_SYS_GOTO_ERROR(H5E_FILE, H5E_READERROR, FAIL, - "couldn't read from subfiling configuration file"); + HSYS_GOTO_ERROR(H5E_VFL, H5E_READERROR, FAIL, "couldn't read from subfiling configuration file"); config_buf[config_file_len] = '\0'; if (stripe_size) { if (NULL == (substr = strstr(config_buf, "stripe_size"))) - H5_SUBFILING_GOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, - "malformed subfiling configuration file - no stripe size entry"); + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, + "malformed subfiling configuration file - no stripe size entry"); if (EOF == sscanf(substr, "stripe_size=%" PRId64, &read_stripe_size)) - H5_SUBFILING_SYS_GOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, - "couldn't get stripe size from subfiling configuration file"); + HSYS_GOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, + "couldn't get stripe size from subfiling configuration file"); if (read_stripe_size <= 0) - H5_SUBFILING_GOTO_ERROR( - H5E_FILE, H5E_BADVALUE, FAIL, - "invalid stripe size (%" PRId64 ") read from subfiling configuration file", read_stripe_size); + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, + "invalid stripe size (%" PRId64 ") read from subfiling configuration file", + read_stripe_size); *stripe_size = read_stripe_size; } if (num_subfiles) { if (NULL == (substr = strstr(config_buf, "subfile_count"))) - H5_SUBFILING_GOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, - "malformed subfiling configuration file - no subfile count entry"); + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, + "malformed subfiling configuration file - no subfile count entry"); if (EOF == sscanf(substr, "subfile_count=%" PRId64, &read_num_subfiles)) - H5_SUBFILING_SYS_GOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, - "couldn't get number of subfiles from subfiling configuration file"); + HSYS_GOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, + "couldn't get number of subfiles from subfiling configuration file"); if (read_num_subfiles <= 0) - H5_SUBFILING_GOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, - "invalid number of subfiles (%" PRId64 - ") read from subfiling configuration file", - read_num_subfiles); + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, + "invalid number of subfiles (%" PRId64 ") read from subfiling configuration file", + read_num_subfiles); *num_subfiles = read_num_subfiles; } done: - free(config_buf); + H5MM_free(config_buf); - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /*------------------------------------------------------------------------- - * Function: H5_resolve_pathname + * Function: H5FD__subfiling_resolve_pathname * * Purpose: Simple wrapper routine around realpath(3) to fully resolve * a given filepath. Collective across the specified MPI @@ -2610,7 +2473,7 @@ H5_get_subfiling_config_from_file(FILE *config_file, int64_t *stripe_size, int64 *------------------------------------------------------------------------- */ herr_t -H5_resolve_pathname(const char *filepath, MPI_Comm comm, char **resolved_filepath) +H5FD__subfiling_resolve_pathname(const char *filepath, MPI_Comm comm, char **resolved_filepath) { hsize_t path_len = HSIZE_UNDEF; bool bcasted_path_len = false; @@ -2624,121 +2487,104 @@ H5_resolve_pathname(const char *filepath, MPI_Comm comm, char **resolved_filepat int mpi_code; herr_t ret_value = SUCCEED; + FUNC_ENTER_PACKAGE + assert(filepath); assert(resolved_filepath); if (MPI_SUCCESS != (mpi_code = MPI_Comm_rank(comm, &mpi_rank))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Comm_rank failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Comm_rank failed", mpi_code); if (MPI_SUCCESS != (mpi_code = MPI_Comm_size(comm, &mpi_size))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Comm_size failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Comm_size failed", mpi_code); if (mpi_rank == 0) { + errno = 0; if (NULL == (resolved_path = HDrealpath(filepath, NULL))) { if (ENOENT == errno) { if (H5_dirname(filepath, &file_dirname) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't get file dirname"); + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "can't get file dirname"); /* If filepath is just the filename, set up path using CWD */ if (!strcmp(file_dirname, ".")) { - if (NULL == (resolved_path = malloc(PATH_MAX))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, - "can't allocate buffer for filepath"); + if (NULL == (resolved_path = H5MM_malloc(PATH_MAX))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "can't allocate buffer for filepath"); if (H5_basename(filepath, &file_basename) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't get file basename"); - if (NULL == (cwd = malloc(PATH_MAX))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, - "can't allocate buffer for CWD"); + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "can't get file basename"); + if (NULL == (cwd = H5MM_malloc(PATH_MAX))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "can't allocate buffer for CWD"); if (NULL == HDgetcwd(cwd, PATH_MAX)) - H5_SUBFILING_GOTO_ERROR( - H5E_VFL, H5E_CANTGET, FAIL, - "can't get current working directory, errno = %d, error message = '%s'", errno, - strerror(errno)); + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, + "can't get current working directory, errno = %d, error message = '%s'", + errno, strerror(errno)); snprintf(resolved_path, PATH_MAX, "%s/%s", cwd, file_basename); } - else { + else /* Otherwise, just use what was given as the pathname */ if (NULL == (resolved_path = strdup(filepath))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't copy filename"); - } + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "can't copy filename"); } else - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, - "can't resolve subfile path, errno = %d, error message = '%s'", errno, - strerror(errno)); + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, + "can't resolve subfile path, errno = %d, error message = '%s'", errno, + strerror(errno)); } - if (resolved_path) { + if (resolved_path) H5_CHECKED_ASSIGN(path_len, hsize_t, (strlen(resolved_path) + 1), size_t); - } else path_len = HSIZE_UNDEF; } /* Broadcast the size of the resolved filepath string to other ranks */ bcasted_path_len = true; - if (mpi_size > 1) { + if (mpi_size > 1) if (MPI_SUCCESS != (mpi_code = MPI_Bcast(&path_len, 1, HSIZE_AS_MPI_TYPE, 0, comm))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Bcast failed", mpi_code); - } + HMPI_GOTO_ERROR(FAIL, "MPI_Bcast failed", mpi_code); if (path_len == HSIZE_UNDEF) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "couldn't resolve filepath"); + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "couldn't resolve filepath"); - if (mpi_rank != 0) { - if (NULL == (resolved_path = malloc(path_len))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't allocate file name buffer"); - } + if (mpi_rank != 0) + if (NULL == (resolved_path = H5MM_malloc(path_len))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "can't allocate file name buffer"); /* Broadcast the resolved filepath to other ranks */ bcasted_path = true; if (mpi_size > 1) { H5_CHECK_OVERFLOW(path_len, hsize_t, int); if (MPI_SUCCESS != (mpi_code = MPI_Bcast(resolved_path, (int)path_len, MPI_CHAR, 0, comm))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Bcast failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Bcast failed", mpi_code); } *resolved_filepath = resolved_path; done: - free(cwd); + H5MM_free(cwd); H5MM_free(file_basename); H5MM_free(file_dirname); if (ret_value < 0) { - if (!bcasted_path_len) { + if (!bcasted_path_len) if (MPI_SUCCESS != (mpi_code = MPI_Bcast(&path_len, 1, HSIZE_AS_MPI_TYPE, 0, comm))) - H5_SUBFILING_MPI_DONE_ERROR(FAIL, "MPI_Bcast failed", mpi_code); - } + HMPI_DONE_ERROR(FAIL, "MPI_Bcast failed", mpi_code); if (!bcasted_path && (path_len != HSIZE_UNDEF)) { H5_CHECK_OVERFLOW(path_len, hsize_t, int); if (MPI_SUCCESS != (mpi_code = MPI_Bcast(resolved_path, (int)path_len, MPI_CHAR, 0, comm))) - H5_SUBFILING_MPI_DONE_ERROR(FAIL, "MPI_Bcast failed", mpi_code); + HMPI_DONE_ERROR(FAIL, "MPI_Bcast failed", mpi_code); } - free(resolved_path); + H5MM_free(resolved_path); } - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /*------------------------------------------------------------------------- - * Function: H5_close_subfiles - * - * Purpose: This is a simple wrapper function for the internal version - * which actually manages all subfile closing via commands - * to the set of IO Concentrators. - * - * Return: Success (0) or Failure (non-zero) - * Errors: If MPI operations fail for some reason. - * - *------------------------------------------------------------------------- - */ -/*------------------------------------------------------------------------- - * Function: Internal close__subfiles + * Function: H5FD__subfiling_close_subfiles * - * Purpose: When closing and HDF5 file, we need to close any associated + * Purpose: When closing an HDF5 file, we need to close any associated * subfiles as well. This function cycles through all known * IO Concentrators to send a file CLOSE_OP command. * @@ -2757,7 +2603,7 @@ H5_resolve_pathname(const char *filepath, MPI_Comm comm, char **resolved_filepat *------------------------------------------------------------------------- */ herr_t -H5_close_subfiles(int64_t subfiling_context_id, MPI_Comm file_comm) +H5FD__subfiling_close_subfiles(int64_t subfiling_context_id, MPI_Comm file_comm) { subfiling_context_t *sf_context = NULL; MPI_Request barrier_req = MPI_REQUEST_NULL; @@ -2765,84 +2611,78 @@ H5_close_subfiles(int64_t subfiling_context_id, MPI_Comm file_comm) int mpi_code; herr_t ret_value = SUCCEED; - if (NULL == (sf_context = H5_get_subfiling_object(subfiling_context_id))) - H5_SUBFILING_GOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "couldn't get subfiling object from context ID"); + FUNC_ENTER_PACKAGE + + if (NULL == (sf_context = H5FD__subfiling_get_object(subfiling_context_id))) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "couldn't get subfiling object from context ID"); if (MPI_SUCCESS != (mpi_code = MPI_Comm_size(file_comm, &mpi_size))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Comm_size failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Comm_size failed", mpi_code); - /* We make the subfile close operation collective. - * Otherwise, there may be a race condition between - * our closing the subfiles and the user application + /* We make the subfile close operation collective. Otherwise, there may be a + * race condition between our closing the subfiles and the user application * moving ahead and possibly re-opening a file. * - * If we can, we utilize an async barrier which gives - * us the opportunity to reduce the CPU load due to - * MPI spinning while waiting for the barrier to - * complete. This is especially important if there - * is heavy thread utilization due to subfiling - * activities, i.e. the thread pool might be - * extremely busy servicing I/O requests from all - * HDF5 application ranks. + * If we can, we utilize an async barrier which gives us the opportunity to + * reduce the CPU load due to MPI spinning while waiting for the barrier to + * complete. This is especially important if there is heavy thread + * utilization due to subfiling activities, i.e. the thread pool might be + * busy servicing I/O requests from all HDF5 application ranks. */ if (mpi_size > 1) { #if H5_CHECK_MPI_VERSION(3, 1) int barrier_complete = 0; if (MPI_SUCCESS != (mpi_code = MPI_Ibarrier(file_comm, &barrier_req))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Ibarrier failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Ibarrier failed", mpi_code); while (!barrier_complete) { useconds_t t_delay = 5; usleep(t_delay); if (MPI_SUCCESS != (mpi_code = MPI_Test(&barrier_req, &barrier_complete, MPI_STATUS_IGNORE))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Test failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Test failed", mpi_code); } #else if (MPI_SUCCESS != (mpi_code = MPI_Barrier(file_comm))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Barrier failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Barrier failed", mpi_code); #endif } /* The map from file handle to subfiling context can now be cleared */ - if (sf_context->h5_file_id != UINT64_MAX) { - clear_fid_map_entry(sf_context->h5_file_id, sf_context->sf_context_id); - } + if (sf_context->h5_file_id != UINT64_MAX) + H5FD__subfiling_clear_fid_map_entry(sf_context->h5_file_id, sf_context->sf_context_id); - if (sf_context->topology->rank_is_ioc) { - if (sf_context->sf_fids) { + if (sf_context->topology->rank_is_ioc) + if (sf_context->sf_fids) for (int i = 0; i < sf_context->sf_num_fids; i++) { errno = 0; if (sf_context->sf_fids[i] >= 0 && HDclose(sf_context->sf_fids[i]) < 0) - H5_SUBFILING_SYS_GOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "couldn't close subfile"); + HSYS_GOTO_ERROR(H5E_VFL, H5E_CANTCLOSEFILE, FAIL, "couldn't close subfile"); sf_context->sf_fids[i] = -1; } - } - } /* - * Run another barrier to prevent some ranks from running ahead, - * and opening another file before this file is completely closed - * down. + * Run another barrier to prevent some ranks from running ahead, and opening + * another file before this file is completely closed down. */ if (mpi_size > 1) { #if H5_CHECK_MPI_VERSION(3, 1) int barrier_complete = 0; if (MPI_SUCCESS != (mpi_code = MPI_Ibarrier(file_comm, &barrier_req))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Ibarrier failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Ibarrier failed", mpi_code); while (!barrier_complete) { useconds_t t_delay = 5; usleep(t_delay); if (MPI_SUCCESS != (mpi_code = MPI_Test(&barrier_req, &barrier_complete, MPI_STATUS_IGNORE))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Test failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Test failed", mpi_code); } #else if (MPI_SUCCESS != (mpi_code = MPI_Barrier(file_comm))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Barrier failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Barrier failed", mpi_code); #endif } @@ -2854,7 +2694,7 @@ H5_close_subfiles(int64_t subfiling_context_id, MPI_Comm file_comm) cur_time = time(NULL); tm = localtime(&cur_time); - H5_subfiling_log(sf_context->sf_context_id, "\n-- LOGGING FINISH - %s", asctime(tm)); + H5FD__subfiling_log(sf_context->sf_context_id, "\n-- LOGGING FINISH - %s", asctime(tm)); fclose(sf_context->sf_logfile); sf_context->sf_logfile = NULL; @@ -2862,11 +2702,11 @@ H5_close_subfiles(int64_t subfiling_context_id, MPI_Comm file_comm) #endif done: - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /*------------------------------------------------------------------------- - * Function: H5_subfiling_set_config_prop + * Function: H5FD__subfiling_set_config_prop * * Purpose: Sets the specified Subfiling VFD configuration as a * property on the given FAPL pointer. The Subfiling VFD uses @@ -2879,50 +2719,43 @@ H5_close_subfiles(int64_t subfiling_context_id, MPI_Comm file_comm) *------------------------------------------------------------------------- */ herr_t -H5_subfiling_set_config_prop(H5P_genplist_t *plist_ptr, const H5FD_subfiling_params_t *vfd_config) +H5FD__subfiling_set_config_prop(H5P_genplist_t *plist, const H5FD_subfiling_params_t *vfd_config) { htri_t prop_exists = FAIL; herr_t ret_value = SUCCEED; - if (!plist_ptr) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL FAPL pointer"); + FUNC_ENTER_PACKAGE + + if (!plist) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL FAPL pointer"); if (!vfd_config) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid subfiling configuration pointer"); + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid subfiling configuration pointer"); - if ((prop_exists = H5P_exist_plist(plist_ptr, H5FD_SUBFILING_CONFIG_PROP)) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, - "can't check if subfiling configuration property exists in FAPL"); + if ((prop_exists = H5P_exist_plist(plist, H5FD_SUBFILING_CONFIG_PROP)) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, + "can't check if subfiling configuration property exists in FAPL"); if (prop_exists) { - if (H5P_set(plist_ptr, H5FD_SUBFILING_CONFIG_PROP, vfd_config) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, - "can't set subfiling configuration property on FAPL"); + if (H5P_set(plist, H5FD_SUBFILING_CONFIG_PROP, vfd_config) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTSET, FAIL, "can't set subfiling configuration property on FAPL"); } - else { - union { - const void *const_ptr_to_data; - void *ptr_to_data; - } eliminate_const_warning; - + else /* * Cast away const since H5P_insert doesn't match the signature * for "value" as H5P_set */ - eliminate_const_warning.const_ptr_to_data = vfd_config; - - if (H5P_insert(plist_ptr, H5FD_SUBFILING_CONFIG_PROP, sizeof(H5FD_subfiling_params_t), - eliminate_const_warning.ptr_to_data, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + if (H5P_insert(plist, H5FD_SUBFILING_CONFIG_PROP, sizeof(H5FD_subfiling_params_t), + H5FD__subfiling_cast_to_void(vfd_config), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, - "unable to register subfiling configuration property in FAPL"); - } + HGOTO_ERROR(H5E_VFL, H5E_CANTREGISTER, FAIL, + "unable to register subfiling configuration property in FAPL"); done: - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /*------------------------------------------------------------------------- - * Function: H5_subfiling_get_config_prop + * Function: H5FD__subfiling_get_config_prop * * Purpose: Retrieves the Subfiling VFD configuration from the given * FAPL pointer. The Subfiling VFD uses this property to pass @@ -2934,24 +2767,25 @@ H5_subfiling_set_config_prop(H5P_genplist_t *plist_ptr, const H5FD_subfiling_par *------------------------------------------------------------------------- */ herr_t -H5_subfiling_get_config_prop(H5P_genplist_t *plist_ptr, H5FD_subfiling_params_t *vfd_config) +H5FD__subfiling_get_config_prop(H5P_genplist_t *plist, H5FD_subfiling_params_t *vfd_config) { htri_t prop_exists = FAIL; herr_t ret_value = SUCCEED; - if (!plist_ptr) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL FAPL pointer"); + FUNC_ENTER_PACKAGE + + if (!plist) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL FAPL pointer"); if (!vfd_config) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid subfiling configuration pointer"); + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid subfiling configuration pointer"); - if ((prop_exists = H5P_exist_plist(plist_ptr, H5FD_SUBFILING_CONFIG_PROP)) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, - "can't check if subfiling configuration property exists in FAPL"); + if ((prop_exists = H5P_exist_plist(plist, H5FD_SUBFILING_CONFIG_PROP)) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, + "can't check if subfiling configuration property exists in FAPL"); if (prop_exists) { - if (H5P_get(plist_ptr, H5FD_SUBFILING_CONFIG_PROP, vfd_config) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, - "can't get subfiling configuration property from FAPL"); + if (H5P_get(plist, H5FD_SUBFILING_CONFIG_PROP, vfd_config) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get subfiling configuration property from FAPL"); } else { vfd_config->ioc_selection = SELECT_IOC_ONE_PER_NODE; @@ -2960,11 +2794,11 @@ H5_subfiling_get_config_prop(H5P_genplist_t *plist_ptr, H5FD_subfiling_params_t } done: - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /*------------------------------------------------------------------------- - * Function: H5_subfiling_set_file_id_prop + * Function: H5FD__subfiling_set_file_id_prop * * Purpose: Sets the specified file ID (Inode) value as a property on * the given FAPL pointer. The Subfiling VFD uses this @@ -2976,37 +2810,35 @@ H5_subfiling_get_config_prop(H5P_genplist_t *plist_ptr, H5FD_subfiling_params_t *------------------------------------------------------------------------- */ herr_t -H5_subfiling_set_file_id_prop(H5P_genplist_t *plist_ptr, uint64_t file_id) +H5FD__subfiling_set_file_id_prop(H5P_genplist_t *plist, uint64_t file_id) { htri_t prop_exists = FAIL; herr_t ret_value = SUCCEED; - if (!plist_ptr) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL FAPL pointer"); + FUNC_ENTER_PACKAGE + + if (!plist) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL FAPL pointer"); if (file_id == UINT64_MAX) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file ID value"); + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file ID value"); - if ((prop_exists = H5P_exist_plist(plist_ptr, H5FD_SUBFILING_STUB_FILE_ID)) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, - "can't check if file ID property exists in FAPL"); + if ((prop_exists = H5P_exist_plist(plist, H5FD_SUBFILING_STUB_FILE_ID)) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't check if file ID property exists in FAPL"); if (prop_exists) { - if (H5P_set(plist_ptr, H5FD_SUBFILING_STUB_FILE_ID, &file_id) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set file ID property on FAPL"); - } - else { - if (H5P_insert(plist_ptr, H5FD_SUBFILING_STUB_FILE_ID, sizeof(uint64_t), &file_id, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, - "unable to register file ID property in FAPL"); + if (H5P_set(plist, H5FD_SUBFILING_STUB_FILE_ID, &file_id) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTSET, FAIL, "can't set file ID property on FAPL"); } + else if (H5P_insert(plist, H5FD_SUBFILING_STUB_FILE_ID, sizeof(uint64_t), &file_id, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTREGISTER, FAIL, "unable to register file ID property in FAPL"); done: - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /*------------------------------------------------------------------------- - * Function: H5_subfiling_get_file_id_prop + * Function: H5FD__subfiling_get_file_id_prop * * Purpose: Retrieves the file ID (Inode) value from the given FAPL * pointer. The Subfiling VFD uses this property to pass the @@ -3017,33 +2849,34 @@ H5_subfiling_set_file_id_prop(H5P_genplist_t *plist_ptr, uint64_t file_id) *------------------------------------------------------------------------- */ herr_t -H5_subfiling_get_file_id_prop(H5P_genplist_t *plist_ptr, uint64_t *file_id) +H5FD__subfiling_get_file_id_prop(H5P_genplist_t *plist, uint64_t *file_id) { htri_t prop_exists = FAIL; herr_t ret_value = SUCCEED; - if (!plist_ptr) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL FAPL pointer"); + FUNC_ENTER_PACKAGE + + if (!plist) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL FAPL pointer"); if (!file_id) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL file ID pointer"); + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL file ID pointer"); - if ((prop_exists = H5P_exist_plist(plist_ptr, H5FD_SUBFILING_STUB_FILE_ID)) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, - "can't check if file ID property exists in FAPL"); + if ((prop_exists = H5P_exist_plist(plist, H5FD_SUBFILING_STUB_FILE_ID)) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't check if file ID property exists in FAPL"); if (prop_exists) { - if (H5P_get(plist_ptr, H5FD_SUBFILING_STUB_FILE_ID, file_id) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get file ID property from FAPL"); + if (H5P_get(plist, H5FD_SUBFILING_STUB_FILE_ID, file_id) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get file ID property from FAPL"); } else *file_id = UINT64_MAX; done: - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /*------------------------------------------------------------------------- - * Function: H5_subfile_fid_to_context + * Function: H5FD__subfile_fid_to_context * * Purpose: This is a basic lookup function which returns the subfiling * context ID associated with the specified file ID. If no @@ -3055,27 +2888,29 @@ H5_subfiling_get_file_id_prop(H5P_genplist_t *plist_ptr, uint64_t *file_id) *------------------------------------------------------------------------- */ herr_t -H5_subfile_fid_to_context(uint64_t file_id, int64_t *context_id_out) +H5FD__subfile_fid_to_context(uint64_t file_id, int64_t *context_id_out) { herr_t ret_value = SUCCEED; + FUNC_ENTER_PACKAGE + assert(context_id_out); *context_id_out = -1; - if (init_open_file_map() < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "couldn't initialize open file mapping"); + if (H5FD__subfiling_init_open_file_map() < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "couldn't initialize open file mapping"); for (int i = 0; i < sf_file_map_size; i++) if (sf_open_file_map[i].file_id == file_id) *context_id_out = sf_open_file_map[i].sf_context_id; done: - H5_SUBFILING_FUNC_LEAVE; -} /* end H5_subfile_fid_to_context() */ + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5FD__subfile_fid_to_context() */ /*------------------------------------------------------------------------- - * Function: H5_subfiling_validate_config + * Function: H5FD__subfiling_validate_config_params * * Purpose: Checks that the given subfiling configuration parameters * are valid @@ -3084,13 +2919,15 @@ H5_subfile_fid_to_context(uint64_t file_id, int64_t *context_id_out) *------------------------------------------------------------------------- */ herr_t -H5_subfiling_validate_config(const H5FD_subfiling_params_t *subf_config) +H5FD__subfiling_validate_config_params(const H5FD_subfiling_params_t *subf_config) { H5FD_subfiling_ioc_select_t ioc_sel_type; herr_t ret_value = SUCCEED; + FUNC_ENTER_PACKAGE + if (!subf_config) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL subfiling configuration pointer"); + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL subfiling configuration pointer"); /* * Compare against each IOC selection value directly since @@ -3100,20 +2937,20 @@ H5_subfiling_validate_config(const H5FD_subfiling_params_t *subf_config) ioc_sel_type = subf_config->ioc_selection; if (ioc_sel_type != SELECT_IOC_ONE_PER_NODE && ioc_sel_type != SELECT_IOC_EVERY_NTH_RANK && ioc_sel_type != SELECT_IOC_WITH_CONFIG && ioc_sel_type != SELECT_IOC_TOTAL) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid IOC selection method"); + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid IOC selection method"); if (subf_config->stripe_size <= 0) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid stripe size"); + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid stripe size"); if (subf_config->stripe_count <= 0 && subf_config->stripe_count != H5FD_SUBFILING_DEFAULT_STRIPE_COUNT) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid stripe count"); + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid stripe count"); done: - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /*------------------------------------------------------------------------- - * Function: H5_subfiling_terminate + * Function: H5FD__subfiling_terminate * * Purpose: A cleanup routine to be called by the Subfiling VFD when * it is terminating. Cleans up internal resources such as the @@ -3124,62 +2961,63 @@ H5_subfiling_validate_config(const H5FD_subfiling_params_t *subf_config) *------------------------------------------------------------------------- */ herr_t -H5_subfiling_terminate(void) +H5FD__subfiling_terminate(void) { herr_t ret_value = SUCCEED; + FUNC_ENTER_PACKAGE + /* Clean up subfiling context and topology caches */ if (sf_context_cache) { - for (size_t i = 0; i < sf_context_cache_size; i++) { + for (size_t i = 0; i < sf_context_cache_size; i++) if (sf_context_cache[i]) { - if (H5_free_subfiling_object_int(sf_context_cache[i]) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, - "couldn't free subfiling context object"); + if (H5FD__subfiling_free_context(sf_context_cache[i]) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "couldn't free subfiling context object"); sf_context_cache[i] = NULL; } - } sf_context_cache_size = 0; sf_context_cache_next_index = 0; - free(sf_context_cache); + H5MM_free(sf_context_cache); sf_context_cache = NULL; } if (sf_topology_cache) { for (size_t i = 0; i < sf_topology_cache_num_entries; i++) { - if (H5_free_subfiling_topology(sf_topology_cache[i]) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, - "couldn't free subfiling topology object"); + if (H5FD__subfiling_free_topology(sf_topology_cache[i]) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "couldn't free subfiling topology object"); sf_topology_cache[i] = NULL; } sf_topology_cache_size = 0; sf_topology_cache_num_entries = 0; - free(sf_topology_cache); + H5MM_free(sf_topology_cache); sf_topology_cache = NULL; } /* Clean up the file ID to context object mapping */ sf_file_map_size = 0; - free(sf_open_file_map); + H5MM_free(sf_open_file_map); sf_open_file_map = NULL; done: - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } #ifdef H5_SUBFILING_DEBUG void -H5_subfiling_log(int64_t sf_context_id, const char *fmt, ...) +H5FD__subfiling_log(int64_t sf_context_id, const char *fmt, ...) { subfiling_context_t *sf_context = NULL; va_list log_args; + FUNC_ENTER_PACKAGE_NOERR + va_start(log_args, fmt); /* Retrieve the subfiling object for the newly-created context ID */ - if (NULL == (sf_context = H5_get_subfiling_object(sf_context_id))) { + if (NULL == (sf_context = H5FD__subfiling_get_object(sf_context_id))) { printf("%s: couldn't get subfiling object from context ID\n", __func__); goto done; } @@ -3202,19 +3040,21 @@ H5_subfiling_log(int64_t sf_context_id, const char *fmt, ...) done: va_end(log_args); - return; + FUNC_LEAVE_NOAPI_VOID } void -H5_subfiling_log_nonewline(int64_t sf_context_id, const char *fmt, ...) +H5FD__subfiling_log_nonewline(int64_t sf_context_id, const char *fmt, ...) { subfiling_context_t *sf_context = NULL; va_list log_args; + FUNC_ENTER_PACKAGE_NOERR + va_start(log_args, fmt); /* Retrieve the subfiling object for the newly-created context ID */ - if (NULL == (sf_context = H5_get_subfiling_object(sf_context_id))) { + if (NULL == (sf_context = H5FD__subfiling_get_object(sf_context_id))) { printf("%s: couldn't get subfiling object from context ID\n", __func__); goto done; } @@ -3235,6 +3075,6 @@ H5_subfiling_log_nonewline(int64_t sf_context_id, const char *fmt, ...) done: va_end(log_args); - return; + FUNC_LEAVE_NOAPI_VOID } #endif diff --git a/src/H5FDsubfiling/H5subfiling_common.h b/src/H5FDsubfiling/H5subfiling_common.h index 2c614cc6803..cef396b9e42 100644 --- a/src/H5FDsubfiling/H5subfiling_common.h +++ b/src/H5FDsubfiling/H5subfiling_common.h @@ -258,38 +258,52 @@ typedef struct { /* MPI Datatype used to send/receive an RPC message */ extern MPI_Datatype H5_subfiling_rpc_msg_type; +/* + * Utility routine to hack around casting away const + */ +static inline void * +H5FD__subfiling_cast_to_void(const void *data) +{ + union { + const void *const_ptr_to_data; + void *ptr_to_data; + } eliminate_const_warning; + eliminate_const_warning.const_ptr_to_data = data; + return eliminate_const_warning.ptr_to_data; +} + #ifdef __cplusplus extern "C" { #endif -H5_DLL herr_t H5_open_subfiling_stub_file(const char *name, unsigned flags, MPI_Comm file_comm, - H5FD_t **file_ptr, uint64_t *file_id); -H5_DLL herr_t H5_open_subfiles(const char *base_filename, uint64_t file_id, - H5FD_subfiling_params_t *subfiling_config, int file_acc_flags, - MPI_Comm file_comm, int64_t *context_id_out); -H5_DLL herr_t H5_close_subfiles(int64_t subfiling_context_id, MPI_Comm file_comm); +H5_DLL herr_t H5FD__subfiling_open_stub_file(const char *name, unsigned flags, MPI_Comm file_comm, + H5FD_t **file_ptr, uint64_t *file_id); +H5_DLL herr_t H5FD__subfiling_open_subfiles(const char *base_filename, uint64_t file_id, + H5FD_subfiling_params_t *subfiling_config, int file_acc_flags, + MPI_Comm file_comm, int64_t *context_id_out); +H5_DLL herr_t H5FD__subfiling_close_subfiles(int64_t subfiling_context_id, MPI_Comm file_comm); -H5_DLL int64_t H5_new_subfiling_object_id(sf_obj_type_t obj_type); -H5_DLL void *H5_get_subfiling_object(int64_t object_id); -H5_DLL herr_t H5_free_subfiling_object(int64_t object_id); -H5_DLL herr_t H5_get_subfiling_config_from_file(FILE *config_file, int64_t *stripe_size, - int64_t *num_subfiles); -H5_DLL herr_t H5_resolve_pathname(const char *filepath, MPI_Comm comm, char **resolved_filepath); +H5_DLL void *H5FD__subfiling_get_object(int64_t object_id); +H5_DLL herr_t H5FD__subfiling_free_object(int64_t object_id); +H5_DLL herr_t H5FD__subfiling_get_config_from_file(FILE *config_file, int64_t *stripe_size, + int64_t *num_subfiles); +H5_DLL herr_t H5FD__subfiling_resolve_pathname(const char *filepath, MPI_Comm comm, char **resolved_filepath); -H5_DLL herr_t H5_subfiling_set_config_prop(H5P_genplist_t *plist_ptr, - const H5FD_subfiling_params_t *vfd_config); -H5_DLL herr_t H5_subfiling_get_config_prop(H5P_genplist_t *plist_ptr, H5FD_subfiling_params_t *vfd_config); -H5_DLL herr_t H5_subfiling_set_file_id_prop(H5P_genplist_t *plist_ptr, uint64_t file_id); -H5_DLL herr_t H5_subfiling_get_file_id_prop(H5P_genplist_t *plist_ptr, uint64_t *file_id); -H5_DLL herr_t H5_subfile_fid_to_context(uint64_t file_id, int64_t *context_id_out); +H5_DLL herr_t H5FD__subfiling_set_config_prop(H5P_genplist_t *plist_ptr, + const H5FD_subfiling_params_t *vfd_config); +H5_DLL herr_t H5FD__subfiling_get_config_prop(H5P_genplist_t *plist_ptr, H5FD_subfiling_params_t *vfd_config); +H5_DLL herr_t H5FD__subfiling_set_file_id_prop(H5P_genplist_t *plist_ptr, uint64_t file_id); +H5_DLL herr_t H5FD__subfiling_get_file_id_prop(H5P_genplist_t *plist_ptr, uint64_t *file_id); +H5_DLL herr_t H5FD__subfile_fid_to_context(uint64_t file_id, int64_t *context_id_out); -H5_DLL herr_t H5_subfiling_validate_config(const H5FD_subfiling_params_t *subf_config); +H5_DLL herr_t H5FD__subfiling_validate_config_params(const H5FD_subfiling_params_t *subf_config); +H5_DLL herr_t H5FD__subfiling_get_default_ioc_config(H5FD_ioc_config_t *config); -H5_DLL herr_t H5_subfiling_terminate(void); +H5_DLL herr_t H5FD__subfiling_terminate(void); #ifdef H5_SUBFILING_DEBUG -H5_DLL void H5_subfiling_log(int64_t sf_context_id, const char *fmt, ...); -H5_DLL void H5_subfiling_log_nonewline(int64_t sf_context_id, const char *fmt, ...); +H5_DLL void H5FD__subfiling_log(int64_t sf_context_id, const char *fmt, ...); +H5_DLL void H5FD__subfiling_log_nonewline(int64_t sf_context_id, const char *fmt, ...); #endif #ifdef __cplusplus diff --git a/src/H5FDsubfiling/H5subfiling_err.h b/src/H5FDsubfiling/H5subfiling_err.h deleted file mode 100644 index efdfaab0d6c..00000000000 --- a/src/H5FDsubfiling/H5subfiling_err.h +++ /dev/null @@ -1,272 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Copyright by The HDF Group. * - * All rights reserved. * - * * - * This file is part of HDF5. The full HDF5 copyright notice, including * - * terms governing use, modification, and redistribution, is contained in * - * the COPYING file, which can be found at the root of the source code * - * distribution tree, or in https://www.hdfgroup.org/licenses. * - * If you do not have access to either file, you may request a copy from * - * help@hdfgroup.org. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -/* - * Error handling for the HDF5 Subfiling feature - */ - -#ifndef H5SUBFILING_ERR_H -#define H5SUBFILING_ERR_H - -#include - -#include "H5Epublic.h" - -extern hid_t H5subfiling_err_stack_g; -extern hid_t H5subfiling_err_class_g; - -#define H5SUBFILING_ERR_CLS_NAME "HDF5 Subfiling" -#define H5SUBFILING_ERR_LIB_NAME "HDF5 Subfiling" -#define H5SUBFILING_ERR_VER "1.0.0" - -/* Error macros */ - -#ifdef H5_NO_DEPRECATED_SYMBOLS - -/* - * Macro to push the current function to the current error stack - * and then goto the "done" label, which should appear inside the - * function. (v2 errors only) - */ -#define H5_SUBFILING_GOTO_ERROR(err_major, err_minor, ret_val, ...) \ - do { \ - H5E_auto2_t err_func; \ - \ - /* Check whether automatic error reporting has been disabled */ \ - (void)H5Eget_auto2(H5E_DEFAULT, &err_func, NULL); \ - if (err_func) { \ - if (H5subfiling_err_stack_g >= 0 && H5subfiling_err_class_g >= 0) { \ - H5Epush2(H5subfiling_err_stack_g, __FILE__, __func__, __LINE__, H5subfiling_err_class_g, \ - err_major, err_minor, __VA_ARGS__); \ - } \ - else { \ - fprintf(stderr, __VA_ARGS__); \ - fprintf(stderr, "\n"); \ - } \ - } \ - \ - ret_value = ret_val; \ - goto done; \ - } while (0) - -/* - * Macro to push the current function to the current error stack - * without calling goto. This is used for handling the case where - * an error occurs during cleanup past the "done" label inside a - * function so that an infinite loop does not occur where goto - * continually branches back to the label. (v2 errors only) - */ -#define H5_SUBFILING_DONE_ERROR(err_major, err_minor, ret_val, ...) \ - do { \ - H5E_auto2_t err_func; \ - \ - /* Check whether automatic error reporting has been disabled */ \ - (void)H5Eget_auto2(H5E_DEFAULT, &err_func, NULL); \ - if (err_func) { \ - if (H5subfiling_err_stack_g >= 0 && H5subfiling_err_class_g >= 0) \ - H5Epush2(H5subfiling_err_stack_g, __FILE__, __func__, __LINE__, H5subfiling_err_class_g, \ - err_major, err_minor, __VA_ARGS__); \ - else { \ - fprintf(stderr, __VA_ARGS__); \ - fprintf(stderr, "\n"); \ - } \ - } \ - \ - ret_value = ret_val; \ - } while (0) - -/* - * Macro to print out the current error stack and then clear it - * for future use. (v2 errors only) - */ -#define PRINT_ERROR_STACK \ - do { \ - H5E_auto2_t err_func; \ - \ - /* Check whether automatic error reporting has been disabled */ \ - (void)H5Eget_auto2(H5E_DEFAULT, &err_func, NULL); \ - if (err_func) { \ - if ((H5subfiling_err_stack_g >= 0) && (H5Eget_num(H5subfiling_err_stack_g) > 0)) { \ - H5Eprint2(H5subfiling_err_stack_g, NULL); \ - H5Eclear2(H5subfiling_err_stack_g); \ - } \ - } \ - } while (0) - -#else /* H5_NO_DEPRECATED_SYMBOLS */ - -/* - * Macro to push the current function to the current error stack - * and then goto the "done" label, which should appear inside the - * function. (compatible with v1 and v2 errors) - */ -#define H5_SUBFILING_GOTO_ERROR(err_major, err_minor, ret_val, ...) \ - do { \ - unsigned is_v2_err; \ - union { \ - H5E_auto1_t err_func_v1; \ - H5E_auto2_t err_func_v2; \ - } err_func; \ - \ - /* Determine version of error */ \ - (void)H5Eauto_is_v2(H5E_DEFAULT, &is_v2_err); \ - \ - if (is_v2_err) \ - (void)H5Eget_auto2(H5E_DEFAULT, &err_func.err_func_v2, NULL); \ - else \ - (void)H5Eget_auto1(&err_func.err_func_v1, NULL); \ - \ - /* Check whether automatic error reporting has been disabled */ \ - if ((is_v2_err && err_func.err_func_v2) || (!is_v2_err && err_func.err_func_v1)) { \ - if (H5subfiling_err_stack_g >= 0 && H5subfiling_err_class_g >= 0) { \ - H5Epush2(H5subfiling_err_stack_g, __FILE__, __func__, __LINE__, H5subfiling_err_class_g, \ - err_major, err_minor, __VA_ARGS__); \ - } \ - else { \ - fprintf(stderr, __VA_ARGS__); \ - fprintf(stderr, "\n"); \ - } \ - } \ - \ - ret_value = ret_val; \ - goto done; \ - } while (0) - -/* - * Macro to push the current function to the current error stack - * without calling goto. This is used for handling the case where - * an error occurs during cleanup past the "done" label inside a - * function so that an infinite loop does not occur where goto - * continually branches back to the label. (compatible with v1 - * and v2 errors) - */ -#define H5_SUBFILING_DONE_ERROR(err_major, err_minor, ret_val, ...) \ - do { \ - unsigned is_v2_err; \ - union { \ - H5E_auto1_t err_func_v1; \ - H5E_auto2_t err_func_v2; \ - } err_func; \ - \ - /* Determine version of error */ \ - (void)H5Eauto_is_v2(H5E_DEFAULT, &is_v2_err); \ - \ - if (is_v2_err) \ - (void)H5Eget_auto2(H5E_DEFAULT, &err_func.err_func_v2, NULL); \ - else \ - (void)H5Eget_auto1(&err_func.err_func_v1, NULL); \ - \ - /* Check whether automatic error reporting has been disabled */ \ - if ((is_v2_err && err_func.err_func_v2) || (!is_v2_err && err_func.err_func_v1)) { \ - if (H5subfiling_err_stack_g >= 0 && H5subfiling_err_class_g >= 0) { \ - H5Epush2(H5subfiling_err_stack_g, __FILE__, __func__, __LINE__, H5subfiling_err_class_g, \ - err_major, err_minor, __VA_ARGS__); \ - } \ - else { \ - fprintf(stderr, __VA_ARGS__); \ - fprintf(stderr, "\n"); \ - } \ - } \ - \ - ret_value = ret_val; \ - } while (0) - -/* - * Macro to print out the current error stack and then clear it - * for future use. (compatible with v1 and v2 errors) - */ -#define PRINT_ERROR_STACK \ - do { \ - unsigned is_v2_err; \ - union { \ - H5E_auto1_t err_func_v1; \ - H5E_auto2_t err_func_v2; \ - } err_func; \ - \ - /* Determine version of error */ \ - (void)H5Eauto_is_v2(H5E_DEFAULT, &is_v2_err); \ - \ - if (is_v2_err) \ - (void)H5Eget_auto2(H5E_DEFAULT, &err_func.err_func_v2, NULL); \ - else \ - (void)H5Eget_auto1(&err_func.err_func_v1, NULL); \ - \ - /* Check whether automatic error reporting has been disabled */ \ - if ((is_v2_err && err_func.err_func_v2) || (!is_v2_err && err_func.err_func_v1)) { \ - if ((H5subfiling_err_stack_g >= 0) && (H5Eget_num(H5subfiling_err_stack_g) > 0)) { \ - H5Eprint2(H5subfiling_err_stack_g, NULL); \ - H5Eclear2(H5subfiling_err_stack_g); \ - } \ - } \ - } while (0) - -#endif /* H5_NO_DEPRECATED_SYMBOLS */ - -#define H5_SUBFILING_SYS_GOTO_ERROR(err_major, err_minor, ret_val, str) \ - do { \ - int myerrno = errno; \ - H5_SUBFILING_GOTO_ERROR(err_major, err_minor, ret_val, "%s, errno = %d, error message = '%s'", str, \ - myerrno, strerror(myerrno)); \ - } while (0) - -/* MPI error handling macros. */ - -extern char H5subfiling_mpi_error_str[MPI_MAX_ERROR_STRING]; -extern int H5subfiling_mpi_error_str_len; - -#define H5_SUBFILING_MPI_DONE_ERROR(retcode, str, mpierr) \ - do { \ - MPI_Error_string(mpierr, H5subfiling_mpi_error_str, &H5subfiling_mpi_error_str_len); \ - H5_SUBFILING_DONE_ERROR(H5E_INTERNAL, H5E_MPI, retcode, "%s: MPI error string is '%s'", str, \ - H5subfiling_mpi_error_str); \ - } while (0) -#define H5_SUBFILING_MPI_GOTO_ERROR(retcode, str, mpierr) \ - do { \ - MPI_Error_string(mpierr, H5subfiling_mpi_error_str, &H5subfiling_mpi_error_str_len); \ - H5_SUBFILING_GOTO_ERROR(H5E_INTERNAL, H5E_MPI, retcode, "%s: MPI error string is '%s'", str, \ - H5subfiling_mpi_error_str); \ - } while (0) - -/* - * Macro to simply jump to the "done" label inside the function, - * setting ret_value to the given value. This is often used for - * short circuiting in functions when certain conditions arise. - */ -#define H5_SUBFILING_GOTO_DONE(ret_val) \ - do { \ - ret_value = ret_val; \ - goto done; \ - } while (0) - -/* - * Macro to return from a top-level API function, printing - * out the error stack on the way out. - * It should be ensured that this macro is only called once - * per HDF5 operation. If it is called multiple times per - * operation (e.g. due to calling top-level API functions - * internally), the error stack will be inconsistent/incoherent. - */ -#define H5_SUBFILING_FUNC_LEAVE_API \ - do { \ - PRINT_ERROR_STACK; \ - return ret_value; \ - } while (0) - -/* - * Macro to return from internal functions. - */ -#define H5_SUBFILING_FUNC_LEAVE \ - do { \ - return ret_value; \ - } while (0) - -#endif /* H5SUBFILING_ERR_H */ From 32f1daf418184be3bfefbca881334ca5eca7a5d1 Mon Sep 17 00:00:00 2001 From: mattjala <124107509+mattjala@users.noreply.github.com> Date: Wed, 26 Jun 2024 22:39:12 -0500 Subject: [PATCH 38/45] Correct documentation for return-and-read fields (#4598) --- src/H5CX.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/H5CX.c b/src/H5CX.c index 8454ef7374a..0e14eeadac1 100644 --- a/src/H5CX.c +++ b/src/H5CX.c @@ -170,17 +170,17 @@ * H5CX_TEST_SET_PROP and H5CX_SET_PROP macros to work properly. * * - "Return-and-read" properties that are returned to the application to send out introspection information, - * but are also queried by the library internally. Internal queries always retrieve the original value - * from the property list, and update the context's value to match. These properties have both a 'valid' - * and 'set' flag. _valid is true if the field has ever been populated from its underlying property - * list. _set flag is true if this field has ever been set on the context for application - * introspection. The naming of these fields is important for the H5CX_RETRIEVE_PROP_VALID_SET macro to - * work properly. - * - * Note that if a set operation is followed by an internal read, it is possible for _set to be true - * while the value in the context matches the underlying property list, resulting in a redundant write to - * the property list when the context is popped. Similarly, if a field has been set on the context but - * never read internally, _valid will be false despite the context containing a meaningful value. + * but are also queried by the library internally. If the context value has been 'set' by an accessor, + * all future queries will return the stored value from the context, to avoid later queries overwriting + * that stored value with the value from the property list. + * + * These properties have both a 'valid' and 'set' flag. _valid is true if the field has ever been + * populated from its underlying property list. _set flag is true if this field has ever been set on + * the context for application introspection. The naming of these fields is important for the + * H5CX_RETRIEVE_PROP_VALID_SET macro to work properly. + * + * If a field has been set on the context but never read internally, _valid will be false + * despite the context containing a meaningful cached value. */ typedef struct H5CX_t { /* DXPL */ From 03ea427d1e4f916dcebce7757218774a4974878f Mon Sep 17 00:00:00 2001 From: Allen Byrne <50328838+byrnHDF@users.noreply.github.com> Date: Wed, 26 Jun 2024 22:40:35 -0500 Subject: [PATCH 39/45] These two generators create strings without NUL for testing (#4608) --- tools/test/h5dump/h5dumpgentest.c | 54 ++++++++++++++++--------------- tools/test/h5repack/h5repacktst.c | 52 +++++++++++++++-------------- 2 files changed, 55 insertions(+), 51 deletions(-) diff --git a/tools/test/h5dump/h5dumpgentest.c b/tools/test/h5dump/h5dumpgentest.c index c357477c125..55014aeeecf 100644 --- a/tools/test/h5dump/h5dumpgentest.c +++ b/tools/test/h5dump/h5dumpgentest.c @@ -4064,7 +4064,7 @@ write_attr_in(hid_t loc_id, const char *dset_name, /* for saving reference to da /* create 1D attributes with dimension [2], 2 elements */ hsize_t dims[1] = {2}; - char buf1[2][3] = {"ab", "de"}; /* string */ + char buf1[2][2] = {"ab", "de"}; /* string, NO NUL fixed length */ char buf2[2] = {1, 2}; /* bitfield, opaque */ s_t buf3[2] = {{1, 2}, {3, 4}}; /* compound */ hobj_ref_t buf4[2]; /* reference */ @@ -4076,8 +4076,8 @@ write_attr_in(hid_t loc_id, const char *dset_name, /* for saving reference to da /* create 2D attributes with dimension [3][2], 6 elements */ hsize_t dims2[2] = {3, 2}; - char buf12[6][3] = {"ab", "cd", "ef", "gh", "ij", "kl"}; /* string */ - char buf22[3][2] = {{1, 2}, {3, 4}, {5, 6}}; /* bitfield, opaque */ + char buf12[6][2] = {"ab", "cd", "ef", "gh", "ij", "kl"}; /* string, NO NUL fixed length */ + char buf22[3][2] = {{1, 2}, {3, 4}, {5, 6}}; /* bitfield, opaque */ s_t buf32[6] = {{1, 2}, {3, 4}, {5, 6}, {7, 8}, {9, 10}, {11, 12}}; /* compound */ hobj_ref_t buf42[3][2]; /* reference */ hvl_t buf52[3][2]; /* vlen */ @@ -4086,16 +4086,17 @@ write_attr_in(hid_t loc_id, const char *dset_name, /* for saving reference to da float buf82[3][2] = {{1, 2}, {3, 4}, {5, 6}}; /* float */ /* create 3D attributes with dimension [4][3][2], 24 elements */ - hsize_t dims3[3] = {4, 3, 2}; - char buf13[24][3] = {"ab", "cd", "ef", "gh", "ij", "kl", "mn", "pq", "rs", "tu", "vw", "xz", - "AB", "CD", "EF", "GH", "IJ", "KL", "MN", "PQ", "RS", "TU", "VW", "XZ"}; /* string */ - char buf23[4][3][2]; /* bitfield, opaque */ - s_t buf33[4][3][2]; /* compound */ - hobj_ref_t buf43[4][3][2]; /* reference */ - hvl_t buf53[4][3][2]; /* vlen */ - int buf63[24][3]; /* array */ - int buf73[4][3][2]; /* integer */ - float buf83[4][3][2]; /* float */ + hsize_t dims3[3] = {4, 3, 2}; + char buf13[24][2] = { + "ab", "cd", "ef", "gh", "ij", "kl", "mn", "pq", "rs", "tu", "vw", "xz", "AB", + "CD", "EF", "GH", "IJ", "KL", "MN", "PQ", "RS", "TU", "VW", "XZ"}; /* string, NO NUL fixed length */ + char buf23[4][3][2]; /* bitfield, opaque */ + s_t buf33[4][3][2]; /* compound */ + hobj_ref_t buf43[4][3][2]; /* reference */ + hvl_t buf53[4][3][2]; /* vlen */ + int buf63[24][3]; /* array */ + int buf73[4][3][2]; /* integer */ + float buf83[4][3][2]; /* float */ /*------------------------------------------------------------------------- * 1D attributes @@ -4489,7 +4490,7 @@ write_dset_in(hid_t loc_id, const char *dset_name, /* for saving reference to da /* create 1D attributes with dimension [2], 2 elements */ hsize_t dims[1] = {2}; - char buf1[2][3] = {"ab", "de"}; /* string */ + char buf1[2][2] = {"ab", "de"}; /* string, NO NUL fixed length */ char buf2[2] = {1, 2}; /* bitfield, opaque */ s_t buf3[2] = {{1, 2}, {3, 4}}; /* compound */ hobj_ref_t buf4[2]; /* reference */ @@ -4501,8 +4502,8 @@ write_dset_in(hid_t loc_id, const char *dset_name, /* for saving reference to da /* create 2D attributes with dimension [3][2], 6 elements */ hsize_t dims2[2] = {3, 2}; - char buf12[6][3] = {"ab", "cd", "ef", "gh", "ij", "kl"}; /* string */ - char buf22[3][2] = {{1, 2}, {3, 4}, {5, 6}}; /* bitfield, opaque */ + char buf12[6][2] = {"ab", "cd", "ef", "gh", "ij", "kl"}; /* string, NO NUL fixed length */ + char buf22[3][2] = {{1, 2}, {3, 4}, {5, 6}}; /* bitfield, opaque */ s_t buf32[6] = {{1, 2}, {3, 4}, {5, 6}, {7, 8}, {9, 10}, {11, 12}}; /* compound */ hobj_ref_t buf42[3][2]; /* reference */ hvl_t buf52[3][2]; /* vlen */ @@ -4511,16 +4512,17 @@ write_dset_in(hid_t loc_id, const char *dset_name, /* for saving reference to da float buf82[3][2] = {{1, 2}, {3, 4}, {5, 6}}; /* float */ /* create 3D attributes with dimension [4][3][2], 24 elements */ - hsize_t dims3[3] = {4, 3, 2}; - char buf13[24][3] = {"ab", "cd", "ef", "gh", "ij", "kl", "mn", "pq", "rs", "tu", "vw", "xz", - "AB", "CD", "EF", "GH", "IJ", "KL", "MN", "PQ", "RS", "TU", "VW", "XZ"}; /* string */ - char buf23[4][3][2]; /* bitfield, opaque */ - s_t buf33[4][3][2]; /* compound */ - hobj_ref_t buf43[4][3][2]; /* reference */ - hvl_t buf53[4][3][2]; /* vlen */ - int buf63[24][3]; /* array */ - int buf73[4][3][2]; /* integer */ - float buf83[4][3][2]; /* float */ + hsize_t dims3[3] = {4, 3, 2}; + char buf13[24][2] = { + "ab", "cd", "ef", "gh", "ij", "kl", "mn", "pq", "rs", "tu", "vw", "xz", "AB", + "CD", "EF", "GH", "IJ", "KL", "MN", "PQ", "RS", "TU", "VW", "XZ"}; /* string, NO NUL fixed length */ + char buf23[4][3][2]; /* bitfield, opaque */ + s_t buf33[4][3][2]; /* compound */ + hobj_ref_t buf43[4][3][2]; /* reference */ + hvl_t buf53[4][3][2]; /* vlen */ + int buf63[24][3]; /* array */ + int buf73[4][3][2]; /* integer */ + float buf83[4][3][2]; /* float */ /*------------------------------------------------------------------------- * 1D diff --git a/tools/test/h5repack/h5repacktst.c b/tools/test/h5repack/h5repacktst.c index fccd339849a..c9d64188695 100644 --- a/tools/test/h5repack/h5repacktst.c +++ b/tools/test/h5repack/h5repacktst.c @@ -3974,17 +3974,18 @@ write_dset_in(hid_t loc_id, const char *dset_name, /* for saving reference to da float buf82[3][2] = {{1, 2}, {3, 4}, {5, 6}}; /* float */ /* create 3D attributes with dimension [4][3][2], 24 elements */ - hsize_t dims3[3] = {4, 3, 2}; - hsize_t dims3r[3] = {1, 1, 1}; - char buf13[24][3] = {"ab", "cd", "ef", "gh", "ij", "kl", "mn", "pq", "rs", "tu", "vw", "xz", - "AB", "CD", "EF", "GH", "IJ", "KL", "MN", "PQ", "RS", "TU", "VW", "XZ"}; /* string */ - char buf23[4][3][2]; /* bitfield, opaque */ - s_t buf33[4][3][2]; /* compound */ - hobj_ref_t buf43[1][1][1]; /* reference */ - hvl_t buf53[4][3][2]; /* vlen */ - int buf63[24][3]; /* array */ - int buf73[4][3][2]; /* integer */ - float buf83[4][3][2]; /* float */ + hsize_t dims3[3] = {4, 3, 2}; + hsize_t dims3r[3] = {1, 1, 1}; + char buf13[24][2] = { + "ab", "cd", "ef", "gh", "ij", "kl", "mn", "pq", "rs", "tu", "vw", "xz", "AB", + "CD", "EF", "GH", "IJ", "KL", "MN", "PQ", "RS", "TU", "VW", "XZ"}; /* string, NO NUL fixed length */ + char buf23[4][3][2]; /* bitfield, opaque */ + s_t buf33[4][3][2]; /* compound */ + hobj_ref_t buf43[1][1][1]; /* reference */ + hvl_t buf53[4][3][2]; /* vlen */ + int buf63[24][3]; /* array */ + int buf73[4][3][2]; /* integer */ + float buf83[4][3][2]; /* float */ /*------------------------------------------------------------------------- * 1D @@ -4789,7 +4790,7 @@ write_attr_in(hid_t loc_id, const char *dset_name, /* for saving reference to da /* create 1D attributes with dimension [2], 2 elements */ hsize_t dims[1] = {2}; - char buf1[2][3] = {"ab", "de"}; /* string */ + char buf1[2][2] = {"ab", "de"}; /* string, NO NUL fixed length */ char buf2[2] = {1, 2}; /* bitfield, opaque */ s_t buf3[2] = {{1, 2}, {3, 4}}; /* compound */ hobj_ref_t buf4[2]; /* reference */ @@ -4802,8 +4803,8 @@ write_attr_in(hid_t loc_id, const char *dset_name, /* for saving reference to da /* create 2D attributes with dimension [3][2], 6 elements */ hsize_t dims2[2] = {3, 2}; - char buf12[6][3] = {"ab", "cd", "ef", "gh", "ij", "kl"}; /* string */ - char buf22[3][2] = {{1, 2}, {3, 4}, {5, 6}}; /* bitfield, opaque */ + char buf12[6][2] = {"ab", "cd", "ef", "gh", "ij", "kl"}; /* string, NO NUL fixed length */ + char buf22[3][2] = {{1, 2}, {3, 4}, {5, 6}}; /* bitfield, opaque */ s_t buf32[6] = {{1, 2}, {3, 4}, {5, 6}, {7, 8}, {9, 10}, {11, 12}}; /* compound */ hobj_ref_t buf42[3][2]; /* reference */ e_t buf452[3][2]; /* enum */ @@ -4813,17 +4814,18 @@ write_attr_in(hid_t loc_id, const char *dset_name, /* for saving reference to da float buf82[3][2] = {{1, 2}, {3, 4}, {5, 6}}; /* float */ /* create 3D attributes with dimension [4][3][2], 24 elements */ - hsize_t dims3[3] = {4, 3, 2}; - char buf13[24][3] = {"ab", "cd", "ef", "gh", "ij", "kl", "mn", "pq", "rs", "tu", "vw", "xz", - "AB", "CD", "EF", "GH", "IJ", "KL", "MN", "PQ", "RS", "TU", "VW", "XZ"}; /* string */ - char buf23[4][3][2]; /* bitfield, opaque */ - s_t buf33[4][3][2]; /* compound */ - hobj_ref_t buf43[4][3][2]; /* reference */ - e_t buf453[4][3][2]; /* enum */ - hvl_t buf53[4][3][2]; /* vlen */ - int buf63[24][3]; /* array */ - int buf73[4][3][2]; /* integer */ - float buf83[4][3][2]; /* float */ + hsize_t dims3[3] = {4, 3, 2}; + char buf13[24][2] = { + "ab", "cd", "ef", "gh", "ij", "kl", "mn", "pq", "rs", "tu", "vw", "xz", "AB", + "CD", "EF", "GH", "IJ", "KL", "MN", "PQ", "RS", "TU", "VW", "XZ"}; /* string, NO NUL fixed length */ + char buf23[4][3][2]; /* bitfield, opaque */ + s_t buf33[4][3][2]; /* compound */ + hobj_ref_t buf43[4][3][2]; /* reference */ + e_t buf453[4][3][2]; /* enum */ + hvl_t buf53[4][3][2]; /* vlen */ + int buf63[24][3]; /* array */ + int buf73[4][3][2]; /* integer */ + float buf83[4][3][2]; /* float */ /*------------------------------------------------------------------------- * 1D attributes From 3b286f064fdb27d150561196d0bafac67bba1d93 Mon Sep 17 00:00:00 2001 From: Allen Byrne <50328838+byrnHDF@users.noreply.github.com> Date: Thu, 27 Jun 2024 13:36:20 -0500 Subject: [PATCH 40/45] Fix Fortran pkconfig to indicate full path of modules (#4593) --- fortran/src/CMakeLists.txt | 9 ++++++++- hl/fortran/src/CMakeLists.txt | 9 ++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/fortran/src/CMakeLists.txt b/fortran/src/CMakeLists.txt index cb0ff44f907..c94abaa6c53 100644 --- a/fortran/src/CMakeLists.txt +++ b/fortran/src/CMakeLists.txt @@ -583,7 +583,14 @@ set (_PKG_CONFIG_PREFIX ${CMAKE_INSTALL_PREFIX}) set (_PKG_CONFIG_EXEC_PREFIX \${prefix}) set (_PKG_CONFIG_LIBDIR \${exec_prefix}/${HDF5_INSTALL_LIB_DIR}) set (_PKG_CONFIG_INCLUDEDIR \${prefix}/${HDF5_INSTALL_INCLUDE_DIR}) -set (_PKG_CONFIG_MODULEDIR \${prefix}/${HDF5_INSTALL_MODULE_DIR}) +if (BUILD_SHARED_LIBS) + set (_PKG_CONFIG_MODULEDIR \${prefix}/${HDF5_INSTALL_MODULE_DIR}/shared) +else () + set (_PKG_CONFIG_MODULEDIR \${prefix}/${HDF5_INSTALL_MODULE_DIR}/static) +endif () +if (NOT HDF5_INSTALL_MOD_FORTRAN MATCHES "NO") + set (_PKG_CONFIG_MODULEDIR \${prefix}/${HDF5_INSTALL_INCLUDE_DIR}) +endif () set (_PKG_CONFIG_LIBNAME "${HDF5_F90_LIB_NAME}") set (_PKG_CONFIG_VERSION "${HDF5_PACKAGE_VERSION}") set (PKG_CONFIG_LIBNAME "${HDF5_F90_LIB_NAME}") diff --git a/hl/fortran/src/CMakeLists.txt b/hl/fortran/src/CMakeLists.txt index 6ebe08bdc6f..60226c81ab1 100644 --- a/hl/fortran/src/CMakeLists.txt +++ b/hl/fortran/src/CMakeLists.txt @@ -322,7 +322,14 @@ set (_PKG_CONFIG_PREFIX ${CMAKE_INSTALL_PREFIX}) set (_PKG_CONFIG_EXEC_PREFIX \${prefix}) set (_PKG_CONFIG_LIBDIR \${exec_prefix}/${HDF5_INSTALL_LIB_DIR}) set (_PKG_CONFIG_INCLUDEDIR \${prefix}/${HDF5_INSTALL_INCLUDE_DIR}) -set (_PKG_CONFIG_MODULEDIR \${prefix}/${HDF5_INSTALL_MODULE_DIR}) +if (BUILD_SHARED_LIBS) + set (_PKG_CONFIG_MODULEDIR \${prefix}/${HDF5_INSTALL_MODULE_DIR}/shared) +else () + set (_PKG_CONFIG_MODULEDIR \${prefix}/${HDF5_INSTALL_MODULE_DIR}/static) +endif () +if (NOT HDF5_INSTALL_MOD_FORTRAN MATCHES "NO") + set (_PKG_CONFIG_MODULEDIR \${prefix}/${HDF5_INSTALL_INCLUDE_DIR}) +endif () set (_PKG_CONFIG_LIBNAME "${HDF5_HL_F90_LIB_NAME}") set (_PKG_CONFIG_VERSION "${HDF5_PACKAGE_VERSION}") set (PKG_CONFIG_LIBNAME "${HDF5_HL_F90_LIB_NAME}") From 3a57256e894c3731711c2ecd5977a963d0581abc Mon Sep 17 00:00:00 2001 From: Dana Robinson <43805+derobins@users.noreply.github.com> Date: Sat, 29 Jun 2024 13:18:34 -0700 Subject: [PATCH 41/45] Updated release schedule (#4615) 1.16 and 2.0 information --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index ee65b1e1399..af48a7f8656 100644 --- a/README.md +++ b/README.md @@ -69,7 +69,6 @@ conversation. Please read the [instructions](https://forum.hdfgroup.org/t/quick ) pertaining to the Forum's use and configuration. - SNAPSHOTS, PREVIOUS RELEASES AND SOURCE CODE -------------------------------------------- Periodically development code snapshots are provided at the following URL: From dd177731b5542df9e6ab16815914de70cb8cc34d Mon Sep 17 00:00:00 2001 From: mattjala <124107509+mattjala@users.noreply.github.com> Date: Sat, 29 Jun 2024 15:22:35 -0500 Subject: [PATCH 42/45] Document VOL object wrapping context (#4611) --- doxygen/dox/VOLConnGuide.dox | 39 +++++++++++++++++++++++++++--------- src/H5VLcallback.c | 5 ++++- src/H5VLconnector.h | 3 ++- src/H5VLint.c | 11 +++++++++- 4 files changed, 46 insertions(+), 12 deletions(-) diff --git a/doxygen/dox/VOLConnGuide.dox b/doxygen/dox/VOLConnGuide.dox index 190d1fb2048..1f0fb20b022 100644 --- a/doxygen/dox/VOLConnGuide.dox +++ b/doxygen/dox/VOLConnGuide.dox @@ -664,7 +664,11 @@ structure. It is the opposite of the to_str callback. \subsection subsecVOLRefWrap Object Wrap Callbacks The object wrap callbacks are used by passthrough connectors to wrap/unwrap objects and contexts when -passing them up and down the VOL chain. +passing them up and down the VOL chain. Each passthrough VOL must define an object wrapping structure and a wrap context. +The object wrapping structure should contain the information necessary to recursively unwrap the object - at a minimum, this is the object provided from and the ID of the next connector in the stack. +The wrap context should contain the information necessary to recursively wrap the object - at a minimum, this is the ID and the wrap context of the next VOL connector in the stack. + +Each callback should use H5VL<callback> to recursively invoke the same callback in all lower passthrough VOl connectors. Wrap class for object wrapping routines, H5VLconnector.h \code @@ -678,7 +682,13 @@ typedef struct H5VL_wrap_class_t { \endcode \subsubsection subsubsecVOLRefWrapobj wrap: get_object -Retrieves an underlying object. +Retrieves the underlying object from a wrapped object. Should return a pointer to the underlying object belonging to the terminal VOL connector. + +This will generally be done by unwrapping this VOL's object wrapping structure, before recursively calling H5VLget_object to invoke the get_object +callback for all lower VOL connectors which define it. H5VLget_object requires the object returned by the next VOL and the next VOL's ID. Both of +these fields should be stored by the VOL somehow, generally on the wrapped object structure. + +This callback should not cleanup or modify the provided object wrapping structure.
Feature @@ -59,7 +59,7 @@ These examples (C, C++, Fortran) are provided in the HDF5 source code and (Unix)
Create a file C Fortran C++ Java Python +C Fortran C++ Java Python
Create a dataset C Fortran C++ Java Python +C Fortran C++ Java Python
Read and write to a dataset C Fortran C++ Java Python +C Fortran C++ Java Python
Create an attribute C Fortran C++ Java Python +C Fortran C++ Java Python
Create a group C Fortran C++ Java Python +C Fortran C++ Java Python
Create groups in a file using absolute and relative paths C Fortran C++ Java Python +C Fortran C++ Java Python
Create datasets in a group C Fortran C++ Java Python +C Fortran C++ Java Python
Create a file and dataset and select/read a subset from the dataset C Fortran C++ Java Python +C Fortran C++ Java Python Also see examples to Write by row (and column) below.
Create an extendible (unlimited dimension) dataset C Fortran C++ Java Python +C Fortran C++ Java Python Also see examples to Extend by row (and column) below
Create a chunked and compressed dataset C Fortran C++ Java Python +C Fortran C++ Java Python
@@ -696,7 +706,7 @@ Retrieves an underlying object. @@ -704,6 +714,9 @@ Retrieves an underlying object. \subsubsection subsubsecVOLRefWrapctx wrap: get_wrap_ctx Get a VOL connector's object wrapping context. + +The context should be returned in dynamically allocated memory under *wrap_ctx. +Any resources this callback allocates should be freed within free_wrap_ctx.
Signature:
\code - obj (IN): Object being unwrapped. + obj (IN): The object to be unwrapped. \endcode
@@ -721,7 +734,7 @@ Get a VOL connector's object wrapping context. @@ -729,7 +742,11 @@ Get a VOL connector's object wrapping context.
Signature:
\code - obj (IN): Object for which we need a context. + obj (IN): Object wrapped by this VOL connector, for which we need a context. wrap_ctx (OUT): Context. \endcode
\subsubsection subsubsecVOLRefWrapwrap wrap: wrap_object -Asks a connector to wrap an underlying object. +Asks a connector to wrap an underlying object. This callback should use H5VLwrap_object +to recursively have the object wrapped by all lower VOL connectors before performing its own wrapping. + +The wrapped object should provide the information necessary for unwrap_object to recursively +unwrap it - at a minimum, the object provided from and the ID of the next VOL connector. @@ -747,7 +764,7 @@ Asks a connector to wrap an underlying object.
Signature:
\code - obj (IN): Object being wrapped. + obj (IN): The object to be wrapped. obj_type (IN): Object type (see H5Ipublic.h). wrap_ctx (IN): Context. \endcode @@ -756,7 +773,10 @@ Asks a connector to wrap an underlying object.
\subsubsection subsubsecVOLRefWrapunwrap wrap: unwrap_object -Unwrap an object from connector. +Unwrap an object from connector. Any resources allocated during wrap_object should be released and cleaned up here. + +This callback should clean up this VOL's object wrapping structure before recursively invoking H5VLunwrap_object. + @@ -774,14 +794,15 @@ Unwrap an object from connector.
Signature:
\code - obj (IN): Object being unwrapped. + obj (IN): Object to be unwrapped. \endcode
\subsubsection subsubsecVOLRefWrapfree wrap: free_wrap_ctx -Release a VOL connector's object wrapping context. +Release a VOL connector's object wrapping context. This should free any resources allocated during get_wrap_ctx, and recursively invoke H5VLfree_wrap_ctx +to execute the free callback for the lower VOL connectors in the stack. diff --git a/src/H5VLcallback.c b/src/H5VLcallback.c index 2d89d50e7af..196a559608f 100644 --- a/src/H5VLcallback.c +++ b/src/H5VLcallback.c @@ -739,7 +739,10 @@ H5VL_get_wrap_ctx(const H5VL_class_t *connector, void *obj, void **wrap_ctx) /*--------------------------------------------------------------------------- * Function: H5VLget_wrap_ctx * - * Purpose: Get a VOL connector's object wrapping context + * Purpose: Get a VOL connector's object wrapping context. The output + * wrap context is stored in memory allocated by the VOL callback + * under *wrap_ctx and must be freed by the caller through + * H5VLfree_wrap_ctx(). * * Return: Success: Non-negative * Failure: Negative diff --git a/src/H5VLconnector.h b/src/H5VLconnector.h index 02d22314ebc..83a5b087133 100644 --- a/src/H5VLconnector.h +++ b/src/H5VLconnector.h @@ -845,7 +845,8 @@ typedef struct H5VL_info_class_t { } H5VL_info_class_t; /* VOL object wrap / retrieval callbacks */ -/* (These only need to be implemented by "pass through" VOL connectors) */ +/* (These must be implemented by "pass through" VOL connectors, and should not be implemented by terminal VOL + * connectors) */ typedef struct H5VL_wrap_class_t { void *(*get_object)(const void *obj); /* Callback to retrieve underlying object */ herr_t (*get_wrap_ctx)( diff --git a/src/H5VLint.c b/src/H5VLint.c index 1aef656cf65..4c7b38af521 100644 --- a/src/H5VLint.c +++ b/src/H5VLint.c @@ -55,7 +55,16 @@ /* Local Typedefs */ /******************/ -/* Object wrapping context info */ +/* Object wrapping context info for passthrough VOL connectors. + * Passthrough VOL connectors must wrap objects returned from lower level(s) of the VOL connector stack + * so that they may be passed back up the stack to the library, and must unwrap objects + * passed down the stack before providing them to the next lower VOL connector. + * This is generally done individually within each VOL object callback. However, the library sometimes + * needs to wrap objects from places that don't pass through the VOL layer. + * In this case, the wrap callbacks defined in H5VL_wrap_class_t are used, and the VOL-defined wrap context + * (obj_wrap_ctx) provides necessary information - at a minimum, the object originally returned by the lower + * VOL connector, and the ID of the next VOL connector. + */ typedef struct H5VL_wrap_ctx_t { unsigned rc; /* Ref. count for the # of times the context was set / reset */ H5VL_t *connector; /* VOL connector for "outermost" class to start wrap */ From 525bc1698652247098447f1aa28265905bf41b6c Mon Sep 17 00:00:00 2001 From: Larry Knox Date: Tue, 2 Jul 2024 16:42:34 -0500 Subject: [PATCH 43/45] Earray.c and farray.c in hdf5_1_14 still need time_t curr_time for HDsrandom. --- test/earray.c | 1 + test/farray.c | 1 + 2 files changed, 2 insertions(+) diff --git a/test/earray.c b/test/earray.c index 871c6fa46a9..078318af8a8 100644 --- a/test/earray.c +++ b/test/earray.c @@ -2297,6 +2297,7 @@ main(void) earray_iter_type_t curr_iter; /* Current iteration type being worked on */ hid_t fapl = H5I_INVALID_HID; /* File access property list for data files */ unsigned nerrors = 0; /* Cumulative error count */ + time_t curr_time; /* Current time, for seeding random number generator */ bool api_ctx_pushed = false; /* Whether API context pushed */ /* Reset library */ diff --git a/test/farray.c b/test/farray.c index 0c47a607306..7f6ce949dd7 100644 --- a/test/farray.c +++ b/test/farray.c @@ -1628,6 +1628,7 @@ main(void) farray_iter_type_t curr_iter; /* Current iteration type being worked on */ hid_t fapl = H5I_INVALID_HID; /* File access property list for data files */ unsigned nerrors = 0; /* Cumulative error count */ + time_t curr_time; /* Current time, for seeding random number generator */ bool api_ctx_pushed = false; /* Whether API context pushed */ /* Reset library */ From 99d12b1d66c9477f5664c0e9397d0e739082cb70 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 2 Jul 2024 21:46:36 +0000 Subject: [PATCH 44/45] Committing clang-format changes --- test/earray.c | 16 ++++++++-------- test/farray.c | 16 ++++++++-------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/test/earray.c b/test/earray.c index 078318af8a8..3740ae1e61b 100644 --- a/test/earray.c +++ b/test/earray.c @@ -2291,14 +2291,14 @@ test_skip_elmts(hid_t fapl, H5EA_create_t *cparam, earray_test_param_t *tparam, int main(void) { - H5EA_create_t cparam; /* Creation parameters for extensible array */ - earray_test_param_t tparam; /* Testing parameters */ - earray_test_type_t curr_test; /* Current test being worked on */ - earray_iter_type_t curr_iter; /* Current iteration type being worked on */ - hid_t fapl = H5I_INVALID_HID; /* File access property list for data files */ - unsigned nerrors = 0; /* Cumulative error count */ - time_t curr_time; /* Current time, for seeding random number generator */ - bool api_ctx_pushed = false; /* Whether API context pushed */ + H5EA_create_t cparam; /* Creation parameters for extensible array */ + earray_test_param_t tparam; /* Testing parameters */ + earray_test_type_t curr_test; /* Current test being worked on */ + earray_iter_type_t curr_iter; /* Current iteration type being worked on */ + hid_t fapl = H5I_INVALID_HID; /* File access property list for data files */ + unsigned nerrors = 0; /* Cumulative error count */ + time_t curr_time; /* Current time, for seeding random number generator */ + bool api_ctx_pushed = false; /* Whether API context pushed */ /* Reset library */ h5_test_init(); diff --git a/test/farray.c b/test/farray.c index 7f6ce949dd7..d8b2d454226 100644 --- a/test/farray.c +++ b/test/farray.c @@ -1622,14 +1622,14 @@ test_skip_elmts(hid_t fapl, H5FA_create_t *cparam, farray_test_param_t *tparam, int main(void) { - H5FA_create_t cparam; /* Creation parameters for fixed array */ - farray_test_param_t tparam; /* Testing parameters */ - farray_test_type_t curr_test; /* Current test being worked on */ - farray_iter_type_t curr_iter; /* Current iteration type being worked on */ - hid_t fapl = H5I_INVALID_HID; /* File access property list for data files */ - unsigned nerrors = 0; /* Cumulative error count */ - time_t curr_time; /* Current time, for seeding random number generator */ - bool api_ctx_pushed = false; /* Whether API context pushed */ + H5FA_create_t cparam; /* Creation parameters for fixed array */ + farray_test_param_t tparam; /* Testing parameters */ + farray_test_type_t curr_test; /* Current test being worked on */ + farray_iter_type_t curr_iter; /* Current iteration type being worked on */ + hid_t fapl = H5I_INVALID_HID; /* File access property list for data files */ + unsigned nerrors = 0; /* Cumulative error count */ + time_t curr_time; /* Current time, for seeding random number generator */ + bool api_ctx_pushed = false; /* Whether API context pushed */ /* Reset library */ h5_test_init(); From 16abdd2def2c25712ba1a00abf8498bc5ca3c9d3 Mon Sep 17 00:00:00 2001 From: Larry Knox Date: Wed, 3 Jul 2024 09:39:01 -0500 Subject: [PATCH 45/45] Remove line to use future 116_API from CMakeListat.txt files in HDF5 examples directories --- HDF5Examples/C/H5D/CMakeLists.txt | 3 --- HDF5Examples/C/H5FLT/CMakeLists.txt | 1 - HDF5Examples/C/H5G/CMakeLists.txt | 3 --- HDF5Examples/C/H5PAR/CMakeLists.txt | 1 - HDF5Examples/C/H5T/CMakeLists.txt | 2 -- HDF5Examples/C/H5VDS/CMakeLists.txt | 1 - HDF5Examples/C/Perf/CMakeLists.txt | 1 - HDF5Examples/C/TUTR/CMakeLists.txt | 1 - HDF5Examples/CXX/H5D/CMakeLists.txt | 1 - HDF5Examples/CXX/TUTR/CMakeLists.txt | 1 - HDF5Examples/FORTRAN/H5D/CMakeLists.txt | 2 -- HDF5Examples/FORTRAN/H5G/CMakeLists.txt | 2 -- HDF5Examples/FORTRAN/H5PAR/CMakeLists.txt | 1 - HDF5Examples/FORTRAN/H5T/CMakeLists.txt | 2 -- HDF5Examples/FORTRAN/TUTR/CMakeLists.txt | 2 -- 15 files changed, 24 deletions(-) diff --git a/HDF5Examples/C/H5D/CMakeLists.txt b/HDF5Examples/C/H5D/CMakeLists.txt index 6f6086b3939..e268aff38ce 100644 --- a/HDF5Examples/C/H5D/CMakeLists.txt +++ b/HDF5Examples/C/H5D/CMakeLists.txt @@ -19,7 +19,6 @@ foreach (example_name ${common_examples}) "$<$:-DH5_USE_110_API>" "$<$:-DH5_USE_112_API>" "$<$:-DH5_USE_114_API>" - "$<$:-DH5_USE_116_API>" ) if (H5_HAVE_PARALLEL) target_include_directories (${EXAMPLE_VARNAME}_${example_name} PUBLIC ${MPI_C_INCLUDE_DIRS}) @@ -45,7 +44,6 @@ if (HDF5_VERSION_MAJOR VERSION_GREATER_EQUAL "1.8") "$<$:-DH5_USE_110_API>" "$<$:-DH5_USE_112_API>" "$<$:-DH5_USE_114_API>" - "$<$:-DH5_USE_116_API>" ) if (H5_HAVE_PARALLEL) target_include_directories (${EXAMPLE_VARNAME}_${example_name} PUBLIC ${MPI_C_INCLUDE_DIRS}) @@ -72,7 +70,6 @@ endif () # "$<$:-DH5_USE_110_API>" # "$<$:-DH5_USE_112_API>" # "$<$:-DH5_USE_114_API>" -# "$<$:-DH5_USE_116_API>" # ) # if (H5_HAVE_PARALLEL) # target_include_directories (${EXAMPLE_VARNAME}_${example_name} PUBLIC ${MPI_C_INCLUDE_DIRS}) diff --git a/HDF5Examples/C/H5FLT/CMakeLists.txt b/HDF5Examples/C/H5FLT/CMakeLists.txt index e289bf70ba9..f7a5a0c4f8d 100644 --- a/HDF5Examples/C/H5FLT/CMakeLists.txt +++ b/HDF5Examples/C/H5FLT/CMakeLists.txt @@ -165,7 +165,6 @@ foreach (example ${dyn_examples}) "$<$:-DH5_USE_110_API>" "$<$:-DH5_USE_112_API>" "$<$:-DH5_USE_114_API>" - "$<$:-DH5_USE_116_API>" ) if (H5_HAVE_PARALLEL) target_include_directories (${EXAMPLE_VARNAME}_${example} PUBLIC ${MPI_C_INCLUDE_DIRS}) diff --git a/HDF5Examples/C/H5G/CMakeLists.txt b/HDF5Examples/C/H5G/CMakeLists.txt index 91281d5f0a4..d82319a52ae 100644 --- a/HDF5Examples/C/H5G/CMakeLists.txt +++ b/HDF5Examples/C/H5G/CMakeLists.txt @@ -19,7 +19,6 @@ foreach (example_name ${common_examples}) "$<$:-DH5_USE_110_API>" "$<$:-DH5_USE_112_API>" "$<$:-DH5_USE_114_API>" - "$<$:-DH5_USE_116_API>" ) if (H5_HAVE_PARALLEL) target_include_directories (${EXAMPLE_VARNAME}_${example_name} PUBLIC ${MPI_C_INCLUDE_DIRS}) @@ -47,7 +46,6 @@ if (HDF5_VERSION_MAJOR VERSION_GREATER_EQUAL "1.8" AND NOT ${EXAMPLE_VARNAME}_US "$<$:-DH5_USE_110_API>" "$<$:-DH5_USE_112_API>" "$<$:-DH5_USE_114_API>" - "$<$:-DH5_USE_116_API>" ) if (H5_HAVE_PARALLEL) target_include_directories (${EXAMPLE_VARNAME}_${example_name} PUBLIC ${MPI_C_INCLUDE_DIRS}) @@ -74,7 +72,6 @@ endif () # "$<$:-DH5_USE_110_API>" # "$<$:-DH5_USE_112_API>" # "$<$:-DH5_USE_114_API>" -# "$<$:-DH5_USE_116_API>" # ) # if (H5_HAVE_PARALLEL) # target_include_directories (${EXAMPLE_VARNAME}_${example_name} PUBLIC ${MPI_C_INCLUDE_DIRS}) diff --git a/HDF5Examples/C/H5PAR/CMakeLists.txt b/HDF5Examples/C/H5PAR/CMakeLists.txt index 662cd70d295..b6baf4c7e7f 100644 --- a/HDF5Examples/C/H5PAR/CMakeLists.txt +++ b/HDF5Examples/C/H5PAR/CMakeLists.txt @@ -15,7 +15,6 @@ foreach (example_name ${examples}) "$<$:-DH5_USE_110_API>" "$<$:-DH5_USE_112_API>" "$<$:-DH5_USE_114_API>" - "$<$:-DH5_USE_116_API>" ) target_include_directories (${EXAMPLE_VARNAME}_${example_name} PUBLIC ${MPI_C_INCLUDE_DIRS}) target_link_libraries (${EXAMPLE_VARNAME}_${example_name} ${H5EX_HDF5_LINK_LIBS}) diff --git a/HDF5Examples/C/H5T/CMakeLists.txt b/HDF5Examples/C/H5T/CMakeLists.txt index caf612b0d40..f39eb4df116 100644 --- a/HDF5Examples/C/H5T/CMakeLists.txt +++ b/HDF5Examples/C/H5T/CMakeLists.txt @@ -19,7 +19,6 @@ foreach (example_name ${common_examples}) "$<$:-DH5_USE_110_API>" "$<$:-DH5_USE_112_API>" "$<$:-DH5_USE_114_API>" - "$<$:-DH5_USE_116_API>" ) if (H5_HAVE_PARALLEL) target_include_directories (${EXAMPLE_VARNAME}_${example_name} PUBLIC ${MPI_C_INCLUDE_DIRS}) @@ -45,7 +44,6 @@ endforeach () # "$<$:-DH5_USE_110_API>" # "$<$:-DH5_USE_112_API>" # "$<$:-DH5_USE_114_API>" -# "$<$:-DH5_USE_116_API>" # ) # if (H5_HAVE_PARALLEL) # target_include_directories (${EXAMPLE_VARNAME}_${example_name} PUBLIC ${MPI_C_INCLUDE_DIRS}) diff --git a/HDF5Examples/C/H5VDS/CMakeLists.txt b/HDF5Examples/C/H5VDS/CMakeLists.txt index fb3bd000d4f..ee5eecc8504 100644 --- a/HDF5Examples/C/H5VDS/CMakeLists.txt +++ b/HDF5Examples/C/H5VDS/CMakeLists.txt @@ -19,7 +19,6 @@ if (HDF5_VERSION_MAJOR VERSION_GREATER_EQUAL "1.10") "$<$:-DH5_USE_110_API>" "$<$:-DH5_USE_112_API>" "$<$:-DH5_USE_114_API>" - "$<$:-DH5_USE_116_API>" ) if (H5_HAVE_PARALLEL) target_include_directories (${EXAMPLE_VARNAME}_${example_name} PUBLIC ${MPI_C_INCLUDE_DIRS}) diff --git a/HDF5Examples/C/Perf/CMakeLists.txt b/HDF5Examples/C/Perf/CMakeLists.txt index bf66de3f6de..df9d46f2865 100644 --- a/HDF5Examples/C/Perf/CMakeLists.txt +++ b/HDF5Examples/C/Perf/CMakeLists.txt @@ -16,7 +16,6 @@ foreach (example ${examples}) "$<$:-DH5_USE_110_API>" "$<$:-DH5_USE_112_API>" "$<$:-DH5_USE_114_API>" - "$<$:-DH5_USE_116_API>" ) if (H5_HAVE_PARALLEL) target_include_directories (${EXAMPLE_VARNAME}_${example_name} PUBLIC ${MPI_C_INCLUDE_DIRS}) diff --git a/HDF5Examples/C/TUTR/CMakeLists.txt b/HDF5Examples/C/TUTR/CMakeLists.txt index 064db8b75b6..416bb5e365d 100644 --- a/HDF5Examples/C/TUTR/CMakeLists.txt +++ b/HDF5Examples/C/TUTR/CMakeLists.txt @@ -15,7 +15,6 @@ foreach (example_name ${examples}) "$<$:-DH5_USE_110_API>" "$<$:-DH5_USE_112_API>" "$<$:-DH5_USE_114_API>" - "$<$:-DH5_USE_116_API>" ) if (H5_HAVE_PARALLEL) target_include_directories (${EXAMPLE_VARNAME}_tutr_${example_name} PUBLIC ${MPI_C_INCLUDE_DIRS}) diff --git a/HDF5Examples/CXX/H5D/CMakeLists.txt b/HDF5Examples/CXX/H5D/CMakeLists.txt index 32201d6b344..f237311dbdb 100644 --- a/HDF5Examples/CXX/H5D/CMakeLists.txt +++ b/HDF5Examples/CXX/H5D/CMakeLists.txt @@ -16,7 +16,6 @@ if (HDF5_VERSION_MAJOR VERSION_GREATER_EQUAL "1.8") "$<$:-DH5_USE_110_API>" "$<$:-DH5_USE_112_API>" "$<$:-DH5_USE_114_API>" - "$<$:-DH5_USE_116_API>" ) if (H5_HAVE_PARALLEL) target_include_directories (${EXAMPLE_VARNAME}_cpp_ex_${example_name} PUBLIC ${MPI_C_INCLUDE_DIRS}) diff --git a/HDF5Examples/CXX/TUTR/CMakeLists.txt b/HDF5Examples/CXX/TUTR/CMakeLists.txt index 00d6ee6f6f9..3f8d0947643 100644 --- a/HDF5Examples/CXX/TUTR/CMakeLists.txt +++ b/HDF5Examples/CXX/TUTR/CMakeLists.txt @@ -16,7 +16,6 @@ if (HDF5_VERSION_MAJOR VERSION_GREATER_EQUAL "1.8") "$<$:-DH5_USE_110_API>" "$<$:-DH5_USE_112_API>" "$<$:-DH5_USE_114_API>" - "$<$:-DH5_USE_116_API>" ) if (H5_HAVE_PARALLEL) target_include_directories (${EXAMPLE_VARNAME}_cpp_ex_${example_name} PUBLIC ${MPI_C_INCLUDE_DIRS}) diff --git a/HDF5Examples/FORTRAN/H5D/CMakeLists.txt b/HDF5Examples/FORTRAN/H5D/CMakeLists.txt index b784df864a2..b5d202eca17 100644 --- a/HDF5Examples/FORTRAN/H5D/CMakeLists.txt +++ b/HDF5Examples/FORTRAN/H5D/CMakeLists.txt @@ -28,7 +28,6 @@ foreach (example_name ${common_examples}) "$<$:-DH5_USE_110_API>" "$<$:-DH5_USE_112_API>" "$<$:-DH5_USE_114_API>" - "$<$:-DH5_USE_116_API>" ) if (H5_HAVE_PARALLEL) target_include_directories (${EXAMPLE_VARNAME}_f90_${example_name} PUBLIC ${MPI_Fortran_INCLUDE_DIRS}) @@ -73,7 +72,6 @@ if (HDF5_VERSION_MAJOR VERSION_GREATER_EQUAL "1.10") "$<$:-DH5_USE_110_API>" "$<$:-DH5_USE_112_API>" "$<$:-DH5_USE_114_API>" - "$<$:-DH5_USE_116_API>" ) if (H5_HAVE_PARALLEL) target_include_directories (${EXAMPLE_VARNAME}_f90_${example_name} PUBLIC ${MPI_Fortran_INCLUDE_DIRS}) diff --git a/HDF5Examples/FORTRAN/H5G/CMakeLists.txt b/HDF5Examples/FORTRAN/H5G/CMakeLists.txt index 4b85e4eba37..78e2c4fc399 100644 --- a/HDF5Examples/FORTRAN/H5G/CMakeLists.txt +++ b/HDF5Examples/FORTRAN/H5G/CMakeLists.txt @@ -28,7 +28,6 @@ foreach (example_name ${common_examples}) "$<$:-DH5_USE_110_API>" "$<$:-DH5_USE_112_API>" "$<$:-DH5_USE_114_API>" - "$<$:-DH5_USE_116_API>" ) if (H5_HAVE_PARALLEL) target_include_directories (${EXAMPLE_VARNAME}_f90_${example_name} PUBLIC ${MPI_Fortran_INCLUDE_DIRS}) @@ -57,7 +56,6 @@ endforeach () # "$<$:-DH5_USE_110_API>" # "$<$:-DH5_USE_112_API>" # "$<$:-DH5_USE_114_API>" -# "$<$:-DH5_USE_116_API>" # ) # if (H5_HAVE_PARALLEL) # target_include_directories (${EXAMPLE_VARNAME}_f90_${example_name} PUBLIC ${MPI_C_INCLUDE_DIRS}) diff --git a/HDF5Examples/FORTRAN/H5PAR/CMakeLists.txt b/HDF5Examples/FORTRAN/H5PAR/CMakeLists.txt index c8301c78a5e..293af1e3377 100644 --- a/HDF5Examples/FORTRAN/H5PAR/CMakeLists.txt +++ b/HDF5Examples/FORTRAN/H5PAR/CMakeLists.txt @@ -28,7 +28,6 @@ foreach (example_name ${examples}) "$<$:-DH5_USE_110_API>" "$<$:-DH5_USE_112_API>" "$<$:-DH5_USE_114_API>" - "$<$:-DH5_USE_116_API>" ) target_include_directories (${EXAMPLE_VARNAME}_f90_${example_name} PUBLIC ${MPI_Fortran_INCLUDE_DIRS}) target_link_libraries (${EXAMPLE_VARNAME}_f90_${example_name} ${H5EX_LINK_Fortran_LIBS}) diff --git a/HDF5Examples/FORTRAN/H5T/CMakeLists.txt b/HDF5Examples/FORTRAN/H5T/CMakeLists.txt index 63d4dd78b7b..ff7f6459ff0 100644 --- a/HDF5Examples/FORTRAN/H5T/CMakeLists.txt +++ b/HDF5Examples/FORTRAN/H5T/CMakeLists.txt @@ -23,7 +23,6 @@ include (Fortran_sourcefiles.cmake) "$<$:-DH5_USE_110_API>" "$<$:-DH5_USE_112_API>" "$<$:-DH5_USE_114_API>" - "$<$:-DH5_USE_116_API>" ) if (H5_HAVE_PARALLEL) target_include_directories (${EXAMPLE_VARNAME}_f90_${example_name} PUBLIC ${MPI_Fortran_INCLUDE_DIRS}) @@ -50,7 +49,6 @@ foreach (example_name ${common_examples}) "$<$:-DH5_USE_110_API>" "$<$:-DH5_USE_112_API>" "$<$:-DH5_USE_114_API>" - "$<$:-DH5_USE_116_API>" ) if (H5_HAVE_PARALLEL) target_include_directories (${EXAMPLE_VARNAME}_f90_${example_name} PUBLIC ${MPI_Fortran_INCLUDE_DIRS}) diff --git a/HDF5Examples/FORTRAN/TUTR/CMakeLists.txt b/HDF5Examples/FORTRAN/TUTR/CMakeLists.txt index 4b866d4ec17..9d998f258d0 100644 --- a/HDF5Examples/FORTRAN/TUTR/CMakeLists.txt +++ b/HDF5Examples/FORTRAN/TUTR/CMakeLists.txt @@ -23,7 +23,6 @@ include (Fortran_sourcefiles.cmake) "$<$:-DH5_USE_110_API>" "$<$:-DH5_USE_112_API>" "$<$:-DH5_USE_114_API>" - "$<$:-DH5_USE_116_API>" ) if (H5_HAVE_PARALLEL) target_include_directories (${EXAMPLE_VARNAME}_f90_tutr_${example_name} PUBLIC ${MPI_Fortran_INCLUDE_DIRS}) @@ -42,7 +41,6 @@ foreach (example_name ${common_examples}) "$<$:-DH5_USE_110_API>" "$<$:-DH5_USE_112_API>" "$<$:-DH5_USE_114_API>" - "$<$:-DH5_USE_116_API>" ) if (H5_HAVE_PARALLEL) target_include_directories (${EXAMPLE_VARNAME}_f90_tutr_${example_name} PUBLIC ${MPI_Fortran_INCLUDE_DIRS})
Signature: