summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/H5.c4
-rw-r--r--src/H5ACprivate.h18
-rw-r--r--src/H5Dcompact.c106
-rw-r--r--src/H5FD.c56
-rw-r--r--src/H5FDcore.c45
-rw-r--r--src/H5FDcore.h3
-rw-r--r--src/H5FDdevelop.h3
-rw-r--r--src/H5FDdirect.c84
-rw-r--r--src/H5FDdirect.h6
-rw-r--r--src/H5FDfamily.c232
-rw-r--r--src/H5FDfamily.h3
-rw-r--r--src/H5FDhdfs.c3
-rw-r--r--src/H5FDhdfs.h6
-rw-r--r--src/H5FDint.c371
-rw-r--r--src/H5FDlog.c23
-rw-r--r--src/H5FDlog.h3
-rw-r--r--src/H5FDmirror.c3
-rw-r--r--src/H5FDmirror.h3
-rw-r--r--src/H5FDmpio.c63
-rw-r--r--src/H5FDmulti.c432
-rw-r--r--src/H5FDprivate.h28
-rw-r--r--src/H5FDpublic.h67
-rw-r--r--src/H5FDros3.c3
-rw-r--r--src/H5FDros3.h6
-rw-r--r--src/H5FDsec2.c5
-rw-r--r--src/H5FDsec2.h3
-rw-r--r--src/H5FDsplitter.c355
-rw-r--r--src/H5FDsplitter.h3
-rw-r--r--src/H5FDstdio.c3
-rw-r--r--src/H5FDwindows.c2
-rw-r--r--src/H5Fint.c17
-rw-r--r--src/H5Fprivate.h5
-rw-r--r--src/H5Fquery.c23
-rw-r--r--src/H5Gprivate.h2
-rw-r--r--src/H5PLint.c65
-rw-r--r--src/H5PLpath.c29
-rw-r--r--src/H5PLplugin_cache.c140
-rw-r--r--src/H5PLprivate.h31
-rw-r--r--src/H5PLpublic.h6
-rw-r--r--src/H5Pfapl.c567
-rw-r--r--src/H5Pint.c74
-rw-r--r--src/H5Ppkg.h3
-rw-r--r--src/H5Pprivate.h13
-rw-r--r--src/H5Ppublic.h79
-rw-r--r--src/H5Tconv.c4
-rw-r--r--src/H5Tprivate.h6
-rw-r--r--src/H5VLcallback.c29
-rw-r--r--src/H5VLint.c70
-rw-r--r--src/H5public.h56
-rw-r--r--src/H5trace.c59
50 files changed, 2723 insertions, 497 deletions
diff --git a/src/H5.c b/src/H5.c
index d1c46b9..af090fd 100644
--- a/src/H5.c
+++ b/src/H5.c
@@ -264,7 +264,7 @@ H5_init_library(void)
HGOTO_ERROR(H5E_FUNC, H5E_CANTINIT, FAIL, "unable to initialize error interface")
if (H5VL_init_phase1() < 0)
HGOTO_ERROR(H5E_FUNC, H5E_CANTINIT, FAIL, "unable to initialize vol interface")
- if (H5P_init() < 0)
+ if (H5P_init_phase1() < 0)
HGOTO_ERROR(H5E_FUNC, H5E_CANTINIT, FAIL, "unable to initialize property list interface")
if (H5AC_init() < 0)
HGOTO_ERROR(H5E_FUNC, H5E_CANTINIT, FAIL, "unable to initialize metadata caching interface")
@@ -276,6 +276,8 @@ H5_init_library(void)
HGOTO_ERROR(H5E_FUNC, H5E_CANTINIT, FAIL, "unable to initialize dataspace interface")
/* Finish initializing interfaces that depend on the interfaces above */
+ if (H5P_init_phase2() < 0)
+ HGOTO_ERROR(H5E_FUNC, H5E_CANTINIT, FAIL, "unable to initialize property list interface")
if (H5VL_init_phase2() < 0)
HGOTO_ERROR(H5E_FUNC, H5E_CANTINIT, FAIL, "unable to initialize vol interface")
diff --git a/src/H5ACprivate.h b/src/H5ACprivate.h
index e9b8a47..d252d85 100644
--- a/src/H5ACprivate.h
+++ b/src/H5ACprivate.h
@@ -234,27 +234,27 @@ typedef struct H5AC_proxy_entry_t {
/* hbool_t evictions_enabled = */ TRUE, \
/* hbool_t set_initial_size = */ TRUE, \
/* size_t initial_size = */ ( 2 * 1024 * 1024), \
- /* double min_clean_fraction = */ 0.3f, \
+ /* double min_clean_fraction = */ 0.3, \
/* size_t max_size = */ (32 * 1024 * 1024), \
/* size_t min_size = */ (1 * 1024 * 1024), \
/* long int epoch_length = */ 50000, \
/* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold, \
- /* double lower_hr_threshold = */ 0.9f, \
- /* double increment = */ 2.0f, \
+ /* double lower_hr_threshold = */ 0.9, \
+ /* double increment = */ 2.0, \
/* hbool_t apply_max_increment = */ TRUE, \
/* size_t max_increment = */ (4 * 1024 * 1024), \
/* enum H5C_cache_flash_incr_mode */ \
/* flash_incr_mode = */ H5C_flash_incr__add_space, \
- /* double flash_multiple = */ 1.0f, \
- /* double flash_threshold = */ 0.25f, \
+ /* double flash_multiple = */ 1.0, \
+ /* double flash_threshold = */ 0.25, \
/* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__age_out_with_threshold, \
- /* double upper_hr_threshold = */ 0.999f, \
- /* double decrement = */ 0.9f, \
+ /* double upper_hr_threshold = */ 0.999, \
+ /* double decrement = */ 0.9, \
/* hbool_t apply_max_decrement = */ TRUE, \
/* size_t max_decrement = */ (1 * 1024 * 1024), \
/* int epochs_before_eviction = */ 3, \
/* hbool_t apply_empty_reserve = */ TRUE, \
- /* double empty_reserve = */ 0.1f, \
+ /* double empty_reserve = */ 0.1, \
/* size_t dirty_bytes_threshold = */ (256 * 1024), \
/* int metadata_write_strategy = */ \
H5AC__DEFAULT_METADATA_WRITE_STRATEGY \
@@ -270,7 +270,7 @@ typedef struct H5AC_proxy_entry_t {
/* hbool_t evictions_enabled = */ TRUE, \
/* hbool_t set_initial_size = */ TRUE, \
/* size_t initial_size = */ ( 2 * 1024 * 1024), \
- /* double min_clean_fraction = */ 0.01f, \
+ /* double min_clean_fraction = */ 0.01, \
/* size_t max_size = */ (32 * 1024 * 1024), \
/* size_t min_size = */ ( 1 * 1024 * 1024), \
/* long int epoch_length = */ 50000, \
diff --git a/src/H5Dcompact.c b/src/H5Dcompact.c
index f68a93a..c79bae0 100644
--- a/src/H5Dcompact.c
+++ b/src/H5Dcompact.c
@@ -47,6 +47,15 @@
/* Local Typedefs */
/******************/
+/* Callback info for I/O operation when file driver
+ * wishes to do its own memory management
+ */
+typedef struct H5D_compact_iovv_memmanage_ud_t {
+ H5F_shared_t *f_sh; /* Shared file for dataset */
+ void * dstbuf; /* Pointer to buffer to be read into/written into */
+ const void * srcbuf; /* Pointer to buffer to be read from/written from */
+} H5D_compact_iovv_memmanage_ud_t;
+
/********************/
/* Local Prototypes */
/********************/
@@ -56,6 +65,7 @@ static herr_t H5D__compact_construct(H5F_t *f, H5D_t *dset);
static hbool_t H5D__compact_is_space_alloc(const H5O_storage_t *storage);
static herr_t H5D__compact_io_init(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_t nelmts,
const H5S_t *file_space, const H5S_t *mem_space, H5D_chunk_map_t *cm);
+static herr_t H5D__compact_iovv_memmanage_cb(hsize_t dst_off, hsize_t src_off, size_t len, void *_udata);
static ssize_t H5D__compact_readvv(const H5D_io_info_t *io_info, size_t dset_max_nseq, size_t *dset_curr_seq,
size_t dset_size_arr[], hsize_t dset_offset_arr[], size_t mem_max_nseq,
size_t *mem_curr_seq, size_t mem_size_arr[], hsize_t mem_offset_arr[]);
@@ -239,6 +249,48 @@ H5D__compact_io_init(H5D_io_info_t *io_info, const H5D_type_info_t H5_ATTR_UNUSE
} /* end H5D__compact_io_init() */
/*-------------------------------------------------------------------------
+ * Function: H5D__compact_iovv_memmanage_cb
+ *
+ * Purpose: Callback operator for H5D__compact_readvv()/_writevv() to
+ * send a memory copy request to the underlying file driver.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5D__compact_iovv_memmanage_cb(hsize_t dst_off, hsize_t src_off, size_t len, void *_udata)
+{
+ H5D_compact_iovv_memmanage_ud_t *udata = (H5D_compact_iovv_memmanage_ud_t *)_udata;
+ H5FD_ctl_memcpy_args_t op_args;
+ uint64_t op_flags;
+ H5FD_t * file_handle = NULL;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_STATIC
+
+ /* Retrieve pointer to file driver structure for ctl call */
+ if (H5F_shared_get_file_driver(udata->f_sh, &file_handle) < 0)
+ HGOTO_ERROR(H5E_IO, H5E_CANTGET, FAIL, "can't get file handle")
+
+ /* Setup operation flags and arguments */
+ op_flags = H5FD_CTL__ROUTE_TO_TERMINAL_VFD_FLAG | H5FD_CTL__FAIL_IF_UNKNOWN_FLAG;
+
+ op_args.dstbuf = udata->dstbuf;
+ op_args.dst_off = dst_off;
+ op_args.srcbuf = udata->srcbuf;
+ op_args.src_off = src_off;
+ op_args.len = len;
+
+ /* Make request to file driver */
+ if (H5FD_ctl(file_handle, H5FD_CTL__MEM_COPY, op_flags, &op_args, NULL) < 0)
+ HGOTO_ERROR(H5E_IO, H5E_FCNTL, FAIL, "VFD memcpy request failed")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5D__compact_iovv_memmanage_cb() */
+
+/*-------------------------------------------------------------------------
* Function: H5D__compact_readvv
*
* Purpose: Reads some data vectors from a dataset into a buffer.
@@ -267,11 +319,28 @@ H5D__compact_readvv(const H5D_io_info_t *io_info, size_t dset_max_nseq, size_t *
HDassert(io_info);
- /* Use the vectorized memory copy routine to do actual work */
- if ((ret_value = H5VM_memcpyvv(io_info->u.rbuf, mem_max_nseq, mem_curr_seq, mem_size_arr, mem_offset_arr,
- io_info->store->compact.buf, dset_max_nseq, dset_curr_seq, dset_size_arr,
- dset_offset_arr)) < 0)
- HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "vectorized memcpy failed")
+ /* Check if file driver wishes to do its own memory management */
+ if (H5F_SHARED_HAS_FEATURE(io_info->f_sh, H5FD_FEAT_MEMMANAGE)) {
+ H5D_compact_iovv_memmanage_ud_t udata;
+
+ /* Set up udata for memory copy operation */
+ udata.f_sh = io_info->f_sh;
+ udata.dstbuf = io_info->u.rbuf;
+ udata.srcbuf = io_info->store->compact.buf;
+
+ /* Request that file driver does the memory copy */
+ if ((ret_value = H5VM_opvv(mem_max_nseq, mem_curr_seq, mem_size_arr, mem_offset_arr, dset_max_nseq,
+ dset_curr_seq, dset_size_arr, dset_offset_arr,
+ H5D__compact_iovv_memmanage_cb, &udata)) < 0)
+ HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "vectorized memcpy failed")
+ }
+ else {
+ /* Use the vectorized memory copy routine to do actual work */
+ if ((ret_value = H5VM_memcpyvv(io_info->u.rbuf, mem_max_nseq, mem_curr_seq, mem_size_arr,
+ mem_offset_arr, io_info->store->compact.buf, dset_max_nseq,
+ dset_curr_seq, dset_size_arr, dset_offset_arr)) < 0)
+ HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "vectorized memcpy failed")
+ }
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -309,11 +378,28 @@ H5D__compact_writevv(const H5D_io_info_t *io_info, size_t dset_max_nseq, size_t
HDassert(io_info);
- /* Use the vectorized memory copy routine to do actual work */
- if ((ret_value = H5VM_memcpyvv(io_info->store->compact.buf, dset_max_nseq, dset_curr_seq, dset_size_arr,
- dset_offset_arr, io_info->u.wbuf, mem_max_nseq, mem_curr_seq, mem_size_arr,
- mem_offset_arr)) < 0)
- HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "vectorized memcpy failed")
+ /* Check if file driver wishes to do its own memory management */
+ if (H5F_SHARED_HAS_FEATURE(io_info->f_sh, H5FD_FEAT_MEMMANAGE)) {
+ H5D_compact_iovv_memmanage_ud_t udata;
+
+ /* Set up udata for memory copy operation */
+ udata.f_sh = io_info->f_sh;
+ udata.dstbuf = io_info->store->compact.buf;
+ udata.srcbuf = io_info->u.wbuf;
+
+ /* Request that file driver does the memory copy */
+ if ((ret_value = H5VM_opvv(dset_max_nseq, dset_curr_seq, dset_size_arr, dset_offset_arr, mem_max_nseq,
+ mem_curr_seq, mem_size_arr, mem_offset_arr, H5D__compact_iovv_memmanage_cb,
+ &udata)) < 0)
+ HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "vectorized memcpy failed")
+ }
+ else {
+ /* Use the vectorized memory copy routine to do actual work */
+ if ((ret_value = H5VM_memcpyvv(io_info->store->compact.buf, dset_max_nseq, dset_curr_seq,
+ dset_size_arr, dset_offset_arr, io_info->u.wbuf, mem_max_nseq,
+ mem_curr_seq, mem_size_arr, mem_offset_arr)) < 0)
+ HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "vectorized memcpy failed")
+ }
/* Mark the compact dataset's buffer as dirty */
*io_info->store->compact.dirty = TRUE;
diff --git a/src/H5FD.c b/src/H5FD.c
index 11071d1..940b628 100644
--- a/src/H5FD.c
+++ b/src/H5FD.c
@@ -301,6 +301,62 @@ done:
} /* end H5FD_register() */
/*-------------------------------------------------------------------------
+ * Function: H5FDis_driver_registered_by_name
+ *
+ * Purpose: Tests whether a VFD class has been registered or not
+ * according to a supplied driver name.
+ *
+ * Return: >0 if a VFD with that name has been registered
+ * 0 if a VFD with that name has NOT been registered
+ * <0 on errors
+ *
+ *-------------------------------------------------------------------------
+ */
+htri_t
+H5FDis_driver_registered_by_name(const char *driver_name)
+{
+ htri_t ret_value = FALSE; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE1("t", "*s", driver_name);
+
+ /* Check if driver with this name is registered */
+ if ((ret_value = H5FD_is_driver_registered_by_name(driver_name, NULL)) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't check if VFD is registered")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5FDis_driver_registered_by_name() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5FDis_driver_registered_by_value
+ *
+ * Purpose: Tests whether a VFD class has been registered or not
+ * according to a supplied driver value (ID).
+ *
+ * Return: >0 if a VFD with that value has been registered
+ * 0 if a VFD with that value hasn't been registered
+ * <0 on errors
+ *
+ *-------------------------------------------------------------------------
+ */
+htri_t
+H5FDis_driver_registered_by_value(H5FD_class_value_t driver_value)
+{
+ htri_t ret_value = FALSE;
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE1("t", "DV", driver_value);
+
+ /* Check if driver with this value is registered */
+ if ((ret_value = H5FD_is_driver_registered_by_value(driver_value, NULL)) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't check if VFD is registered")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5FDis_driver_registered_by_value() */
+
+/*-------------------------------------------------------------------------
* Function: H5FDunregister
*
* Purpose: Removes a driver ID from the library. This in no way affects
diff --git a/src/H5FDcore.c b/src/H5FDcore.c
index 9bf49ce..7ae89c6 100644
--- a/src/H5FDcore.c
+++ b/src/H5FDcore.c
@@ -149,8 +149,10 @@ static herr_t H5FD__core_truncate(H5FD_t *_file, hid_t dxpl_id, hbool_t closing
static herr_t H5FD__core_lock(H5FD_t *_file, hbool_t rw);
static herr_t H5FD__core_unlock(H5FD_t *_file);
static herr_t H5FD__core_delete(const char *filename, hid_t fapl_id);
+static inline const H5FD_core_fapl_t *H5FD__core_get_default_config(void);
static const H5FD_class_t H5FD_core_g = {
+ H5FD_CORE_VALUE, /* value */
"core", /* name */
MAXADDR, /* maxaddr */
H5F_CLOSE_WEAK, /* fc_degree */
@@ -191,6 +193,11 @@ static const H5FD_class_t H5FD_core_g = {
H5FD_FLMAP_DICHOTOMY /* fl_map */
};
+/* Default configurations, if none provided */
+static const H5FD_core_fapl_t H5FD_core_default_config_g = {H5_MB, TRUE, H5FD_CORE_WRITE_TRACKING_FLAG,
+ H5FD_CORE_WRITE_TRACKING_PAGE_SIZE};
+static const H5FD_core_fapl_t H5FD_core_default_paged_config_g = {H5_MB, TRUE, TRUE, (size_t)4096};
+
/* Define a free list to manage the region type */
H5FL_DEFINE(H5FD_core_region_t);
@@ -413,6 +420,32 @@ done:
} /* end H5FD__core_write_to_bstore() */
/*-------------------------------------------------------------------------
+ * Function: H5FD__core_get_default_config
+ *
+ * Purpose: Retrieves a default configuration for this VFD when no
+ * configuration information has been provided.
+ *
+ * Return: Valid Core VFD configuration information pointer (can't
+ * fail)
+ *
+ *-------------------------------------------------------------------------
+ */
+static inline const H5FD_core_fapl_t *
+H5FD__core_get_default_config(void)
+{
+ char *driver = HDgetenv(HDF5_DRIVER);
+
+ if (driver) {
+ if (!HDstrcmp(driver, "core"))
+ return &H5FD_core_default_config_g;
+ else if (!HDstrcmp(driver, "core_paged"))
+ return &H5FD_core_default_paged_config_g;
+ }
+
+ return &H5FD_core_default_config_g;
+} /* end H5FD__core_get_default_config() */
+
+/*-------------------------------------------------------------------------
* Function: H5FD__init_package
*
* Purpose: Initializes any interface-specific data or routines.
@@ -430,7 +463,7 @@ H5FD__init_package(void)
FUNC_ENTER_STATIC
/* Check the use disabled file locks environment variable */
- lock_env_var = HDgetenv("HDF5_USE_FILE_LOCKING");
+ lock_env_var = HDgetenv(HDF5_USE_FILE_LOCKING);
if (lock_env_var && !HDstrcmp(lock_env_var, "BEST_EFFORT"))
ignore_disabled_file_locks_s = TRUE; /* Override: Ignore disabled locks */
else if (lock_env_var && (!HDstrcmp(lock_env_var, "TRUE") || !HDstrcmp(lock_env_var, "1")))
@@ -533,7 +566,7 @@ H5Pset_core_write_tracking(hid_t plist_id, hbool_t is_enabled, size_t page_size)
if (H5FD_CORE != H5P_peek_driver(plist))
HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "incorrect VFL driver")
if (NULL == (old_fa = (const H5FD_core_fapl_t *)H5P_peek_driver_info(plist)))
- HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "bad VFL driver info")
+ old_fa = H5FD__core_get_default_config();
/* Set VFD info values */
HDmemset(&fa, 0, sizeof(H5FD_core_fapl_t));
@@ -543,7 +576,7 @@ H5Pset_core_write_tracking(hid_t plist_id, hbool_t is_enabled, size_t page_size)
fa.page_size = page_size;
/* Set the property values & the driver for the FAPL */
- if (H5P_set_driver(plist, H5FD_CORE, &fa) < 0)
+ if (H5P_set_driver(plist, H5FD_CORE, &fa, NULL) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set core VFD as driver")
done:
@@ -627,7 +660,7 @@ H5Pset_fapl_core(hid_t fapl_id, size_t increment, hbool_t backing_store)
fa.page_size = H5FD_CORE_WRITE_TRACKING_PAGE_SIZE;
/* Set the property values & the driver for the FAPL */
- if (H5P_set_driver(plist, H5FD_CORE, &fa) < 0)
+ if (H5P_set_driver(plist, H5FD_CORE, &fa, NULL) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set core VFD as driver")
done:
@@ -752,7 +785,7 @@ H5FD__core_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr
if (NULL == (plist = (H5P_genplist_t *)H5I_object(fapl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file access property list")
if (NULL == (fa = (const H5FD_core_fapl_t *)H5P_peek_driver_info(plist)))
- HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, NULL, "bad VFL driver info")
+ fa = H5FD__core_get_default_config();
/* Build the open flags */
o_flags = (H5F_ACC_RDWR & flags) ? O_RDWR : O_RDONLY;
@@ -1739,7 +1772,7 @@ H5FD__core_delete(const char *filename, hid_t fapl_id)
if (NULL == (plist = (H5P_genplist_t *)H5I_object(fapl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list")
if (NULL == (fa = (const H5FD_core_fapl_t *)H5P_peek_driver_info(plist)))
- HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "bad VFL driver info")
+ fa = H5FD__core_get_default_config();
if (fa->backing_store)
if (HDremove(filename) < 0)
diff --git a/src/H5FDcore.h b/src/H5FDcore.h
index d456c3e..590478e 100644
--- a/src/H5FDcore.h
+++ b/src/H5FDcore.h
@@ -20,7 +20,8 @@
#ifndef H5FDcore_H
#define H5FDcore_H
-#define H5FD_CORE (H5FD_core_init())
+#define H5FD_CORE (H5FD_core_init())
+#define H5FD_CORE_VALUE H5_VFD_CORE
#ifdef __cplusplus
extern "C" {
diff --git a/src/H5FDdevelop.h b/src/H5FDdevelop.h
index bbfb8af..9b31fae 100644
--- a/src/H5FDdevelop.h
+++ b/src/H5FDdevelop.h
@@ -160,6 +160,7 @@ typedef struct H5FD_t H5FD_t;
/* Class information for each file driver */
typedef struct H5FD_class_t {
+ H5FD_class_value_t value;
const char * name;
haddr_t maxaddr;
H5F_close_degree_t fc_degree;
@@ -245,6 +246,8 @@ extern "C" {
#endif
H5_DLL hid_t H5FDregister(const H5FD_class_t *cls);
+H5_DLL htri_t H5FDis_driver_registered_by_name(const char *driver_name);
+H5_DLL htri_t H5FDis_driver_registered_by_value(H5FD_class_value_t driver_value);
H5_DLL herr_t H5FDunregister(hid_t driver_id);
H5_DLL H5FD_t *H5FDopen(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr);
H5_DLL herr_t H5FDclose(H5FD_t *file);
diff --git a/src/H5FDdirect.c b/src/H5FDdirect.c
index 869dc37..81d311f 100644
--- a/src/H5FDdirect.c
+++ b/src/H5FDdirect.c
@@ -120,6 +120,8 @@ typedef struct H5FD_direct_t {
/* Prototypes */
static herr_t H5FD__direct_term(void);
+static herr_t H5FD__direct_populate_config(size_t boundary, size_t block_size, size_t cbuf_size,
+ H5FD_direct_fapl_t *fa_out);
static void * H5FD__direct_fapl_get(H5FD_t *file);
static void * H5FD__direct_fapl_copy(const void *_old_fa);
static H5FD_t *H5FD__direct_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr);
@@ -140,6 +142,7 @@ static herr_t H5FD__direct_unlock(H5FD_t *_file);
static herr_t H5FD__direct_delete(const char *filename, hid_t fapl_id);
static const H5FD_class_t H5FD_direct_g = {
+ H5FD_DIRECT_VALUE, /* value */
"direct", /* name */
MAXADDR, /* maxaddr */
H5F_CLOSE_WEAK, /* fc_degree */
@@ -204,7 +207,7 @@ H5FD__init_package(void)
FUNC_ENTER_STATIC
/* Check the use disabled file locks environment variable */
- lock_env_var = HDgetenv("HDF5_USE_FILE_LOCKING");
+ lock_env_var = HDgetenv(HDF5_USE_FILE_LOCKING);
if (lock_env_var && !HDstrcmp(lock_env_var, "BEST_EFFORT"))
ignore_disabled_file_locks_s = TRUE; /* Override: Ignore disabled locks */
else if (lock_env_var && (!HDstrcmp(lock_env_var, "TRUE") || !HDstrcmp(lock_env_var, "1")))
@@ -300,28 +303,10 @@ H5Pset_fapl_direct(hid_t fapl_id, size_t boundary, size_t block_size, size_t cbu
if (NULL == (plist = H5P_object_verify(fapl_id, H5P_FILE_ACCESS)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list")
- HDmemset(&fa, 0, sizeof(H5FD_direct_fapl_t));
- if (boundary != 0)
- fa.mboundary = boundary;
- else
- fa.mboundary = MBOUNDARY_DEF;
- if (block_size != 0)
- fa.fbsize = block_size;
- else
- fa.fbsize = FBSIZE_DEF;
- if (cbuf_size != 0)
- fa.cbsize = cbuf_size;
- else
- fa.cbsize = CBSIZE_DEF;
-
- /* Set the default to be true for data alignment */
- fa.must_align = TRUE;
-
- /* Copy buffer size must be a multiple of file block size */
- if (fa.cbsize % fa.fbsize != 0)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "copy buffer size must be a multiple of block size")
+ if (H5FD__direct_populate_config(boundary, block_size, cbuf_size, &fa) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTSET, FAIL, "can't initialize driver configuration info")
- ret_value = H5P_set_driver(plist, H5FD_DIRECT, &fa);
+ ret_value = H5P_set_driver(plist, H5FD_DIRECT, &fa, NULL);
done:
FUNC_LEAVE_API(ret_value)
@@ -371,6 +356,53 @@ done:
} /* end H5Pget_fapl_direct() */
/*-------------------------------------------------------------------------
+ * Function: H5FD__direct_populate_config
+ *
+ * Purpose: Populates a H5FD_direct_fapl_t structure with the provided
+ * values, supplying defaults where values are not provided.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5FD__direct_populate_config(size_t boundary, size_t block_size, size_t cbuf_size, H5FD_direct_fapl_t *fa_out)
+{
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_STATIC
+
+ HDassert(fa_out);
+
+ HDmemset(fa_out, 0, sizeof(H5FD_direct_fapl_t));
+
+ if (boundary != 0)
+ fa_out->mboundary = boundary;
+ else
+ fa_out->mboundary = MBOUNDARY_DEF;
+
+ if (block_size != 0)
+ fa_out->fbsize = block_size;
+ else
+ fa_out->fbsize = FBSIZE_DEF;
+
+ if (cbuf_size != 0)
+ fa_out->cbsize = cbuf_size;
+ else
+ fa_out->cbsize = CBSIZE_DEF;
+
+ /* Set the default to be true for data alignment */
+ fa_out->must_align = TRUE;
+
+ /* Copy buffer size must be a multiple of file block size */
+ if (fa_out->cbsize % fa_out->fbsize != 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "copy buffer size must be a multiple of block size")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5FD__direct_populate_config() */
+
+/*-------------------------------------------------------------------------
* Function: H5FD__direct_fapl_get
*
* Purpose: Returns a file access property list which indicates how the
@@ -454,6 +486,7 @@ H5FD__direct_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxad
int fd = (-1);
H5FD_direct_t * file = NULL;
const H5FD_direct_fapl_t *fa;
+ H5FD_direct_fapl_t default_fa;
#ifdef H5_HAVE_WIN32_API
HFILE filehandle;
struct _BY_HANDLE_FILE_INFORMATION fileinfo;
@@ -502,8 +535,11 @@ H5FD__direct_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxad
/* Get the driver specific information */
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 (NULL == (fa = (const H5FD_direct_fapl_t *)H5P_peek_driver_info(plist)))
- HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, NULL, "bad VFL driver info")
+ if (NULL == (fa = (const H5FD_direct_fapl_t *)H5P_peek_driver_info(plist))) {
+ if (H5FD__direct_populate_config(0, 0, 0, &default_fa) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTSET, NULL, "can't initialize driver configuration info")
+ fa = &default_fa;
+ }
file->fd = fd;
H5_CHECKED_ASSIGN(file->eof, haddr_t, sb.st_size, h5_stat_size_t);
diff --git a/src/H5FDdirect.h b/src/H5FDdirect.h
index f06de7f..a439e55 100644
--- a/src/H5FDdirect.h
+++ b/src/H5FDdirect.h
@@ -21,9 +21,11 @@
#define H5FDdirect_H
#ifdef H5_HAVE_DIRECT
-#define H5FD_DIRECT (H5FD_direct_init())
+#define H5FD_DIRECT (H5FD_direct_init())
+#define H5FD_DIRECT_VALUE H5_VFD_DIRECT
#else
-#define H5FD_DIRECT (H5I_INVALID_HID)
+#define H5FD_DIRECT (H5I_INVALID_HID)
+#define H5FD_DIRECT_VALUE H5_VFD_INVALID
#endif /* H5_HAVE_DIRECT */
#ifdef H5_HAVE_DIRECT
diff --git a/src/H5FDfamily.c b/src/H5FDfamily.c
index e45b52e..a1a90d8 100644
--- a/src/H5FDfamily.c
+++ b/src/H5FDfamily.c
@@ -47,6 +47,9 @@
/* The size of the member name buffers */
#define H5FD_FAM_MEMB_NAME_BUF_SIZE 4096
+/* Default member size - 100 MiB */
+#define H5FD_FAM_DEF_MEM_SIZE ((hsize_t)(100 * H5_MB))
+
/* The driver identification number, initialized at runtime */
static hid_t H5FD_FAMILY_g = 0;
@@ -77,6 +80,10 @@ typedef struct H5FD_family_fapl_t {
hid_t memb_fapl_id; /*file access property list of each memb*/
} H5FD_family_fapl_t;
+/* Private routines */
+static herr_t H5FD__family_get_default_config(H5FD_family_fapl_t *fa_out);
+static char * H5FD__family_get_default_printf_filename(const char *old_filename);
+
/* Callback prototypes */
static herr_t H5FD__family_term(void);
static void * H5FD__family_fapl_get(H5FD_t *_file);
@@ -105,6 +112,7 @@ static herr_t H5FD__family_delete(const char *filename, hid_t fapl_id);
/* The class struct */
static const H5FD_class_t H5FD_family_g = {
+ H5FD_FAMILY_VALUE, /* value */
"family", /* name */
HADDR_MAX, /* maxaddr */
H5F_CLOSE_WEAK, /* fc_degree */
@@ -145,6 +153,122 @@ static const H5FD_class_t H5FD_family_g = {
H5FD_FLMAP_DICHOTOMY /* fl_map */
};
+/*-------------------------------------------------------------------------
+ * Function: H5FD__family_get_default_config
+ *
+ * Purpose: Populates a H5FD_family_fapl_t structure with default
+ * values.
+ *
+ * Return: Non-negative on Success/Negative on Failure
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5FD__family_get_default_config(H5FD_family_fapl_t *fa_out)
+{
+ H5P_genplist_t *def_plist;
+ H5P_genplist_t *plist;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_STATIC
+
+ HDassert(fa_out);
+
+ fa_out->memb_size = H5FD_FAM_DEF_MEM_SIZE;
+
+ /* Use copy of default file access property list for member FAPL ID.
+ * The Sec2 driver is explicitly set on the member FAPL ID, as the
+ * default driver might have been replaced with the Family VFD, which
+ * would cause recursion badness in the child members.
+ */
+ if (NULL == (def_plist = (H5P_genplist_t *)H5I_object(H5P_FILE_ACCESS_DEFAULT)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list")
+ if ((fa_out->memb_fapl_id = H5P_copy_plist(def_plist, FALSE)) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTCOPY, FAIL, "can't copy property list")
+ if (NULL == (plist = (H5P_genplist_t *)H5I_object(fa_out->memb_fapl_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list")
+ if (H5P_set_driver_by_value(plist, H5_VFD_SEC2, NULL, TRUE) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTSET, FAIL, "can't set default driver on member FAPL")
+
+done:
+ if (ret_value < 0 && fa_out->memb_fapl_id >= 0) {
+ if (H5I_dec_ref(fa_out->memb_fapl_id) < 0)
+ HDONE_ERROR(H5E_VFL, H5E_CANTDEC, FAIL, "can't decrement ref. count on member FAPL ID")
+ }
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5FD__family_get_default_config() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5FD__family_get_default_printf_filename
+ *
+ * Purpose: Given a filename, allocates and returns a new filename
+ * buffer that contains the given filename modified into this
+ * VFD's printf-style format. For example, the filename
+ * "file1.h5" would be modified to "file1-%06d.h5". This would
+ * allow for member filenames such as "file1-000000.h5",
+ * "file1-000001.h5", etc. The caller is responsible for
+ * freeing the returned buffer.
+ *
+ * Return: Non-negative on Success/Negative on Failure
+ *
+ *-------------------------------------------------------------------------
+ */
+static char *
+H5FD__family_get_default_printf_filename(const char *old_filename)
+{
+ const char *suffix = "-%06d";
+ size_t old_filename_len = 0;
+ size_t new_filename_len = 0;
+ char * file_extension = NULL;
+ char * tmp_buffer = NULL;
+ char * ret_value = NULL;
+
+ FUNC_ENTER_STATIC
+
+ HDassert(old_filename);
+
+ old_filename_len = HDstrlen(old_filename);
+ if (0 == old_filename_len)
+ HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, NULL, "invalid filename")
+
+ new_filename_len = old_filename_len + HDstrlen(suffix) + 1;
+ if (NULL == (tmp_buffer = H5MM_malloc(new_filename_len)))
+ HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, NULL, "can't allocate new filename buffer")
+
+ /* Determine if filename contains a ".h5" extension. */
+ if ((file_extension = strstr(old_filename, ".h5"))) {
+ /* Insert the printf format between the filename and ".h5" extension. */
+ HDstrcpy(tmp_buffer, old_filename);
+ file_extension = strstr(tmp_buffer, ".h5");
+ HDsprintf(file_extension, "%s%s", suffix, ".h5");
+ }
+ else if ((file_extension = strrchr(old_filename, '.'))) {
+ char *new_extension_loc = NULL;
+
+ /* If the filename doesn't contain a ".h5" extension, but contains
+ * AN extension, just insert the printf format before that extension.
+ */
+ HDstrcpy(tmp_buffer, old_filename);
+ new_extension_loc = strrchr(tmp_buffer, '.');
+ HDsprintf(new_extension_loc, "%s%s", suffix, file_extension);
+ }
+ else {
+ /* If the filename doesn't contain an extension at all, just insert
+ * the printf format at the end of the filename.
+ */
+ HDsnprintf(tmp_buffer, new_filename_len, "%s%s", old_filename, suffix);
+ }
+
+ ret_value = tmp_buffer;
+
+done:
+ if (!ret_value)
+ H5MM_xfree(tmp_buffer);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5FD__family_get_default_printf_filename() */
+
/*--------------------------------------------------------------------------
NAME
H5FD__init_package -- Initialize interface-specific information
@@ -247,7 +371,7 @@ herr_t
H5Pset_fapl_family(hid_t fapl_id, hsize_t msize, hid_t memb_fapl_id)
{
herr_t ret_value;
- H5FD_family_fapl_t fa = {0, -1};
+ H5FD_family_fapl_t fa = {0, H5I_INVALID_HID};
H5P_genplist_t * plist; /* Property list pointer */
FUNC_ENTER_API(FAIL)
@@ -256,18 +380,22 @@ H5Pset_fapl_family(hid_t fapl_id, hsize_t msize, hid_t memb_fapl_id)
/* Check arguments */
if (TRUE != H5P_isa_class(fapl_id, H5P_FILE_ACCESS))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list")
- if (H5P_DEFAULT == memb_fapl_id)
- memb_fapl_id = H5P_FILE_ACCESS_DEFAULT;
+ if (H5P_DEFAULT == memb_fapl_id) {
+ /* Get default configuration for member FAPL */
+ if (H5FD__family_get_default_config(&fa) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get default driver configuration info")
+ }
else if (TRUE != H5P_isa_class(memb_fapl_id, H5P_FILE_ACCESS))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access list")
/* Initialize driver specific information. */
- fa.memb_size = msize;
- fa.memb_fapl_id = memb_fapl_id;
+ fa.memb_size = msize;
+ if (H5P_DEFAULT != memb_fapl_id)
+ fa.memb_fapl_id = memb_fapl_id;
if (NULL == (plist = (H5P_genplist_t *)H5I_object(fapl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list")
- ret_value = H5P_set_driver(plist, H5FD_FAMILY, &fa);
+ ret_value = H5P_set_driver(plist, H5FD_FAMILY, &fa, NULL);
done:
FUNC_LEAVE_API(ret_value)
@@ -593,9 +721,10 @@ H5FD__family_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxad
{
H5FD_family_t *file = NULL;
char * memb_name = NULL, *temp = NULL;
- hsize_t eof = HADDR_UNDEF;
- unsigned t_flags = flags & ~H5F_ACC_CREAT;
- H5FD_t * ret_value = NULL;
+ hsize_t eof = HADDR_UNDEF;
+ hbool_t default_config = FALSE;
+ unsigned t_flags = flags & ~H5F_ACC_CREAT;
+ H5FD_t * ret_value = NULL;
FUNC_ENTER_STATIC
@@ -609,21 +738,32 @@ H5FD__family_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxad
if (NULL == (file = (H5FD_family_t *)H5MM_calloc(sizeof(H5FD_family_t))))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "unable to allocate file struct")
if (H5P_FILE_ACCESS_DEFAULT == fapl_id) {
- file->memb_fapl_id = H5P_FILE_ACCESS_DEFAULT;
- if (H5I_inc_ref(file->memb_fapl_id, FALSE) < 0)
- HGOTO_ERROR(H5E_VFL, H5E_CANTINC, NULL, "unable to increment ref count on VFL driver")
- file->memb_size = 1024 * 1024 * 1024; /*1GB. Actual member size to be updated later */
- file->pmem_size = 1024 * 1024 * 1024; /*1GB. Member size passed in through property */
- file->mem_newsize = 0; /*New member size used by h5repart only */
- } /* end if */
+ H5FD_family_fapl_t default_fa;
+
+ /* Get default configuration */
+ if (H5FD__family_get_default_config(&default_fa) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTGET, NULL, "can't get default driver configuration info")
+
+ file->memb_fapl_id = default_fa.memb_fapl_id;
+ file->memb_size = H5FD_FAM_DEF_MEM_SIZE; /* Actual member size to be updated later */
+ file->pmem_size = H5FD_FAM_DEF_MEM_SIZE; /* Member size passed in through property */
+ file->mem_newsize = 0; /*New member size used by h5repart only */
+
+ default_config = TRUE;
+ } /* end if */
else {
H5P_genplist_t * plist; /* Property list pointer */
const H5FD_family_fapl_t *fa;
+ H5FD_family_fapl_t default_fa;
if (NULL == (plist = (H5P_genplist_t *)H5I_object(fapl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file access property list")
- if (NULL == (fa = (const H5FD_family_fapl_t *)H5P_peek_driver_info(plist)))
- HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, NULL, "bad VFL driver info")
+ if (NULL == (fa = (const H5FD_family_fapl_t *)H5P_peek_driver_info(plist))) {
+ if (H5FD__family_get_default_config(&default_fa) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTGET, NULL, "can't get default family VFD configuration")
+ fa = &default_fa;
+ default_config = TRUE;
+ }
/* Check for new family file size. It's used by h5repart only. */
if (H5P_exist_plist(plist, H5F_ACS_FAMILY_NEWSIZE_NAME) > 0) {
@@ -647,7 +787,10 @@ H5FD__family_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxad
} /* end else */
file->memb_size = fa->memb_size; /* Actual member size to be updated later */
file->pmem_size = fa->memb_size; /* Member size passed in through property */
- } /* end else */
+
+ if (default_config && H5I_dec_ref(fa->memb_fapl_id) < 0)
+ HGOTO_ERROR(H5E_ID, H5E_CANTDEC, NULL, "can't decrement ref. count on member FAPL")
+ } /* end else */
file->name = H5MM_strdup(name);
file->flags = flags;
@@ -660,8 +803,16 @@ H5FD__family_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxad
/* Check that names are unique */
HDsnprintf(memb_name, H5FD_FAM_MEMB_NAME_BUF_SIZE, name, 0);
HDsnprintf(temp, H5FD_FAM_MEMB_NAME_BUF_SIZE, name, 1);
- if (!HDstrcmp(memb_name, temp))
- HGOTO_ERROR(H5E_FILE, H5E_FILEEXISTS, NULL, "file names not unique")
+ if (!HDstrcmp(memb_name, temp)) {
+ if (default_config) {
+ temp = H5MM_xfree(temp);
+ if (NULL == (temp = H5FD__family_get_default_printf_filename(name)))
+ HGOTO_ERROR(H5E_VFL, H5E_CANTGET, NULL, "can't get default printf-style filename")
+ name = temp;
+ }
+ else
+ HGOTO_ERROR(H5E_FILE, H5E_FILEEXISTS, NULL, "file names not unique")
+ }
/* Open all the family members */
while (1) {
@@ -1365,7 +1516,9 @@ H5FD__family_delete(const char *filename, hid_t fapl_id)
{
H5P_genplist_t * plist;
const H5FD_family_fapl_t *fa;
- hid_t memb_fapl_id = H5I_INVALID_HID;
+ H5FD_family_fapl_t default_fa = {0, H5I_INVALID_HID};
+ hbool_t default_config = FALSE;
+ hid_t memb_fapl_id = H5I_INVALID_HID;
unsigned current_member;
char * member_name = NULL;
char * temp = NULL;
@@ -1379,13 +1532,21 @@ H5FD__family_delete(const char *filename, hid_t fapl_id)
/* Get the driver info (for the member fapl)
* The family_open call accepts H5P_DEFAULT, so we'll accept that here, too.
*/
- if (H5P_FILE_ACCESS_DEFAULT == fapl_id)
- memb_fapl_id = H5P_FILE_ACCESS_DEFAULT;
+ if (H5P_FILE_ACCESS_DEFAULT == fapl_id) {
+ if (H5FD__family_get_default_config(&default_fa) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get default family VFD configuration")
+ memb_fapl_id = default_fa.memb_fapl_id;
+ default_config = TRUE;
+ }
else {
if (NULL == (plist = (H5P_genplist_t *)H5I_object(fapl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list")
- if (NULL == (fa = (const H5FD_family_fapl_t *)H5P_peek_driver_info(plist)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "bad family VFD driver info")
+ if (NULL == (fa = (const H5FD_family_fapl_t *)H5P_peek_driver_info(plist))) {
+ if (H5FD__family_get_default_config(&default_fa) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get default family VFD configuration")
+ fa = &default_fa;
+ default_config = TRUE;
+ }
memb_fapl_id = fa->memb_fapl_id;
}
@@ -1398,8 +1559,17 @@ H5FD__family_delete(const char *filename, hid_t fapl_id)
/* Sanity check to make sure that generated names are unique */
HDsnprintf(member_name, H5FD_FAM_MEMB_NAME_BUF_SIZE, filename, 0);
HDsnprintf(temp, H5FD_FAM_MEMB_NAME_BUF_SIZE, filename, 1);
- if (!HDstrcmp(member_name, temp))
- HGOTO_ERROR(H5E_VFL, H5E_CANTDELETEFILE, FAIL, "provided file name cannot generate unique sub-files")
+ if (!HDstrcmp(member_name, temp)) {
+ if (default_config) {
+ temp = H5MM_xfree(temp);
+ if (NULL == (temp = H5FD__family_get_default_printf_filename(filename)))
+ HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get default printf-style filename")
+ filename = temp;
+ }
+ else
+ HGOTO_ERROR(H5E_VFL, H5E_CANTDELETEFILE, FAIL,
+ "provided file name cannot generate unique sub-files")
+ }
/* Delete all the family members */
current_member = 0;
@@ -1435,9 +1605,9 @@ done:
if (temp)
H5MM_xfree(temp);
- /* Don't close memb_fapl_id - We didn't bump its reference count since we're
- * only using it in this call.
- */
+ /* Only close memb_fapl_id if we created one from the default configuration */
+ if (default_fa.memb_fapl_id >= 0 && H5I_dec_ref(default_fa.memb_fapl_id) < 0)
+ HDONE_ERROR(H5E_VFL, H5E_CANTDEC, FAIL, "can't decrement ref. count on member FAPL ID")
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5FD__family_delete() */
diff --git a/src/H5FDfamily.h b/src/H5FDfamily.h
index 20ef532..7b76a16 100644
--- a/src/H5FDfamily.h
+++ b/src/H5FDfamily.h
@@ -20,7 +20,8 @@
#ifndef H5FDfamily_H
#define H5FDfamily_H
-#define H5FD_FAMILY (H5FD_family_init())
+#define H5FD_FAMILY (H5FD_family_init())
+#define H5FD_FAMILY_VALUE H5_VFD_FAMILY
#ifdef __cplusplus
extern "C" {
diff --git a/src/H5FDhdfs.c b/src/H5FDhdfs.c
index a1b9a39..82985cc 100644
--- a/src/H5FDhdfs.c
+++ b/src/H5FDhdfs.c
@@ -278,6 +278,7 @@ static herr_t H5FD__hdfs_truncate(H5FD_t *_file, hid_t dxpl_id, hbool_t closing
static herr_t H5FD__hdfs_validate_config(const H5FD_hdfs_fapl_t *fa);
static const H5FD_class_t H5FD_hdfs_g = {
+ H5FD_HDFS_VALUE, /* value */
"hdfs", /* name */
MAXADDR, /* maxaddr */
H5F_CLOSE_WEAK, /* fc_degree */
@@ -628,7 +629,7 @@ H5Pset_fapl_hdfs(hid_t fapl_id, H5FD_hdfs_fapl_t *fa)
if (FAIL == H5FD__hdfs_validate_config(fa))
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid hdfs config")
- ret_value = H5P_set_driver(plist, H5FD_HDFS, (void *)fa);
+ ret_value = H5P_set_driver(plist, H5FD_HDFS, (void *)fa, NULL);
done:
FUNC_LEAVE_API(ret_value)
diff --git a/src/H5FDhdfs.h b/src/H5FDhdfs.h
index 7c871a4..a9f34a0 100644
--- a/src/H5FDhdfs.h
+++ b/src/H5FDhdfs.h
@@ -22,9 +22,11 @@
#define H5FDhdfs_H
#ifdef H5_HAVE_LIBHDFS
-#define H5FD_HDFS (H5FD_hdfs_init())
+#define H5FD_HDFS (H5FD_hdfs_init())
+#define H5FD_HDFS_VALUE H5_VFD_HDFS
#else /* H5_HAVE_LIBHDFS */
-#define H5FD_HDFS (H5I_INVALID_HID)
+#define H5FD_HDFS (H5I_INVALID_HID)
+#define H5FD_HDFS_VALUE H5_VFD_INVALID
#endif /* H5_HAVE_LIBHDFS */
#ifdef H5_HAVE_LIBHDFS
diff --git a/src/H5FDint.c b/src/H5FDint.c
index 0ed49b0..af3562b 100644
--- a/src/H5FDint.c
+++ b/src/H5FDint.c
@@ -35,6 +35,7 @@
#include "H5Fprivate.h" /* File access */
#include "H5FDpkg.h" /* File Drivers */
#include "H5Iprivate.h" /* IDs */
+#include "H5PLprivate.h" /* Plugins */
/****************/
/* Local Macros */
@@ -74,6 +75,20 @@ typedef struct H5FD_vsrt_tmp_t {
int index;
} H5FD_vsrt_tmp_t;
+/* Information needed for iterating over the registered VFD hid_t IDs.
+ * The name or value of the new VFD that is being registered is stored
+ * in the name (or value) field and the found_id field is initialized to
+ * H5I_INVALID_HID (-1). If we find a VFD with the same name / value,
+ * we set the found_id field to the existing ID for return to the function.
+ */
+typedef struct H5FD_get_driver_ud_t {
+ /* IN */
+ H5PL_vfd_key_t key;
+
+ /* OUT */
+ hid_t found_id; /* The driver ID, if we found a match */
+} H5FD_get_driver_ud_t;
+
/********************/
/* Package Typedefs */
/********************/
@@ -81,6 +96,7 @@ typedef struct H5FD_vsrt_tmp_t {
/********************/
/* Local Prototypes */
/********************/
+static int H5FD__get_driver_cb(void *obj, hid_t id, void *_op_data);
/*********************/
/* Package Variables */
@@ -2353,3 +2369,358 @@ H5FD_delete(const char *filename, hid_t fapl_id)
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5FD_delete() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5FD_check_plugin_load
+ *
+ * Purpose: Check if a VFD plugin matches the search criteria, and can
+ * be loaded.
+ *
+ * Note: Matching the driver's name / value, but the driver having
+ * an incompatible version is not an error, but means that the
+ * driver isn't a "match". Setting the SUCCEED value to FALSE
+ * and not failing for that case allows the plugin framework
+ * to keep looking for other DLLs that match and have a
+ * compatible version.
+ *
+ * Return: SUCCEED / FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5FD_check_plugin_load(const H5FD_class_t *cls, const H5PL_key_t *key, hbool_t *success)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(FAIL)
+
+ /* Sanity checks */
+ HDassert(cls);
+ HDassert(key);
+ HDassert(success);
+
+ /* Which kind of key are we looking for? */
+ if (key->vfd.kind == H5FD_GET_DRIVER_BY_NAME) {
+ /* Check if plugin name matches VFD class name */
+ if (cls->name && !HDstrcmp(cls->name, key->vfd.u.name))
+ *success = TRUE;
+ } /* end if */
+ else {
+ /* Sanity check */
+ HDassert(key->vfd.kind == H5FD_GET_DRIVER_BY_VALUE);
+
+ /* Check if plugin value matches VFD class value */
+ if (cls->value == key->vfd.u.value)
+ *success = TRUE;
+ } /* end else */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5FD_check_plugin_load() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5FD__get_driver_cb
+ *
+ * Purpose: Callback routine to search through registered VFDs
+ *
+ * Return: Success: H5_ITER_STOP if the class and op_data name
+ * members match. H5_ITER_CONT otherwise.
+ * Failure: Can't fail
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+H5FD__get_driver_cb(void *obj, hid_t id, void *_op_data)
+{
+ H5FD_get_driver_ud_t *op_data = (H5FD_get_driver_ud_t *)_op_data; /* User data for callback */
+ H5FD_class_t * cls = (H5FD_class_t *)obj;
+ int ret_value = H5_ITER_CONT; /* Callback return value */
+
+ FUNC_ENTER_STATIC_NOERR
+
+ if (H5FD_GET_DRIVER_BY_NAME == op_data->key.kind) {
+ if (0 == HDstrcmp(cls->name, op_data->key.u.name)) {
+ op_data->found_id = id;
+ ret_value = H5_ITER_STOP;
+ } /* end if */
+ } /* end if */
+ else {
+ HDassert(H5FD_GET_DRIVER_BY_VALUE == op_data->key.kind);
+ if (cls->value == op_data->key.u.value) {
+ op_data->found_id = id;
+ ret_value = H5_ITER_STOP;
+ } /* end if */
+ } /* end else */
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5FD__get_driver_cb() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5FD_register_driver_by_name
+ *
+ * Purpose: Registers a new VFD as a member of the virtual file driver
+ * class.
+ *
+ * Return: Success: A VFD ID which is good until the library is
+ * closed.
+ *
+ * Failure: H5I_INVALID_HID
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5FD_register_driver_by_name(const char *name, hbool_t app_ref)
+{
+ htri_t driver_is_registered = FALSE;
+ hid_t driver_id = H5I_INVALID_HID;
+ hid_t ret_value = H5I_INVALID_HID; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5I_INVALID_HID)
+
+ /* Check if driver is already registered */
+ if ((driver_is_registered = H5FD_is_driver_registered_by_name(name, &driver_id)) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_BADITER, H5I_INVALID_HID, "can't check if driver is already registered")
+
+ /* If driver is already registered, increment ref count on ID and return ID */
+ if (driver_is_registered) {
+ HDassert(driver_id >= 0);
+
+ if (H5I_inc_ref(driver_id, app_ref) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTINC, H5I_INVALID_HID, "unable to increment ref count on VFD")
+ } /* end if */
+ else {
+ H5PL_key_t key;
+ const H5FD_class_t *cls;
+
+ /* Try loading the driver */
+ key.vfd.kind = H5FD_GET_DRIVER_BY_NAME;
+ key.vfd.u.name = name;
+ if (NULL == (cls = (const H5FD_class_t *)H5PL_load(H5PL_TYPE_VFD, &key)))
+ HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, H5I_INVALID_HID, "unable to load VFD")
+
+ /* Register the driver we loaded */
+ if ((driver_id = H5FD_register(cls, sizeof(*cls), app_ref)) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register VFD ID")
+ } /* end else */
+
+ ret_value = driver_id;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5FD_register_driver_by_name() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5FD_register_driver_by_value
+ *
+ * Purpose: Registers a new VFD as a member of the virtual file driver
+ * class.
+ *
+ * Return: Success: A VFD ID which is good until the library is
+ * closed.
+ *
+ * Failure: H5I_INVALID_HID
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5FD_register_driver_by_value(H5FD_class_value_t value, hbool_t app_ref)
+{
+ htri_t driver_is_registered = FALSE;
+ hid_t driver_id = H5I_INVALID_HID;
+ hid_t ret_value = H5I_INVALID_HID; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5I_INVALID_HID)
+
+ /* Check if driver is already registered */
+ if ((driver_is_registered = H5FD_is_driver_registered_by_value(value, &driver_id)) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_BADITER, H5I_INVALID_HID, "can't check if driver is already registered")
+
+ /* If driver is already registered, increment ref count on ID and return ID */
+ if (driver_is_registered) {
+ HDassert(driver_id >= 0);
+
+ if (H5I_inc_ref(driver_id, app_ref) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTINC, H5I_INVALID_HID, "unable to increment ref count on VFD")
+ } /* end if */
+ else {
+ H5PL_key_t key;
+ const H5FD_class_t *cls;
+
+ /* Try loading the driver */
+ key.vfd.kind = H5FD_GET_DRIVER_BY_VALUE;
+ key.vfd.u.value = value;
+ if (NULL == (cls = (const H5FD_class_t *)H5PL_load(H5PL_TYPE_VFD, &key)))
+ HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, H5I_INVALID_HID, "unable to load VFD")
+
+ /* Register the driver we loaded */
+ if ((driver_id = H5FD_register(cls, sizeof(*cls), app_ref)) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register VFD ID")
+ } /* end else */
+
+ ret_value = driver_id;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5FD_register_driver_by_value() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5FD_is_driver_registered_by_name
+ *
+ * Purpose: Checks if a driver with a particular name is registered.
+ * If `registered_id` is non-NULL and a driver with the
+ * specified name has been registered, the driver's ID will be
+ * returned in `registered_id`.
+ *
+ * Return: >0 if a VFD with that name has been registered
+ * 0 if a VFD with that name has NOT been registered
+ * <0 on errors
+ *
+ *-------------------------------------------------------------------------
+ */
+htri_t
+H5FD_is_driver_registered_by_name(const char *driver_name, hid_t *registered_id)
+{
+ H5FD_get_driver_ud_t op_data; /* Callback info for driver search */
+ htri_t ret_value = FALSE; /* Return value */
+
+ FUNC_ENTER_NOAPI(FAIL)
+
+ /* Set up op data for iteration */
+ op_data.key.kind = H5FD_GET_DRIVER_BY_NAME;
+ op_data.key.u.name = driver_name;
+ op_data.found_id = H5I_INVALID_HID;
+
+ /* Find driver with name */
+ if (H5I_iterate(H5I_VFL, H5FD__get_driver_cb, &op_data, FALSE) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_BADITER, FAIL, "can't iterate over VFDs")
+
+ /* Found a driver with that name */
+ if (op_data.found_id != H5I_INVALID_HID) {
+ if (registered_id)
+ *registered_id = op_data.found_id;
+ ret_value = TRUE;
+ }
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5FD_is_driver_registered_by_name() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5FD_is_driver_registered_by_value
+ *
+ * Purpose: Checks if a driver with a particular value (ID) is
+ * registered. If `registered_id` is non-NULL and a driver
+ * with the specified value has been registered, the driver's
+ * ID will be returned in `registered_id`.
+ *
+ * Return: >0 if a VFD with that value has been registered
+ * 0 if a VFD with that value has NOT been registered
+ * <0 on errors
+ *
+ *-------------------------------------------------------------------------
+ */
+htri_t
+H5FD_is_driver_registered_by_value(H5FD_class_value_t driver_value, hid_t *registered_id)
+{
+ H5FD_get_driver_ud_t op_data; /* Callback info for driver search */
+ htri_t ret_value = FALSE; /* Return value */
+
+ FUNC_ENTER_NOAPI(FAIL)
+
+ /* Set up op data for iteration */
+ op_data.key.kind = H5FD_GET_DRIVER_BY_VALUE;
+ op_data.key.u.value = driver_value;
+ op_data.found_id = H5I_INVALID_HID;
+
+ /* Find driver with value */
+ if (H5I_iterate(H5I_VFL, H5FD__get_driver_cb, &op_data, FALSE) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_BADITER, FAIL, "can't iterate over VFDs")
+
+ /* Found a driver with that value */
+ if (op_data.found_id != H5I_INVALID_HID) {
+ if (registered_id)
+ *registered_id = op_data.found_id;
+ ret_value = TRUE;
+ }
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5FD_is_driver_registered_by_value() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5FD_get_driver_id_by_name
+ *
+ * Purpose: Retrieves the ID for a registered VFL driver.
+ *
+ * Return: Positive if the VFL driver has been registered
+ * Negative on error (if the driver is not a valid driver or
+ * is not registered)
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5FD_get_driver_id_by_name(const char *name, hbool_t is_api)
+{
+ H5FD_get_driver_ud_t op_data;
+ hid_t ret_value = H5I_INVALID_HID; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5I_INVALID_HID)
+
+ /* Set up op data for iteration */
+ op_data.key.kind = H5FD_GET_DRIVER_BY_NAME;
+ op_data.key.u.name = name;
+ op_data.found_id = H5I_INVALID_HID;
+
+ /* Find driver with specified name */
+ if (H5I_iterate(H5I_VFL, H5FD__get_driver_cb, &op_data, FALSE) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_BADITER, H5I_INVALID_HID, "can't iterate over VFL drivers")
+
+ /* Found a driver with that name */
+ if (op_data.found_id != H5I_INVALID_HID) {
+ ret_value = op_data.found_id;
+ if (H5I_inc_ref(ret_value, is_api) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTINC, H5I_INVALID_HID, "unable to increment ref count on VFL driver")
+ }
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5FD_get_driver_id_by_name() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5FD_get_driver_id_by_value
+ *
+ * Purpose: Retrieves the ID for a registered VFL driver.
+ *
+ * Return: Positive if the VFL driver has been registered
+ * Negative on error (if the driver is not a valid driver or
+ * is not registered)
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5FD_get_driver_id_by_value(H5FD_class_value_t value, hbool_t is_api)
+{
+ H5FD_get_driver_ud_t op_data;
+ hid_t ret_value = H5I_INVALID_HID; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5I_INVALID_HID)
+
+ /* Set up op data for iteration */
+ op_data.key.kind = H5FD_GET_DRIVER_BY_VALUE;
+ op_data.key.u.value = value;
+ op_data.found_id = H5I_INVALID_HID;
+
+ /* Find driver with specified value */
+ if (H5I_iterate(H5I_VFL, H5FD__get_driver_cb, &op_data, FALSE) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_BADITER, H5I_INVALID_HID, "can't iterate over VFL drivers")
+
+ /* Found a driver with that value */
+ if (op_data.found_id != H5I_INVALID_HID) {
+ ret_value = op_data.found_id;
+ if (H5I_inc_ref(ret_value, is_api) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTINC, H5I_INVALID_HID, "unable to increment ref count on VFL driver")
+ }
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5FD_get_driver_id_by_value() */
diff --git a/src/H5FDlog.c b/src/H5FDlog.c
index 0364305..253c35b 100644
--- a/src/H5FDlog.c
+++ b/src/H5FDlog.c
@@ -180,6 +180,7 @@ static herr_t H5FD__log_unlock(H5FD_t *_file);
static herr_t H5FD__log_delete(const char *filename, hid_t fapl_id);
static const H5FD_class_t H5FD_log_g = {
+ H5FD_LOG_VALUE, /* value */
"log", /* name */
MAXADDR, /* maxaddr */
H5F_CLOSE_WEAK, /* fc_degree */
@@ -220,6 +221,9 @@ static const H5FD_class_t H5FD_log_g = {
H5FD_FLMAP_DICHOTOMY /* fl_map */
};
+/* Default configuration, if none provided */
+static const H5FD_log_fapl_t H5FD_log_default_config_g = {NULL, H5FD_LOG_LOC_IO | H5FD_LOG_ALLOC, 4096};
+
/* Declare a free list to manage the H5FD_log_t struct */
H5FL_DEFINE_STATIC(H5FD_log_t);
@@ -241,7 +245,7 @@ H5FD__init_package(void)
FUNC_ENTER_STATIC
/* Check the use disabled file locks environment variable */
- lock_env_var = HDgetenv("HDF5_USE_FILE_LOCKING");
+ lock_env_var = HDgetenv(HDF5_USE_FILE_LOCKING);
if (lock_env_var && !HDstrcmp(lock_env_var, "BEST_EFFORT"))
ignore_disabled_file_locks_s = TRUE; /* Override: Ignore disabled locks */
else if (lock_env_var && (!HDstrcmp(lock_env_var, "TRUE") || !HDstrcmp(lock_env_var, "1")))
@@ -352,7 +356,7 @@ H5Pset_fapl_log(hid_t fapl_id, const char *logfile, unsigned long long flags, si
fa.flags = flags;
fa.buf_size = buf_size;
- ret_value = H5P_set_driver(plist, H5FD_LOG, &fa);
+ ret_value = H5P_set_driver(plist, H5FD_LOG, &fa, NULL);
done:
if (fa.logfile)
@@ -487,10 +491,11 @@ static H5FD_t *
H5FD__log_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr)
{
H5FD_log_t * file = NULL;
- H5P_genplist_t * plist; /* Property list */
- const H5FD_log_fapl_t *fa; /* File access property list information */
- int fd = -1; /* File descriptor */
- int o_flags; /* Flags for open() call */
+ H5P_genplist_t * plist; /* Property list */
+ const H5FD_log_fapl_t *fa; /* File access property list information */
+ H5FD_log_fapl_t default_fa = H5FD_log_default_config_g;
+ int fd = -1; /* File descriptor */
+ int o_flags; /* Flags for open() call */
#ifdef H5_HAVE_WIN32_API
struct _BY_HANDLE_FILE_INFORMATION fileinfo;
#endif
@@ -528,8 +533,10 @@ H5FD__log_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr)
/* Get the driver specific information */
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 (NULL == (fa = (const H5FD_log_fapl_t *)H5P_peek_driver_info(plist)))
- HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, NULL, "bad VFL driver info")
+ if (NULL == (fa = (const H5FD_log_fapl_t *)H5P_peek_driver_info(plist))) {
+ /* Use default driver configuration*/
+ fa = &default_fa;
+ }
/* Start timer for open() call */
if (fa->flags & H5FD_LOG_TIME_OPEN)
diff --git a/src/H5FDlog.h b/src/H5FDlog.h
index 969c091..bc96c52 100644
--- a/src/H5FDlog.h
+++ b/src/H5FDlog.h
@@ -20,7 +20,8 @@
#ifndef H5FDlog_H
#define H5FDlog_H
-#define H5FD_LOG (H5FD_log_init())
+#define H5FD_LOG (H5FD_log_init())
+#define H5FD_LOG_VALUE H5_VFD_LOG
/* Flags for H5Pset_fapl_log() */
/* Flags for tracking 'meta' operations (truncate) */
diff --git a/src/H5FDmirror.c b/src/H5FDmirror.c
index cf3d9ca..f1fbc46 100644
--- a/src/H5FDmirror.c
+++ b/src/H5FDmirror.c
@@ -160,6 +160,7 @@ static herr_t H5FD__mirror_unlock(H5FD_t *_file);
static herr_t H5FD__mirror_verify_reply(H5FD_mirror_t *file);
static const H5FD_class_t H5FD_mirror_g = {
+ H5FD_MIRROR_VALUE, /* value */
"mirror", /* name */
MAXADDR, /* maxaddr */
H5F_CLOSE_WEAK, /* fc_degree */
@@ -1340,7 +1341,7 @@ H5Pset_fapl_mirror(hid_t fapl_id, H5FD_mirror_fapl_t *fa)
if (H5FD_MIRROR_CURR_FAPL_T_VERSION != fa->version)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unknown fapl_t version");
- ret_value = H5P_set_driver(plist, H5FD_MIRROR, (const void *)fa);
+ ret_value = H5P_set_driver(plist, H5FD_MIRROR, (const void *)fa, NULL);
done:
FUNC_LEAVE_API(ret_value)
diff --git a/src/H5FDmirror.h b/src/H5FDmirror.h
index 49e24c1..66954b1 100644
--- a/src/H5FDmirror.h
+++ b/src/H5FDmirror.h
@@ -19,7 +19,8 @@
#ifdef H5_HAVE_MIRROR_VFD
-#define H5FD_MIRROR (H5FD_mirror_init())
+#define H5FD_MIRROR (H5FD_mirror_init())
+#define H5FD_MIRROR_VALUE H5_VFD_MIRROR
#ifdef __cplusplus
extern "C" {
diff --git a/src/H5FDmpio.c b/src/H5FDmpio.c
index 445cc65..00fd3e9 100644
--- a/src/H5FDmpio.c
+++ b/src/H5FDmpio.c
@@ -45,6 +45,9 @@ static hid_t H5FD_MPIO_g = 0;
/* (Can be changed by setting "HDF5_MPI_OPT_TYPES" environment variable to '0' or '1') */
hbool_t H5FD_mpi_opt_types_g = TRUE;
+/* Whether the driver initialized MPI on its own */
+hbool_t H5FD_mpi_self_initialized = FALSE;
+
/*
* The view is set to this value
*/
@@ -97,6 +100,7 @@ static herr_t H5FD__mpio_ctl(H5FD_t *_file, uint64_t op_code, uint64_t flags, c
/* The MPIO file driver information */
static const H5FD_class_t H5FD_mpio_g = {
+ H5_VFD_MPIO, /* value */
"mpio", /* name */
HADDR_MAX, /* maxaddr */
H5F_CLOSE_SEMI, /* fc_degree */
@@ -242,6 +246,7 @@ hid_t
H5FD_mpio_init(void)
{
static int H5FD_mpio_Debug_inited = 0;
+ char * env = NULL;
hid_t ret_value = H5I_INVALID_HID; /* Return value */
FUNC_ENTER_NOAPI(H5I_INVALID_HID)
@@ -250,6 +255,21 @@ H5FD_mpio_init(void)
if (H5I_VFL != H5I_get_type(H5FD_MPIO_g))
H5FD_MPIO_g = H5FD_register((const H5FD_class_t *)&H5FD_mpio_g, sizeof(H5FD_class_t), FALSE);
+ /* Check if MPI driver has been loaded dynamically */
+ env = HDgetenv(HDF5_DRIVER);
+ if (env && !HDstrcmp(env, "mpio")) {
+ int mpi_initialized = 0;
+
+ /* Initialize MPI if not already initialized */
+ if (MPI_SUCCESS != MPI_Initialized(&mpi_initialized))
+ HGOTO_ERROR(H5E_VFL, H5E_UNINITIALIZED, H5I_INVALID_HID, "can't check if MPI is initialized")
+ if (!mpi_initialized) {
+ if (MPI_SUCCESS != MPI_Init(NULL, NULL))
+ HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, H5I_INVALID_HID, "can't initialize MPI")
+ H5FD_mpi_self_initialized = TRUE;
+ }
+ }
+
if (!H5FD_mpio_Debug_inited) {
const char *s; /* String for environment variables */
@@ -295,6 +315,17 @@ H5FD__mpio_term(void)
{
FUNC_ENTER_STATIC_NOERR
+ /* Terminate MPI if the driver initialized it */
+ if (H5FD_mpi_self_initialized) {
+ int mpi_finalized = 0;
+
+ MPI_Finalized(&mpi_finalized);
+ if (!mpi_finalized)
+ MPI_Finalize();
+
+ H5FD_mpi_self_initialized = FALSE;
+ }
+
/* Reset VFL ID */
H5FD_MPIO_g = 0;
@@ -356,7 +387,7 @@ H5Pset_fapl_mpio(hid_t fapl_id, MPI_Comm comm, MPI_Info info)
HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set MPI info object")
/* duplication is done during driver setting. */
- ret_value = H5P_set_driver(plist, H5FD_MPIO, NULL);
+ ret_value = H5P_set_driver(plist, H5FD_MPIO, NULL, NULL);
done:
FUNC_LEAVE_API(ret_value)
@@ -811,11 +842,16 @@ H5FD__mpio_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t H5_ATTR
if (NULL == (plist = H5P_object_verify(fapl_id, H5P_FILE_ACCESS)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file access property list")
- /* Get the MPI communicator and info object from the property list */
- if (H5P_get(plist, H5F_ACS_MPI_PARAMS_COMM_NAME, &comm) < 0)
- HGOTO_ERROR(H5E_VFL, H5E_CANTGET, NULL, "can't get MPI communicator")
- if (H5P_get(plist, H5F_ACS_MPI_PARAMS_INFO_NAME, &info) < 0)
- HGOTO_ERROR(H5E_VFL, H5E_CANTGET, NULL, "can't get MPI info object")
+ if (H5FD_mpi_self_initialized) {
+ comm = MPI_COMM_WORLD;
+ }
+ else {
+ /* Get the MPI communicator and info object from the property list */
+ if (H5P_get(plist, H5F_ACS_MPI_PARAMS_COMM_NAME, &comm) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTGET, NULL, "can't get MPI communicator")
+ if (H5P_get(plist, H5F_ACS_MPI_PARAMS_INFO_NAME, &info) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTGET, NULL, "can't get MPI info object")
+ }
/* Get the MPI rank of this process and the total number of processes */
if (MPI_SUCCESS != (mpi_code = MPI_Comm_rank(comm, &mpi_rank)))
@@ -2760,11 +2796,16 @@ H5FD__mpio_delete(const char *filename, hid_t fapl_id)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list")
HDassert(H5FD_MPIO == H5P_peek_driver(plist));
- /* Get the MPI communicator and info from the fapl */
- if (H5P_get(plist, H5F_ACS_MPI_PARAMS_INFO_NAME, &info) < 0)
- 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)
- HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get MPI communicator")
+ 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)
+ 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)
+ 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)))
diff --git a/src/H5FDmulti.c b/src/H5FDmulti.c
index e51d101..bbc34e7 100644
--- a/src/H5FDmulti.c
+++ b/src/H5FDmulti.c
@@ -135,8 +135,13 @@ typedef struct H5FD_multi_dxpl_t {
} H5FD_multi_dxpl_t;
/* Private functions */
-static int compute_next(H5FD_multi_t *file);
-static int open_members(H5FD_multi_t *file);
+static herr_t H5FD_split_populate_config(const char *meta_ext, hid_t meta_plist_id, const char *raw_ext,
+ hid_t raw_plist_id, hbool_t relax, H5FD_multi_fapl_t *fa_out);
+static herr_t H5FD_multi_populate_config(const H5FD_mem_t *memb_map, const hid_t *memb_fapl,
+ const char *const *memb_name, const haddr_t *memb_addr,
+ hbool_t relax, H5FD_multi_fapl_t *fa_out);
+static int compute_next(H5FD_multi_t *file);
+static int open_members(H5FD_multi_t *file);
/* Callback prototypes */
static herr_t H5FD_multi_term(void);
@@ -171,6 +176,7 @@ static herr_t H5FD_multi_ctl(H5FD_t *_file, uint64_t op_code, uint64_t flags, c
/* The class struct */
static const H5FD_class_t H5FD_multi_g = {
+ H5_VFD_MULTI, /* value */
"multi", /* name */
HADDR_MAX, /* maxaddr */
H5F_CLOSE_WEAK, /* fc_degree */
@@ -278,74 +284,19 @@ herr_t
H5Pset_fapl_split(hid_t fapl, const char *meta_ext, hid_t meta_plist_id, const char *raw_ext,
hid_t raw_plist_id)
{
- H5FD_mem_t memb_map[H5FD_MEM_NTYPES];
- hid_t memb_fapl[H5FD_MEM_NTYPES];
- const char *memb_name[H5FD_MEM_NTYPES];
- char meta_name[H5FD_MULT_MAX_FILE_NAME_LEN];
- char raw_name[H5FD_MULT_MAX_FILE_NAME_LEN];
- haddr_t memb_addr[H5FD_MEM_NTYPES];
+ H5FD_multi_fapl_t fa;
+ static const char *func = "H5Pset_fapl_split"; /* Function Name for error reporting */
/*NO TRACE*/
/* Clear the error stack */
H5Eclear2(H5E_DEFAULT);
- /* Initialize */
- ALL_MEMBERS (mt) {
- /* Treat global heap as raw data, not metadata */
- memb_map[mt] = ((mt == H5FD_MEM_DRAW || mt == H5FD_MEM_GHEAP) ? H5FD_MEM_DRAW : H5FD_MEM_SUPER);
- memb_fapl[mt] = -1;
- memb_name[mt] = NULL;
- memb_addr[mt] = HADDR_UNDEF;
- }
- END_MEMBERS;
-
- /* The file access properties */
- memb_fapl[H5FD_MEM_SUPER] = meta_plist_id;
- memb_fapl[H5FD_MEM_DRAW] = raw_plist_id;
-
- /* The names */
- /* process meta filename */
- if (meta_ext) {
- if (strstr(meta_ext, "%s")) {
- /* Note: this doesn't accommodate for when the '%s' in the user's
- * string is at a position >sizeof(meta_name) - QK & JK - 2013/01/17
- */
- strncpy(meta_name, meta_ext, sizeof(meta_name));
- meta_name[sizeof(meta_name) - 1] = '\0';
- }
- else
- sprintf(meta_name, "%%s%s", meta_ext);
- }
- else {
- strncpy(meta_name, "%s.meta", sizeof(meta_name));
- meta_name[sizeof(meta_name) - 1] = '\0';
- }
- memb_name[H5FD_MEM_SUPER] = meta_name;
-
- /* process raw filename */
- if (raw_ext) {
- if (strstr(raw_ext, "%s")) {
- /* Note: this doesn't accommodate for when the '%s' in the user's
- * string is at a position >sizeof(raw_name) - QK & JK - 2013/01/17
- */
- strncpy(raw_name, raw_ext, sizeof(raw_name));
- raw_name[sizeof(raw_name) - 1] = '\0';
- }
- else
- sprintf(raw_name, "%%s%s", raw_ext);
- }
- else {
- strncpy(raw_name, "%s.raw", sizeof(raw_name));
- raw_name[sizeof(raw_name) - 1] = '\0';
- }
- memb_name[H5FD_MEM_DRAW] = raw_name;
-
- /* The sizes */
- memb_addr[H5FD_MEM_SUPER] = 0;
- memb_addr[H5FD_MEM_DRAW] = HADDR_MAX / 2;
+ if (H5FD_split_populate_config(meta_ext, meta_plist_id, raw_ext, raw_plist_id, TRUE, &fa) < 0)
+ H5Epush_ret(func, H5E_ERR_CLS, H5E_INTERNAL, H5E_CANTSET, "can't setup split driver configuration",
+ -1);
- return H5Pset_fapl_multi(fapl, memb_map, memb_fapl, memb_name, memb_addr, TRUE);
+ return H5Pset_driver(fapl, H5FD_MULTI, &fa);
}
/*-------------------------------------------------------------------------
@@ -429,14 +380,7 @@ H5Pset_fapl_multi(hid_t fapl_id, const H5FD_mem_t *memb_map, const hid_t *memb_f
const char *const *memb_name, const haddr_t *memb_addr, hbool_t relax)
{
H5FD_multi_fapl_t fa;
- H5FD_mem_t mt, mmt;
- H5FD_mem_t _memb_map[H5FD_MEM_NTYPES];
- hid_t _memb_fapl[H5FD_MEM_NTYPES];
- char _memb_name[H5FD_MEM_NTYPES][16];
- const char * _memb_name_ptrs[H5FD_MEM_NTYPES];
- haddr_t _memb_addr[H5FD_MEM_NTYPES];
- static const char *letters = "Xsbrglo";
- static const char *func = "H5FDset_fapl_multi"; /* Function Name for error reporting */
+ static const char *func = "H5FDset_fapl_multi"; /* Function Name for error reporting */
/*NO TRACE*/
@@ -446,66 +390,9 @@ H5Pset_fapl_multi(hid_t fapl_id, const H5FD_mem_t *memb_map, const hid_t *memb_f
/* Check arguments and supply default values */
if (H5I_GENPROP_LST != H5Iget_type(fapl_id) || TRUE != H5Pisa_class(fapl_id, H5P_FILE_ACCESS))
H5Epush_ret(func, H5E_ERR_CLS, H5E_PLIST, H5E_BADVALUE, "not an access list", -1);
- if (!memb_map) {
- for (mt = H5FD_MEM_DEFAULT; mt < H5FD_MEM_NTYPES; mt = (H5FD_mem_t)(mt + 1))
- _memb_map[mt] = H5FD_MEM_DEFAULT;
- memb_map = _memb_map;
- }
- if (!memb_fapl) {
- for (mt = H5FD_MEM_DEFAULT; mt < H5FD_MEM_NTYPES; mt = (H5FD_mem_t)(mt + 1))
- _memb_fapl[mt] = H5Pcreate(H5P_FILE_ACCESS);
- memb_fapl = _memb_fapl;
- }
- if (!memb_name) {
- assert(strlen(letters) == H5FD_MEM_NTYPES);
- for (mt = H5FD_MEM_DEFAULT; mt < H5FD_MEM_NTYPES; mt = (H5FD_mem_t)(mt + 1)) {
- sprintf(_memb_name[mt], "%%s-%c.h5", letters[mt]);
- _memb_name_ptrs[mt] = _memb_name[mt];
- }
- memb_name = _memb_name_ptrs;
- }
- if (!memb_addr) {
- for (mt = H5FD_MEM_DEFAULT; mt < H5FD_MEM_NTYPES; mt = (H5FD_mem_t)(mt + 1))
- _memb_addr[mt] = (hsize_t)(mt ? (mt - 1) : 0) * (HADDR_MAX / (H5FD_MEM_NTYPES - 1));
- memb_addr = _memb_addr;
- }
-
- for (mt = H5FD_MEM_DEFAULT; mt < H5FD_MEM_NTYPES; mt = (H5FD_mem_t)(mt + 1)) {
- /* Map usage type */
- mmt = memb_map[mt];
- if (mmt < 0 || mmt >= H5FD_MEM_NTYPES)
- H5Epush_ret(func, H5E_ERR_CLS, H5E_INTERNAL, H5E_BADRANGE, "file resource type out of range", -1);
- if (H5FD_MEM_DEFAULT == mmt)
- mmt = mt;
+ if (H5FD_multi_populate_config(memb_map, memb_fapl, memb_name, memb_addr, relax, &fa) < 0)
+ H5Epush_ret(func, H5E_ERR_CLS, H5E_INTERNAL, H5E_CANTSET, "can't setup driver configuration", -1);
- /*
- * All members of MEMB_FAPL must be either defaults or actual file
- * access property lists.
- */
- if (H5P_DEFAULT != memb_fapl[mmt] && TRUE != H5Pisa_class(memb_fapl[mmt], H5P_FILE_ACCESS))
- H5Epush_ret(func, H5E_ERR_CLS, H5E_INTERNAL, H5E_BADVALUE, "file resource type incorrect", -1);
-
- /* All names must be defined */
- if (!memb_name[mmt] || !memb_name[mmt][0])
- H5Epush_ret(func, H5E_ERR_CLS, H5E_INTERNAL, H5E_BADVALUE, "file resource type not set", -1);
- }
-
- /*
- * Initialize driver specific information. No need to copy it into the FA
- * struct since all members will be copied by H5Pset_driver().
- */
- memset(&fa, 0, sizeof(H5FD_multi_fapl_t));
- memcpy(fa.memb_map, memb_map, H5FD_MEM_NTYPES * sizeof(H5FD_mem_t));
- memcpy(fa.memb_fapl, memb_fapl, H5FD_MEM_NTYPES * sizeof(hid_t));
- memcpy(fa.memb_name, memb_name, H5FD_MEM_NTYPES * sizeof(char *));
- memcpy(fa.memb_addr, memb_addr, H5FD_MEM_NTYPES * sizeof(haddr_t));
- fa.relax = relax;
-
- /* Patch up H5P_DEFAULT property lists for members */
- for (mt = H5FD_MEM_DEFAULT; mt < H5FD_MEM_NTYPES; mt = (H5FD_mem_t)(mt + 1)) {
- if (fa.memb_fapl[mt] == H5P_DEFAULT)
- fa.memb_fapl[mt] = H5Pcreate(H5P_FILE_ACCESS);
- }
return H5Pset_driver(fapl_id, H5FD_MULTI, &fa);
}
@@ -530,6 +417,7 @@ H5Pget_fapl_multi(hid_t fapl_id, H5FD_mem_t *memb_map /*out*/, hid_t *memb_fapl
char **memb_name /*out*/, haddr_t *memb_addr /*out*/, hbool_t *relax)
{
const H5FD_multi_fapl_t *fa;
+ H5FD_multi_fapl_t default_fa;
H5FD_mem_t mt;
static const char * func = "H5FDget_fapl_multi"; /* Function Name for error reporting */
@@ -542,8 +430,17 @@ H5Pget_fapl_multi(hid_t fapl_id, H5FD_mem_t *memb_map /*out*/, hid_t *memb_fapl
H5Epush_ret(func, H5E_ERR_CLS, H5E_PLIST, H5E_BADTYPE, "not an access list", -1);
if (H5FD_MULTI != H5Pget_driver(fapl_id))
H5Epush_ret(func, H5E_ERR_CLS, H5E_PLIST, H5E_BADVALUE, "incorrect VFL driver", -1);
- if (NULL == (fa = (const H5FD_multi_fapl_t *)H5Pget_driver_info(fapl_id)))
- H5Epush_ret(func, H5E_ERR_CLS, H5E_PLIST, H5E_BADVALUE, "bad VFL driver info", -1);
+ H5E_BEGIN_TRY
+ {
+ fa = (const H5FD_multi_fapl_t *)H5Pget_driver_info(fapl_id);
+ }
+ H5E_END_TRY;
+ if (!fa || (H5P_FILE_ACCESS_DEFAULT == fapl_id)) {
+ if (H5FD_multi_populate_config(NULL, NULL, NULL, NULL, TRUE, &default_fa) < 0)
+ H5Epush_ret(func, H5E_ERR_CLS, H5E_VFL, H5E_CANTSET, "can't setup default driver configuration",
+ -1);
+ fa = &default_fa;
+ }
if (memb_map)
memcpy(memb_map, fa->memb_map, H5FD_MEM_NTYPES * sizeof(H5FD_mem_t));
@@ -572,6 +469,231 @@ H5Pget_fapl_multi(hid_t fapl_id, H5FD_mem_t *memb_map /*out*/, hid_t *memb_fapl
}
/*-------------------------------------------------------------------------
+ * Function: H5FD_split_populate_config
+ *
+ * Purpose: Populates a H5FD_multi_fapl_t structure with the provided
+ * split driver values, supplying defaults where values are not
+ * provided.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5FD_split_populate_config(const char *meta_ext, hid_t meta_plist_id, const char *raw_ext, hid_t raw_plist_id,
+ hbool_t relax, H5FD_multi_fapl_t *fa_out)
+{
+ static const char *func = "H5FD_split_populate_config"; /* Function Name for error reporting */
+ static char
+ meta_name_g[H5FD_MULT_MAX_FILE_NAME_LEN]; /* Static scratch buffer to store metadata member name */
+ static char
+ raw_name_g[H5FD_MULT_MAX_FILE_NAME_LEN]; /* Static scratch buffer to store raw data member name */
+ const char *_memb_name[H5FD_MEM_NTYPES];
+ H5FD_mem_t _memb_map[H5FD_MEM_NTYPES];
+ hid_t _memb_fapl[H5FD_MEM_NTYPES];
+ haddr_t _memb_addr[H5FD_MEM_NTYPES];
+ herr_t ret_value = 0;
+
+ assert(fa_out);
+
+ /* Initialize */
+ ALL_MEMBERS (mt) {
+ /* Treat global heap as raw data, not metadata */
+ _memb_map[mt] = ((mt == H5FD_MEM_DRAW || mt == H5FD_MEM_GHEAP) ? H5FD_MEM_DRAW : H5FD_MEM_SUPER);
+ _memb_fapl[mt] = H5P_DEFAULT;
+ _memb_name[mt] = NULL;
+ _memb_addr[mt] = HADDR_UNDEF;
+ }
+ END_MEMBERS;
+
+ /* The file access properties */
+ _memb_fapl[H5FD_MEM_SUPER] = meta_plist_id;
+ _memb_fapl[H5FD_MEM_DRAW] = raw_plist_id;
+
+ /* The names */
+ /* process meta filename */
+ if (meta_ext) {
+ if (strstr(meta_ext, "%s")) {
+ /* Note: this doesn't accommodate for when the '%s' in the user's
+ * string is at a position >sizeof(meta_name) - QK & JK - 2013/01/17
+ */
+ strncpy(meta_name_g, meta_ext, sizeof(meta_name_g));
+ meta_name_g[sizeof(meta_name_g) - 1] = '\0';
+ }
+ else
+ sprintf(meta_name_g, "%%s%s", meta_ext);
+ }
+ else {
+ strncpy(meta_name_g, "%s.meta", sizeof(meta_name_g));
+ meta_name_g[sizeof(meta_name_g) - 1] = '\0';
+ }
+ _memb_name[H5FD_MEM_SUPER] = meta_name_g;
+
+ /* process raw filename */
+ if (raw_ext) {
+ if (strstr(raw_ext, "%s")) {
+ /* Note: this doesn't accommodate for when the '%s' in the user's
+ * string is at a position >sizeof(raw_name) - QK & JK - 2013/01/17
+ */
+ strncpy(raw_name_g, raw_ext, sizeof(raw_name_g));
+ raw_name_g[sizeof(raw_name_g) - 1] = '\0';
+ }
+ else
+ sprintf(raw_name_g, "%%s%s", raw_ext);
+ }
+ else {
+ strncpy(raw_name_g, "%s.raw", sizeof(raw_name_g));
+ raw_name_g[sizeof(raw_name_g) - 1] = '\0';
+ }
+ _memb_name[H5FD_MEM_DRAW] = raw_name_g;
+
+ /* The sizes */
+ _memb_addr[H5FD_MEM_SUPER] = 0;
+ _memb_addr[H5FD_MEM_DRAW] = HADDR_MAX / 2;
+
+ ALL_MEMBERS (mt) {
+ /* Map usage type */
+ H5FD_mem_t mmt = _memb_map[mt];
+ if (mmt < 0 || mmt >= H5FD_MEM_NTYPES)
+ H5Epush_ret(func, H5E_ERR_CLS, H5E_INTERNAL, H5E_BADRANGE, "file resource type out of range", -1);
+
+ /*
+ * All members of MEMB_FAPL must be either defaults or actual file
+ * access property lists.
+ */
+ if (H5P_DEFAULT != _memb_fapl[mmt] && TRUE != H5Pisa_class(_memb_fapl[mmt], H5P_FILE_ACCESS))
+ H5Epush_ret(func, H5E_ERR_CLS, H5E_INTERNAL, H5E_BADVALUE, "file resource type incorrect", -1);
+
+ /* All names must be defined */
+ if (!_memb_name[mmt] || !_memb_name[mmt][0])
+ H5Epush_ret(func, H5E_ERR_CLS, H5E_INTERNAL, H5E_BADVALUE, "file resource type not set", -1);
+ }
+ END_MEMBERS;
+
+ /*
+ * Initialize driver specific information. No need to copy it into the FA
+ * struct since all members will be copied by H5Pset_driver().
+ */
+ memset(fa_out, 0, sizeof(H5FD_multi_fapl_t));
+ memcpy(fa_out->memb_map, _memb_map, H5FD_MEM_NTYPES * sizeof(H5FD_mem_t));
+ memcpy(fa_out->memb_fapl, _memb_fapl, H5FD_MEM_NTYPES * sizeof(hid_t));
+ memcpy(fa_out->memb_name, _memb_name, H5FD_MEM_NTYPES * sizeof(char *));
+ memcpy(fa_out->memb_addr, _memb_addr, H5FD_MEM_NTYPES * sizeof(haddr_t));
+ fa_out->relax = relax;
+
+ /* Patch up H5P_DEFAULT property lists for members */
+ ALL_MEMBERS (mt) {
+ if (fa_out->memb_fapl[mt] == H5P_DEFAULT) {
+ fa_out->memb_fapl[mt] = H5Pcreate(H5P_FILE_ACCESS);
+ if (H5Pset_fapl_sec2(fa_out->memb_fapl[mt]) < 0)
+ H5Epush_ret(func, H5E_ERR_CLS, H5E_INTERNAL, H5E_CANTSET,
+ "can't set sec2 driver on member FAPL", -1);
+ }
+ }
+ END_MEMBERS;
+
+ return ret_value;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: H5FD_multi_populate_config
+ *
+ * Purpose: Populates a H5FD_multi_fapl_t structure with the provided
+ * values, supplying defaults where values are not provided.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5FD_multi_populate_config(const H5FD_mem_t *memb_map, const hid_t *memb_fapl, const char *const *memb_name,
+ const haddr_t *memb_addr, hbool_t relax, H5FD_multi_fapl_t *fa_out)
+{
+ static const char *func = "H5FD_multi_populate_config"; /* Function Name for error reporting */
+ static const char *letters = "Xsbrglo";
+ static char _memb_name_g[H5FD_MEM_NTYPES][16]; /* Static scratch buffer to store member names */
+ H5FD_mem_t mt, mmt;
+ H5FD_mem_t _memb_map[H5FD_MEM_NTYPES];
+ hid_t _memb_fapl[H5FD_MEM_NTYPES];
+ const char * _memb_name_ptrs[H5FD_MEM_NTYPES];
+ haddr_t _memb_addr[H5FD_MEM_NTYPES];
+ herr_t ret_value = 0;
+
+ assert(fa_out);
+
+ if (!memb_map) {
+ for (mt = H5FD_MEM_DEFAULT; mt < H5FD_MEM_NTYPES; mt = (H5FD_mem_t)(mt + 1))
+ _memb_map[mt] = H5FD_MEM_DEFAULT;
+ memb_map = _memb_map;
+ }
+ if (!memb_fapl) {
+ for (mt = H5FD_MEM_DEFAULT; mt < H5FD_MEM_NTYPES; mt = (H5FD_mem_t)(mt + 1)) {
+ _memb_fapl[mt] = H5Pcreate(H5P_FILE_ACCESS);
+ if (H5Pset_fapl_sec2(_memb_fapl[mt]) < 0)
+ H5Epush_ret(func, H5E_ERR_CLS, H5E_INTERNAL, H5E_CANTSET,
+ "can't set sec2 driver on member FAPL", -1);
+ }
+ memb_fapl = _memb_fapl;
+ }
+ if (!memb_name) {
+ assert(strlen(letters) == H5FD_MEM_NTYPES);
+ for (mt = H5FD_MEM_DEFAULT; mt < H5FD_MEM_NTYPES; mt = (H5FD_mem_t)(mt + 1)) {
+ sprintf(_memb_name_g[mt], "%%s-%c.h5", letters[mt]);
+ _memb_name_ptrs[mt] = _memb_name_g[mt];
+ }
+ memb_name = _memb_name_ptrs;
+ }
+ if (!memb_addr) {
+ for (mt = H5FD_MEM_DEFAULT; mt < H5FD_MEM_NTYPES; mt = (H5FD_mem_t)(mt + 1))
+ _memb_addr[mt] = (hsize_t)(mt ? (mt - 1) : 0) * (HADDR_MAX / (H5FD_MEM_NTYPES - 1));
+ memb_addr = _memb_addr;
+ }
+
+ for (mt = H5FD_MEM_DEFAULT; mt < H5FD_MEM_NTYPES; mt = (H5FD_mem_t)(mt + 1)) {
+ /* Map usage type */
+ mmt = memb_map[mt];
+ if (mmt < 0 || mmt >= H5FD_MEM_NTYPES)
+ H5Epush_ret(func, H5E_ERR_CLS, H5E_INTERNAL, H5E_BADRANGE, "file resource type out of range", -1);
+ if (H5FD_MEM_DEFAULT == mmt)
+ mmt = mt;
+
+ /*
+ * All members of MEMB_FAPL must be either defaults or actual file
+ * access property lists.
+ */
+ if (H5P_DEFAULT != memb_fapl[mmt] && TRUE != H5Pisa_class(memb_fapl[mmt], H5P_FILE_ACCESS))
+ H5Epush_ret(func, H5E_ERR_CLS, H5E_INTERNAL, H5E_BADVALUE, "file resource type incorrect", -1);
+
+ /* All names must be defined */
+ if (!memb_name[mmt] || !memb_name[mmt][0])
+ H5Epush_ret(func, H5E_ERR_CLS, H5E_INTERNAL, H5E_BADVALUE, "file resource type not set", -1);
+ }
+
+ /*
+ * Initialize driver specific information. No need to copy it into the FA
+ * struct since all members will be copied by H5Pset_driver().
+ */
+ memset(fa_out, 0, sizeof(H5FD_multi_fapl_t));
+ memcpy(fa_out->memb_map, memb_map, H5FD_MEM_NTYPES * sizeof(H5FD_mem_t));
+ memcpy(fa_out->memb_fapl, memb_fapl, H5FD_MEM_NTYPES * sizeof(hid_t));
+ memcpy(fa_out->memb_name, memb_name, H5FD_MEM_NTYPES * sizeof(char *));
+ memcpy(fa_out->memb_addr, memb_addr, H5FD_MEM_NTYPES * sizeof(haddr_t));
+ fa_out->relax = relax;
+
+ /* Patch up H5P_DEFAULT property lists for members */
+ for (mt = H5FD_MEM_DEFAULT; mt < H5FD_MEM_NTYPES; mt = (H5FD_mem_t)(mt + 1)) {
+ if (fa_out->memb_fapl[mt] == H5P_DEFAULT) {
+ fa_out->memb_fapl[mt] = H5Pcreate(H5P_FILE_ACCESS);
+ if (H5Pset_fapl_sec2(fa_out->memb_fapl[mt]) < 0)
+ H5Epush_ret(func, H5E_ERR_CLS, H5E_INTERNAL, H5E_CANTSET,
+ "can't set sec2 driver on member FAPL", -1);
+ }
+ }
+
+ return ret_value;
+} /* end H5FD_multi_populate_config() */
+
+/*-------------------------------------------------------------------------
* Function: H5FD_multi_sb_size
*
* Purpose: Returns the size of the private information to be stored in
@@ -1016,12 +1138,26 @@ H5FD_multi_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr
*/
if (NULL == (file = (H5FD_multi_t *)calloc((size_t)1, sizeof(H5FD_multi_t))))
H5Epush_ret(func, H5E_ERR_CLS, H5E_RESOURCE, H5E_NOSPACE, "memory allocation failed", NULL);
- if (H5P_FILE_ACCESS_DEFAULT == fapl_id || H5FD_MULTI != H5Pget_driver(fapl_id)) {
+ H5E_BEGIN_TRY
+ {
+ fa = (const H5FD_multi_fapl_t *)H5Pget_driver_info(fapl_id);
+ }
+ H5E_END_TRY;
+ if (!fa || (H5P_FILE_ACCESS_DEFAULT == fapl_id) || (H5FD_MULTI != H5Pget_driver(fapl_id))) {
+ char *env = getenv(HDF5_DRIVER);
+
close_fapl = fapl_id = H5Pcreate(H5P_FILE_ACCESS);
- if (H5Pset_fapl_multi(fapl_id, NULL, NULL, NULL, NULL, TRUE) < 0)
- H5Epush_goto(func, H5E_ERR_CLS, H5E_FILE, H5E_CANTSET, "can't set property value", error)
+ if (env && !strcmp(env, "split")) {
+ if (H5Pset_fapl_split(fapl_id, NULL, H5P_DEFAULT, NULL, H5P_DEFAULT) < 0)
+ H5Epush_goto(func, H5E_ERR_CLS, H5E_FILE, H5E_CANTSET, "can't set property value", error)
+ }
+ else {
+ if (H5Pset_fapl_multi(fapl_id, NULL, NULL, NULL, NULL, TRUE) < 0)
+ H5Epush_goto(func, H5E_ERR_CLS, H5E_FILE, H5E_CANTSET, "can't set property value", error)
+ }
+
+ fa = (const H5FD_multi_fapl_t *)H5Pget_driver_info(fapl_id);
}
- fa = (const H5FD_multi_fapl_t *)H5Pget_driver_info(fapl_id);
assert(fa);
ALL_MEMBERS (mt) {
file->fa.memb_map[mt] = fa->memb_map[mt];
@@ -2044,6 +2180,7 @@ H5FD_multi_delete(const char *filename, hid_t fapl_id)
char full_filename[H5FD_MULT_MAX_FILE_NAME_LEN];
int nchars;
const H5FD_multi_fapl_t *fa;
+ H5FD_multi_fapl_t default_fa;
static const char * func = "H5FD_multi_delete"; /* Function Name for error reporting */
/* Clear the error stack */
@@ -2051,11 +2188,26 @@ H5FD_multi_delete(const char *filename, hid_t fapl_id)
assert(filename);
- /* Quiet compiler */
- (void)fapl_id;
-
/* Get the driver info */
- fa = (const H5FD_multi_fapl_t *)H5Pget_driver_info(fapl_id);
+ H5E_BEGIN_TRY
+ {
+ fa = (const H5FD_multi_fapl_t *)H5Pget_driver_info(fapl_id);
+ }
+ H5E_END_TRY;
+ if (!fa) {
+ char *env = getenv(HDF5_DRIVER);
+
+ if (env && !strcmp(env, "split")) {
+ if (H5FD_split_populate_config(NULL, H5P_DEFAULT, NULL, H5P_DEFAULT, TRUE, &default_fa) < 0)
+ H5Epush_ret(func, H5E_ERR_CLS, H5E_VFL, H5E_CANTSET, "can't setup driver configuration", -1);
+ }
+ else {
+ if (H5FD_multi_populate_config(NULL, NULL, NULL, NULL, TRUE, &default_fa) < 0)
+ H5Epush_ret(func, H5E_ERR_CLS, H5E_VFL, H5E_CANTSET, "can't setup driver configuration", -1);
+ }
+
+ fa = &default_fa;
+ }
assert(fa);
/* Delete each member file using the underlying fapl */
diff --git a/src/H5FDprivate.h b/src/H5FDprivate.h
index a13e7af..1660f48 100644
--- a/src/H5FDprivate.h
+++ b/src/H5FDprivate.h
@@ -82,12 +82,22 @@ typedef struct {
} \
}
-/* Define structure to hold driver ID & info for FAPLs */
+/* Define structure to hold driver ID, info & configuration string for FAPLs */
typedef struct {
- hid_t driver_id; /* Driver's ID */
- const void *driver_info; /* Driver info, for open callbacks */
+ hid_t driver_id; /* Driver's ID */
+ const void *driver_info; /* Driver info, for open callbacks */
+ const char *driver_config_str; /* Driver configuration string */
} H5FD_driver_prop_t;
+/* Which kind of VFD field to use for searching */
+typedef enum H5FD_get_driver_kind_t {
+ H5FD_GET_DRIVER_BY_NAME, /* Name field is set */
+ H5FD_GET_DRIVER_BY_VALUE /* Value field is set */
+} H5FD_get_driver_kind_t;
+
+/* Forward declarations for prototype arguments */
+struct H5S_t;
+
/*****************************/
/* Library Private Variables */
/*****************************/
@@ -98,6 +108,7 @@ typedef struct {
/* Forward declarations for prototype arguments */
struct H5F_t;
+union H5PL_key_t;
H5_DLL int H5FD_term_interface(void);
H5_DLL herr_t H5FD_locate_signature(H5FD_t *file, haddr_t *sig_addr);
@@ -108,10 +119,17 @@ H5_DLL herr_t H5FD_sb_load(H5FD_t *file, const char *name, const uint8_t
H5_DLL void * H5FD_fapl_get(H5FD_t *file);
H5_DLL herr_t H5FD_free_driver_info(hid_t driver_id, const void *driver_info);
H5_DLL hid_t H5FD_register(const void *cls, size_t size, hbool_t app_ref);
+H5_DLL hid_t H5FD_register_driver_by_name(const char *name, hbool_t app_ref);
+H5_DLL hid_t H5FD_register_driver_by_value(H5FD_class_value_t value, hbool_t app_ref);
+H5_DLL htri_t H5FD_is_driver_registered_by_name(const char *driver_name, hid_t *registered_id);
+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, hbool_t is_api);
+H5_DLL hid_t H5FD_get_driver_id_by_value(H5FD_class_value_t value, hbool_t 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_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*/);
+H5_DLL herr_t H5FD_check_plugin_load(const H5FD_class_t *cls, const union H5PL_key_t *key, hbool_t *success);
H5_DLL haddr_t H5FD_alloc(H5FD_t *file, H5FD_mem_t type, struct H5F_t *f, hsize_t size, haddr_t *frag_addr,
hsize_t *frag_size);
H5_DLL herr_t H5FD_free(H5FD_t *file, H5FD_mem_t type, struct H5F_t *f, haddr_t addr, hsize_t size);
@@ -131,10 +149,10 @@ H5_DLL herr_t H5FD_read_vector(H5FD_t *file, uint32_t count, H5FD_mem_t types[]
H5_DLL herr_t H5FD_write_vector(H5FD_t *file, uint32_t count, H5FD_mem_t types[], haddr_t addrs[],
size_t sizes[], const void *bufs[] /* out */);
H5_DLL herr_t H5FD_read_selection(H5FD_t *file, H5FD_mem_t type, uint32_t count,
- const H5S_t *const *mem_spaces, const H5S_t *const *file_spaces,
+ const struct H5S_t *const *mem_spaces, const struct H5S_t *const *file_spaces,
haddr_t offsets[], size_t element_sizes[], void *bufs[] /* out */);
H5_DLL herr_t H5FD_write_selection(H5FD_t *file, H5FD_mem_t type, uint32_t count,
- const H5S_t *const *mem_spaces, const H5S_t *const *file_spaces,
+ const struct H5S_t *const *mem_spaces, const struct H5S_t *const *file_spaces,
haddr_t offsets[], size_t element_sizes[], const void *bufs[]);
H5_DLL herr_t H5FD_read_selection_id(H5FD_t *file, H5FD_mem_t type, uint32_t count, hid_t mem_space_ids[],
hid_t file_space_ids[], haddr_t offsets[], size_t element_sizes[],
diff --git a/src/H5FDpublic.h b/src/H5FDpublic.h
index b8f4f12..d774210 100644
--- a/src/H5FDpublic.h
+++ b/src/H5FDpublic.h
@@ -28,6 +28,39 @@
#define H5FD_VFD_DEFAULT 0 /* Default VFL driver value */
+/* VFD identifier values
+ * These are H5FD_class_value_t values, NOT hid_t values!
+ */
+#define H5_VFD_INVALID ((H5FD_class_value_t)(-1))
+#define H5_VFD_SEC2 ((H5FD_class_value_t)(0))
+#define H5_VFD_CORE ((H5FD_class_value_t)(1))
+#define H5_VFD_LOG ((H5FD_class_value_t)(2))
+#define H5_VFD_FAMILY ((H5FD_class_value_t)(3))
+#define H5_VFD_MULTI ((H5FD_class_value_t)(4))
+#define H5_VFD_STDIO ((H5FD_class_value_t)(5))
+#define H5_VFD_SPLITTER ((H5FD_class_value_t)(6))
+#ifdef H5_HAVE_PARALLEL
+#define H5_VFD_MPIO ((H5FD_class_value_t)(7))
+#endif
+#ifdef H5_HAVE_DIRECT
+#define H5_VFD_DIRECT ((H5FD_class_value_t)(8))
+#endif
+#ifdef H5_HAVE_MIRROR_VFD
+#define H5_VFD_MIRROR ((H5FD_class_value_t)(9))
+#endif
+#ifdef H5_HAVE_LIBHDFS
+#define H5_VFD_HDFS ((H5FD_class_value_t)(10))
+#endif
+#ifdef H5_HAVE_ROS3_VFD
+#define H5_VFD_ROS3 ((H5FD_class_value_t)(11))
+#endif
+
+/* VFD IDs below this value are reserved for library use. */
+#define H5_VFD_RESERVED 256
+
+/* Maximum VFD ID */
+#define H5_VFD_MAX 65535
+
/* Define VFL driver features that can be enabled on a per-driver basis */
/* These are returned with the 'query' function pointer in H5FD_class_t */
/*
@@ -137,6 +170,14 @@
* enabled may be used as the Write-Only (W/O) channel driver.
*/
#define H5FD_FEAT_DEFAULT_VFD_COMPATIBLE 0x00008000
+/*
+ * Defining H5FD_FEAT_MEMMANAGE for a VFL driver means that
+ * the driver uses special memory management routines or wishes
+ * to do memory management in a specific manner. Therefore, HDF5
+ * should request that the driver handle any memory management
+ * operations when appropriate.
+ */
+#define H5FD_FEAT_MEMMANAGE 0x00010000
/* ctl function definitions: */
#define H5FD_CTL_OPC_RESERVED 512 /* Opcodes below this value are reserved for library use */
@@ -152,6 +193,9 @@
#define H5FD_CTL__GET_MPI_COMMUNICATOR_OPCODE 2
#define H5FD_CTL__GET_MPI_RANK_OPCODE 3
#define H5FD_CTL__GET_MPI_SIZE_OPCODE 4
+#define H5FD_CTL__MEM_ALLOC 5
+#define H5FD_CTL__MEM_FREE 6
+#define H5FD_CTL__MEM_COPY 7
/* ctl function flags: */
@@ -213,6 +257,16 @@
/* Public Typedefs */
/*******************/
+/*
+ * File driver identifiers.
+ *
+ * Values 0 through 255 are for drivers defined by the HDF5 library.
+ * Values 256 through 511 are available for testing new drivers.
+ * Subsequent values should be obtained from the HDF5 development
+ * team at mailto:help@hdfgroup.org.
+ */
+typedef int H5FD_class_value_t;
+
/* Types of allocation requests: see H5Fpublic.h */
typedef enum H5F_mem_t H5FD_mem_t;
@@ -324,6 +378,19 @@ typedef struct {
} H5FD_file_image_callbacks_t;
//! <!-- [H5FD_file_image_callbacks_t_snip] -->
+/**
+ * Define structure to hold "ctl memory copy" parameters
+ */
+//! <!-- [H5FD_ctl_memcpy_args_t_snip] -->
+typedef struct H5FD_ctl_memcpy_args_t {
+ void * dstbuf; /**< Destination buffer */
+ hsize_t dst_off; /**< Offset within destination buffer */
+ const void *srcbuf; /**< Source buffer */
+ hsize_t src_off; /**< Offset within source buffer */
+ size_t len; /**< Length of data to copy from source buffer */
+} H5FD_ctl_memcpy_args_t;
+//! <!-- [H5FD_ctl_memcpy_args_t_snip] -->
+
/********************/
/* Public Variables */
/********************/
diff --git a/src/H5FDros3.c b/src/H5FDros3.c
index 0dd8cc3..6c855a1 100644
--- a/src/H5FDros3.c
+++ b/src/H5FDros3.c
@@ -237,6 +237,7 @@ static herr_t H5FD__ros3_truncate(H5FD_t *_file, hid_t dxpl_id, hbool_t closing
static herr_t H5FD__ros3_validate_config(const H5FD_ros3_fapl_t *fa);
static const H5FD_class_t H5FD_ros3_g = {
+ H5FD_ROS3_VALUE, /* value */
"ros3", /* name */
MAXADDR, /* maxaddr */
H5F_CLOSE_WEAK, /* fc_degree */
@@ -415,7 +416,7 @@ H5Pset_fapl_ros3(hid_t fapl_id, H5FD_ros3_fapl_t *fa)
if (FAIL == H5FD__ros3_validate_config(fa))
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid ros3 config")
- ret_value = H5P_set_driver(plist, H5FD_ROS3, (void *)fa);
+ ret_value = H5P_set_driver(plist, H5FD_ROS3, (void *)fa, NULL);
done:
FUNC_LEAVE_API(ret_value)
diff --git a/src/H5FDros3.h b/src/H5FDros3.h
index 8e42ca2..d69ebe4 100644
--- a/src/H5FDros3.h
+++ b/src/H5FDros3.h
@@ -22,9 +22,11 @@
#define H5FDros3_H
#ifdef H5_HAVE_ROS3_VFD
-#define H5FD_ROS3 (H5FD_ros3_init())
+#define H5FD_ROS3 (H5FD_ros3_init())
+#define H5FD_ROS3_VALUE H5_VFD_ROS3
#else
-#define H5FD_ROS3 (H5I_INVALID_HID)
+#define H5FD_ROS3 (H5I_INVALID_HID)
+#define H5FD_ROS3_VALUE H5_VFD_INVALID
#endif /* H5_HAVE_ROS3_VFD */
#ifdef H5_HAVE_ROS3_VFD
diff --git a/src/H5FDsec2.c b/src/H5FDsec2.c
index be59102..90844c1 100644
--- a/src/H5FDsec2.c
+++ b/src/H5FDsec2.c
@@ -143,6 +143,7 @@ static herr_t H5FD__sec2_ctl(H5FD_t *_file, uint64_t op_code, uint64_t flags, c
void **output);
static const H5FD_class_t H5FD_sec2_g = {
+ H5FD_SEC2_VALUE, /* value */
"sec2", /* name */
MAXADDR, /* maxaddr */
H5F_CLOSE_WEAK, /* fc_degree */
@@ -204,7 +205,7 @@ H5FD__init_package(void)
FUNC_ENTER_STATIC
/* Check the use disabled file locks environment variable */
- lock_env_var = HDgetenv("HDF5_USE_FILE_LOCKING");
+ lock_env_var = HDgetenv(HDF5_USE_FILE_LOCKING);
if (lock_env_var && !HDstrcmp(lock_env_var, "BEST_EFFORT"))
ignore_disabled_file_locks_s = TRUE; /* Override: Ignore disabled locks */
else if (lock_env_var && (!HDstrcmp(lock_env_var, "TRUE") || !HDstrcmp(lock_env_var, "1")))
@@ -299,7 +300,7 @@ H5Pset_fapl_sec2(hid_t fapl_id)
if (NULL == (plist = H5P_object_verify(fapl_id, H5P_FILE_ACCESS)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list")
- ret_value = H5P_set_driver(plist, H5FD_SEC2, NULL);
+ ret_value = H5P_set_driver(plist, H5FD_SEC2, NULL, NULL);
done:
FUNC_LEAVE_API(ret_value)
diff --git a/src/H5FDsec2.h b/src/H5FDsec2.h
index 541ac71..5c35677 100644
--- a/src/H5FDsec2.h
+++ b/src/H5FDsec2.h
@@ -20,7 +20,8 @@
#ifndef H5FDsec2_H
#define H5FDsec2_H
-#define H5FD_SEC2 (H5FD_sec2_init())
+#define H5FD_SEC2 (H5FD_sec2_init())
+#define H5FD_SEC2_VALUE H5_VFD_SEC2
#ifdef __cplusplus
extern "C" {
diff --git a/src/H5FDsplitter.c b/src/H5FDsplitter.c
index b178b5b..3e03c9f 100644
--- a/src/H5FDsplitter.c
+++ b/src/H5FDsplitter.c
@@ -104,6 +104,10 @@ static int H5FD__copy_plist(hid_t fapl_id, hid_t *id_out_ptr);
/* Prototypes */
static herr_t H5FD__splitter_term(void);
+static herr_t H5FD__splitter_populate_config(H5FD_splitter_vfd_config_t *vfd_config,
+ H5FD_splitter_fapl_t * fapl_out);
+static herr_t H5FD__splitter_get_default_wo_path(char *new_path, size_t new_path_len,
+ const char *base_filename);
static hsize_t H5FD__splitter_sb_size(H5FD_t *_file);
static herr_t H5FD__splitter_sb_encode(H5FD_t *_file, char *name /*out*/, unsigned char *buf /*out*/);
static herr_t H5FD__splitter_sb_decode(H5FD_t *_file, const char *name, const unsigned char *buf);
@@ -129,10 +133,12 @@ static herr_t H5FD__splitter_flush(H5FD_t *_file, hid_t dxpl_id, hbool_t closin
static herr_t H5FD__splitter_truncate(H5FD_t *_file, hid_t dxpl_id, hbool_t closing);
static herr_t H5FD__splitter_lock(H5FD_t *_file, hbool_t rw);
static herr_t H5FD__splitter_unlock(H5FD_t *_file);
+static herr_t H5FD__splitter_delete(const char *filename, hid_t fapl_id);
static herr_t H5FD__splitter_ctl(H5FD_t *_file, uint64_t op_code, uint64_t flags, const void *input,
void **output);
static const H5FD_class_t H5FD_splitter_g = {
+ H5FD_SPLITTER_VALUE, /* value */
"splitter", /* name */
MAXADDR, /* maxaddr */
H5F_CLOSE_WEAK, /* fc_degree */
@@ -140,7 +146,7 @@ static const H5FD_class_t H5FD_splitter_g = {
H5FD__splitter_sb_size, /* sb_size */
H5FD__splitter_sb_encode, /* sb_encode */
H5FD__splitter_sb_decode, /* sb_decode */
- sizeof(H5FD_splitter_fapl_t), /* fapl_size */
+ sizeof(H5FD_splitter_fapl_t), /* fapl_size */
H5FD__splitter_fapl_get, /* fapl_get */
H5FD__splitter_fapl_copy, /* fapl_copy */
H5FD__splitter_fapl_free, /* fapl_free */
@@ -151,7 +157,7 @@ static const H5FD_class_t H5FD_splitter_g = {
H5FD__splitter_close, /* close */
H5FD__splitter_cmp, /* cmp */
H5FD__splitter_query, /* query */
- H5FD__splitter_get_type_map, /* get_type_map */
+ H5FD__splitter_get_type_map, /* get_type_map */
H5FD__splitter_alloc, /* alloc */
H5FD__splitter_free, /* free */
H5FD__splitter_get_eoa, /* get_eoa */
@@ -168,7 +174,7 @@ static const H5FD_class_t H5FD_splitter_g = {
H5FD__splitter_truncate, /* truncate */
H5FD__splitter_lock, /* lock */
H5FD__splitter_unlock, /* unlock */
- NULL, /* del */
+ H5FD__splitter_delete, /* del */
H5FD__splitter_ctl, /* ctl */
H5FD_FLMAP_DICHOTOMY /* fl_map */
};
@@ -316,57 +322,14 @@ H5Pset_fapl_splitter(hid_t fapl_id, H5FD_splitter_vfd_config_t *vfd_config)
if (NULL == (plist_ptr = (H5P_genplist_t *)H5I_object(fapl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a valid property list")
- /* Make sure that the W/O channel supports write-only capability.
- * Some drivers (e.g. family or multi) do revision of the superblock
- * in-memory, causing problems in that channel.
- * Uses the feature flag H5FD_FEAT_DEFAULT_VFD_COMPATIBLE as the
- * determining attribute.
- */
- if (H5P_DEFAULT != vfd_config->wo_fapl_id) {
- H5FD_class_t * wo_driver = NULL;
- H5FD_driver_prop_t wo_driver_prop;
- H5P_genplist_t * wo_plist_ptr = NULL;
- unsigned long wo_driver_flags = 0;
-
- wo_plist_ptr = (H5P_genplist_t *)H5I_object(vfd_config->wo_fapl_id);
- if (NULL == wo_plist_ptr)
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list")
- if (H5P_peek(wo_plist_ptr, H5F_ACS_FILE_DRV_NAME, &wo_driver_prop) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get driver ID & info")
- wo_driver = (H5FD_class_t *)H5I_object(wo_driver_prop.driver_id);
- if (NULL == wo_driver)
- HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "invalid driver ID in file access property list")
- if (H5FD_driver_query(wo_driver, &wo_driver_flags) < 0)
- HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "can't query VFD flags")
- if (0 == (H5FD_FEAT_DEFAULT_VFD_COMPATIBLE & wo_driver_flags))
- HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "unsuitable W/O driver")
- } /* end if W/O VFD is non-default */
-
info = H5FL_CALLOC(H5FD_splitter_fapl_t);
if (NULL == info)
HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "unable to allocate file access property list struct")
- info->ignore_wo_errs = vfd_config->ignore_wo_errs;
- HDstrncpy(info->wo_path, vfd_config->wo_path, H5FD_SPLITTER_PATH_MAX + 1);
- info->wo_path[H5FD_SPLITTER_PATH_MAX] = '\0';
- HDstrncpy(info->log_file_path, vfd_config->log_file_path, H5FD_SPLITTER_PATH_MAX + 1);
- info->log_file_path[H5FD_SPLITTER_PATH_MAX] = '\0';
- info->rw_fapl_id = H5P_FILE_ACCESS_DEFAULT; /* pre-set value */
- info->wo_fapl_id = H5P_FILE_ACCESS_DEFAULT; /* pre-set value */
-
- /* Set non-default channel FAPL IDs in splitter configuration info */
- if (H5P_DEFAULT != vfd_config->rw_fapl_id) {
- if (FALSE == H5P_isa_class(vfd_config->rw_fapl_id, H5P_FILE_ACCESS))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access list")
- info->rw_fapl_id = vfd_config->rw_fapl_id;
- }
- if (H5P_DEFAULT != vfd_config->wo_fapl_id) {
- if (FALSE == H5P_isa_class(vfd_config->wo_fapl_id, H5P_FILE_ACCESS))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access list")
- info->wo_fapl_id = vfd_config->wo_fapl_id;
- }
+ if (H5FD__splitter_populate_config(vfd_config, info) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTSET, FAIL, "can't setup driver configuration")
- ret_value = H5P_set_driver(plist_ptr, H5FD_SPLITTER, info);
+ ret_value = H5P_set_driver(plist_ptr, H5FD_SPLITTER, info, NULL);
done:
if (info)
@@ -390,9 +353,10 @@ done:
herr_t
H5Pget_fapl_splitter(hid_t fapl_id, H5FD_splitter_vfd_config_t *config /*out*/)
{
- const H5FD_splitter_fapl_t *fapl_ptr = NULL;
- H5P_genplist_t * plist_ptr = NULL;
- herr_t ret_value = SUCCEED;
+ const H5FD_splitter_fapl_t *fapl_ptr = NULL;
+ H5FD_splitter_fapl_t * default_fapl = NULL;
+ H5P_genplist_t * plist_ptr = NULL;
+ herr_t ret_value = SUCCEED;
FUNC_ENTER_API(FAIL)
H5TRACE2("e", "ix", fapl_id, config);
@@ -418,8 +382,14 @@ H5Pget_fapl_splitter(hid_t fapl_id, H5FD_splitter_vfd_config_t *config /*out*/)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list")
if (H5FD_SPLITTER != H5P_peek_driver(plist_ptr))
HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "incorrect VFL driver")
- if (NULL == (fapl_ptr = (const H5FD_splitter_fapl_t *)H5P_peek_driver_info(plist_ptr)))
- HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "unable to get specific-driver info")
+ fapl_ptr = (const H5FD_splitter_fapl_t *)H5P_peek_driver_info(plist_ptr);
+ if (NULL == fapl_ptr) {
+ if (NULL == (default_fapl = H5FL_CALLOC(H5FD_splitter_fapl_t)))
+ HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "unable to allocate file access property list struct")
+ if (H5FD__splitter_populate_config(NULL, default_fapl) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTSET, FAIL, "can't initialize driver configuration info")
+ fapl_ptr = default_fapl;
+ }
HDstrncpy(config->wo_path, fapl_ptr->wo_path, H5FD_SPLITTER_PATH_MAX + 1);
HDstrncpy(config->log_file_path, fapl_ptr->log_file_path, H5FD_SPLITTER_PATH_MAX + 1);
@@ -432,10 +402,188 @@ H5Pget_fapl_splitter(hid_t fapl_id, H5FD_splitter_vfd_config_t *config /*out*/)
HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "can't copy W/O FAPL");
done:
+ if (default_fapl)
+ H5FL_FREE(H5FD_splitter_fapl_t, default_fapl);
+
FUNC_LEAVE_API(ret_value)
} /* end H5Pget_fapl_splitter() */
/*-------------------------------------------------------------------------
+ * Function: H5FD__splitter_populate_config
+ *
+ * Purpose: Populates a H5FD_splitter_fapl_t structure with the provided
+ * values, supplying defaults where values are not provided.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5FD__splitter_populate_config(H5FD_splitter_vfd_config_t *vfd_config, H5FD_splitter_fapl_t *fapl_out)
+{
+ H5P_genplist_t *def_plist;
+ H5P_genplist_t *plist;
+ hbool_t free_config = FALSE;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_STATIC
+
+ HDassert(fapl_out);
+
+ HDmemset(fapl_out, 0, sizeof(H5FD_splitter_fapl_t));
+
+ if (!vfd_config) {
+ vfd_config = H5MM_calloc(sizeof(H5FD_splitter_vfd_config_t));
+ if (NULL == vfd_config)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "unable to allocate file access property list struct")
+
+ vfd_config->magic = H5FD_SPLITTER_MAGIC;
+ vfd_config->version = H5FD_CURR_SPLITTER_VFD_CONFIG_VERSION;
+ vfd_config->rw_fapl_id = H5P_DEFAULT;
+ vfd_config->wo_fapl_id = H5P_DEFAULT;
+
+ free_config = TRUE;
+ }
+
+ /* Make sure that the W/O channel supports write-only capability.
+ * Some drivers (e.g. family or multi) do revision of the superblock
+ * in-memory, causing problems in that channel.
+ * Uses the feature flag H5FD_FEAT_DEFAULT_VFD_COMPATIBLE as the
+ * determining attribute.
+ */
+ if (H5P_DEFAULT != vfd_config->wo_fapl_id) {
+ H5FD_class_t * wo_driver = NULL;
+ H5FD_driver_prop_t wo_driver_prop;
+ H5P_genplist_t * wo_plist_ptr = NULL;
+ unsigned long wo_driver_flags = 0;
+
+ wo_plist_ptr = (H5P_genplist_t *)H5I_object(vfd_config->wo_fapl_id);
+ if (NULL == wo_plist_ptr)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list")
+ if (H5P_peek(wo_plist_ptr, H5F_ACS_FILE_DRV_NAME, &wo_driver_prop) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get driver ID & info")
+ wo_driver = (H5FD_class_t *)H5I_object(wo_driver_prop.driver_id);
+ if (NULL == wo_driver)
+ HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "invalid driver ID in file access property list")
+ if (H5FD_driver_query(wo_driver, &wo_driver_flags) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "can't query VFD flags")
+ if (0 == (H5FD_FEAT_DEFAULT_VFD_COMPATIBLE & wo_driver_flags))
+ HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "unsuitable W/O driver")
+ } /* end if W/O VFD is non-default */
+
+ fapl_out->ignore_wo_errs = vfd_config->ignore_wo_errs;
+ HDstrncpy(fapl_out->wo_path, vfd_config->wo_path, H5FD_SPLITTER_PATH_MAX + 1);
+ fapl_out->wo_path[H5FD_SPLITTER_PATH_MAX] = '\0';
+ HDstrncpy(fapl_out->log_file_path, vfd_config->log_file_path, H5FD_SPLITTER_PATH_MAX + 1);
+ fapl_out->log_file_path[H5FD_SPLITTER_PATH_MAX] = '\0';
+ fapl_out->rw_fapl_id = H5P_FILE_ACCESS_DEFAULT; /* pre-set value */
+ fapl_out->wo_fapl_id = H5P_FILE_ACCESS_DEFAULT; /* pre-set value */
+
+ if (NULL == (def_plist = (H5P_genplist_t *)H5I_object(H5P_FILE_ACCESS_DEFAULT)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list")
+
+ /* Set non-default channel FAPL IDs in splitter configuration info */
+ if (H5P_DEFAULT != vfd_config->rw_fapl_id) {
+ if (FALSE == H5P_isa_class(vfd_config->rw_fapl_id, H5P_FILE_ACCESS))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access list")
+ fapl_out->rw_fapl_id = vfd_config->rw_fapl_id;
+ }
+ else {
+ /* Use copy of default file access property list for R/W channel FAPL ID.
+ * The Sec2 driver is explicitly set on the FAPL ID, as the default
+ * driver might have been replaced with the Splitter VFD, which
+ * would cause recursion badness.
+ */
+ if ((fapl_out->rw_fapl_id = H5P_copy_plist(def_plist, FALSE)) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTCOPY, FAIL, "can't copy property list")
+ if (NULL == (plist = (H5P_genplist_t *)H5I_object(fapl_out->rw_fapl_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list")
+ if (H5P_set_driver_by_value(plist, H5_VFD_SEC2, NULL, TRUE) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTSET, FAIL, "can't set default driver on R/W channel FAPL")
+ }
+ if (H5P_DEFAULT != vfd_config->wo_fapl_id) {
+ if (FALSE == H5P_isa_class(vfd_config->wo_fapl_id, H5P_FILE_ACCESS))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access list")
+ fapl_out->wo_fapl_id = vfd_config->wo_fapl_id;
+ }
+ else {
+ /* Use copy of default file access property list for W/O channel FAPL ID.
+ * The Sec2 driver is explicitly set on the FAPL ID, as the default
+ * driver might have been replaced with the Splitter VFD, which
+ * would cause recursion badness.
+ */
+ if ((fapl_out->wo_fapl_id = H5P_copy_plist(def_plist, FALSE)) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTCOPY, FAIL, "can't copy property list")
+ if (NULL == (plist = (H5P_genplist_t *)H5I_object(fapl_out->wo_fapl_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list")
+ if (H5P_set_driver_by_value(plist, H5_VFD_SEC2, NULL, TRUE) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTSET, FAIL, "can't set default driver on R/W channel FAPL")
+ }
+
+done:
+ if (free_config && vfd_config)
+ H5MM_free(vfd_config);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5FD__splitter_populate_config() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5FD__splitter_get_default_wo_path
+ *
+ * Purpose: Given a base filename, returns a default filename for the
+ * W/O channel file by appending '_wo' to the base file name.
+ *
+ * Return: Non-negative on Success/Negative on Failure
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5FD__splitter_get_default_wo_path(char *new_path, size_t new_path_len, const char *base_filename)
+{
+ const char *suffix = "_wo";
+ size_t old_filename_len = 0;
+ char * file_extension = NULL;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_STATIC
+
+ HDassert(new_path);
+ HDassert(base_filename);
+
+ /* Check that output buffer can hold base filename + `_wo` suffix */
+ old_filename_len = HDstrlen(base_filename);
+ if (old_filename_len > H5FD_SPLITTER_PATH_MAX - HDstrlen(suffix) - 1)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTSET, FAIL, "filename exceeds max length")
+
+ /* Determine if filename contains a ".h5" extension. */
+ if ((file_extension = strstr(base_filename, ".h5"))) {
+ /* Insert the suffix between the filename and ".h5" extension. */
+ HDstrcpy(new_path, base_filename);
+ file_extension = strstr(new_path, ".h5");
+ HDsprintf(file_extension, "%s%s", suffix, ".h5");
+ }
+ else if ((file_extension = strrchr(base_filename, '.'))) {
+ char *new_extension_loc = NULL;
+
+ /* If the filename doesn't contain a ".h5" extension, but contains
+ * AN extension, just insert the suffix before that extension.
+ */
+ HDstrcpy(new_path, base_filename);
+ new_extension_loc = strrchr(new_path, '.');
+ HDsprintf(new_extension_loc, "%s%s", suffix, file_extension);
+ }
+ else {
+ /* If the filename doesn't contain an extension at all, just insert
+ * the suffix at the end of the filename.
+ */
+ HDsnprintf(new_path, new_path_len, "%s%s", base_filename, suffix);
+ }
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5FD__splitter_get_default_wo_path() */
+
+/*-------------------------------------------------------------------------
* Function: H5FD__splitter_flush
*
* Purpose: Flushes all data to disk for both channels.
@@ -662,10 +810,11 @@ done:
static H5FD_t *
H5FD__splitter_open(const char *name, unsigned flags, hid_t splitter_fapl_id, haddr_t maxaddr)
{
- H5FD_splitter_t * file_ptr = NULL; /* Splitter VFD info */
- const H5FD_splitter_fapl_t *fapl_ptr = NULL; /* Driver-specific property list */
- H5P_genplist_t * plist_ptr = NULL;
- H5FD_t * ret_value = NULL;
+ H5FD_splitter_t * file_ptr = NULL; /* Splitter VFD info */
+ const H5FD_splitter_fapl_t *fapl_ptr = NULL; /* Driver-specific property list */
+ H5FD_splitter_fapl_t * default_fapl = NULL;
+ H5P_genplist_t * plist_ptr = NULL;
+ H5FD_t * ret_value = NULL;
FUNC_ENTER_STATIC
@@ -678,8 +827,7 @@ H5FD__splitter_open(const char *name, unsigned flags, hid_t splitter_fapl_id, ha
HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, NULL, "bogus maxaddr")
if (ADDR_OVERFLOW(maxaddr))
HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, NULL, "bogus maxaddr")
- if ((H5P_FILE_ACCESS_DEFAULT == splitter_fapl_id) || (H5FD_SPLITTER != H5Pget_driver(splitter_fapl_id)))
- /* presupposes that H5P_FILE_ACCESS_DEFAULT is not a splitter */
+ if (H5FD_SPLITTER != H5Pget_driver(splitter_fapl_id))
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "driver is not splitter")
file_ptr = (H5FD_splitter_t *)H5FL_CALLOC(H5FD_splitter_t);
@@ -693,8 +841,20 @@ H5FD__splitter_open(const char *name, unsigned flags, hid_t splitter_fapl_id, ha
if (NULL == plist_ptr)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file access property list")
fapl_ptr = (const H5FD_splitter_fapl_t *)H5P_peek_driver_info(plist_ptr);
- if (NULL == fapl_ptr)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "unable to get VFL driver info")
+ if (NULL == fapl_ptr) {
+ if (NULL == (default_fapl = H5FL_CALLOC(H5FD_splitter_fapl_t)))
+ HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, NULL, "unable to allocate file access property list struct")
+ if (H5FD__splitter_populate_config(NULL, default_fapl) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTSET, NULL, "can't initialize driver configuration info")
+
+ /* If W/O path is not set, use base filename with '_wo' suffix */
+ if (*default_fapl->wo_path == '\0')
+ if (H5FD__splitter_get_default_wo_path(default_fapl->wo_path, H5FD_SPLITTER_PATH_MAX + 1, name) <
+ 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTSET, NULL, "can't generate default filename for W/O channel")
+
+ fapl_ptr = default_fapl;
+ }
/* Copy simpler info */
HDstrncpy(file_ptr->fa.wo_path, fapl_ptr->wo_path, H5FD_SPLITTER_PATH_MAX + 1);
@@ -730,6 +890,9 @@ H5FD__splitter_open(const char *name, unsigned flags, hid_t splitter_fapl_id, ha
ret_value = (H5FD_t *)file_ptr;
done:
+ if (default_fapl)
+ H5FL_FREE(H5FD_splitter_fapl_t, default_fapl);
+
if (NULL == ret_value) {
if (file_ptr) {
if (H5I_INVALID_HID != file_ptr->fa.rw_fapl_id)
@@ -1343,6 +1506,74 @@ done:
} /* end H5FD__splitter_free() */
/*-------------------------------------------------------------------------
+ * Function: H5FD__splitter_delete
+ *
+ * Purpose: Delete a file
+ *
+ * Return: SUCCEED/FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5FD__splitter_delete(const char *filename, hid_t fapl_id)
+{
+ const H5FD_splitter_fapl_t *fapl_ptr = NULL;
+ H5FD_splitter_fapl_t * default_fapl = NULL;
+ H5P_genplist_t * plist;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_STATIC
+
+ HDassert(filename);
+
+ /* Get the driver info */
+ if (H5P_FILE_ACCESS_DEFAULT == fapl_id) {
+ if (NULL == (default_fapl = H5FL_CALLOC(H5FD_splitter_fapl_t)))
+ HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "unable to allocate file access property list struct")
+ if (H5FD__splitter_populate_config(NULL, default_fapl) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTSET, FAIL, "can't initialize driver configuration info")
+
+ /* If W/O path is not set, use base filename with '_wo' suffix */
+ if (*default_fapl->wo_path == '\0')
+ if (H5FD__splitter_get_default_wo_path(default_fapl->wo_path, H5FD_SPLITTER_PATH_MAX + 1,
+ filename) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTSET, FAIL, "can't generate default filename for W/O channel")
+
+ fapl_ptr = default_fapl;
+ }
+ else {
+ if (NULL == (plist = (H5P_genplist_t *)H5I_object(fapl_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list")
+ if (NULL == (fapl_ptr = (const H5FD_splitter_fapl_t *)H5P_peek_driver_info(plist))) {
+ if (NULL == (default_fapl = H5FL_CALLOC(H5FD_splitter_fapl_t)))
+ HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL,
+ "unable to allocate file access property list struct")
+ if (H5FD__splitter_populate_config(NULL, default_fapl) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTSET, FAIL, "can't initialize driver configuration info")
+
+ /* If W/O path is not set, use base filename with '_wo' suffix */
+ if (*default_fapl->wo_path == '\0')
+ if (H5FD__splitter_get_default_wo_path(default_fapl->wo_path, H5FD_SPLITTER_PATH_MAX + 1,
+ filename) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTSET, FAIL, "can't generate default filename for W/O channel")
+
+ fapl_ptr = default_fapl;
+ }
+ }
+
+ if (H5FDdelete(filename, fapl_ptr->rw_fapl_id) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTDELETEFILE, FAIL, "unable to delete file")
+ if (H5FDdelete(fapl_ptr->wo_path, fapl_ptr->wo_fapl_id) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTDELETEFILE, FAIL, "unable to delete W/O channel file")
+
+done:
+ if (default_fapl)
+ H5FL_FREE(H5FD_splitter_fapl_t, default_fapl);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+}
+
+/*-------------------------------------------------------------------------
* Function: H5FD__splitter_log_error
*
* Purpose: Log an error from the W/O channel appropriately.
diff --git a/src/H5FDsplitter.h b/src/H5FDsplitter.h
index ee6e7c5..3a743e4 100644
--- a/src/H5FDsplitter.h
+++ b/src/H5FDsplitter.h
@@ -17,7 +17,8 @@
#ifndef H5FDsplitter_H
#define H5FDsplitter_H
-#define H5FD_SPLITTER (H5FD_splitter_init())
+#define H5FD_SPLITTER (H5FD_splitter_init())
+#define H5FD_SPLITTER_VALUE H5_VFD_SPLITTER
/* The version of the H5FD_splitter_vfd_config_t structure used */
#define H5FD_CURR_SPLITTER_VFD_CONFIG_VERSION 1
diff --git a/src/H5FDstdio.c b/src/H5FDstdio.c
index f9cf350..22d6323 100644
--- a/src/H5FDstdio.c
+++ b/src/H5FDstdio.c
@@ -183,6 +183,7 @@ static herr_t H5FD_stdio_unlock(H5FD_t *_file);
static herr_t H5FD_stdio_delete(const char *filename, hid_t fapl_id);
static const H5FD_class_t H5FD_stdio_g = {
+ H5_VFD_STDIO, /* value */
"stdio", /* name */
MAXADDR, /* maxaddr */
H5F_CLOSE_WEAK, /* fc_degree */
@@ -247,7 +248,7 @@ H5FD_stdio_init(void)
H5Eclear2(H5E_DEFAULT);
/* Check the use disabled file locks environment variable */
- lock_env_var = getenv("HDF5_USE_FILE_LOCKING");
+ lock_env_var = getenv(HDF5_USE_FILE_LOCKING);
if (lock_env_var && !strcmp(lock_env_var, "BEST_EFFORT"))
ignore_disabled_file_locks_s = 1; /* Override: Ignore disabled locks */
else if (lock_env_var && (!strcmp(lock_env_var, "TRUE") || !strcmp(lock_env_var, "1")))
diff --git a/src/H5FDwindows.c b/src/H5FDwindows.c
index 6ce33a7..fa3c05f 100644
--- a/src/H5FDwindows.c
+++ b/src/H5FDwindows.c
@@ -56,7 +56,7 @@ H5Pset_fapl_windows(hid_t fapl_id)
if (NULL == (plist = H5P_object_verify(fapl_id, H5P_FILE_ACCESS)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list")
- ret_value = H5P_set_driver(plist, H5FD_WINDOWS, NULL);
+ ret_value = H5P_set_driver(plist, H5FD_WINDOWS, NULL, NULL);
done:
FUNC_LEAVE_API(ret_value)
diff --git a/src/H5Fint.c b/src/H5Fint.c
index c2d3e77..d772088 100644
--- a/src/H5Fint.c
+++ b/src/H5Fint.c
@@ -277,7 +277,7 @@ H5F__parse_file_lock_env_var(htri_t *use_locks)
FUNC_ENTER_PACKAGE_NOERR
/* Check the file locking environment variable */
- lock_env_var = HDgetenv("HDF5_USE_FILE_LOCKING");
+ lock_env_var = HDgetenv(HDF5_USE_FILE_LOCKING);
if (lock_env_var && (!HDstrcmp(lock_env_var, "FALSE") || !HDstrcmp(lock_env_var, "0")))
*use_locks = FALSE; /* Override: Never use locks */
else if (lock_env_var && (!HDstrcmp(lock_env_var, "TRUE") || !HDstrcmp(lock_env_var, "BEST_EFFORT") ||
@@ -454,9 +454,10 @@ H5F_get_access_plist(H5F_t *f, hbool_t app_ref)
HGOTO_ERROR(H5E_FILE, H5E_CANTSET, H5I_INVALID_HID, "can't set initial metadata cache resize config.")
/* Prepare the driver property */
- driver_prop.driver_id = f->shared->lf->driver_id;
- driver_prop.driver_info = H5FD_fapl_get(f->shared->lf);
- driver_prop_copied = TRUE;
+ driver_prop.driver_id = f->shared->lf->driver_id;
+ driver_prop.driver_info = H5FD_fapl_get(f->shared->lf);
+ driver_prop.driver_config_str = H5P_peek_driver_config_str(old_plist);
+ driver_prop_copied = TRUE;
/* Set the driver property */
if (H5P_set(new_plist, H5F_ACS_FILE_DRV_NAME, &driver_prop) < 0)
@@ -1828,7 +1829,13 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id)
else
tent_flags = flags;
- if (NULL == (lf = H5FD_open(name, tent_flags, fapl_id, HADDR_UNDEF))) {
+ H5E_BEGIN_TRY
+ {
+ lf = H5FD_open(name, tent_flags, fapl_id, HADDR_UNDEF);
+ }
+ H5E_END_TRY;
+
+ if (NULL == lf) {
if (tent_flags == flags)
HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to open file: name = '%s', tent_flags = %x",
name, tent_flags)
diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h
index a6c2f8a..354226b 100644
--- a/src/H5Fprivate.h
+++ b/src/H5Fprivate.h
@@ -24,11 +24,9 @@ typedef struct H5F_t H5F_t;
/* Include package's public header */
#include "H5Fpublic.h"
-/* Public headers needed by this file */
-#include "H5FDpublic.h" /* File drivers */
-
/* Private headers needed by this file */
#include "H5MMprivate.h" /* Memory management */
+#include "H5FDprivate.h" /* File drivers */
#ifdef H5_HAVE_PARALLEL
#include "H5Pprivate.h" /* Property lists */
#endif /* H5_HAVE_PARALLEL */
@@ -907,6 +905,7 @@ H5_DLL hbool_t H5F_shared_has_feature(const H5F_shared_t *f, unsigned feature);
H5_DLL hbool_t H5F_has_feature(const H5F_t *f, unsigned feature);
H5_DLL haddr_t H5F_shared_get_eoa(const H5F_shared_t *f_sh, H5FD_mem_t type);
H5_DLL haddr_t H5F_get_eoa(const H5F_t *f, H5FD_mem_t type);
+H5_DLL herr_t H5F_shared_get_file_driver(const H5F_shared_t *f_sh, H5FD_t **file_handle);
H5_DLL herr_t H5F_get_vfd_handle(const H5F_t *file, hid_t fapl, void **file_handle);
/* File mounting routines */
diff --git a/src/H5Fquery.c b/src/H5Fquery.c
index 04792b4..a625897 100644
--- a/src/H5Fquery.c
+++ b/src/H5Fquery.c
@@ -950,6 +950,29 @@ done:
} /* end H5F_get_eoa() */
/*-------------------------------------------------------------------------
+ * Function: H5F_shared_get_file_driver
+ *
+ * Purpose: Returns a pointer to the file driver structure of the
+ * file's 'shared' structure.
+ *
+ * Return: file handle on success/abort on failure (shouldn't fail)
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5F_shared_get_file_driver(const H5F_shared_t *f_sh, H5FD_t **file_handle)
+{
+ /* Use FUNC_ENTER_NOAPI_NOINIT_NOERR here to avoid performance issues */
+ FUNC_ENTER_NOAPI_NOINIT_NOERR
+
+ HDassert(f_sh);
+ HDassert(file_handle);
+
+ *file_handle = f_sh->lf;
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5F_shared_get_file_driver() */
+
+/*-------------------------------------------------------------------------
* Function: H5F_get_vfd_handle
*
* Purpose: Returns a pointer to the file handle of the low-level file
diff --git a/src/H5Gprivate.h b/src/H5Gprivate.h
index 4cf4623..d1725f6 100644
--- a/src/H5Gprivate.h
+++ b/src/H5Gprivate.h
@@ -130,7 +130,7 @@ typedef enum {
typedef int H5G_own_loc_t;
/* Structure to store information about the name an object was opened with */
-typedef struct {
+typedef struct H5G_name_t {
H5RS_str_t *full_path_r; /* Path to object, as seen from root of current file mounting hierarchy */
H5RS_str_t *user_path_r; /* Path to object, as opened by user */
unsigned obj_hidden; /* Whether the object is visible in group hier. */
diff --git a/src/H5PLint.c b/src/H5PLint.c
index d20401e..848bd1d 100644
--- a/src/H5PLint.c
+++ b/src/H5PLint.c
@@ -144,7 +144,7 @@ H5PL__init_package(void)
* to ignore plugins. The special symbol H5PL_NO_PLUGIN (defined in
* H5PLpublic.h) means we don't want to load plugins.
*/
- if (NULL != (env_var = HDgetenv("HDF5_PLUGIN_PRELOAD")))
+ if (NULL != (env_var = HDgetenv(HDF5_PLUGIN_PRELOAD)))
if (!HDstrcmp(env_var, H5PL_NO_PLUGIN)) {
H5PL_plugin_control_mask_g = 0;
H5PL_allow_plugins_g = FALSE;
@@ -243,6 +243,11 @@ H5PL_load(H5PL_type_t type, const H5PL_key_t *key)
"Virtual Object Layer (VOL) driver plugins disabled")
break;
+ case H5PL_TYPE_VFD:
+ if ((H5PL_plugin_control_mask_g & H5PL_VFD_PLUGIN) == 0)
+ HGOTO_ERROR(H5E_PLUGIN, H5E_CANTLOAD, NULL, "Virtual File Driver (VFD) plugins disabled")
+ break;
+
case H5PL_TYPE_ERROR:
case H5PL_TYPE_NONE:
default:
@@ -275,9 +280,31 @@ done:
*
* Purpose: Opens a plugin.
*
- * The success parameter will be set to TRUE and the plugin_info
- * parameter will be filled in on success. Otherwise, they
- * will be FALSE and NULL, respectively.
+ * `path` specifies the path to the plugin library file.
+ *
+ * `type` specifies the type of plugin being searched for and
+ * will be used to verify that a loaded plugin matches the
+ * type requested. H5PL_TYPE_NONE may be passed, in which case
+ * no plugin type verification is performed. This is most
+ * useful when iterating over available plugins without regard
+ * to their types.
+ *
+ * `key` specifies the information that will be used to find a
+ * specific plugin. For filter plugins, this is typically an
+ * integer identifier. For VOL connector and VFD plugins, this
+ * is typically either an integer identifier or a name string.
+ * After a plugin has been opened, this information will be
+ * compared against the relevant information provided by the
+ * plugin to ensure that the plugin is a match. If
+ * H5PL_TYPE_NONE is provided for `type`, then `key` should be
+ * NULL.
+ *
+ * On successful open of a plugin, the `success` parameter
+ * will be set to TRUE and the `plugin_type` and `plugin_info`
+ * parameters will be filled appropriately. On failure, the
+ * `success` parameter will be set to FALSE, the `plugin_type`
+ * parameter will be set to H5PL_TYPE_ERROR and the
+ * `plugin_info` parameter will be set to NULL.
*
* Return: SUCCEED/FAIL
*
@@ -308,6 +335,8 @@ H5PL__open(const char *path, H5PL_type_t type, const H5PL_key_t *key, hbool_t *s
/* Check args - Just assert on package functions */
HDassert(path);
+ if (type == H5PL_TYPE_NONE)
+ HDassert(!key);
HDassert(success);
HDassert(plugin_info);
@@ -396,6 +425,34 @@ H5PL__open(const char *path, H5PL_type_t type, const H5PL_key_t *key, hbool_t *s
break;
}
+ case H5PL_TYPE_VFD: {
+ const void *cls;
+
+ /* Get the plugin info */
+ if (NULL == (cls = (const void *)(*get_plugin_info)()))
+ HGOTO_ERROR(H5E_PLUGIN, H5E_CANTGET, FAIL, "can't get VFD info from plugin")
+
+ /* Setup temporary plugin key if one wasn't supplied */
+ if (!key) {
+ tmp_key.vfd.kind = H5FD_GET_DRIVER_BY_NAME;
+ tmp_key.vfd.u.name = ((const H5FD_class_t *)cls)->name;
+ key = &tmp_key;
+ }
+
+ /* Ask VFD interface if this class is the one we are looking for and is compatible, etc */
+ if (H5FD_check_plugin_load(cls, key, success) < 0)
+ HGOTO_ERROR(H5E_PLUGIN, H5E_CANTLOAD, FAIL, "VFD compatibility check failed")
+
+ /* Check for finding the correct plugin */
+ if (*success) {
+ if (plugin_type)
+ *plugin_type = H5PL_TYPE_VFD;
+ *plugin_info = cls;
+ }
+
+ break;
+ }
+
case H5PL_TYPE_ERROR:
case H5PL_TYPE_NONE:
default:
diff --git a/src/H5PLpath.c b/src/H5PLpath.c
index 39a7d0d..9aecad1 100644
--- a/src/H5PLpath.c
+++ b/src/H5PLpath.c
@@ -248,7 +248,7 @@ H5PL__create_path_table(void)
/* Retrieve paths from HDF5_PLUGIN_PATH if the user sets it
* or from the default paths if it isn't set.
*/
- env_var = HDgetenv("HDF5_PLUGIN_PATH");
+ env_var = HDgetenv(HDF5_PLUGIN_PATH);
if (NULL == env_var)
paths = H5MM_strdup(H5PL_DEFAULT_PATH);
else
@@ -571,12 +571,12 @@ H5PL__path_table_iterate(H5PL_iterate_type_t iter_type, H5PL_iterate_t iter_op,
FUNC_ENTER_PACKAGE
- for (u = 0; (u < H5PL_num_paths_g) && (ret_value == H5_ITER_CONT); u++)
- ret_value = H5PL__path_table_iterate_process_path(H5PL_paths_g[u], iter_type, iter_op, op_data);
-
- if (ret_value < 0)
- HGOTO_ERROR(H5E_PLUGIN, H5E_BADITER, H5_ITER_ERROR, "can't iterate over plugins in plugin path '%s'",
- H5PL_paths_g[u]);
+ for (u = 0; (u < H5PL_num_paths_g) && (ret_value == H5_ITER_CONT); u++) {
+ if ((ret_value =
+ H5PL__path_table_iterate_process_path(H5PL_paths_g[u], iter_type, iter_op, op_data)) < 0)
+ HGOTO_ERROR(H5E_PLUGIN, H5E_BADITER, H5_ITER_ERROR,
+ "can't iterate over plugins in plugin path '%s'", H5PL_paths_g[u]);
+ }
done:
FUNC_LEAVE_NOAPI(ret_value);
@@ -615,9 +615,9 @@ H5PL__path_table_iterate_process_path(const char *plugin_path, H5PL_iterate_type
HDassert(plugin_path);
HDassert(iter_op);
- /* Open the directory */
+ /* Open the directory - skip the path if the directory can't be opened */
if (!(dirp = HDopendir(plugin_path)))
- HGOTO_ERROR(H5E_PLUGIN, H5E_OPENERROR, H5_ITER_ERROR, "can't open directory: %s", plugin_path)
+ HGOTO_DONE(H5_ITER_CONT)
/* Iterate through all entries in the directory */
while (NULL != (dp = HDreaddir(dirp))) {
@@ -663,7 +663,8 @@ H5PL__path_table_iterate_process_path(const char *plugin_path, H5PL_iterate_type
/* Determine if we should process this plugin */
plugin_matches = (iter_type == H5PL_ITER_TYPE_ALL) ||
((iter_type == H5PL_ITER_TYPE_FILTER) && (plugin_type == H5PL_TYPE_FILTER)) ||
- ((iter_type == H5PL_ITER_TYPE_VOL) && (plugin_type == H5PL_TYPE_VOL));
+ ((iter_type == H5PL_ITER_TYPE_VOL) && (plugin_type == H5PL_TYPE_VOL)) ||
+ ((iter_type == H5PL_ITER_TYPE_VFD) && (plugin_type == H5PL_TYPE_VFD));
/* If the plugin was successfully loaded, call supplied callback function on plugin */
if (plugin_loaded && plugin_matches && (ret_value = iter_op(plugin_type, plugin_info, op_data)))
@@ -706,10 +707,11 @@ H5PL__path_table_iterate_process_path(const char *plugin_path, H5PL_iterate_type
HDassert(plugin_path);
HDassert(iter_op);
- /* Specify a file mask. *.* = We want everything! */
+ /* Specify a file mask. *.* = We want everything! -
+ * skip the path if the directory can't be opened */
HDsprintf(service, "%s\\*.dll", plugin_path);
if ((hFind = FindFirstFileA(service, &fdFile)) == INVALID_HANDLE_VALUE)
- HGOTO_ERROR(H5E_PLUGIN, H5E_OPENERROR, H5_ITER_ERROR, "can't open directory")
+ HGOTO_DONE(H5_ITER_CONT)
/* Loop over all the files */
do {
@@ -740,7 +742,8 @@ H5PL__path_table_iterate_process_path(const char *plugin_path, H5PL_iterate_type
/* Determine if we should process this plugin */
plugin_matches = (iter_type == H5PL_ITER_TYPE_ALL) ||
((iter_type == H5PL_ITER_TYPE_FILTER) && (plugin_type == H5PL_TYPE_FILTER)) ||
- ((iter_type == H5PL_ITER_TYPE_VOL) && (plugin_type == H5PL_TYPE_VOL));
+ ((iter_type == H5PL_ITER_TYPE_VOL) && (plugin_type == H5PL_TYPE_VOL)) ||
+ ((iter_type == H5PL_ITER_TYPE_VFD) && (plugin_type == H5PL_TYPE_VFD));
/* If the plugin was successfully loaded, call supplied callback function on plugin */
if (plugin_loaded && plugin_matches && (ret_value = iter_op(plugin_type, plugin_info, op_data)))
diff --git a/src/H5PLplugin_cache.c b/src/H5PLplugin_cache.c
index b7cdac0..25e373f 100644
--- a/src/H5PLplugin_cache.c
+++ b/src/H5PLplugin_cache.c
@@ -263,59 +263,99 @@ H5PL__find_plugin_in_cache(const H5PL_search_params_t *search_params, hbool_t *f
/* Loop over all the plugins, looking for one that matches */
for (u = 0; u < H5PL_num_plugins_g; u++) {
- /* If the plugin type (filter, VOL connector, etc.) match, proceed */
- if (search_params->type == H5PL_cache_g[u].type) {
- hbool_t matched = FALSE; /* Whether cached plugin info matches */
+ hbool_t matched = FALSE; /* Whether cached plugin info matches */
- switch (search_params->type) {
- case H5PL_TYPE_FILTER:
- if (search_params->key->id == H5PL_cache_g[u].key.id)
+ /* Determine if the plugin types match */
+ if (search_params->type != H5PL_cache_g[u].type)
+ continue;
+
+ /* Determine if cache entry matches based on type-specific information */
+ switch (search_params->type) {
+ case H5PL_TYPE_FILTER:
+ /* Check if specified filter plugin ID matches cache entry's ID */
+ if (search_params->key->id == H5PL_cache_g[u].key.id)
+ matched = TRUE;
+
+ break;
+
+ case H5PL_TYPE_VOL:
+ if (search_params->key->vol.kind == H5VL_GET_CONNECTOR_BY_NAME) {
+ /* Make sure the plugin cache entry key type matches our search key type */
+ if (H5PL_cache_g[u].key.vol.kind != H5VL_GET_CONNECTOR_BY_NAME)
+ continue;
+
+ /* Check if specified VOL connector name matches cache entry's name */
+ if (!HDstrcmp(search_params->key->vol.u.name, H5PL_cache_g[u].key.vol.u.name))
+ matched = TRUE;
+ }
+ else {
+ HDassert(search_params->key->vol.kind == H5VL_GET_CONNECTOR_BY_VALUE);
+
+ /* Make sure the plugin cache entry key type matches our search key type */
+ if (H5PL_cache_g[u].key.vol.kind != H5VL_GET_CONNECTOR_BY_VALUE)
+ continue;
+
+ /* Check if specified VOL connector ID matches cache entry's ID */
+ if (search_params->key->vol.u.value == H5PL_cache_g[u].key.vol.u.value)
+ matched = TRUE;
+ }
+
+ break;
+
+ case H5PL_TYPE_VFD:
+ if (search_params->key->vfd.kind == H5FD_GET_DRIVER_BY_NAME) {
+ /* Make sure the plugin cache entry key type matches our search key type */
+ if (H5PL_cache_g[u].key.vfd.kind != H5FD_GET_DRIVER_BY_NAME)
+ continue;
+
+ /* Check if specified VFD name matches cache entry's name */
+ if (!HDstrcmp(search_params->key->vfd.u.name, H5PL_cache_g[u].key.vfd.u.name))
matched = TRUE;
- break;
-
- case H5PL_TYPE_VOL:
- if (search_params->key->vol.kind == H5VL_GET_CONNECTOR_BY_VALUE) {
- if (search_params->key->vol.u.value == H5PL_cache_g[u].key.vol.u.value)
- matched = TRUE;
- } /* end if */
- else if (search_params->key->vol.kind == H5VL_GET_CONNECTOR_BY_NAME) {
- if (0 == HDstrcmp(search_params->key->vol.u.name, H5PL_cache_g[u].key.vol.u.name))
- matched = TRUE;
- } /* end else-if */
- else
- HGOTO_ERROR(H5E_PLUGIN, H5E_BADVALUE, FAIL, "bad VOL plugin search key type")
- break;
-
- case H5PL_TYPE_ERROR:
- case H5PL_TYPE_NONE:
- default:
- HGOTO_ERROR(H5E_PLUGIN, H5E_BADVALUE, FAIL, "bad plugin type")
- } /* end switch */
-
- /* If the plugin type (filter, VOL connector, etc.) and key match, query the plugin for its info
- */
- if (matched) {
- H5PL_get_plugin_info_t get_plugin_info_function;
- const void * info;
-
- /* Get the "get plugin info" function from the plugin. */
- if (NULL == (get_plugin_info_function = (H5PL_get_plugin_info_t)H5PL_GET_LIB_FUNC(
- (H5PL_cache_g[u]).handle, "H5PLget_plugin_info")))
- HGOTO_ERROR(H5E_PLUGIN, H5E_CANTGET, FAIL, "can't get function for H5PLget_plugin_info")
-
- /* Call the "get plugin info" function */
- if (NULL == (info = (*get_plugin_info_function)()))
- HGOTO_ERROR(H5E_PLUGIN, H5E_CANTGET, FAIL, "can't get plugin info")
-
- /* Set output parameters */
- *found = TRUE;
- *plugin_info = info;
-
- /* No need to continue processing */
+ }
+ else {
+ HDassert(search_params->key->vfd.kind == H5FD_GET_DRIVER_BY_VALUE);
+
+ /* Make sure the plugin cache entry key type matches our search key type */
+ if (H5PL_cache_g[u].key.vfd.kind != H5FD_GET_DRIVER_BY_VALUE)
+ continue;
+
+ /* Check if specified VFD ID matches cache entry's ID */
+ if (search_params->key->vfd.u.value == H5PL_cache_g[u].key.vfd.u.value)
+ matched = TRUE;
+ }
+
break;
- } /* end if */
- } /* end if */
- } /* end for */
+
+ case H5PL_TYPE_ERROR:
+ case H5PL_TYPE_NONE:
+ default:
+ HGOTO_ERROR(H5E_PLUGIN, H5E_CANTGET, FAIL, "Invalid plugin type specified")
+ }
+
+ /* If the plugin type (filter, VOL connector, VFD plugin, etc.) and key match,
+ * query the plugin for its info.
+ */
+ if (matched) {
+ H5PL_get_plugin_info_t get_plugin_info_function;
+ const void * info;
+
+ /* Get the "get plugin info" function from the plugin. */
+ if (NULL == (get_plugin_info_function = (H5PL_get_plugin_info_t)H5PL_GET_LIB_FUNC(
+ H5PL_cache_g[u].handle, "H5PLget_plugin_info")))
+ HGOTO_ERROR(H5E_PLUGIN, H5E_CANTGET, FAIL, "can't get function for H5PLget_plugin_info")
+
+ /* Call the "get plugin info" function */
+ if (NULL == (info = (*get_plugin_info_function)()))
+ HGOTO_ERROR(H5E_PLUGIN, H5E_CANTGET, FAIL, "can't get plugin info")
+
+ /* Set output parameters */
+ *found = TRUE;
+ *plugin_info = info;
+
+ /* No need to continue processing */
+ break;
+ }
+ } /* end for */
done:
FUNC_LEAVE_NOAPI(ret_value)
diff --git a/src/H5PLprivate.h b/src/H5PLprivate.h
index 7eae513..7ff5c1a 100644
--- a/src/H5PLprivate.h
+++ b/src/H5PLprivate.h
@@ -22,6 +22,7 @@
/* Private headers needed by this file */
#include "H5private.h" /* Generic Functions */
+#include "H5FDprivate.h" /* File Drivers */
#include "H5VLprivate.h" /* Virtual Object Layer */
/**************************/
@@ -32,16 +33,29 @@
/* Library Private Typedefs */
/****************************/
+/* Key used to find VOL connector plugins */
+typedef struct H5PL_vol_key_t {
+ H5VL_get_connector_kind_t kind; /* Kind of VOL lookup to do */
+ union {
+ H5VL_class_value_t value; /* VOL connector value */
+ const char * name; /* VOL connector name */
+ } u;
+} H5PL_vol_key_t;
+
+/* Key used to find VFD plugins */
+typedef struct H5PL_vfd_key_t {
+ H5FD_get_driver_kind_t kind; /* Kind of VFD lookup to do */
+ union {
+ H5FD_class_value_t value; /* VFD value */
+ const char * name; /* VFD name */
+ } u;
+} H5PL_vfd_key_t;
+
/* The key that will be used to find the plugin */
typedef union H5PL_key_t {
- int id; /* I/O filters */
- struct {
- H5VL_get_connector_kind_t kind; /* Kind of VOL lookup to do */
- union {
- H5VL_class_value_t value; /* VOL connector value */
- const char * name; /* VOL connector name */
- } u;
- } vol;
+ int id; /* I/O filters */
+ H5PL_vol_key_t vol;
+ H5PL_vfd_key_t vfd;
} H5PL_key_t;
/* Enum dictating the type of plugins to process
@@ -50,6 +64,7 @@ typedef union H5PL_key_t {
typedef enum {
H5PL_ITER_TYPE_FILTER,
H5PL_ITER_TYPE_VOL,
+ H5PL_ITER_TYPE_VFD,
H5PL_ITER_TYPE_ALL,
} H5PL_iterate_type_t;
diff --git a/src/H5PLpublic.h b/src/H5PLpublic.h
index 55ff594..ab24bd5 100644
--- a/src/H5PLpublic.h
+++ b/src/H5PLpublic.h
@@ -35,14 +35,16 @@
typedef enum H5PL_type_t {
H5PL_TYPE_ERROR = -1, /**< Error */
H5PL_TYPE_FILTER = 0, /**< Filter */
- H5PL_TYPE_VOL = 1, /**< VOL driver */
- H5PL_TYPE_NONE = 2 /**< Sentinel: This must be last! */
+ H5PL_TYPE_VOL = 1, /**< VOL connector */
+ H5PL_TYPE_VFD = 2, /**< VFD */
+ H5PL_TYPE_NONE = 3 /**< Sentinel: This must be last! */
} H5PL_type_t;
//! <!-- [H5PL_type_t_snip] -->
/* Common dynamic plugin type flags used by the set/get_loading_state functions */
#define H5PL_FILTER_PLUGIN 0x0001
#define H5PL_VOL_PLUGIN 0x0002
+#define H5PL_VFD_PLUGIN 0x0004
#define H5PL_ALL_PLUGIN 0xFFFF
#ifdef __cplusplus
diff --git a/src/H5Pfapl.c b/src/H5Pfapl.c
index a8e0d8e..f37cb74 100644
--- a/src/H5Pfapl.c
+++ b/src/H5Pfapl.c
@@ -41,8 +41,28 @@
#include "H5VMprivate.h" /* Vector Functions */
/* Includes needed to set default file driver */
-#include "H5FDsec2.h" /* POSIX unbuffered I/O */
+#include "H5FDsec2.h" /* POSIX unbuffered I/O */
+#include "H5FDcore.h"
+#include "H5FDlog.h"
+#include "H5FDfamily.h"
+#include "H5FDmulti.h"
#include "H5FDstdio.h" /* Standard C buffered I/O */
+#include "H5FDsplitter.h"
+#ifdef H5_HAVE_PARALLEL
+#include "H5FDmpio.h"
+#endif
+#ifdef H5_HAVE_DIRECT
+#include "H5FDdirect.h"
+#endif
+#ifdef H5_HAVE_MIRROR_VFD
+#include "H5FDmirror.h"
+#endif
+#ifdef H5_HAVE_LIBHDFS
+#include "H5FDhdfs.h"
+#endif
+#ifdef H5_HAVE_ROS3_VFD
+#include "H5FDros3.h"
+#endif
#ifdef H5_HAVE_WINDOWS
#include "H5FDwindows.h" /* Win32 I/O */
#endif
@@ -113,7 +133,7 @@
#define H5F_ACS_FILE_DRV_SIZE sizeof(H5FD_driver_prop_t)
#define H5F_ACS_FILE_DRV_DEF \
{ \
- H5_DEFAULT_VFD, NULL \
+ H5_DEFAULT_VFD, NULL, NULL \
}
#define H5F_ACS_FILE_DRV_CRT H5P__facc_file_driver_create
#define H5F_ACS_FILE_DRV_SET H5P__facc_file_driver_set
@@ -398,6 +418,9 @@ static int H5P__facc_mpi_info_cmp(const void *value1, const void *value2, siz
static herr_t H5P__facc_mpi_info_close(const char *name, size_t size, void *value);
#endif /* H5_HAVE_PARALLEL */
+/* Internal routines */
+static herr_t H5P__facc_set_def_driver_check_predefined(const char *driver_name, hid_t *driver_id);
+
/*********************/
/* Package Variables */
/*********************/
@@ -809,6 +832,208 @@ done:
} /* end H5P__facc_reg_prop() */
/*-------------------------------------------------------------------------
+ * Function: H5P__facc_set_def_driver
+ *
+ * Purpose: Parses a string that contains the name of the default VFL
+ * driver for the default FAPL.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5P__facc_set_def_driver(void)
+{
+ const char *driver_env_var;
+ hbool_t driver_ref_inc = FALSE;
+ hid_t driver_id = H5I_INVALID_HID; /* VFL driver ID */
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_STATIC
+
+ /* Check if VFL driver environment variable is set */
+ driver_env_var = HDgetenv(HDF5_DRIVER);
+
+ /* Only parse VFL driver string if it's set */
+ if (driver_env_var && *driver_env_var) {
+ H5FD_driver_prop_t driver_prop;
+ H5P_genplist_t * def_fapl; /* Default file access property list */
+ H5P_genclass_t * def_fapclass; /* Default file access property class */
+ const char * driver_config_env_var;
+ htri_t driver_is_registered;
+
+ /* Check to see if the driver is already registered */
+ if ((driver_is_registered = H5FD_is_driver_registered_by_name(driver_env_var, &driver_id)) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't check if VFL driver is already registered")
+ if (driver_is_registered) {
+ HDassert(driver_id >= 0);
+
+ if (H5I_inc_ref(driver_id, TRUE) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTINC, FAIL, "unable to increment ref count on VFD")
+ driver_ref_inc = TRUE;
+ } /* end else-if */
+ else {
+ /* Check for VFL drivers that ship with the library */
+ if (H5P__facc_set_def_driver_check_predefined(driver_env_var, &driver_id) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't check for predefined VFL driver name")
+ else if (driver_id > 0) {
+ if (H5I_inc_ref(driver_id, TRUE) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTINC, FAIL, "can't increment VFL driver refcount")
+ driver_ref_inc = TRUE;
+ }
+ else {
+ /* Register the VFL driver */
+ if ((driver_id = H5FD_register_driver_by_name(driver_env_var, TRUE)) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTREGISTER, FAIL, "can't register VFL driver")
+ driver_ref_inc = TRUE;
+ } /* end else */
+ } /* end else */
+
+ /* Retrieve driver configuration string from environment variable, if set. */
+ driver_config_env_var = HDgetenv(HDF5_DRIVER_CONFIG);
+
+ driver_prop.driver_id = driver_id;
+ driver_prop.driver_info = NULL;
+ driver_prop.driver_config_str = driver_config_env_var;
+
+ /* Get default file access pclass */
+ if (NULL == (def_fapclass = (H5P_genclass_t *)H5I_object(H5P_FILE_ACCESS)))
+ HGOTO_ERROR(H5E_VFL, H5E_BADID, FAIL,
+ "can't find object for default file access property class ID")
+
+ /* Set new default VFL driver for default file access pclass */
+ if (H5P__class_set(def_fapclass, H5F_ACS_FILE_DRV_NAME, &driver_prop) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTSET, FAIL,
+ "can't set default VFL driver for default file access property list class")
+
+ /* Get default file access plist */
+ if (NULL == (def_fapl = (H5P_genplist_t *)H5I_object(H5P_FILE_ACCESS_DEFAULT)))
+ HGOTO_ERROR(H5E_VFL, H5E_BADID, FAIL, "can't find object for default fapl ID")
+
+ /* Set new default VFL driver for default FAPL */
+ if (H5P_set_driver(def_fapl, driver_prop.driver_id, driver_prop.driver_info,
+ driver_prop.driver_config_str) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTSET, FAIL, "can't set default VFL driver for default FAPL")
+ }
+
+done:
+ /* Clean up on error */
+ if (ret_value < 0) {
+ if (driver_id >= 0 && driver_ref_inc && H5I_dec_app_ref(driver_id) < 0)
+ HDONE_ERROR(H5E_PLIST, H5E_CANTDEC, FAIL, "unable to unregister VFL driver")
+ } /* end if */
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5P__facc_set_def_driver() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5P__facc_set_def_driver_check_predefined
+ *
+ * Purpose: Checks a given driver name against a list of predefined
+ * names for VFL drivers that are internal to HDF5. If a name
+ * is matched, the ID for that driver is returned through
+ * `driver_id`. Otherwise, `driver_id` is set to
+ * H5I_INVALID_HID.
+ *
+ * Return: Non-negative on sucess/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5P__facc_set_def_driver_check_predefined(const char *driver_name, hid_t *driver_id)
+{
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_STATIC
+
+ HDassert(driver_name);
+ HDassert(driver_id);
+
+ if (!HDstrcmp(driver_name, "sec2")) {
+ if ((*driver_id = H5FD_SEC2) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_UNINITIALIZED, FAIL, "couldn't initialize sec2 VFD")
+ }
+ else if (!HDstrcmp(driver_name, "core") || !HDstrcmp(driver_name, "core_paged")) {
+ if ((*driver_id = H5FD_CORE) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_UNINITIALIZED, FAIL, "couldn't initialize core VFD")
+ }
+ else if (!HDstrcmp(driver_name, "log")) {
+ if ((*driver_id = H5FD_LOG) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_UNINITIALIZED, FAIL, "couldn't initialize log VFD")
+ }
+ else if (!HDstrcmp(driver_name, "family")) {
+ if ((*driver_id = H5FD_FAMILY) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_UNINITIALIZED, FAIL, "couldn't initialize family VFD")
+ }
+ else if (!HDstrcmp(driver_name, "multi") || !HDstrcmp(driver_name, "split")) {
+ if ((*driver_id = H5FD_MULTI) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_UNINITIALIZED, FAIL, "couldn't initialize multi VFD")
+ }
+ else if (!HDstrcmp(driver_name, "stdio")) {
+ if ((*driver_id = H5FD_STDIO) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_UNINITIALIZED, FAIL, "couldn't initialize stdio VFD")
+ }
+ else if (!HDstrcmp(driver_name, "splitter")) {
+ if ((*driver_id = H5FD_SPLITTER) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_UNINITIALIZED, FAIL, "couldn't initialize splitter VFD")
+ }
+ else if (!HDstrcmp(driver_name, "mpio")) {
+#ifdef H5_HAVE_PARALLEL
+ if ((*driver_id = H5FD_MPIO) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_UNINITIALIZED, FAIL, "couldn't initialize MPI I/O VFD")
+#else
+ HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "MPI-I/O VFD is not enabled")
+#endif
+ }
+ else if (!HDstrcmp(driver_name, "direct")) {
+#ifdef H5_HAVE_DIRECT
+ if ((*driver_id = H5FD_DIRECT) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_UNINITIALIZED, FAIL, "couldn't initialize Direct I/O VFD")
+#else
+ HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "Direct I/O VFD is not enabled")
+#endif
+ }
+ else if (!HDstrcmp(driver_name, "mirror")) {
+#ifdef H5_HAVE_MIRROR_VFD
+ if ((*driver_id = H5FD_MIRROR) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_UNINITIALIZED, FAIL, "couldn't initialize mirror VFD")
+#else
+ HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "Mirror VFD is not enabled")
+#endif
+ }
+ else if (!HDstrcmp(driver_name, "hdfs")) {
+#ifdef H5_HAVE_LIBHDFS
+ if ((*driver_id = H5FD_HDFS) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_UNINITIALIZED, FAIL, "couldn't initialize HDFS VFD")
+#else
+ HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "HDFS VFD is not enabled")
+#endif
+ }
+ else if (!HDstrcmp(driver_name, "ros3")) {
+#ifdef H5_HAVE_ROS3_VFD
+ if ((*driver_id = H5FD_ROS3) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_UNINITIALIZED, FAIL, "couldn't initialize ROS3 VFD")
+#else
+ HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "ROS3 VFD is not enabled")
+#endif
+ }
+ else if (!HDstrcmp(driver_name, "windows")) {
+#ifdef H5_HAVE_WINDOWS
+ if ((*driver_id = H5FD_WINDOWS) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_UNINITIALIZED, FAIL, "couldn't initialize Windows VFD")
+#else
+ HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "Windows VFD is not enabled")
+#endif
+ }
+ else {
+ *driver_id = H5I_INVALID_HID;
+ }
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5P__facc_set_def_driver_check_predefined() */
+
+/*-------------------------------------------------------------------------
* Function: H5Pset_alignment
*
* Purpose: Sets the alignment properties of a file access property list
@@ -899,42 +1124,52 @@ done:
} /* end H5Pget_alignment() */
/*-------------------------------------------------------------------------
- * Function: H5P_set_driver
+ * Function: H5P_set_driver
*
- * Purpose: Set the file driver (DRIVER_ID) for a file access
- * property list (PLIST_ID) and supply an optional
- * struct containing the driver-specific properites
- * (DRIVER_INFO). The driver properties will be copied into the
- * property list and the reference count on the driver will be
- * incremented, allowing the caller to close the driver ID but
- * still use the property list.
+ * Purpose: Set the file driver (NEW_DRIVER_ID) for a file access
+ * property list (PLIST). A struct (NEW_DRIVER_INFO) or string
+ * (NEW_DRIVER_CONFIG_STR) containing the driver-specific
+ * properties can optionally be supplied. The driver properties
+ * (struct or string) will be copied into the property list and
+ * the reference count on the driver will be incremented,
+ * allowing the caller to close the driver ID but still use the
+ * property list.
*
- * Return: Success: Non-negative
- * Failure: Negative
+ * Note: Only one of either NEW_DRIVER_INFO or NEW_DRIVER_CONFIG_STR
+ * should be specified, but not both.
+ *
+ * Return: Non-negative on success/Negative on failure
*
* Programmer: Robb Matzke
- * Tuesday, August 3, 1999
+ * Tuesday, August 3, 1999
*
*-------------------------------------------------------------------------
*/
herr_t
-H5P_set_driver(H5P_genplist_t *plist, hid_t new_driver_id, const void *new_driver_info)
+H5P_set_driver(H5P_genplist_t *plist, hid_t new_driver_id, const void *new_driver_info,
+ const char *new_driver_config_str)
{
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(FAIL)
+ /* If VFD configuration information is supplied, ensure that either binary
+ * configuration data or a configuration string is supplied, but not both.
+ */
+ HDassert(!new_driver_info || !new_driver_config_str);
+
if (NULL == H5I_object_verify(new_driver_id, H5I_VFL))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file driver ID")
if (TRUE == H5P_isa_class(plist->plist_id, H5P_FILE_ACCESS)) {
- H5FD_driver_prop_t driver_prop; /* Property for driver ID & info */
+ H5FD_driver_prop_t driver_prop; /* Property for driver ID, info & config. string */
/* Prepare the driver property */
- driver_prop.driver_id = new_driver_id;
- driver_prop.driver_info = new_driver_info;
+ driver_prop.driver_id = new_driver_id;
+ driver_prop.driver_info = new_driver_info;
+ driver_prop.driver_config_str = new_driver_config_str;
- /* Set the driver ID & info property */
+ /* Set the driver ID, info & config. string property */
if (H5P_set(plist, H5F_ACS_FILE_DRV_NAME, &driver_prop) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set driver ID & info")
} /* end if */
@@ -980,7 +1215,7 @@ H5Pset_driver(hid_t plist_id, hid_t new_driver_id, const void *new_driver_info)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file driver ID")
/* Set the driver */
- if (H5P_set_driver(plist, new_driver_id, new_driver_info) < 0)
+ if (H5P_set_driver(plist, new_driver_id, new_driver_info, NULL) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set driver info")
done:
@@ -988,6 +1223,180 @@ done:
} /* end H5Pset_driver() */
/*-------------------------------------------------------------------------
+ * Function: H5P_set_driver_by_name
+ *
+ * Purpose: Set the file driver name (DRIVER_NAME) for a file access
+ * property list (PLIST) and supply an optional string
+ * containing the driver-specific properties (DRIVER_CONFIG).
+ * The driver properties string will be copied into the
+ * property list.
+ *
+ * If the file driver specified by DRIVER_NAME is not
+ * currently registered, an attempt will be made to load the
+ * driver as a plugin.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5P_set_driver_by_name(H5P_genplist_t *plist, const char *driver_name, const char *driver_config,
+ hbool_t app_ref)
+{
+ hid_t new_driver_id = H5I_INVALID_HID;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI(FAIL)
+
+ assert(plist);
+ assert(driver_name);
+
+ /* Register the driver */
+ if ((new_driver_id = H5FD_register_driver_by_name(driver_name, app_ref)) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTREGISTER, FAIL, "unable to register VFD")
+
+ /* Set the driver */
+ if (H5P_set_driver(plist, new_driver_id, NULL, driver_config) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set driver info")
+
+done:
+ if (ret_value < 0) {
+ if (new_driver_id >= 0 && H5I_dec_app_ref(new_driver_id) < 0)
+ HDONE_ERROR(H5E_PLIST, H5E_CANTDEC, FAIL, "can't decrement count on VFD ID")
+ }
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5P_set_driver_by_name() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5Pset_driver_by_name
+ *
+ * Purpose: Set the file driver name (DRIVER_NAME) for a file access
+ * property list (PLIST_ID) and supply an optional string
+ * containing the driver-specific properties (DRIVER_CONFIG).
+ * The driver properties string will be copied into the
+ * property list.
+ *
+ * If the file driver specified by DRIVER_NAME is not
+ * currently registered, an attempt will be made to load the
+ * driver as a plugin.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Pset_driver_by_name(hid_t plist_id, const char *driver_name, const char *driver_config)
+{
+ H5P_genplist_t *plist; /* Property list pointer */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE3("e", "i*s*s", plist_id, driver_name, driver_config);
+
+ /* Check arguments */
+ if (NULL == (plist = (H5P_genplist_t *)H5I_object_verify(plist_id, H5I_GENPROP_LST)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list")
+ if (!driver_name)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "driver_name parameter cannot be NULL")
+ if (!*driver_name)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "driver_name parameter cannot be an empty string")
+
+ /* Set the driver */
+ if (H5P_set_driver_by_name(plist, driver_name, driver_config, TRUE) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set driver info")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Pset_driver_by_name() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5P_set_driver_by_value
+ *
+ * Purpose: Set the file driver value (DRIVER_VALUE) for a file access
+ * property list (PLIST) and supply an optional string
+ * containing the driver-specific properties (DRIVER_CONFIG).
+ * The driver properties string will be copied into the
+ * property list.
+ *
+ * If the file driver specified by DRIVER_VALUE is not
+ * currently registered, an attempt will be made to load the
+ * driver as a plugin.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5P_set_driver_by_value(H5P_genplist_t *plist, H5FD_class_value_t driver_value, const char *driver_config,
+ hbool_t app_ref)
+{
+ hid_t new_driver_id = H5I_INVALID_HID;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI(FAIL)
+
+ assert(plist);
+ assert(driver_value >= 0);
+
+ /* Register the driver */
+ if ((new_driver_id = H5FD_register_driver_by_value(driver_value, app_ref)) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTREGISTER, FAIL, "unable to register VFD")
+
+ /* Set the driver */
+ if (H5P_set_driver(plist, new_driver_id, NULL, driver_config) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set driver info")
+
+done:
+ if (ret_value < 0) {
+ if (new_driver_id >= 0 && H5I_dec_app_ref(new_driver_id) < 0)
+ HDONE_ERROR(H5E_PLIST, H5E_CANTDEC, FAIL, "can't decrement count on VFD ID")
+ }
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5P_set_driver_by_value() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5Pset_driver_by_value
+ *
+ * Purpose: Set the file driver value (DRIVER_VALUE) for a file access
+ * property list (PLIST_ID) and supply an optional string
+ * containing the driver-specific properties (DRIVER_CONFIG).
+ * The driver properties string will be copied into the
+ * property list.
+ *
+ * If the file driver specified by DRIVER_VALUE is not
+ * currently registered, an attempt will be made to load the
+ * driver as a plugin.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Pset_driver_by_value(hid_t plist_id, H5FD_class_value_t driver_value, const char *driver_config)
+{
+ H5P_genplist_t *plist; /* Property list pointer */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE3("e", "iDV*s", plist_id, driver_value, driver_config);
+
+ /* Check arguments */
+ if (NULL == (plist = (H5P_genplist_t *)H5I_object_verify(plist_id, H5I_GENPROP_LST)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list")
+ if (driver_value < 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "negative VFD value is disallowed")
+
+ /* Set the driver */
+ if (H5P_set_driver_by_value(plist, driver_value, driver_config, TRUE) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set driver info")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Pset_driver_by_value() */
+
+/*-------------------------------------------------------------------------
* Function: H5P_peek_driver
*
* Purpose: Return the ID of the low-level file driver. PLIST_ID should
@@ -1014,7 +1423,7 @@ H5P_peek_driver(H5P_genplist_t *plist)
/* Get the current driver ID */
if (TRUE == H5P_isa_class(plist->plist_id, H5P_FILE_ACCESS)) {
- H5FD_driver_prop_t driver_prop; /* Property for driver ID & info */
+ H5FD_driver_prop_t driver_prop; /* Property for driver ID, info & configuration string */
if (H5P_peek(plist, H5F_ACS_FILE_DRV_NAME, &driver_prop) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get driver ID")
@@ -1098,7 +1507,7 @@ H5P_peek_driver_info(H5P_genplist_t *plist)
/* Get the current driver info */
if (TRUE == H5P_isa_class(plist->plist_id, H5P_FILE_ACCESS)) {
- H5FD_driver_prop_t driver_prop; /* Property for driver ID & info */
+ H5FD_driver_prop_t driver_prop; /* Property for driver ID, info & configuration string */
if (H5P_peek(plist, H5F_ACS_FILE_DRV_NAME, &driver_prop) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get driver info")
@@ -1151,13 +1560,104 @@ done:
} /* end H5Pget_driver_info() */
/*-------------------------------------------------------------------------
+ * Function: H5P_peek_driver_config_str
+ *
+ * Purpose: Returns a pointer directly to the file driver configuration
+ * string of a file access property list.
+ *
+ * Return: Success: Ptr to *uncopied* driver configuration string, if
+ * any.
+ *
+ * Failure: NULL. NULL is also returned if the driver has not
+ * been configured with a driver configuration string.
+ *
+ *-------------------------------------------------------------------------
+ */
+const char *
+H5P_peek_driver_config_str(H5P_genplist_t *plist)
+{
+ const char *ret_value = NULL; /* Return value */
+
+ FUNC_ENTER_NOAPI(NULL)
+
+ /* Get the current driver configuration string */
+ if (TRUE == H5P_isa_class(plist->plist_id, H5P_FILE_ACCESS)) {
+ H5FD_driver_prop_t driver_prop; /* Property for driver ID, info & configuration string */
+
+ if (H5P_peek(plist, H5F_ACS_FILE_DRV_NAME, &driver_prop) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get driver configuration string")
+ ret_value = driver_prop.driver_config_str;
+ } /* end if */
+ else
+ HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, NULL, "not a file access property list")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5P_peek_driver_config_str() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5Pget_driver_config_str
+ *
+ * Purpose: Retrieves a string representation of the configuration for
+ * the driver set on the given FAPL. The returned string can
+ * be used to configure the same driver in an identical way.
+ *
+ * `config_buf` may be NULL, in which case the length of the
+ * driver configuration string is simply returned. The caller
+ * can then allocate a buffer of the appropriate size and call
+ * this routine again.
+ *
+ * Return: Length of the driver configuration string on success (not
+ * including the NUL terminator)
+ * Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+ssize_t
+H5Pget_driver_config_str(hid_t fapl_id, char *config_buf, size_t buf_size)
+{
+ H5P_genplist_t *plist; /* Property list pointer */
+ const char * config_str = NULL;
+ ssize_t ret_value = -1;
+
+ FUNC_ENTER_API((-1))
+ H5TRACE3("Zs", "i*sz", fapl_id, config_buf, buf_size);
+
+ /* Check arguments */
+ if (!config_buf && buf_size)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, (-1), "config_buf cannot be NULL if buf_size is non-zero")
+
+ /* Get the plist structure */
+ if (NULL == (plist = H5P_object_verify(fapl_id, H5P_FILE_ACCESS)))
+ HGOTO_ERROR(H5E_ID, H5E_BADID, (-1), "can't find object for ID")
+
+ /* Retrieve configuration string property */
+ if ((config_str = H5P_peek_driver_config_str(plist))) {
+ size_t config_str_len = HDstrlen(config_str);
+
+ if (config_buf) {
+ HDstrncpy(config_buf, config_str, MIN(config_str_len + 1, buf_size));
+ if (config_str_len >= buf_size)
+ config_buf[buf_size - 1] = '\0';
+ }
+
+ ret_value = (ssize_t)config_str_len;
+ }
+ else
+ ret_value = 0;
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* H5Pget_driver_config_str() */
+
+/*-------------------------------------------------------------------------
* Function: H5P__file_driver_copy
*
* Purpose: Copy file driver ID & info.
*
* Note: This is an "in-place" copy, since this routine gets called
* after the top-level copy has been performed and this routine
- * finishes the "deep" part of the copy.
+ * finishes the "deep" part of the copy.
*
* Return: Success: Non-negative
* Failure: Negative
@@ -1208,6 +1708,15 @@ H5P__file_driver_copy(void *value)
/* Set the driver info for the copy */
info->driver_info = new_pl;
} /* end if */
+
+ /* Copy driver configuration string, if it exists */
+ if (info->driver_config_str) {
+ char *new_config_str = NULL;
+
+ if (NULL == (new_config_str = H5MM_strdup(info->driver_config_str)))
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "driver configuration string copy failed")
+ info->driver_config_str = new_config_str;
+ } /* end if */
} /* end if */
} /* end if */
@@ -1238,7 +1747,6 @@ H5P__file_driver_free(void *value)
if (value) {
H5FD_driver_prop_t *info = (H5FD_driver_prop_t *)value; /* Driver ID & info struct */
- /* Copy the driver & info, if there is one */
if (info->driver_id > 0) {
/* Free the driver info, if it exists */
@@ -1246,6 +1754,9 @@ H5P__file_driver_free(void *value)
if (H5FD_free_driver_info(info->driver_id, info->driver_info) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTFREE, FAIL, "driver info free request failed")
+ /* Free the driver configuration string, if it exists */
+ H5MM_xfree_const(info->driver_config_str);
+
/* Decrement reference count for driver */
if (H5I_dec_ref(info->driver_id) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTDEC, FAIL, "can't decrement reference count for driver ID")
@@ -1465,6 +1976,16 @@ H5P__facc_file_driver_cmp(const void *_info1, const void *_info2, size_t H5_ATTR
HGOTO_DONE(cmp_value);
} /* end if */
+ /* Compare driver configuration strings */
+ if (info1->driver_config_str == NULL && info2->driver_config_str != NULL)
+ HGOTO_DONE(-1);
+ if (info1->driver_config_str != NULL && info2->driver_config_str == NULL)
+ HGOTO_DONE(1);
+ if (info1->driver_config_str) {
+ if (0 != (cmp_value = HDstrcmp(info1->driver_config_str, info2->driver_config_str)))
+ HGOTO_DONE(cmp_value);
+ }
+
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5P__facc_file_driver_cmp() */
diff --git a/src/H5Pint.c b/src/H5Pint.c
index 9530d87..9206d4c 100644
--- a/src/H5Pint.c
+++ b/src/H5Pint.c
@@ -412,20 +412,22 @@ static const H5I_class_t H5I_GENPROPLST_CLS[1] = {{
}};
/*-------------------------------------------------------------------------
- * Function: H5P_init
+ * Function: H5P_init_phase1
*
- * Purpose: Initialize the interface from some other layer.
+ * Purpose: Initialize the interface from some other layer. This should
+ * be followed with a call to H5P_init_phase2 after the H5P
+ * interface is completely setup.
*
- * Return: Success: non-negative
- * Failure: negative
+ * Return: Success: non-negative
+ * Failure: negative
*
- * Programmer: Quincey Koziol
+ * Programmer: Quincey Koziol
* Saturday, March 4, 2000
*
*-------------------------------------------------------------------------
*/
herr_t
-H5P_init(void)
+H5P_init_phase1(void)
{
herr_t ret_value = SUCCEED; /* Return value */
@@ -434,7 +436,36 @@ H5P_init(void)
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5P_init() */
+} /* end H5P_init_phase1() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5P_init_phase2
+ *
+ * Purpose: Finish initializing the interface from some other package.
+ *
+ * Note: This is broken out as a separate routine so that the
+ * library's default VFL driver can be chosen and initialized
+ * after the entire H5P interface has been initialized.
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5P_init_phase2(void)
+{
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI(FAIL)
+
+ /* Set up the default VFL driver */
+ if (H5P__facc_set_def_driver() < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTSET, FAIL, "unable to set default VFL driver")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5P_init_phase2() */
/*--------------------------------------------------------------------------
NAME
@@ -449,8 +480,9 @@ DESCRIPTION
herr_t
H5P__init_package(void)
{
- size_t tot_init; /* Total # of classes initialized */
- size_t pass_init; /* # of classes initialized in each pass */
+ size_t tot_init = 0; /* Total # of classes initialized */
+ size_t pass_init; /* # of classes initialized in each pass */
+ size_t u;
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_PACKAGE
@@ -472,8 +504,6 @@ H5P__init_package(void)
*/
tot_init = 0;
do {
- size_t u; /* Local index variable */
-
/* Reset pass initialization counter */
pass_init = 0;
@@ -523,6 +553,28 @@ H5P__init_package(void)
HDassert(tot_init == NELMTS(init_class));
done:
+ if (ret_value < 0 && tot_init > 0) {
+ /* First uninitialize all default property lists */
+ H5I_clear_type(H5I_GENPROP_LST, FALSE, FALSE);
+
+ /* Then uninitialize any initialized libclass */
+ for (u = 0; u < NELMTS(init_class); u++) {
+ H5P_libclass_t const *lib_class = init_class[u]; /* Current class to operate on */
+
+ HDassert(lib_class->class_id);
+ if (*lib_class->class_id >= 0) {
+ /* Close the class ID */
+ if (H5I_dec_ref(*lib_class->class_id) < 0)
+ HDONE_ERROR(H5E_PLIST, H5E_CLOSEERROR, FAIL, "unable to close property list class ID")
+ }
+ else if (lib_class->pclass && *lib_class->pclass) {
+ /* Close a half-initialized pclass */
+ if (H5P__close_class(*lib_class->pclass) < 0)
+ HDONE_ERROR(H5E_PLIST, H5E_CLOSEERROR, FAIL, "unable to close property list class")
+ }
+ }
+ }
+
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5P__init_package() */
diff --git a/src/H5Ppkg.h b/src/H5Ppkg.h
index dd43f76..2946931 100644
--- a/src/H5Ppkg.h
+++ b/src/H5Ppkg.h
@@ -188,6 +188,9 @@ H5_DLL herr_t H5P__decode_double(const void **_pp, void *value);
H5_DLL herr_t H5P__encode_coll_md_read_flag_t(const void *value, void **_pp, size_t *size);
H5_DLL herr_t H5P__decode_coll_md_read_flag_t(const void **_pp, void *value);
+/* Private FAPL routines */
+H5_DLL herr_t H5P__facc_set_def_driver(void);
+
/* Private OCPL routines */
H5_DLL herr_t H5P__get_filter(const struct H5Z_filter_info_t *filter, unsigned int *flags, size_t *cd_nelmts,
unsigned cd_values[], size_t namelen, char name[], unsigned *filter_config);
diff --git a/src/H5Pprivate.h b/src/H5Pprivate.h
index 6ebe5d3..7cbb397 100644
--- a/src/H5Pprivate.h
+++ b/src/H5Pprivate.h
@@ -156,8 +156,9 @@ struct H5O_fill_t;
struct H5T_t;
struct H5VL_connector_prop_t;
-/* Package initialization routine */
-H5_DLL herr_t H5P_init(void);
+/* Package initialization routines */
+H5_DLL herr_t H5P_init_phase1(void);
+H5_DLL herr_t H5P_init_phase2(void);
/* Internal versions of API routines */
H5_DLL herr_t H5P_close(H5P_genplist_t *plist);
@@ -181,7 +182,13 @@ H5_DLL char * H5P_get_class_name(H5P_genclass_t *pclass);
H5_DLL herr_t H5P_get_nprops_pclass(const H5P_genclass_t *pclass, size_t *nprops, hbool_t recurse);
H5_DLL hid_t H5P_peek_driver(H5P_genplist_t *plist);
H5_DLL const void *H5P_peek_driver_info(H5P_genplist_t *plist);
-H5_DLL herr_t H5P_set_driver(H5P_genplist_t *plist, hid_t new_driver_id, const void *new_driver_info);
+H5_DLL const char *H5P_peek_driver_config_str(H5P_genplist_t *plist);
+H5_DLL herr_t H5P_set_driver(H5P_genplist_t *plist, hid_t new_driver_id, const void *new_driver_info,
+ const char *new_driver_config_str);
+H5_DLL herr_t H5P_set_driver_by_name(H5P_genplist_t *plist, const char *driver_name,
+ const char *driver_config, hbool_t app_ref);
+H5_DLL herr_t H5P_set_driver_by_value(H5P_genplist_t *plist, H5FD_class_value_t driver_value,
+ const char *driver_config, hbool_t app_ref);
H5_DLL herr_t H5P_set_vol(H5P_genplist_t *plist, hid_t vol_id, const void *vol_info);
H5_DLL herr_t H5P_reset_vol_class(const H5P_genclass_t *pclass, const struct H5VL_connector_prop_t *vol_prop);
H5_DLL herr_t H5P_set_vlen_mem_manager(H5P_genplist_t *plist, H5MM_allocate_t alloc_func, void *alloc_info,
diff --git a/src/H5Ppublic.h b/src/H5Ppublic.h
index a5c5c37..3fa7118 100644
--- a/src/H5Ppublic.h
+++ b/src/H5Ppublic.h
@@ -3448,6 +3448,34 @@ H5_DLL const void *H5Pget_driver_info(hid_t plist_id);
/**
* \ingroup FAPL
*
+ * \brief Retrieves a string representation of the configuration for
+ * the driver set on the given FAPL. The returned string can
+ * be used to configure the same driver in an identical way.
+ *
+ * \fapl_id
+ * \param[out] config_buf Driver configuration string output buffer
+ * \param[in] buf_size Size of driver configuration string output buffer
+ *
+ * \return Returns the length of the driver configuration string on
+ * success (not including the NUL terminator). Returns negative
+ * on failure.
+ *
+ * \details H5Pget_driver_config_str() retrieves a string representation
+ * of the configuration for the driver set on the given FAPL. The
+ * returned string can be used to configure the same driver in
+ * an identical way.
+ *
+ * If \p config_buf is NULL, the length of the driver configuration
+ * string is simply returned. The caller can then allocate a buffer
+ * of the appropriate size and call this routine again.
+ *
+ * \version 1.12.1 Function publicized in this release.
+ *
+ */
+H5_DLL ssize_t H5Pget_driver_config_str(hid_t fapl_id, char *config_buf, size_t buf_size);
+/**
+ * \ingroup FAPL
+ *
* \brief Retrieves the size of the external link open file cache
*
* \fapl_id{plist_id}
@@ -4287,6 +4315,57 @@ H5_DLL herr_t H5Pset_driver(hid_t plist_id, hid_t driver_id, const void *driver_
/**
* \ingroup FAPL
*
+ * \brief Sets a file driver according to a given driver name
+ *
+ * \plist_id
+ * \param[in] driver_name The new driver name
+ * \param[in] driver_config Optional string containing driver properties
+ *
+ * \return \herr_t
+ *
+ * \details H5Pset_driver_by_name() sets the file driver, by the name
+ * driver_name, for a file access or data transfer property list,
+ * \p plist_id, and supplies an optional string containing the
+ * driver-specific properties, \p driver_config. The driver
+ * properties string will be copied into the property list.
+ *
+ * If the driver specified by \p driver_name is not currently
+ * registered, an attempt will be made to load the driver as a
+ * plugin.
+ *
+ * \version 1.12.1 Function publicized in this release.
+ *
+ */
+H5_DLL herr_t H5Pset_driver_by_name(hid_t plist_id, const char *driver_name, const char *driver_config);
+/**
+ * \ingroup FAPL
+ *
+ * \brief Sets a file driver according to a given driver value (ID).
+ *
+ * \plist_id
+ * \param[in] driver_value The new driver value (ID)
+ * \param[in] driver_config Optional string containing driver properties
+ *
+ * \return \herr_t
+ *
+ * \details H5Pset_driver_by_value() sets the file driver, by the value
+ * driver_value, for a file access or data transfer property list,
+ * \p plist_id, and supplies an optional string containing the
+ * driver-specific properties, \p driver_config. The driver
+ * properties string will be copied into the property list.
+ *
+ * If the driver specified by \p driver_value is not currently
+ * registered, an attempt will be made to load the driver as a
+ * plugin.
+ *
+ * \version 1.12.1 Function publicized in this release.
+ *
+ */
+H5_DLL herr_t H5Pset_driver_by_value(hid_t plist_id, H5FD_class_value_t driver_value,
+ const char *driver_config);
+/**
+ * \ingroup FAPL
+ *
* \brief Sets the number of files that can be held open in an external
* link open file cache
*
diff --git a/src/H5Tconv.c b/src/H5Tconv.c
index 18cbcf1..273bb23 100644
--- a/src/H5Tconv.c
+++ b/src/H5Tconv.c
@@ -3205,14 +3205,14 @@ H5T__conv_vlen(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, si
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, FAIL, "unable to copy src type for conversion")
/* References need to know about the src file */
if (tsrc_cpy->shared->type == H5T_REFERENCE)
- if (H5T_set_loc(tsrc_cpy, src->shared->u.vlen.file, H5T_LOC_MEMORY) < 0)
+ if (H5T_set_loc(tsrc_cpy, src->shared->u.vlen.file, src->shared->u.vlen.loc) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTSET, FAIL, "can't set datatype location");
if (NULL == (tdst_cpy = H5T_copy(dst->shared->parent, H5T_COPY_ALL)))
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, FAIL, "unable to copy dst type for conversion")
/* References need to know about the dst file */
if (tdst_cpy->shared->type == H5T_REFERENCE)
- if (H5T_set_loc(tdst_cpy, dst->shared->u.vlen.file, H5T_LOC_MEMORY) < 0)
+ if (H5T_set_loc(tdst_cpy, dst->shared->u.vlen.file, dst->shared->u.vlen.loc) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTSET, FAIL, "can't set datatype location");
if (((tsrc_id = H5I_register(H5I_DATATYPE, tsrc_cpy, FALSE)) < 0) ||
diff --git a/src/H5Tprivate.h b/src/H5Tprivate.h
index 6624096..735adc7 100644
--- a/src/H5Tprivate.h
+++ b/src/H5Tprivate.h
@@ -101,6 +101,8 @@ typedef struct H5T_subset_info_t {
} H5T_subset_info_t;
/* Forward declarations for prototype arguments */
+struct H5G_loc_t;
+struct H5G_name_t;
struct H5O_shared_t;
/* The native endianness of the platform */
@@ -123,7 +125,7 @@ H5_DLL herr_t H5T_encode(H5T_t *obj, unsigned char *buf, size_t *nalloc);
H5_DLL H5T_t * H5T_decode(size_t buf_size, const unsigned char *buf);
H5_DLL herr_t H5T_debug(const H5T_t *dt, FILE *stream);
H5_DLL struct H5O_loc_t *H5T_oloc(H5T_t *dt);
-H5_DLL H5G_name_t *H5T_nameof(const H5T_t *dt);
+H5_DLL struct H5G_name_t *H5T_nameof(const H5T_t *dt);
H5_DLL htri_t H5T_is_immutable(const H5T_t *dt);
H5_DLL htri_t H5T_is_named(const H5T_t *dt);
H5_DLL herr_t H5T_convert_committed_datatype(H5T_t *dt, H5F_t *f);
@@ -159,7 +161,7 @@ H5_DLL herr_t H5T_invoke_vol_optional(H5T_t *dt, H5VL_optional_args_t *args, hi
H5_DLL H5R_type_t H5T_get_ref_type(const H5T_t *dt);
/* Operations on named datatypes */
-H5_DLL H5T_t *H5T_open(const H5G_loc_t *loc);
+H5_DLL H5T_t *H5T_open(const struct H5G_loc_t *loc);
H5_DLL int H5T_link(const H5T_t *type, int adjust);
H5_DLL herr_t H5T_update_shared(H5T_t *type);
diff --git a/src/H5VLcallback.c b/src/H5VLcallback.c
index a61b003..2369be5 100644
--- a/src/H5VLcallback.c
+++ b/src/H5VLcallback.c
@@ -3527,6 +3527,7 @@ H5VL__file_open_find_connector_cb(H5PL_type_t plugin_type, const void *plugin_in
H5P_genplist_t * fapl_plist;
H5P_genplist_t * fapl_plist_copy;
hbool_t is_accessible = FALSE; /* Whether file is accessible */
+ ssize_t num_errors = 0;
herr_t status;
hid_t connector_id = H5I_INVALID_HID;
hid_t fapl_id = H5I_INVALID_HID;
@@ -3565,6 +3566,10 @@ H5VL__file_open_find_connector_cb(H5PL_type_t plugin_type, const void *plugin_in
vol_cb_args.args.is_accessible.fapl_id = fapl_id;
vol_cb_args.args.is_accessible.accessible = &is_accessible;
+ /* Store current error stack size */
+ if ((num_errors = H5Eget_num(H5E_DEFAULT)) < 0)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTGET, H5_ITER_ERROR, "can't get current error stack size")
+
/* Check if file is accessible with given VOL connector */
H5E_BEGIN_TRY
{
@@ -3572,11 +3577,23 @@ H5VL__file_open_find_connector_cb(H5PL_type_t plugin_type, const void *plugin_in
}
H5E_END_TRY;
- /* If the file was accessible with the current VOL connector, return
- * the FAPL with that VOL connector set on it. Errors are ignored here
- * as some VOL connectors may not support H5Fis_accessible.
- */
- if (status == SUCCEED && is_accessible) {
+ if (status < 0) {
+ ssize_t new_num_errors = 0;
+
+ /* Pop any errors generated by the above call */
+ if ((new_num_errors = H5Eget_num(H5E_DEFAULT)) < 0)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTGET, H5_ITER_ERROR, "can't get current error stack size")
+ if (new_num_errors > num_errors) {
+ new_num_errors -= num_errors;
+ if (H5Epop(H5E_DEFAULT, (size_t)new_num_errors) < 0)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTRELEASE, H5_ITER_ERROR, "can't sanitize error stack")
+ }
+ }
+ else if (status == SUCCEED && is_accessible) {
+ /* If the file was accessible with the current VOL connector, return
+ * the FAPL with that VOL connector set on it.
+ */
+
/* Modify 'connector_prop' to point to the VOL connector that
* was actually used to open the file, rather than the original
* VOL connector that was requested.
@@ -3586,7 +3603,7 @@ H5VL__file_open_find_connector_cb(H5PL_type_t plugin_type, const void *plugin_in
udata->fapl_id = fapl_id;
ret_value = H5_ITER_STOP;
- } /* end if */
+ }
done:
if (ret_value != H5_ITER_STOP) {
diff --git a/src/H5VLint.c b/src/H5VLint.c
index b4432d0..936614f 100644
--- a/src/H5VLint.c
+++ b/src/H5VLint.c
@@ -69,11 +69,7 @@ typedef struct H5VL_wrap_ctx_t {
*/
typedef struct {
/* IN */
- H5VL_get_connector_kind_t kind; /* Which kind of connector search to make */
- union {
- const char * name; /* The name of the VOL connector to check */
- H5VL_class_value_t value; /* The value of the VOL connector to check */
- } u;
+ H5PL_vol_key_t key;
/* OUT */
hid_t found_id; /* The connector ID, if we found a match */
@@ -341,15 +337,15 @@ H5VL__get_connector_cb(void *obj, hid_t id, void *_op_data)
FUNC_ENTER_STATIC_NOERR
- if (H5VL_GET_CONNECTOR_BY_NAME == op_data->kind) {
- if (0 == HDstrcmp(cls->name, op_data->u.name)) {
+ if (H5VL_GET_CONNECTOR_BY_NAME == op_data->key.kind) {
+ if (0 == HDstrcmp(cls->name, op_data->key.u.name)) {
op_data->found_id = id;
ret_value = H5_ITER_STOP;
} /* end if */
} /* end if */
else {
- HDassert(H5VL_GET_CONNECTOR_BY_VALUE == op_data->kind);
- if (cls->value == op_data->u.value) {
+ HDassert(H5VL_GET_CONNECTOR_BY_VALUE == op_data->key.kind);
+ if (cls->value == op_data->key.u.value) {
op_data->found_id = id;
ret_value = H5_ITER_STOP;
} /* end if */
@@ -398,7 +394,7 @@ H5VL__set_def_conn(void)
} /* end if */
/* Check for environment variable set */
- env_var = HDgetenv("HDF5_VOL_CONNECTOR");
+ env_var = HDgetenv(HDF5_VOL_CONNECTOR);
/* Only parse the string if it's set */
if (env_var && *env_var) {
@@ -1299,9 +1295,9 @@ H5VL__register_connector_by_class(const H5VL_class_t *cls, hbool_t app_ref, hid_
"callback is provided")
/* Set up op data for iteration */
- op_data.kind = H5VL_GET_CONNECTOR_BY_NAME;
- op_data.u.name = cls->name;
- op_data.found_id = H5I_INVALID_HID;
+ op_data.key.kind = H5VL_GET_CONNECTOR_BY_NAME;
+ op_data.key.u.name = cls->name;
+ op_data.found_id = H5I_INVALID_HID;
/* Check if connector is already registered */
if (H5I_iterate(H5I_VOL, H5VL__get_connector_cb, &op_data, TRUE) < 0)
@@ -1350,9 +1346,9 @@ H5VL__register_connector_by_name(const char *name, hbool_t app_ref, hid_t vipl_i
FUNC_ENTER_PACKAGE
/* Set up op data for iteration */
- op_data.kind = H5VL_GET_CONNECTOR_BY_NAME;
- op_data.u.name = name;
- op_data.found_id = H5I_INVALID_HID;
+ op_data.key.kind = H5VL_GET_CONNECTOR_BY_NAME;
+ op_data.key.u.name = name;
+ op_data.found_id = H5I_INVALID_HID;
/* Check if connector is already registered */
if (H5I_iterate(H5I_VOL, H5VL__get_connector_cb, &op_data, app_ref) < 0)
@@ -1410,12 +1406,12 @@ H5VL__register_connector_by_value(H5VL_class_value_t value, hbool_t app_ref, hid
FUNC_ENTER_PACKAGE
/* Set up op data for iteration */
- op_data.kind = H5VL_GET_CONNECTOR_BY_VALUE;
- op_data.u.value = value;
- op_data.found_id = H5I_INVALID_HID;
+ op_data.key.kind = H5VL_GET_CONNECTOR_BY_VALUE;
+ op_data.key.u.value = value;
+ op_data.found_id = H5I_INVALID_HID;
/* Check if connector is already registered */
- if (H5I_iterate(H5I_VOL, H5VL__get_connector_cb, &op_data, TRUE) < 0)
+ if (H5I_iterate(H5I_VOL, H5VL__get_connector_cb, &op_data, app_ref) < 0)
HGOTO_ERROR(H5E_VOL, H5E_BADITER, H5I_INVALID_HID, "can't iterate over VOL ids")
/* If connector alread registered, increment ref count on ID and return ID */
@@ -1449,8 +1445,9 @@ done:
*
* Purpose: Checks if a connector with a particular name is registered.
*
- * Return: Success: 0
- * Failure: -1
+ * Return: >0 if a VOL connector with that name has been registered
+ * 0 if a VOL connector with that name has NOT been registered
+ * <0 on errors
*
* Programmer: Dana Robinson
* June 17, 2017
@@ -1466,9 +1463,9 @@ H5VL__is_connector_registered_by_name(const char *name)
FUNC_ENTER_PACKAGE
/* Set up op data for iteration */
- op_data.kind = H5VL_GET_CONNECTOR_BY_NAME;
- op_data.u.name = name;
- op_data.found_id = H5I_INVALID_HID;
+ op_data.key.kind = H5VL_GET_CONNECTOR_BY_NAME;
+ op_data.key.u.name = name;
+ op_data.found_id = H5I_INVALID_HID;
/* Find connector with name */
if (H5I_iterate(H5I_VOL, H5VL__get_connector_cb, &op_data, TRUE) < 0)
@@ -1488,8 +1485,9 @@ done:
* Purpose: Checks if a connector with a particular value (ID) is
* registered.
*
- * Return: Success: 0
- * Failure: -1
+ * Return: >0 if a VOL connector with that value has been registered
+ * 0 if a VOL connector with that value hasn't been registered
+ * <0 on errors
*
*-------------------------------------------------------------------------
*/
@@ -1502,9 +1500,9 @@ H5VL__is_connector_registered_by_value(H5VL_class_value_t value)
FUNC_ENTER_PACKAGE
/* Set up op data for iteration */
- op_data.kind = H5VL_GET_CONNECTOR_BY_VALUE;
- op_data.u.value = value;
- op_data.found_id = H5I_INVALID_HID;
+ op_data.key.kind = H5VL_GET_CONNECTOR_BY_VALUE;
+ op_data.key.u.value = value;
+ op_data.found_id = H5I_INVALID_HID;
/* Find connector with value */
if (H5I_iterate(H5I_VOL, H5VL__get_connector_cb, &op_data, TRUE) < 0)
@@ -1635,9 +1633,9 @@ H5VL__peek_connector_id_by_name(const char *name)
FUNC_ENTER_PACKAGE
/* Set up op data for iteration */
- op_data.kind = H5VL_GET_CONNECTOR_BY_NAME;
- op_data.u.name = name;
- op_data.found_id = H5I_INVALID_HID;
+ op_data.key.kind = H5VL_GET_CONNECTOR_BY_NAME;
+ op_data.key.u.name = name;
+ op_data.found_id = H5I_INVALID_HID;
/* Find connector with name */
if (H5I_iterate(H5I_VOL, H5VL__get_connector_cb, &op_data, TRUE) < 0)
@@ -1671,9 +1669,9 @@ H5VL__peek_connector_id_by_value(H5VL_class_value_t value)
FUNC_ENTER_PACKAGE
/* Set up op data for iteration */
- op_data.kind = H5VL_GET_CONNECTOR_BY_VALUE;
- op_data.u.value = value;
- op_data.found_id = H5I_INVALID_HID;
+ op_data.key.kind = H5VL_GET_CONNECTOR_BY_VALUE;
+ op_data.key.u.value = value;
+ op_data.found_id = H5I_INVALID_HID;
/* Find connector with value */
if (H5I_iterate(H5I_VOL, H5VL__get_connector_cb, &op_data, TRUE) < 0)
diff --git a/src/H5public.h b/src/H5public.h
index 65709c6..3e59e24 100644
--- a/src/H5public.h
+++ b/src/H5public.h
@@ -87,11 +87,11 @@
/**
* For pre-releases like \c snap0. Empty string for official releases.
*/
-#define H5_VERS_SUBRELEASE ""
+#define H5_VERS_SUBRELEASE "7"
/**
* Full version string
*/
-#define H5_VERS_INFO "HDF5 library version: 1.13.0"
+#define H5_VERS_INFO "HDF5 library version: 1.13.0-7"
#define H5check() H5check_version(H5_VERS_MAJOR, H5_VERS_MINOR, H5_VERS_RELEASE)
@@ -168,6 +168,58 @@
(((H5_VERS_MAJOR == Maj) && (H5_VERS_MINOR == Min) && (H5_VERS_RELEASE <= Rel)) || \
((H5_VERS_MAJOR == Maj) && (H5_VERS_MINOR < Min)) || (H5_VERS_MAJOR < Maj))
+/* Macros for various environment variables that HDF5 interprets */
+/**
+ * Used to specify the name of an HDF5 Virtual File Driver to use as
+ * the default file driver for file access. Setting this environment
+ * variable overrides the default file driver for File Access Property
+ * Lists.
+ */
+#define HDF5_DRIVER "HDF5_DRIVER"
+/**
+ * Used to specify a configuration string for the HDF5 Virtual File
+ * Driver being used for file access.
+ */
+#define HDF5_DRIVER_CONFIG "HDF5_DRIVER_CONFIG"
+/**
+ * Used to specify the name of an HDF5 Virtual Object Layer Connector
+ * to use as the default VOL connector for file access. Setting this
+ * environment variable overrides the default VOL connector for File
+ * Access Property Lists.
+ */
+#define HDF5_VOL_CONNECTOR "HDF5_VOL_CONNECTOR"
+/**
+ * Used to specify a delimiter-separated (currently, ';' for Windows
+ * and ':' for other systems) list of paths that HDF5 should search
+ * when loading plugins.
+ */
+#define HDF5_PLUGIN_PATH "HDF5_PLUGIN_PATH"
+/**
+ * Used to control the loading of HDF5 plugins at runtime. If this
+ * environment variable is set to the special string "::" (defined
+ * in H5PLpublic.h as H5PL_NO_PLUGIN), then dynamic loading of any
+ * HDF5 plugins will be disabled. No other values are valid for this
+ * environment variable.
+ */
+#define HDF5_PLUGIN_PRELOAD "HDF5_PLUGIN_PRELOAD"
+/**
+ * Used to control whether HDF5 uses file locking when creating or
+ * opening a file. Valid values for this environment variable are
+ * as follows:
+ *
+ * "TRUE" or "1" - Request that file locks should be used
+ * "FALSE" or "0" - Request that file locks should NOT be used
+ * "BEST_EFFORT" - Request that file locks should be used and
+ * that any locking errors caused by file
+ * locking being disabled on the system
+ * should be ignored
+ */
+#define HDF5_USE_FILE_LOCKING "HDF5_USE_FILE_LOCKING"
+/**
+ * Used to instruct HDF5 not to cleanup files created during testing.
+ */
+#define HDF5_NOCLEANUP "HDF5_NOCLEANUP"
+
/**
* Status return values. Failed integer functions in HDF5 result almost
* always in a negative value (unsigned failing functions sometimes return
diff --git a/src/H5trace.c b/src/H5trace.c
index 3a5d420..0797f65 100644
--- a/src/H5trace.c
+++ b/src/H5trace.c
@@ -1046,6 +1046,65 @@ H5_trace_args(H5RS_str_t *rs, const char *type, va_list ap)
} /* end block */
break;
+ case 'V': /* H5FD_class_value_t */
+ {
+ H5FD_class_value_t class_val =
+ (H5FD_class_value_t)HDva_arg(ap, H5FD_class_value_t);
+
+ switch (class_val) {
+ case H5_VFD_INVALID:
+ H5RS_acat(rs, "H5_VFD_INVALID");
+ break;
+ case H5_VFD_SEC2:
+ H5RS_acat(rs, "H5_VFD_SEC2");
+ break;
+ case H5_VFD_CORE:
+ H5RS_acat(rs, "H5_VFD_CORE");
+ break;
+ case H5_VFD_LOG:
+ H5RS_acat(rs, "H5_VFD_LOG");
+ break;
+ case H5_VFD_FAMILY:
+ H5RS_acat(rs, "H5_VFD_FAMILY");
+ break;
+ case H5_VFD_MULTI:
+ H5RS_acat(rs, "H5_VFD_MULTI");
+ break;
+ case H5_VFD_STDIO:
+ H5RS_acat(rs, "H5_VFD_STDIO");
+ break;
+#ifdef H5_HAVE_PARALLEL
+ case H5_VFD_MPIO:
+ H5RS_acat(rs, "H5_VFD_MPIO");
+ break;
+#endif
+#ifdef H5_HAVE_DIRECT
+ case H5_VFD_DIRECT:
+ H5RS_acat(rs, "H5_VFD_DIRECT");
+ break;
+#endif
+#ifdef H5_HAVE_MIRROR_VFD
+ case H5_VFD_MIRROR:
+ H5RS_acat(rs, "H5_VFD_MIRROR");
+ break;
+#endif
+#ifdef H5_HAVE_LIBHDFS
+ case H5_VFD_HDFS:
+ H5RS_acat(rs, "H5_VFD_HDFS");
+ break;
+#endif
+#ifdef H5_HAVE_ROS3_VFD
+ case H5_VFD_ROS3:
+ H5RS_acat(rs, "H5_VFD_ROS3");
+ break;
+#endif
+ default:
+ H5RS_asprintf_cat(rs, "%ld", (long)class_val);
+ break;
+ }
+ } /* end block */
+ break;
+
default:
H5RS_asprintf_cat(rs, "BADTYPE(D%c)", type[1]);
goto error;