summaryrefslogtreecommitdiffstats
path: root/src/H5Fint.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/H5Fint.c')
-rw-r--r--src/H5Fint.c331
1 files changed, 295 insertions, 36 deletions
diff --git a/src/H5Fint.c b/src/H5Fint.c
index 8212eb5..b135ce1 100644
--- a/src/H5Fint.c
+++ b/src/H5Fint.c
@@ -30,6 +30,7 @@
#include "H5FDprivate.h" /* File drivers */
#include "H5Gprivate.h" /* Groups */
#include "H5Iprivate.h" /* IDs */
+#include "H5Lprivate.h" /* Links */
#include "H5MFprivate.h" /* File memory management */
#include "H5MMprivate.h" /* Memory management */
#include "H5Pprivate.h" /* Property lists */
@@ -98,7 +99,7 @@ H5FL_DEFINE(H5F_t);
/* Declare a free list to manage the H5F_file_t struct */
H5FL_DEFINE(H5F_file_t);
-
+
/*-------------------------------------------------------------------------
* Function: H5F_get_access_plist
*
@@ -213,7 +214,7 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5F_get_access_plist() */
-
+
/*-------------------------------------------------------------------------
* Function: H5F_get_obj_count
*
@@ -241,7 +242,7 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5F_get_obj_count() */
-
+
/*-------------------------------------------------------------------------
* Function: H5F_get_obj_ids
*
@@ -268,7 +269,7 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5F_get_obj_ids() */
-
+
/*---------------------------------------------------------------------------
* Function: H5F_get_objects
*
@@ -370,7 +371,7 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5F_get_objects() */
-
+
/*-------------------------------------------------------------------------
* Function: H5F_get_objects_cb
*
@@ -479,7 +480,265 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5F_get_objects_cb() */
-
+/*--------------------------------------------------------------------------
+ * Function: H5F_build_name
+ *
+ * Purpose: Prepend PREFIX to FILE_NAME and store in FULL_NAME
+ *
+ * Return: Non-negative on success/Negative on failure
+ *--------------------------------------------------------------------------*/
+herr_t
+H5F_build_name(char *prefix, char *file_name, char **full_name/*out*/)
+{
+ size_t prefix_len; /* length of prefix */
+ size_t fname_len; /* Length of external link file name */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ prefix_len = HDstrlen(prefix);
+ fname_len = HDstrlen(file_name);
+
+ /* Allocate a buffer to hold the filename + prefix + possibly the delimiter + terminating null byte */
+ if(NULL == (*full_name = (char *)H5MM_malloc(prefix_len + fname_len + 2)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate filename buffer")
+
+ /* Compose the full file name */
+ HDsnprintf(*full_name, (prefix_len + fname_len + 2), "%s%s%s", prefix,
+ (H5_CHECK_DELIMITER(prefix[prefix_len - 1]) ? "" : H5_DIR_SEPS), file_name);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5F_build_name() */
+
+
+/*--------------------------------------------------------------------------
+ * Function: H5F_getenv_prefix_name --
+ *
+ * Purpose: Get the first pathname in the list of pathnames stored in env_prefix,
+ * which is separated by the environment delimiter.
+ * env_prefix is modified to point to the remaining pathnames
+ * in the list.
+ *
+ * Return: A pointer to a pathname
+--------------------------------------------------------------------------*/
+char *
+H5F_getenv_prefix_name(char **env_prefix/*in,out*/)
+{
+ char *retptr=NULL;
+ char *strret=NULL;
+
+ FUNC_ENTER_NOAPI_NOINIT_NOERR
+
+ strret = HDstrchr(*env_prefix, H5_COLON_SEPC);
+ if (strret == NULL) {
+ retptr = *env_prefix;
+ *env_prefix = strret;
+ } else {
+ retptr = *env_prefix;
+ *env_prefix = strret + 1;
+ *strret = '\0';
+ }
+
+ FUNC_LEAVE_NOAPI(retptr)
+} /* end H5F_getenv_prefix_name() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_prefix_open_file
+ *
+ * Purpose: Attempts to open a dataset file.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *-------------------------------------------------------------------------
+ */
+H5F_t *
+H5F_prefix_open_file(hid_t plist_id, H5F_t *primary_file, const char *prefix_type,
+ const char *file_name, unsigned file_intent, hid_t fapl_id, hid_t dxpl_id)
+{
+ H5F_t *src_file = NULL; /* Source file */
+ H5F_t *ret_value = NULL; /* Actual return value */
+ char *full_name = NULL; /* File name with prefix */
+ char *my_prefix = NULL; /* Library's copy of the prefix */
+ char *actual_file_name = NULL; /* File's actual name */
+ char *temp_file_name = NULL; /* Temporary pointer to file name */
+ size_t temp_file_name_len; /* Length of temporary file name */
+
+ FUNC_ENTER_STATIC
+
+ /* Simplify intent flags for open calls */
+ file_intent &= (H5F_ACC_RDWR | H5F_ACC_SWMR_WRITE | H5F_ACC_SWMR_READ);
+
+ /* Copy the file name to use */
+ if(NULL == (temp_file_name = H5MM_strdup(file_name)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+ temp_file_name_len = HDstrlen(temp_file_name);
+
+ /* target file_name is an absolute pathname: see RM for detailed description */
+ if(H5_CHECK_ABSOLUTE(file_name) || H5_CHECK_ABS_PATH(file_name)) {
+ /* Try opening file */
+ if(NULL == (src_file = H5F_efc_open(primary_file, file_name, file_intent, H5P_FILE_CREATE_DEFAULT, fapl_id, dxpl_id))) {
+ char *ptr;
+
+ H5E_clear_stack(NULL);
+
+ /* get last component of file_name */
+ H5_GET_LAST_DELIMITER(file_name, ptr)
+ HDassert(ptr);
+
+ /* Increment past delimiter */
+ ptr++;
+
+ /* Copy into the temp. file name */
+ HDstrncpy(temp_file_name, ptr, temp_file_name_len);
+ temp_file_name[temp_file_name_len - 1] = '\0';
+ } /* end if */
+ } /* end if */
+ else if(H5_CHECK_ABS_DRIVE(file_name)) {
+ /* Try opening file */
+ if(NULL == (src_file = H5F_efc_open(primary_file, file_name, file_intent, H5P_FILE_CREATE_DEFAULT, fapl_id, dxpl_id))) {
+
+ H5E_clear_stack(NULL);
+
+ /* strip "<drive-letter>:" */
+ HDstrncpy(temp_file_name, &file_name[2], temp_file_name_len);
+ temp_file_name[temp_file_name_len - 1] = '\0';
+ } /* end if */
+ } /* end if */
+
+ /* try searching from paths set in the environment variable */
+ if(src_file == NULL) {
+ char *env_prefix;
+
+ if (HDstrcmp(prefix_type, H5D_ACS_VDS_PREFIX_NAME) == 0)
+ env_prefix = HDgetenv("HDF5_VDS_PREFIX");
+ else if (HDstrcmp(prefix_type, H5L_ACS_ELINK_PREFIX_NAME) == 0)
+ env_prefix = HDgetenv("HDF5_EXT_PREFIX");
+ else
+ HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, NULL, "prefix name is not sensible")
+ if(NULL != env_prefix) {
+ char *tmp_env_prefix, *saved_env;
+
+ if(NULL == (saved_env = tmp_env_prefix = H5MM_strdup(env_prefix)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+
+ while((tmp_env_prefix) && (*tmp_env_prefix)) {
+ char *out_prefix_name;
+
+ out_prefix_name = H5F_getenv_prefix_name(&tmp_env_prefix/*in,out*/);
+ if(out_prefix_name && (*out_prefix_name)) {
+ if(H5F_build_name(out_prefix_name, temp_file_name, &full_name/*out*/) < 0) {
+ saved_env = (char *)H5MM_xfree(saved_env);
+ HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "can't prepend prefix to filename")
+ } /* end if */
+
+ src_file = H5F_efc_open(primary_file, full_name, file_intent, H5P_FILE_CREATE_DEFAULT, fapl_id, dxpl_id);
+ full_name = (char *)H5MM_xfree(full_name);
+ if(src_file != NULL)
+ break;
+ H5E_clear_stack(NULL);
+ } /* end if */
+ } /* end while */
+ saved_env = (char *)H5MM_xfree(saved_env);
+ } /* end if */
+ } /* end if */
+
+ /* try searching from property list */
+ if(src_file == NULL) {
+ ssize_t size = 0;
+ H5E_BEGIN_TRY {
+ if (HDstrcmp(prefix_type, H5D_ACS_VDS_PREFIX_NAME) == 0)
+ size = H5Pget_virtual_prefix(plist_id, NULL, 0);
+ else if (HDstrcmp(prefix_type, H5L_ACS_ELINK_PREFIX_NAME) == 0)
+ size = H5Pget_elink_prefix(plist_id, NULL, 0);
+ } H5E_END_TRY;
+ if(size <= 0)
+ my_prefix = NULL;
+ else {
+ /* Allocate a buffer to hold the filename + prefix + possibly the delimiter + terminating null byte */
+ if(NULL == (my_prefix = (char *)H5MM_malloc((size_t)size + 1)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "unable to allocate prefix buffer")
+ if (HDstrcmp(prefix_type, H5D_ACS_VDS_PREFIX_NAME) == 0)
+ size = H5Pget_virtual_prefix(plist_id, my_prefix, (size_t)size+1);
+ else if (HDstrcmp(prefix_type, H5L_ACS_ELINK_PREFIX_NAME) == 0)
+ size = H5Pget_elink_prefix(plist_id, my_prefix, (size_t)size+1);
+ if(size < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get file prefix")
+ if(my_prefix) {
+ if(H5F_build_name(my_prefix, temp_file_name, &full_name/*out*/) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "can't prepend prefix to filename")
+ my_prefix = (char *)H5MM_xfree(my_prefix);
+ if(NULL == (src_file = H5F_efc_open(primary_file, full_name, file_intent, H5P_FILE_CREATE_DEFAULT, fapl_id, dxpl_id)))
+ H5E_clear_stack(NULL);
+ full_name = (char *)H5MM_xfree(full_name);
+ }
+ }
+ }
+
+ /* try searching from main file's "extpath": see description in H5F_open() & H5_build_extpath() */
+ if(src_file == NULL) {
+ char *dspath;
+
+ if(NULL != (dspath = H5F_EXTPATH(primary_file))) {
+ if(H5F_build_name(dspath, temp_file_name, &full_name/*out*/) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "can't prepend prefix to filename")
+ if(NULL == (src_file = H5F_efc_open(primary_file, full_name, file_intent, H5P_FILE_CREATE_DEFAULT, fapl_id, dxpl_id)))
+ H5E_clear_stack(NULL);
+ full_name = (char *)H5MM_xfree(full_name);
+ } /* end if */
+ } /* end if */
+
+ /* try the relative file_name stored in temp_file_name */
+ if(src_file == NULL) {
+ if(NULL == (src_file = H5F_efc_open(primary_file, temp_file_name, file_intent, H5P_FILE_CREATE_DEFAULT, fapl_id, dxpl_id)))
+ H5E_clear_stack(NULL);
+ } /* end if */
+
+ /* try the 'resolved' name for the virtual file */
+ if(src_file == NULL) {
+ char *ptr = NULL;
+
+ /* Copy resolved file name */
+ if(NULL == (actual_file_name = H5MM_strdup(H5F_ACTUAL_NAME(primary_file))))
+ HGOTO_ERROR(H5E_FILE, H5E_CANTALLOC, NULL, "can't duplicate resolved file name string")
+
+ /* get last component of file_name */
+ H5_GET_LAST_DELIMITER(actual_file_name, ptr)
+ if(!ptr)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to open file, file name = '%s', temp_file_name = '%s'", file_name, temp_file_name)
+
+ /* Truncate filename portion from actual file name path */
+ *ptr = '\0';
+
+ /* Build new file name for the external file */
+ if(H5F_build_name(actual_file_name, temp_file_name, &full_name/*out*/) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "can't prepend prefix to filename")
+ actual_file_name = (char *)H5MM_xfree(actual_file_name);
+
+ /* Try opening with the resolved name */
+ if(NULL == (src_file = H5F_efc_open(primary_file, full_name, file_intent, H5P_FILE_CREATE_DEFAULT, fapl_id, dxpl_id)))
+ HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to open file, file name = '%s', temp_file_name = '%s'", file_name, temp_file_name)
+ full_name = (char *)H5MM_xfree(full_name);
+ } /* end if */
+
+ /* Success */
+ ret_value = src_file;
+done:
+ if((NULL == ret_value) && src_file)
+ if(H5F_efc_close(primary_file, src_file) < 0)
+ HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, NULL, "can't close source file")
+ if(my_prefix)
+ my_prefix = (char *)H5MM_xfree(my_prefix);
+ if(full_name)
+ full_name = (char *)H5MM_xfree(full_name);
+ if(temp_file_name)
+ temp_file_name = (char *)H5MM_xfree(temp_file_name);
+ if(actual_file_name)
+ actual_file_name = (char *)H5MM_xfree(actual_file_name);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5F_prefix_open_file() */
+
+
/*-------------------------------------------------------------------------
* Function: H5F__is_hdf5
*
@@ -528,7 +787,7 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5F__is_hdf5() */
-
+
/*-------------------------------------------------------------------------
* Function: H5F_new
*
@@ -792,7 +1051,7 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5F_new() */
-
+
/*-------------------------------------------------------------------------
* Function: H5F__dest
*
@@ -1051,7 +1310,7 @@ H5F__dest(H5F_t *f, hid_t meta_dxpl_id, hid_t raw_dxpl_id, hbool_t flush)
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5F_dest() */
-
+
/*-------------------------------------------------------------------------
* Function: H5F_open
*
@@ -1469,7 +1728,7 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5F_open() */
-
+
/*-------------------------------------------------------------------------
* Function: H5F_flush_phase1
*
@@ -1506,7 +1765,7 @@ H5F__flush_phase1(H5F_t *f, hid_t meta_dxpl_id)
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5F__flush_phase1() */
-
+
/*-------------------------------------------------------------------------
* Function: H5F__flush_phase2
*
@@ -1568,7 +1827,7 @@ H5F__flush_phase2(H5F_t *f, hid_t meta_dxpl_id, hid_t raw_dxpl_id, hbool_t closi
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5F__flush_phase2() */
-
+
/*-------------------------------------------------------------------------
* Function: H5F__flush
*
@@ -1600,7 +1859,7 @@ H5F__flush(H5F_t *f, hid_t meta_dxpl_id, hid_t raw_dxpl_id, hbool_t closing)
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5F__flush() */
-
+
/*-------------------------------------------------------------------------
* Function: H5F_close
*
@@ -1661,7 +1920,7 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5F_close() */
-
+
/*-------------------------------------------------------------------------
* Function: H5F_try_close
*
@@ -1834,7 +2093,7 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5F_try_close() */
-
+
/*-------------------------------------------------------------------------
* Function: H5F_get_id
*
@@ -1870,7 +2129,7 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5F_get_id() */
-
+
/*-------------------------------------------------------------------------
* Function: H5F_incr_nopen_objs
*
@@ -1891,7 +2150,7 @@ H5F_incr_nopen_objs(H5F_t *f)
FUNC_LEAVE_NOAPI(++f->nopen_objs)
} /* end H5F_incr_nopen_objs() */
-
+
/*-------------------------------------------------------------------------
* Function: H5F_decr_nopen_objs
*
@@ -1912,7 +2171,7 @@ H5F_decr_nopen_objs(H5F_t *f)
FUNC_LEAVE_NOAPI(--f->nopen_objs)
} /* end H5F_decr_nopen_objs() */
-
+
/*-------------------------------------------------------------------------
* Function: H5F_build_actual_name
*
@@ -2034,7 +2293,7 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* H5F_build_actual_name() */
-
+
/*-------------------------------------------------------------------------
* Function: H5F_addr_encode_len
*
@@ -2071,7 +2330,7 @@ H5F_addr_encode_len(size_t addr_len, uint8_t **pp/*in,out*/, haddr_t addr)
FUNC_LEAVE_NOAPI_VOID
} /* end H5F_addr_encode_len() */
-
+
/*-------------------------------------------------------------------------
* Function: H5F_addr_encode
*
@@ -2095,7 +2354,7 @@ H5F_addr_encode(const H5F_t *f, uint8_t **pp/*in,out*/, haddr_t addr)
FUNC_LEAVE_NOAPI_VOID
} /* end H5F_addr_encode() */
-
+
/*-------------------------------------------------------------------------
* Function: H5F_addr_decode_len
*
@@ -2159,7 +2418,7 @@ H5F_addr_decode_len(size_t addr_len, const uint8_t **pp/*in,out*/, haddr_t *addr
FUNC_LEAVE_NOAPI_VOID
} /* end H5F_addr_decode_len() */
-
+
/*-------------------------------------------------------------------------
* Function: H5F_addr_decode
*
@@ -2186,7 +2445,7 @@ H5F_addr_decode(const H5F_t *f, const uint8_t **pp/*in,out*/, haddr_t *addr_p/*o
FUNC_LEAVE_NOAPI_VOID
} /* end H5F_addr_decode() */
-
+
/*-------------------------------------------------------------------------
* Function: H5F_set_grp_btree_shared
*
@@ -2212,7 +2471,7 @@ H5F_set_grp_btree_shared(H5F_t *f, H5UC_t *rc)
FUNC_LEAVE_NOAPI(SUCCEED)
} /* H5F_set_grp_btree_shared() */
-
+
/*-------------------------------------------------------------------------
* Function: H5F_set_sohm_addr
*
@@ -2237,7 +2496,7 @@ H5F_set_sohm_addr(H5F_t *f, haddr_t addr)
FUNC_LEAVE_NOAPI(SUCCEED)
} /* H5F_set_sohm_addr() */
-
+
/*-------------------------------------------------------------------------
* Function: H5F_set_sohm_vers
*
@@ -2262,7 +2521,7 @@ H5F_set_sohm_vers(H5F_t *f, unsigned vers)
FUNC_LEAVE_NOAPI(SUCCEED)
} /* H5F_set_sohm_vers() */
-
+
/*-------------------------------------------------------------------------
* Function: H5F_set_sohm_nindexes
*
@@ -2287,7 +2546,7 @@ H5F_set_sohm_nindexes(H5F_t *f, unsigned nindexes)
FUNC_LEAVE_NOAPI(SUCCEED)
} /* H5F_set_sohm_nindexes() */
-
+
/*-------------------------------------------------------------------------
* Function: H5F_set_store_msg_crt_idx
*
@@ -2312,7 +2571,7 @@ H5F_set_store_msg_crt_idx(H5F_t *f, hbool_t flag)
FUNC_LEAVE_NOAPI(SUCCEED)
} /* H5F_set_store_msg_crt_idx() */
-
+
/*-------------------------------------------------------------------------
* Function: H5F_get_file_image
*
@@ -2428,7 +2687,7 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* H5F_get_file_image() */
-
+
/*-------------------------------------------------------------------------
* Function: H5F_track_metadata_read_retries
*
@@ -2476,7 +2735,7 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* H5F_track_metadata_read_retries() */
-
+
/*-------------------------------------------------------------------------
* Function: H5F_set_retries
*
@@ -2512,7 +2771,7 @@ H5F_set_retries(H5F_t *f)
FUNC_LEAVE_NOAPI(SUCCEED)
} /* H5F_set_retries() */
-
+
/*-------------------------------------------------------------------------
* Function: H5F_object_flush_cb
*
@@ -2542,7 +2801,7 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* H5F_object_flush_cb() */
-
+
/*-------------------------------------------------------------------------
* Function: H5F__set_base_addr
*
@@ -2569,7 +2828,7 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5F__set_base_addr() */
-
+
/*-------------------------------------------------------------------------
* Function: H5F__set_eoa
*
@@ -2596,7 +2855,7 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5F__set_eoa() */
-
+
/*-------------------------------------------------------------------------
* Function: H5F__set_paged_aggr
*
@@ -2625,7 +2884,7 @@ done:
} /* end H5F__set_paged_aggr() */
#ifdef H5_HAVE_PARALLEL
-
+
/*-------------------------------------------------------------------------
* Function: H5F_set_coll_md_read
*
@@ -2650,7 +2909,7 @@ H5F_set_coll_md_read(H5F_t *f, H5P_coll_md_read_flag_t cmr)
} /* H5F_set_coll_md_read() */
#endif /* H5_HAVE_PARALLEL */
-
+
/*-------------------------------------------------------------------------
* Function: H5F_set_latest_flags
*