From 249acc03550e9cb2ed3cfaa56737215910a7a194 Mon Sep 17 00:00:00 2001 From: Jonathan Kim Date: Thu, 22 Apr 2010 13:17:35 -0500 Subject: [svn-r18614] Purpose: Fix for bug 1817 : h5copy fail to copy dangling link by specifying link path directly Tested: jam, amani, linew --- tools/h5copy/h5copy.c | 29 ++++- tools/h5copy/testfiles/h5copy_extlinks_src.out.ls | 16 ++- tools/h5copy/testh5copy.sh | 12 +- tools/lib/h5diff.c | 145 ---------------------- tools/lib/h5tools_utils.c | 132 ++++++++++++++++++++ tools/lib/h5tools_utils.h | 31 +++++ 6 files changed, 205 insertions(+), 160 deletions(-) diff --git a/tools/h5copy/h5copy.c b/tools/h5copy/h5copy.c index 992195d..0ea8e16 100644 --- a/tools/h5copy/h5copy.c +++ b/tools/h5copy/h5copy.c @@ -213,6 +213,8 @@ main (int argc, const char *argv[]) hid_t lcpl_id = (-1); /* Link creation property list */ char str_flag[20]; int opt; + int li_ret; + h5tool_link_info_t linkinfo; /* initialize h5tools lib */ h5tools_init(); @@ -406,7 +408,22 @@ main (int argc, const char *argv[]) /*------------------------------------------------------------------------- * do the copy *-------------------------------------------------------------------------*/ - + /* init linkinfo struct */ + memset(&linkinfo, 0, sizeof(h5tool_link_info_t)); + + if(verbose) + linkinfo.opt.msg_mode = 1; + + li_ret = H5tools_get_link_info(fid_src, oname_src, &linkinfo); + if (li_ret == 0) /* dangling link */ + { + if(H5Lcopy(fid_src, oname_src, + fid_dst, oname_dst, + H5P_DEFAULT, H5P_DEFAULT) < 0) + goto error; + } + else /* valid link */ + { if (H5Ocopy(fid_src, /* Source file or group identifier */ oname_src, /* Name of the source object to be copied */ fid_dst, /* Destination file or group identifier */ @@ -414,6 +431,11 @@ main (int argc, const char *argv[]) ocpl_id, /* Object copy property list */ lcpl_id)<0) /* Link creation property list */ goto error; + } + + /* free link info path */ + if (linkinfo.trg_path) + free(linkinfo.trg_path); /* close propertis */ if(H5Pclose(ocpl_id)<0) @@ -442,6 +464,11 @@ main (int argc, const char *argv[]) error: printf("Error in copy...Exiting\n"); + + /* free link info path */ + if (linkinfo.trg_path) + free(linkinfo.trg_path); + H5E_BEGIN_TRY { H5Pclose(ocpl_id); H5Pclose(lcpl_id); diff --git a/tools/h5copy/testfiles/h5copy_extlinks_src.out.ls b/tools/h5copy/testfiles/h5copy_extlinks_src.out.ls index a9927f8..e0047a7 100644 --- a/tools/h5copy/testfiles/h5copy_extlinks_src.out.ls +++ b/tools/h5copy/testfiles/h5copy_extlinks_src.out.ls @@ -11,7 +11,7 @@ Opened "./testfiles/h5copy_extlinks_src.out.h5" with sec2 driver. Storage:
Type: 32-bit little-endian integer /copy1_group Group - Location: 1:4344 + Location: 1:4696 Links: 1 /copy1_group/extlink_datatype External Link {h5copy_extlinks_trg.h5//datatype} /copy1_group/extlink_dset External Link {h5copy_extlinks_trg.h5//simple} @@ -24,19 +24,23 @@ Opened "./testfiles/h5copy_extlinks_src.out.h5" with sec2 driver. Storage:
Type: 32-bit little-endian integer /copy2_group Group - Location: 1:4712 + Location: 1:5128 Links: 1 /copy2_group/extlink_datatype Type - Location: 1:5912 + Location: 1:6328 Links: 1 - Type: shared-1:5912 32-bit little-endian integer + Type: shared-1:6328 32-bit little-endian integer /copy2_group/extlink_dset Dataset {6/6} - Location: 1:5080 + Location: 1:5496 Links: 1 Storage:
Type: 32-bit little-endian integer /copy2_group/extlink_grp Group - Location: 1:5872 + Location: 1:6288 Links: 1 /copy2_group/extlink_notyet1 External Link {h5copy_extlinks_trg.h5//notyet} /copy2_group/extlink_notyet2 External Link {notyet_file.h5//notyet} +/copy_dangle1_1 External Link {h5copy_extlinks_trg.h5//notyet} +/copy_dangle1_2 External Link {h5copy_extlinks_trg.h5//notyet} +/copy_dangle2_1 External Link {notyet_file.h5//notyet} +/copy_dangle2_2 External Link {notyet_file.h5//notyet} diff --git a/tools/h5copy/testh5copy.sh b/tools/h5copy/testh5copy.sh index d8dfe52..31104dd 100644 --- a/tools/h5copy/testh5copy.sh +++ b/tools/h5copy/testh5copy.sh @@ -353,20 +353,16 @@ COPY_EXT_LINKS() TOOLTEST -f ext -i $TESTFILE -o $FILEOUT -v -s /group_ext/extlink_dset -d /copy2_dset echo "Test copying dangling external link (no obj) directly without -f ext" - #TOOLTEST -i $TESTFILE -o $FILEOUT -v -s /copy2_group/extlink_notyet1 -d /copy2_dangle1 - SKIP -s /copy2_group/extlink_notyet1 -d /copy2_dangle1 + TOOLTEST -i $TESTFILE -o $FILEOUT -v -s /group_ext/extlink_notyet1 -d /copy_dangle1_1 echo "Test copying dangling external link (no obj) directly with -f ext" - #TOOLTEST -f ext -i $TESTFILE -o $FILEOUT -v -s /copy2_group/extlink_notyet1 -d /copy2_dangle1 - SKIP -f ext -s /copy2_group/extlink_notyet1 -d /copy2_dangle1 + TOOLTEST -f ext -i $TESTFILE -o $FILEOUT -v -s /group_ext/extlink_notyet1 -d /copy_dangle1_2 echo "Test copying dangling external link (no file) directly without -f ext" - #TOOLTEST -i $TESTFILE -o $FILEOUT -v -s /copy2_group/extlink_notyet2 -d /copy2_dangle2 - SKIP -s /copy2_group/extlink_notyet2 -d /copy2_dangle2 + TOOLTEST -i $TESTFILE -o $FILEOUT -v -s /group_ext/extlink_notyet2 -d /copy_dangle2_1 echo "Test copying dangling external link (no file) directly with -f ext" - #TOOLTEST -f ext -i $TESTFILE -o $FILEOUT -v -s /copy2_group/extlink_notyet2 -d /copy2_dangle2 - SKIP -f ext -s /copy2_group/extlink_notyet2 -d /copy2_dangle2 + TOOLTEST -f ext -i $TESTFILE -o $FILEOUT -v -s /group_ext/extlink_notyet2 -d /copy_dangle2_2 echo "Test copying a group contains external links without -f ext" TOOLTEST -v -i $TESTFILE -o $FILEOUT -s /group_ext -d /copy1_group diff --git a/tools/lib/h5diff.c b/tools/lib/h5diff.c index 9e753fe..5f18ab3 100644 --- a/tools/lib/h5diff.c +++ b/tools/lib/h5diff.c @@ -20,28 +20,6 @@ #include "h5tools.h" #include "h5tools_utils.h" -/* This code is layout for common code among tools */ -typedef enum toolname_t { - TOOL_H5DIFF, TOOL_H5LS, TOOL__H5DUMP /* add as necessary */ -} h5tool_toolname_t; -/* this struct can be used to differntiate among tools if necessary */ -typedef struct { - h5tool_toolname_t toolname; - int msg_mode; -} h5tool_opt_t; - -/* To return link info - * Functions: - * H5tools_get_link_info() - * Note: this may be move to h5tools code if used by other tools - */ -typedef struct { - H5O_type_t trg_type; /* OUT: target type */ - const char *trg_path; /* OUT: target obj path. This must be freed - * when used with H5tools_get_link_info() */ - H5L_info_t linfo; /* OUT: link info */ - h5tool_opt_t opt; /* IN: options */ -} h5tool_link_info_t; /* * Debug printf macros. The prefix allows output filtering by test scripts. */ @@ -254,129 +232,6 @@ out: } -/*------------------------------------------------------------------------- - * Function: H5tools_get_link_info - * - * Purpose: Get link (soft, external) info and its target object type - (dataset, group, named datatype) and path, if exist - * - * Patameters: - * - [IN] fileid : link file id - * - [IN] linkpath : link path - * - [OUT] h5li : link's info (H5L_info_t) - * - [OUT] link_info: returning target object info (h5tool_link_info_t) - * - * Return: - * 1 : Succed to get link info. - * 0 : Detected as a dangling link - * -1 : H5 API failed. - * - * NOTE: - * link_info->trg_path must be freed out of this function - * - * Programmer: Jonathan Kim - * - * Date: Feb 8, 2010 - *-------------------------------------------------------------------------*/ -static int H5tools_get_link_info(hid_t file_id, const char * linkpath, h5tool_link_info_t *link_info) -{ - int Ret = -1; /* init to fail */ - htri_t l_ret; - H5O_info_t trg_oinfo; - hid_t fapl; - hid_t lapl = H5P_DEFAULT; - - /* init */ - link_info->trg_type = H5O_TYPE_UNKNOWN; - - /* check if link itself exist */ - if((H5Lexists(file_id, linkpath, H5P_DEFAULT) <= 0)) - { - if(link_info->opt.msg_mode==1) - parallel_print("Warning: link <%s> doesn't exist \n",linkpath); - goto out; - } - - /* get info from link */ - if(H5Lget_info(file_id, linkpath, &(link_info->linfo), H5P_DEFAULT) < 0) - { - if(link_info->opt.msg_mode==1) - parallel_print("Warning: unable to get link info from <%s>\n",linkpath); - goto out; - } - - /* trg_path must be freed out of this function when finished using */ - link_info->trg_path = (char*)HDcalloc(link_info->linfo.u.val_size, sizeof(char)); - HDassert(link_info->trg_path); - - /* get link value */ - if(H5Lget_val(file_id, linkpath, link_info->trg_path, link_info->linfo.u.val_size, H5P_DEFAULT) < 0) - { - if(link_info->opt.msg_mode==1) - parallel_print("Warning: unable to get link value from <%s>\n",linkpath); - goto out; - } - - /*----------------------------------------------------- - * if link type is external link use different lapl to - * follow object in other file - */ - if (link_info->linfo.type == H5L_TYPE_EXTERNAL) - { - fapl = H5Pcreate(H5P_FILE_ACCESS); - H5Pset_fapl_sec2(fapl); - lapl = H5Pcreate(H5P_LINK_ACCESS); - H5Pset_elink_fapl(lapl, fapl); - } - - /*-------------------------------------------------------------- - * if link's target object exist, get type - */ - /* check if target object exist */ - l_ret = H5Oexists_by_name(file_id, linkpath, lapl); - - /* detect dangling link */ - if(l_ret == FALSE) - { - Ret = 0; - goto out; - } - /* function failed */ - else if (l_ret < 0) - { - goto out; - } - - /* get target object info */ - if(H5Oget_info_by_name(file_id, linkpath, &trg_oinfo, lapl) < 0) - { - if(link_info->opt.msg_mode==1) - parallel_print("Warning: unable to get object information for <%s>\n", linkpath); - goto out; - } - - /* check unknown type */ - if (trg_oinfo.type < H5O_TYPE_GROUP || trg_oinfo.type >=H5O_TYPE_NTYPES) - { - if(link_info->opt.msg_mode==1) - parallel_print("Warning: target object of <%s> is unknown type\n", linkpath); - goto out; - } - - /* set target obj type to return */ - link_info->trg_type = trg_oinfo.type; - - /* succeed */ - Ret = 1; -out: - if (link_info->linfo.type == H5L_TYPE_EXTERNAL) - { - H5Pclose(fapl); - H5Pclose(lapl); - } - - return Ret; -} /*------------------------------------------------------------------------- * Function: h5diff diff --git a/tools/lib/h5tools_utils.c b/tools/lib/h5tools_utils.c index c5bc761..a51a286 100644 --- a/tools/lib/h5tools_utils.c +++ b/tools/lib/h5tools_utils.c @@ -626,3 +626,135 @@ tmpfile(void) } #endif + +/*------------------------------------------------------------------------- + * Function: H5tools_get_link_info + * + * Purpose: Get link (soft, external) info and its target object type + (dataset, group, named datatype) and path, if exist + * + * Patameters: + * - [IN] fileid : link file id + * - [IN] linkpath : link path + * - [OUT] h5li : link's info (H5L_info_t) + * - [OUT] link_info: returning target object info (h5tool_link_info_t) + * + * Return: + * 2 : given pathname is object + * 1 : Succed to get link info. + * 0 : Detected as a dangling link + * -1 : H5 API failed. + * + * NOTE: + * link_info->trg_path must be freed out of this function + * + * Programmer: Jonathan Kim + * + * Date: Feb 8, 2010 + *-------------------------------------------------------------------------*/ +int H5tools_get_link_info(hid_t file_id, const char * linkpath, h5tool_link_info_t *link_info) +{ + int Ret = -1; /* init to fail */ + htri_t l_ret; + H5O_info_t trg_oinfo; + hid_t fapl; + hid_t lapl = H5P_DEFAULT; + + /* init */ + link_info->trg_type = H5O_TYPE_UNKNOWN; + + /* check if link itself exist */ + if((H5Lexists(file_id, linkpath, H5P_DEFAULT) <= 0)) + { + if(link_info->opt.msg_mode==1) + parallel_print("Warning: link <%s> doesn't exist \n",linkpath); + goto out; + } + + /* get info from link */ + if(H5Lget_info(file_id, linkpath, &(link_info->linfo), H5P_DEFAULT) < 0) + { + if(link_info->opt.msg_mode==1) + parallel_print("Warning: unable to get link info from <%s>\n",linkpath); + goto out; + } + + /* given path is hard link (object) */ + if (link_info->linfo.type == H5L_TYPE_HARD) + { + Ret = 2; + goto out; + } + + /* trg_path must be freed out of this function when finished using */ + link_info->trg_path = (char*)HDcalloc(link_info->linfo.u.val_size, sizeof(char)); + HDassert(link_info->trg_path); + + /* get link value */ + if(H5Lget_val(file_id, linkpath, link_info->trg_path, link_info->linfo.u.val_size, H5P_DEFAULT) < 0) + { + if(link_info->opt.msg_mode==1) + parallel_print("Warning: unable to get link value from <%s>\n",linkpath); + goto out; + } + + /*----------------------------------------------------- + * if link type is external link use different lapl to + * follow object in other file + */ + if (link_info->linfo.type == H5L_TYPE_EXTERNAL) + { + fapl = H5Pcreate(H5P_FILE_ACCESS); + H5Pset_fapl_sec2(fapl); + lapl = H5Pcreate(H5P_LINK_ACCESS); + H5Pset_elink_fapl(lapl, fapl); + } + + /*-------------------------------------------------------------- + * if link's target object exist, get type + */ + /* check if target object exist */ + l_ret = H5Oexists_by_name(file_id, linkpath, lapl); + + /* detect dangling link */ + if(l_ret == FALSE) + { + Ret = 0; + goto out; + } + /* function failed */ + else if (l_ret < 0) + { + goto out; + } + + /* get target object info */ + if(H5Oget_info_by_name(file_id, linkpath, &trg_oinfo, lapl) < 0) + { + if(link_info->opt.msg_mode==1) + parallel_print("Warning: unable to get object information for <%s>\n", linkpath); + goto out; + } + + /* check unknown type */ + if (trg_oinfo.type < H5O_TYPE_GROUP || trg_oinfo.type >=H5O_TYPE_NTYPES) + { + if(link_info->opt.msg_mode==1) + parallel_print("Warning: target object of <%s> is unknown type\n", linkpath); + goto out; + } + + /* set target obj type to return */ + link_info->trg_type = trg_oinfo.type; + + /* succeed */ + Ret = 1; +out: + if (link_info->linfo.type == H5L_TYPE_EXTERNAL) + { + H5Pclose(fapl); + H5Pclose(lapl); + } + + return Ret; +} diff --git a/tools/lib/h5tools_utils.h b/tools/lib/h5tools_utils.h index e7b175c..dcd8f2b 100644 --- a/tools/lib/h5tools_utils.h +++ b/tools/lib/h5tools_utils.h @@ -119,4 +119,35 @@ extern obj_t *search_obj(table_t *temp, haddr_t objno); extern FILE * tmpfile(void); #endif + +/************************************************************* + * + * candidate functions to be public + * + *************************************************************/ + +/* This code is layout for common code among tools */ +typedef enum toolname_t { + TOOL_H5DIFF, TOOL_H5LS, TOOL__H5DUMP /* add as necessary */ +} h5tool_toolname_t; + +/* this struct can be used to differntiate among tools */ +typedef struct { + h5tool_toolname_t toolname; + int msg_mode; +} h5tool_opt_t; + +/* obtain link info from H5tools_get_link_info() */ +typedef struct { + H5O_type_t trg_type; /* OUT: target type */ + const char *trg_path; /* OUT: target obj path. This must be freed + * when used with H5tools_get_link_info() */ + H5L_info_t linfo; /* OUT: link info */ + h5tool_opt_t opt; /* IN: options */ +} h5tool_link_info_t; + + +/* Definitions of routines */ +extern int H5tools_get_link_info(hid_t file_id, const char * linkpath, h5tool_link_info_t *link_info); + #endif /* H5TOOLS_UTILS_H__ */ -- cgit v0.12