summaryrefslogtreecommitdiffstats
path: root/src/H5Pfapl.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/H5Pfapl.c')
-rw-r--r--src/H5Pfapl.c567
1 files changed, 544 insertions, 23 deletions
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() */