summaryrefslogtreecommitdiffstats
path: root/src/H5FDfamily.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/H5FDfamily.c')
-rw-r--r--src/H5FDfamily.c232
1 files changed, 201 insertions, 31 deletions
diff --git a/src/H5FDfamily.c b/src/H5FDfamily.c
index af67c78..d187b7b 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 */
@@ -141,6 +149,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
@@ -243,7 +367,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)
@@ -252,18 +376,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)
@@ -589,9 +717,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
@@ -605,21 +734,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) {
@@ -643,7 +783,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;
@@ -656,8 +799,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) {
@@ -1361,7 +1512,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;
@@ -1375,13 +1528,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;
}
@@ -1394,8 +1555,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;
@@ -1431,9 +1601,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() */