mirror of
https://github.com/HDFGroup/hdf5.git
synced 2024-12-09 07:32:32 +08:00
[svn-r18376] Purpose: Fix bug 1733
Description: Support for expanding external links was not implemented in H5Ocopy, even though a flag existed for H5Pset_copy_object to enable this. This patch implements this feature. Tested: jam, amani, linew (h5committest); Fedora
This commit is contained in:
parent
179b54da83
commit
1872925320
@ -208,6 +208,9 @@ Bug Fixes since HDF5-1.8.0 release
|
||||
|
||||
Library
|
||||
-------
|
||||
- Added support for H5O_COPY_EXPAND_EXT_LINK_FLAG to H5Ocopy. External
|
||||
links will now be expanded if this flag is set.
|
||||
(NAF - 2010/03/05 - 1733)
|
||||
- Fixed a bug where the library, when traversing an external link, would
|
||||
reopen the source file if nothing else worked. (NAF - 2010/03/05)
|
||||
- Fixed an intermittent bug in the b-tree code which could be triggered
|
||||
|
@ -250,7 +250,7 @@ H5Gcreate1(hid_t loc_id, const char *name, size_t size_hint)
|
||||
|
||||
done:
|
||||
if(tmp_gcpl > 0 && tmp_gcpl != H5P_GROUP_CREATE_DEFAULT)
|
||||
if(H5I_dec_ref(tmp_gcpl, TRUE) < 0)
|
||||
if(H5I_dec_ref(tmp_gcpl, FALSE) < 0)
|
||||
HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "unable to release property list")
|
||||
|
||||
if(ret_value < 0)
|
||||
|
@ -403,6 +403,10 @@ H5G_link_copy_file(H5F_t *dst_file, hid_t dxpl_id, const H5O_link_t *_src_lnk,
|
||||
H5O_link_t tmp_src_lnk; /* Temporary copy of src link, when needed */
|
||||
const H5O_link_t *src_lnk = _src_lnk; /* Source link */
|
||||
hbool_t dst_lnk_init = FALSE; /* Whether the destination link is initialized */
|
||||
hbool_t expanded_link_open = FALSE; /* Whether the target location has been opened */
|
||||
H5G_loc_t tmp_src_loc; /* Group location holding target object */
|
||||
H5G_name_t tmp_src_path; /* Path for target object */
|
||||
H5O_loc_t tmp_src_oloc; /* Object location for target object */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_NOAPI(H5G_link_copy_file, FAIL)
|
||||
@ -413,61 +417,79 @@ H5G_link_copy_file(H5F_t *dst_file, hid_t dxpl_id, const H5O_link_t *_src_lnk,
|
||||
HDassert(dst_lnk);
|
||||
HDassert(cpy_info);
|
||||
|
||||
/* Expand soft link */
|
||||
if(H5L_TYPE_SOFT == src_lnk->type && cpy_info->expand_soft_link) {
|
||||
H5O_info_t oinfo; /* Information about object pointed to by soft link */
|
||||
H5G_loc_t grp_loc; /* Group location holding soft link */
|
||||
H5G_name_t grp_path; /* Path for group holding soft link */
|
||||
/* Expand soft or external link, if requested */
|
||||
if((H5L_TYPE_SOFT == src_lnk->type && cpy_info->expand_soft_link)
|
||||
|| (H5L_TYPE_EXTERNAL == src_lnk->type
|
||||
&& cpy_info->expand_ext_link)) {
|
||||
H5G_loc_t lnk_grp_loc; /* Group location holding link */
|
||||
H5G_name_t lnk_grp_path; /* Path for link */
|
||||
htri_t tar_exists; /* Whether the target object exists */
|
||||
|
||||
/* Make a temporary copy, so that it will not change the info in the cache */
|
||||
if(NULL == H5O_msg_copy(H5O_LINK_ID, src_lnk, &tmp_src_lnk))
|
||||
HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, H5_ITER_ERROR, "unable to copy message")
|
||||
/* Set up group location for link */
|
||||
H5G_name_reset(&lnk_grp_path);
|
||||
lnk_grp_loc.path = &lnk_grp_path;
|
||||
lnk_grp_loc.oloc = (H5O_loc_t *)src_oloc; /* Casting away const OK -QAK */
|
||||
|
||||
/* Set up group location for soft link to start in */
|
||||
H5G_name_reset(&grp_path);
|
||||
grp_loc.path = &grp_path;
|
||||
grp_loc.oloc = (H5O_loc_t *)src_oloc; /* Casting away const OK -QAK */
|
||||
/* Check if the target object exists */
|
||||
if((tar_exists = H5G_loc_exists(&lnk_grp_loc, src_lnk->name, H5P_DEFAULT,
|
||||
dxpl_id)) < 0)
|
||||
HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to check if target object exists")
|
||||
|
||||
/* Check if the object pointed by the soft link exists in the source file */
|
||||
if(H5G_loc_info(&grp_loc, tmp_src_lnk.u.soft.name, FALSE, &oinfo, H5P_DEFAULT, dxpl_id) >= 0) {
|
||||
/* Convert soft link to hard link */
|
||||
tmp_src_lnk.u.soft.name = (char *)H5MM_xfree(tmp_src_lnk.u.soft.name);
|
||||
if(tar_exists) {
|
||||
/* Make a temporary copy of the link, so that it will not change the
|
||||
* info in the cache when we change it to a hard link */
|
||||
if(NULL == H5O_msg_copy(H5O_LINK_ID, src_lnk, &tmp_src_lnk))
|
||||
HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy message")
|
||||
|
||||
/* Set up group location for target object. Let H5G_traverse expand
|
||||
* the link. */
|
||||
tmp_src_loc.path = &tmp_src_path;
|
||||
tmp_src_loc.oloc = &tmp_src_oloc;
|
||||
if(H5G_loc_reset(&tmp_src_loc) < 0)
|
||||
HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to reset location")
|
||||
|
||||
/* Find the target object */
|
||||
if(H5G_loc_find(&lnk_grp_loc, src_lnk->name, &tmp_src_loc,
|
||||
H5P_DEFAULT, dxpl_id) < 0)
|
||||
HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to find target object")
|
||||
expanded_link_open = TRUE;
|
||||
|
||||
/* Convert symbolic link to hard link */
|
||||
if(tmp_src_lnk.type == H5L_TYPE_SOFT)
|
||||
tmp_src_lnk.u.soft.name =
|
||||
(char *)H5MM_xfree(tmp_src_lnk.u.soft.name);
|
||||
else if(tmp_src_lnk.u.ud.size > 0)
|
||||
tmp_src_lnk.u.ud.udata = H5MM_xfree(tmp_src_lnk.u.ud.udata);
|
||||
tmp_src_lnk.type = H5L_TYPE_HARD;
|
||||
tmp_src_lnk.u.hard.addr = oinfo.addr;
|
||||
tmp_src_lnk.u.hard.addr = tmp_src_oloc.addr;
|
||||
src_lnk = &tmp_src_lnk;
|
||||
} /* end if */
|
||||
else {
|
||||
/* Discard any errors from a dangling soft link */
|
||||
H5E_clear_stack(NULL);
|
||||
|
||||
/* Release any information copied for temporary src link */
|
||||
H5O_msg_reset(H5O_LINK_ID, &tmp_src_lnk);
|
||||
} /* end else */
|
||||
} /* end if */
|
||||
|
||||
/* Copy src link information to dst link information */
|
||||
if(NULL == H5O_msg_copy(H5O_LINK_ID, src_lnk, dst_lnk))
|
||||
HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, H5_ITER_ERROR, "unable to copy message")
|
||||
HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy message")
|
||||
dst_lnk_init = TRUE;
|
||||
|
||||
/* Check if object in source group is a hard link & copy it */
|
||||
if(H5L_TYPE_HARD == src_lnk->type) {
|
||||
H5O_loc_t new_dst_oloc; /* Copied object location in destination */
|
||||
H5O_loc_t tmp_src_oloc; /* Temporary object location for source object */
|
||||
|
||||
/* Set up copied object location to fill in */
|
||||
H5O_loc_reset(&new_dst_oloc);
|
||||
new_dst_oloc.file = dst_file;
|
||||
|
||||
/* Build temporary object location for source */
|
||||
H5O_loc_reset(&tmp_src_oloc);
|
||||
tmp_src_oloc.file = src_oloc->file;
|
||||
HDassert(H5F_addr_defined(src_lnk->u.hard.addr));
|
||||
tmp_src_oloc.addr = src_lnk->u.hard.addr;
|
||||
if(!expanded_link_open) {
|
||||
/* Build temporary object location for source */
|
||||
H5O_loc_reset(&tmp_src_oloc);
|
||||
tmp_src_oloc.file = src_oloc->file;
|
||||
tmp_src_oloc.addr = src_lnk->u.hard.addr;
|
||||
} /* end if */
|
||||
HDassert(H5F_addr_defined(tmp_src_oloc.addr));
|
||||
|
||||
/* Copy the shared object from source to destination */
|
||||
if(H5O_copy_header_map(&tmp_src_oloc, &new_dst_oloc, dxpl_id, cpy_info, TRUE) < 0)
|
||||
HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, H5_ITER_ERROR, "unable to copy object")
|
||||
HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object")
|
||||
|
||||
/* Copy new destination object's information for eventual insertion */
|
||||
dst_lnk->u.hard.addr = new_dst_oloc.addr;
|
||||
@ -482,6 +504,10 @@ done:
|
||||
if(ret_value < 0)
|
||||
if(dst_lnk_init)
|
||||
H5O_msg_reset(H5O_LINK_ID, dst_lnk);
|
||||
/* Check if we need to free the temp source oloc */
|
||||
if(expanded_link_open)
|
||||
if(H5G_loc_free(&tmp_src_loc) < 0)
|
||||
HDONE_ERROR(H5E_OHDR, H5E_CANTFREE, FAIL, "unable to free object")
|
||||
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5G_link_copy_file() */
|
||||
|
@ -661,12 +661,14 @@ H5O_copy_header_real(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */,
|
||||
|
||||
/* Insert the address mapping for the new object into the copied list */
|
||||
/* (Do this here, because "post copy" possibly checks it) */
|
||||
addr_map->src_addr = oloc_src->addr;
|
||||
H5F_GET_FILENO(oloc_src->file, addr_map->src_obj_pos.fileno);
|
||||
addr_map->src_obj_pos.addr = oloc_src->addr;
|
||||
addr_map->dst_addr = oloc_dst->addr;
|
||||
addr_map->is_locked = TRUE; /* We've locked the object currently */
|
||||
addr_map->inc_ref_count = 0; /* Start with no additional ref counts to add */
|
||||
|
||||
if(H5SL_insert(cpy_info->map_list, addr_map, &(addr_map->src_addr)) < 0)
|
||||
/* Insert into skip list */
|
||||
if(H5SL_insert(cpy_info->map_list, addr_map, &(addr_map->src_obj_pos)) < 0)
|
||||
HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, FAIL, "can't insert object into skip list")
|
||||
|
||||
/* "post copy" loop over messages, to fix up any messages which require a complete
|
||||
@ -765,20 +767,27 @@ herr_t
|
||||
H5O_copy_header_map(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */,
|
||||
hid_t dxpl_id, H5O_copy_t *cpy_info, hbool_t inc_depth)
|
||||
{
|
||||
H5O_addr_map_t *addr_map; /* Address mapping of object copied */
|
||||
H5O_addr_map_t *addr_map = NULL; /* Address mapping of object copied */
|
||||
H5_obj_t src_obj_pos; /* Position of source object */
|
||||
hbool_t inc_link; /* Whether to increment the link count for the object */
|
||||
herr_t ret_value = SUCCEED;
|
||||
herr_t ret_value = SUCCEED;
|
||||
|
||||
FUNC_ENTER_NOAPI(H5O_copy_header_map, FAIL)
|
||||
|
||||
/* Sanity check */
|
||||
HDassert(oloc_src);
|
||||
HDassert(oloc_src->file);
|
||||
HDassert(oloc_dst);
|
||||
HDassert(oloc_dst->file);
|
||||
HDassert(cpy_info);
|
||||
|
||||
/* Look up the address of the object to copy in the skip list */
|
||||
addr_map = (H5O_addr_map_t *)H5SL_search(cpy_info->map_list, &(oloc_src->addr));
|
||||
/* Create object "position" struct */
|
||||
H5F_GET_FILENO(oloc_src->file, src_obj_pos.fileno);
|
||||
src_obj_pos.addr = oloc_src->addr;
|
||||
|
||||
/* Search for the object in the skip list of copied objects */
|
||||
addr_map = (H5O_addr_map_t *)H5SL_search(cpy_info->map_list,
|
||||
&src_obj_pos);
|
||||
|
||||
/* Check if address is already in list of objects copied */
|
||||
if(addr_map == NULL) {
|
||||
@ -910,7 +919,7 @@ H5O_copy_header(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */,
|
||||
cpy_info.preserve_null = TRUE;
|
||||
|
||||
/* Create a skip list to keep track of which objects are copied */
|
||||
if((cpy_info.map_list = H5SL_create(H5SL_TYPE_HADDR)) == NULL)
|
||||
if((cpy_info.map_list = H5SL_create(H5SL_TYPE_OBJ)) == NULL)
|
||||
HGOTO_ERROR(H5E_SLIST, H5E_CANTCREATE, FAIL, "cannot make skip list")
|
||||
|
||||
/* copy the object from the source file to the destination file */
|
||||
|
@ -326,7 +326,7 @@ typedef struct H5O_obj_class_t {
|
||||
|
||||
/* Node in skip list to map addresses from one file to another during object header copy */
|
||||
typedef struct H5O_addr_map_t {
|
||||
haddr_t src_addr; /* Address of object in source file */
|
||||
H5_obj_t src_obj_pos; /* Location of source object */
|
||||
haddr_t dst_addr; /* Address of object in destination file */
|
||||
hbool_t is_locked; /* Indicate that the destination object is locked currently */
|
||||
hsize_t inc_ref_count; /* Number of deferred increments to reference count */
|
||||
|
272
test/objcopy.c
272
test/objcopy.c
@ -103,8 +103,11 @@ const char *FILENAME[] = {
|
||||
#define NAME_LINK_SOFT "/g_links/soft_link_to_dataset_simple"
|
||||
#define NAME_LINK_SOFT2 "/g_links2/soft_link_to_dataset_simple"
|
||||
#define NAME_LINK_EXTERN "/g_links/external_link_to_dataset_simple"
|
||||
#define NAME_LINK_EXTERN2 "/g_links2/external_link_to_dataset_simple"
|
||||
#define NAME_LINK_SOFT_DANGLE "/g_links/soft_link_to_nowhere"
|
||||
#define NAME_LINK_SOFT_DANGLE2 "/g_links2/soft_link_to_nowhere"
|
||||
#define NAME_LINK_EXTERN_DANGLE "/g_links/external_link_to_nowhere"
|
||||
#define NAME_LINK_EXTERN_DANGLE2 "/g_links2/external_link_to_nowhere"
|
||||
#define NAME_OLD_FORMAT "/dset1"
|
||||
|
||||
#define NAME_BUF_SIZE 1024
|
||||
@ -5229,21 +5232,32 @@ error:
|
||||
* Friday, September 30, 2005
|
||||
*
|
||||
* Modifications:
|
||||
* Neil Fortner
|
||||
* Tuesday, February 16, 2010
|
||||
* Modified test to test flags for expanding soft and external
|
||||
* links.
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static int
|
||||
test_copy_group_links(hid_t fcpl_src, hid_t fcpl_dst, hid_t fapl)
|
||||
{
|
||||
hid_t fid_src = -1, fid_dst = -1; /* File IDs */
|
||||
hid_t fid_src = -1, fid_dst = -1, fid_ext = -1; /* File IDs */
|
||||
hid_t sid = -1; /* Dataspace ID */
|
||||
hid_t did = -1; /* Dataset ID */
|
||||
hid_t did = -1, did2 = -1; /* Dataset ID */
|
||||
hid_t gid = -1, gid2 = -1; /* Group IDs */
|
||||
hid_t plid = -1; /* Object copy plist ID */
|
||||
hsize_t dim2d[2];
|
||||
hsize_t dim1d[1];
|
||||
H5L_info_t linfo;
|
||||
int buf[DIM_SIZE_1][DIM_SIZE_2];
|
||||
int i, j;
|
||||
unsigned expand_soft;
|
||||
unsigned expand_ext;
|
||||
unsigned copy_options;
|
||||
char src_filename[NAME_BUF_SIZE];
|
||||
char dst_filename[NAME_BUF_SIZE];
|
||||
char ext_filename[NAME_BUF_SIZE];
|
||||
|
||||
TESTING("H5Ocopy(): group with links");
|
||||
|
||||
@ -5255,6 +5269,7 @@ test_copy_group_links(hid_t fcpl_src, hid_t fcpl_dst, hid_t fapl)
|
||||
/* Initialize the filenames */
|
||||
h5_fixname(FILENAME[0], fapl, src_filename, sizeof src_filename);
|
||||
h5_fixname(FILENAME[1], fapl, dst_filename, sizeof dst_filename);
|
||||
h5_fixname(FILENAME[2], fapl, ext_filename, sizeof ext_filename);
|
||||
|
||||
/* Reset file address checking info */
|
||||
addr_reset();
|
||||
@ -5262,11 +5277,16 @@ test_copy_group_links(hid_t fcpl_src, hid_t fcpl_dst, hid_t fapl)
|
||||
/* create source file */
|
||||
if((fid_src = H5Fcreate(src_filename, H5F_ACC_TRUNC, fcpl_src, fapl)) < 0) TEST_ERROR
|
||||
|
||||
/* create group at the SRC file */
|
||||
if((gid = H5Gcreate2(fid_src, NAME_GROUP_LINK, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
|
||||
/* create file to hold external dataset */
|
||||
if((fid_ext = H5Fcreate(ext_filename, H5F_ACC_TRUNC, fcpl_src, fapl)) < 0) TEST_ERROR
|
||||
|
||||
/* attach attributes to the group */
|
||||
/* create groups at the SRC file. Group 2 will hold dangling links. */
|
||||
if((gid = H5Gcreate2(fid_src, NAME_GROUP_LINK, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
|
||||
if((gid2 = H5Gcreate2(fid_src, NAME_GROUP_LINK2, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
|
||||
|
||||
/* attach attributes to the groups */
|
||||
if(test_copy_attach_attributes(gid, H5T_NATIVE_INT) < 0) TEST_ERROR
|
||||
if(test_copy_attach_attributes(gid2, H5T_NATIVE_INT) < 0) TEST_ERROR
|
||||
|
||||
/* Set dataspace dimensions */
|
||||
dim2d[0]=DIM_SIZE_1;
|
||||
@ -5285,57 +5305,162 @@ test_copy_group_links(hid_t fcpl_src, hid_t fcpl_dst, hid_t fapl)
|
||||
/* close the dataset */
|
||||
if(H5Dclose(did) < 0) TEST_ERROR
|
||||
|
||||
/* Now create a 1-D dataset in an external file */
|
||||
/* Set dataspace dimensions */
|
||||
dim1d[0]=DIM_SIZE_2;
|
||||
|
||||
/* create dataspace */
|
||||
if((sid = H5Screate_simple(1, dim1d, NULL)) < 0) TEST_ERROR
|
||||
|
||||
/* add a dataset to the external file */
|
||||
if((did = H5Dcreate2(fid_ext, NAME_DATASET_SIMPLE, H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
|
||||
if(H5Dwrite(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf) < 0) TEST_ERROR
|
||||
|
||||
/* close dataspace */
|
||||
if(H5Sclose(sid) < 0) TEST_ERROR
|
||||
|
||||
/* close the dataset */
|
||||
if(H5Dclose(did) < 0) TEST_ERROR
|
||||
|
||||
/* make a hard link to the dataset */
|
||||
if(H5Lcreate_hard(fid_src, NAME_LINK_DATASET, H5L_SAME_LOC, NAME_LINK_HARD, H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR
|
||||
|
||||
/* make a soft link to the dataset */
|
||||
if(H5Lcreate_soft(NAME_LINK_DATASET, fid_src, NAME_LINK_SOFT, H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR
|
||||
|
||||
/* make a soft link to nowhere */
|
||||
if(H5Lcreate_soft("nowhere", fid_src, NAME_LINK_SOFT_DANGLE, H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR
|
||||
/* make an external link to the external dataset */
|
||||
if(H5Lcreate_external(ext_filename, NAME_DATASET_SIMPLE, fid_src, NAME_LINK_EXTERN, H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR
|
||||
|
||||
/* make a dangling soft link */
|
||||
if(H5Lcreate_soft("nowhere", fid_src, NAME_LINK_SOFT_DANGLE2, H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR
|
||||
|
||||
/* make a dangling external link */
|
||||
if(H5Lcreate_external("filename", "obj_name", fid_src, NAME_LINK_EXTERN, H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR
|
||||
if(H5Lcreate_external("no_file", "no_object", fid_src, NAME_LINK_EXTERN_DANGLE2, H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR
|
||||
|
||||
/* close the group */
|
||||
/* close the groups */
|
||||
if(H5Gclose(gid) < 0) TEST_ERROR
|
||||
|
||||
/* close the SRC file */
|
||||
if(H5Fclose(fid_src) < 0) TEST_ERROR
|
||||
|
||||
|
||||
/* open the source file with read-only */
|
||||
if((fid_src = H5Fopen(src_filename, H5F_ACC_RDONLY, fapl)) < 0) TEST_ERROR
|
||||
|
||||
/* create destination file */
|
||||
if((fid_dst = H5Fcreate(dst_filename, H5F_ACC_TRUNC, fcpl_dst, fapl)) < 0) TEST_ERROR
|
||||
|
||||
/* Create an uncopied object in destination file so that addresses in source and destination files aren't the same */
|
||||
if(H5Gclose(H5Gcreate2(fid_dst, NAME_GROUP_UNCOPIED, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
|
||||
|
||||
/* copy the group from SRC to DST */
|
||||
if(H5Ocopy(fid_src, NAME_GROUP_LINK, fid_dst, NAME_GROUP_LINK, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
|
||||
|
||||
/* open the group for copy */
|
||||
if((gid = H5Gopen2(fid_src, NAME_GROUP_LINK, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR
|
||||
|
||||
/* open the destination group */
|
||||
if((gid2 = H5Gopen2(fid_dst, NAME_GROUP_LINK, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR
|
||||
|
||||
/* Check if the groups are equal */
|
||||
if(compare_groups(gid, gid2, H5P_DEFAULT, -1, 0) != TRUE) TEST_ERROR
|
||||
|
||||
/* close the destination group */
|
||||
if(H5Gclose(gid2) < 0) TEST_ERROR
|
||||
|
||||
/* close the source group */
|
||||
if(H5Gclose(gid) < 0) TEST_ERROR
|
||||
|
||||
/* close the SRC file */
|
||||
/* close the SRC and EXT files */
|
||||
if(H5Fclose(fid_src) < 0) TEST_ERROR
|
||||
if(H5Fclose(fid_ext) < 0) TEST_ERROR
|
||||
|
||||
/* close the DST file */
|
||||
if(H5Fclose(fid_dst) < 0) TEST_ERROR
|
||||
|
||||
/* Create the object copy plist */
|
||||
if((plid = H5Pcreate(H5P_OBJECT_COPY)) < 0) TEST_ERROR
|
||||
|
||||
/* Loop over all configurations (expand soft/external links) */
|
||||
for(expand_soft=0; expand_soft<=1; expand_soft++) {
|
||||
for(expand_ext=0; expand_ext<=1; expand_ext++) {
|
||||
/* Set the correct copy options on the obj copy plist */
|
||||
copy_options = 0;
|
||||
if(expand_soft)
|
||||
copy_options |= H5O_COPY_EXPAND_SOFT_LINK_FLAG;
|
||||
if(expand_ext)
|
||||
copy_options |= H5O_COPY_EXPAND_EXT_LINK_FLAG;
|
||||
if(H5Pset_copy_object(plid, copy_options) < 0) TEST_ERROR
|
||||
|
||||
/* open the source file with read-only */
|
||||
if((fid_src = H5Fopen(src_filename, H5F_ACC_RDONLY, fapl)) < 0) TEST_ERROR
|
||||
|
||||
/* create destination file */
|
||||
if((fid_dst = H5Fcreate(dst_filename, H5F_ACC_TRUNC, fcpl_dst, fapl)) < 0) TEST_ERROR
|
||||
|
||||
/* Create an uncopied object in destination file so that addresses in source and destination files aren't the same */
|
||||
if(H5Gclose(H5Gcreate2(fid_dst, NAME_GROUP_UNCOPIED, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
|
||||
|
||||
/* copy the group from SRC to DST */
|
||||
if(H5Ocopy(fid_src, NAME_GROUP_LINK, fid_dst, NAME_GROUP_LINK, plid, H5P_DEFAULT) < 0) TEST_ERROR
|
||||
|
||||
/* open the group for copy */
|
||||
if((gid = H5Gopen2(fid_src, NAME_GROUP_LINK, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR
|
||||
|
||||
/* open the destination group */
|
||||
if((gid2 = H5Gopen2(fid_dst, NAME_GROUP_LINK, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR
|
||||
|
||||
/* If expand_soft is set to true, verify that the soft link is now a
|
||||
* hard link, and compare the expanded dataset, then delete it and
|
||||
* re-add it as a soft link so compare_groups() works */
|
||||
if(expand_soft) {
|
||||
/* Check link type */
|
||||
if(H5Lget_info(fid_dst, NAME_LINK_SOFT, &linfo, H5P_DEFAULT) < 0) TEST_ERROR
|
||||
if(linfo.type != H5L_TYPE_HARD)
|
||||
FAIL_PUTS_ERROR("Soft link was not expanded to a hard link")
|
||||
|
||||
/* Compare datasets */
|
||||
if((did = H5Dopen2(fid_src, NAME_LINK_DATASET, H5P_DEFAULT)) < 0) TEST_ERROR
|
||||
if((did2 = H5Dopen2(fid_dst, NAME_LINK_SOFT, H5P_DEFAULT)) < 0) TEST_ERROR
|
||||
if(compare_datasets(did, did2, H5P_DEFAULT, NULL) != TRUE) TEST_ERROR
|
||||
|
||||
/* Delete expanded dataset, add soft link */
|
||||
if(H5Ldelete(fid_dst, NAME_LINK_SOFT, H5P_DEFAULT) < 0) TEST_ERROR
|
||||
if(H5Lcreate_soft(NAME_LINK_DATASET, fid_dst, NAME_LINK_SOFT, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
|
||||
|
||||
/* Close datasets */
|
||||
if(H5Dclose(did) < 0) TEST_ERROR
|
||||
if(H5Dclose(did2) < 0) TEST_ERROR
|
||||
} /* end if */
|
||||
|
||||
/* If expand_ext is set to true, verify that the external link is
|
||||
* now a hard link, and compare the expanded dataset, then delete it
|
||||
* and re-add it as an external link so compare_groups() works */
|
||||
if(expand_ext) {
|
||||
/* Check link type */
|
||||
if(H5Lget_info(fid_dst, NAME_LINK_EXTERN, &linfo, H5P_DEFAULT) < 0) TEST_ERROR
|
||||
if(linfo.type != H5L_TYPE_HARD)
|
||||
FAIL_PUTS_ERROR("External link was not expanded to a hard link")
|
||||
|
||||
/* Compare datasets */
|
||||
if((fid_ext = H5Fopen(ext_filename, H5F_ACC_RDONLY, fapl)) < 0) TEST_ERROR
|
||||
if((did = H5Dopen2(fid_ext, NAME_DATASET_SIMPLE, H5P_DEFAULT)) < 0) TEST_ERROR
|
||||
if((did2 = H5Dopen2(fid_dst, NAME_LINK_EXTERN, H5P_DEFAULT)) < 0) TEST_ERROR
|
||||
if(compare_datasets(did, did2, H5P_DEFAULT, NULL) != TRUE) TEST_ERROR
|
||||
|
||||
/* Delete expanded dataset, add external link */
|
||||
if(H5Ldelete(fid_dst, NAME_LINK_EXTERN, H5P_DEFAULT) < 0) TEST_ERROR
|
||||
if(H5Lcreate_external(ext_filename, NAME_DATASET_SIMPLE, fid_dst, NAME_LINK_EXTERN, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
|
||||
|
||||
/* Close datasets and external file */
|
||||
if(H5Dclose(did) < 0) TEST_ERROR
|
||||
if(H5Dclose(did2) < 0) TEST_ERROR
|
||||
if(H5Fclose(fid_ext) < 0) TEST_ERROR
|
||||
} /* end if */
|
||||
|
||||
/* Check if the groups are equal */
|
||||
if(compare_groups(gid, gid2, H5P_DEFAULT, -1, 0) != TRUE) TEST_ERROR
|
||||
|
||||
/* close the destination group */
|
||||
if(H5Gclose(gid2) < 0) TEST_ERROR
|
||||
|
||||
/* close the source group */
|
||||
if(H5Gclose(gid) < 0) TEST_ERROR
|
||||
|
||||
/* Now try to copy the group containing the dangling link. They
|
||||
* should always be copied as the same type of link, never expanded
|
||||
* to hard links. */
|
||||
if(H5Ocopy(fid_src, NAME_GROUP_LINK2, fid_dst, NAME_GROUP_LINK2, plid, H5P_DEFAULT) < 0) TEST_ERROR
|
||||
|
||||
/* Open the original and copied groups */
|
||||
if((gid = H5Gopen2(fid_src, NAME_GROUP_LINK2, H5P_DEFAULT)) < 0) TEST_ERROR
|
||||
if((gid2 = H5Gopen2(fid_dst, NAME_GROUP_LINK2, H5P_DEFAULT)) < 0) TEST_ERROR
|
||||
|
||||
/* Compare the groups */
|
||||
if(compare_groups(gid, gid2, H5P_DEFAULT, -1, 0) != TRUE) TEST_ERROR
|
||||
|
||||
/* Close groups */
|
||||
if(H5Gclose(gid2) < 0) TEST_ERROR
|
||||
if(H5Gclose(gid) < 0) TEST_ERROR
|
||||
|
||||
/* close the SRC file */
|
||||
if(H5Fclose(fid_src) < 0) TEST_ERROR
|
||||
|
||||
/* close the DST file */
|
||||
if(H5Fclose(fid_dst) < 0) TEST_ERROR
|
||||
} /* end for */
|
||||
} /* end for */
|
||||
|
||||
/* Close the object copy plist */
|
||||
if(H5Pclose(plid) < 0) TEST_ERROR
|
||||
|
||||
PASSED();
|
||||
return 0;
|
||||
@ -5343,11 +5468,14 @@ test_copy_group_links(hid_t fcpl_src, hid_t fcpl_dst, hid_t fapl)
|
||||
error:
|
||||
H5E_BEGIN_TRY {
|
||||
H5Sclose(sid);
|
||||
H5Dclose(did2);
|
||||
H5Dclose(did);
|
||||
H5Gclose(gid2);
|
||||
H5Gclose(gid);
|
||||
H5Fclose(fid_ext);
|
||||
H5Fclose(fid_dst);
|
||||
H5Fclose(fid_src);
|
||||
H5Pclose(plid);
|
||||
} H5E_END_TRY;
|
||||
return 1;
|
||||
} /* end test_copy_group_links */
|
||||
@ -5516,7 +5644,7 @@ test_copy_ext_link(hid_t fcpl_src, hid_t fcpl_dst, hid_t fapl)
|
||||
/* Initialize the filenames */
|
||||
h5_fixname(FILENAME[0], fapl, src_filename, sizeof src_filename);
|
||||
h5_fixname(FILENAME[1], fapl, dst_filename, sizeof dst_filename);
|
||||
h5_fixname(FILENAME[2], fapl, ext_filename, sizeof dst_filename);
|
||||
h5_fixname(FILENAME[2], fapl, ext_filename, sizeof ext_filename);
|
||||
|
||||
/* Reset file address checking info */
|
||||
addr_reset();
|
||||
@ -7679,7 +7807,7 @@ error:
|
||||
static int
|
||||
test_copy_option(hid_t fcpl_src, hid_t fcpl_dst, hid_t fapl, unsigned flag, hbool_t crt_intermediate_grp, const char* test_desciption)
|
||||
{
|
||||
hid_t fid_src = -1, fid_dst = -1; /* File IDs */
|
||||
hid_t fid_src = -1, fid_dst = -1, fid_ext = -1; /* File IDs */
|
||||
hid_t sid = -1; /* Dataspace ID */
|
||||
hid_t did = -1; /* Dataset ID */
|
||||
hid_t gid=-1, gid2=-1, gid_ref=-1; /* Group IDs */
|
||||
@ -7770,6 +7898,45 @@ test_copy_option(hid_t fcpl_src, hid_t fcpl_dst, hid_t fapl, unsigned flag, hboo
|
||||
if(H5Gclose(gid) < 0) FAIL_STACK_ERROR
|
||||
} /* end if */
|
||||
|
||||
if((flag & H5O_COPY_EXPAND_EXT_LINK_FLAG) > 0) {
|
||||
char ext_filename[NAME_BUF_SIZE];
|
||||
|
||||
h5_fixname(FILENAME[2], fapl, ext_filename, sizeof ext_filename);
|
||||
|
||||
/* Create the external file and dataset */
|
||||
if((fid_ext = H5Fcreate(ext_filename, H5F_ACC_TRUNC, fcpl_src, fapl)) < 0) TEST_ERROR
|
||||
if((sid = H5Screate_simple(2, dim2d, NULL)) < 0) TEST_ERROR
|
||||
if((did = H5Dcreate2(fid_ext, NAME_DATASET_SIMPLE, H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
|
||||
if(H5Dwrite(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf) < 0) TEST_ERROR
|
||||
if(H5Dclose(did) < 0) TEST_ERROR
|
||||
if(H5Fclose(fid_ext) < 0) TEST_ERROR
|
||||
|
||||
/* Create group to copy */
|
||||
if(!(flag & H5O_COPY_EXPAND_SOFT_LINK_FLAG)) {
|
||||
if((gid = H5Gcreate2(fid_src, NAME_GROUP_LINK, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
|
||||
} /* end if */
|
||||
else
|
||||
if((gid = H5Gopen2(fid_src, NAME_GROUP_LINK, H5P_DEFAULT)) < 0) TEST_ERROR
|
||||
if(H5Lcreate_external(ext_filename, NAME_DATASET_SIMPLE, fid_src, NAME_LINK_EXTERN, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
|
||||
if(H5Lcreate_external("no_file", "no_object", fid_src, NAME_LINK_EXTERN_DANGLE, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
|
||||
if(H5Gclose(gid) < 0) TEST_ERROR
|
||||
|
||||
/* Create group to compare with */
|
||||
if(!(flag & H5O_COPY_EXPAND_SOFT_LINK_FLAG)) {
|
||||
if((gid = H5Gcreate2(fid_src, NAME_GROUP_LINK2, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
|
||||
} /* end if */
|
||||
else
|
||||
if((gid = H5Gopen2(fid_src, NAME_GROUP_LINK2, H5P_DEFAULT)) < 0) TEST_ERROR
|
||||
if((did = H5Dcreate2(fid_src, NAME_LINK_EXTERN2, H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
|
||||
if(H5Dwrite(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf) < 0) TEST_ERROR
|
||||
if(H5Lcreate_external("no_file", "no_object", fid_src, NAME_LINK_EXTERN_DANGLE2, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
|
||||
if(H5Dclose(did) < 0) TEST_ERROR
|
||||
if(H5Gclose(gid) < 0) TEST_ERROR
|
||||
|
||||
/* Close dataspace */
|
||||
if(H5Sclose(sid) < 0) TEST_ERROR
|
||||
} /* end if */
|
||||
|
||||
if((flag & H5O_COPY_EXPAND_REFERENCE_FLAG) > 0) {
|
||||
if((gid_ref = H5Gcreate2(fid_src, NAME_GROUP_REF, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
|
||||
|
||||
@ -7830,12 +7997,14 @@ test_copy_option(hid_t fcpl_src, hid_t fcpl_dst, hid_t fapl, unsigned flag, hboo
|
||||
/* open the destination group */
|
||||
if((gid2 = H5Gopen2(fid_dst, "/new_g0/new_g00", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR
|
||||
|
||||
} else if((flag & H5O_COPY_EXPAND_SOFT_LINK_FLAG) > 0) {
|
||||
} else if(((flag & H5O_COPY_EXPAND_SOFT_LINK_FLAG) > 0)
|
||||
|| ((flag & H5O_COPY_EXPAND_EXT_LINK_FLAG) > 0)) {
|
||||
if(H5Ocopy(fid_src, NAME_GROUP_LINK, fid_dst, NAME_GROUP_LINK, pid, H5P_DEFAULT) < 0) TEST_ERROR
|
||||
|
||||
/* Unlink dataset to copy from original location */
|
||||
/* (So group comparison works properly) */
|
||||
if(H5Ldelete(fid_src, NAME_DATASET_SUB_SUB, H5P_DEFAULT) < 0) FAIL_STACK_ERROR
|
||||
if((flag & H5O_COPY_EXPAND_SOFT_LINK_FLAG) > 0)
|
||||
/* Unlink dataset to copy from original location */
|
||||
/* (So group comparison works properly) */
|
||||
if(H5Ldelete(fid_src, NAME_DATASET_SUB_SUB, H5P_DEFAULT) < 0) FAIL_STACK_ERROR
|
||||
|
||||
/* open the group for copy */
|
||||
if((gid = H5Gopen2(fid_src, NAME_GROUP_LINK2, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR
|
||||
@ -7904,6 +8073,7 @@ error:
|
||||
H5Gclose(gid);
|
||||
H5Fclose(fid_dst);
|
||||
H5Fclose(fid_src);
|
||||
H5Fclose(fid_ext);
|
||||
} H5E_END_TRY;
|
||||
return 1;
|
||||
} /* end test_copy_option */
|
||||
@ -8043,6 +8213,11 @@ main(void)
|
||||
"H5Ocopy(): with missing groups");
|
||||
nerrors += test_copy_option(fcpl_src, fcpl_dst, my_fapl, H5O_COPY_EXPAND_SOFT_LINK_FLAG,
|
||||
FALSE, "H5Ocopy(): expand soft link");
|
||||
nerrors += test_copy_option(fcpl_src, fcpl_dst, my_fapl, H5O_COPY_EXPAND_EXT_LINK_FLAG,
|
||||
FALSE, "H5Ocopy: expand external link");
|
||||
nerrors += test_copy_option(fcpl_src, fcpl_dst, my_fapl,
|
||||
H5O_COPY_EXPAND_SOFT_LINK_FLAG | H5O_COPY_EXPAND_EXT_LINK_FLAG,
|
||||
FALSE, "H5Ocopy: expand soft and external links");
|
||||
nerrors += test_copy_option(fcpl_src, fcpl_dst, my_fapl, H5O_COPY_SHALLOW_HIERARCHY_FLAG,
|
||||
FALSE, "H5Ocopy(): shallow group copy");
|
||||
nerrors += test_copy_option(fcpl_src, fcpl_dst, my_fapl, H5O_COPY_EXPAND_REFERENCE_FLAG,
|
||||
@ -8086,7 +8261,6 @@ main(void)
|
||||
}
|
||||
|
||||
/* TODO: not implemented
|
||||
nerrors += test_copy_option(my_fapl, H5O_COPY_EXPAND_EXT_LINK_FLAG, FALSE, "H5Ocopy: expand external link");
|
||||
nerrors += test_copy_mount(my_fapl);
|
||||
*/
|
||||
} /* end for */
|
||||
|
Loading…
Reference in New Issue
Block a user