From bf566b775bbef681e9135c38dbf414df2162cdcc Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Sun, 29 May 2016 05:57:47 -0500 Subject: [svn-r29969] Description: Bring r29934 from revise_chunks branch to trunk: (1) Fix for HDFFV-9434: throw an error instead of assertion when v1 btree level hits the 1 byte limit. (2) Modifications to better handle error recovery when conversion by h5format_convert fails. Tested on: MacOSX/64 10.11.5 (amazon) w/serial, parallel & production (h5committest forthcoming) --- MANIFEST | 2 + src/H5AC.c | 35 +++++ src/H5ACprivate.h | 1 + src/H5Bcache.c | 5 + src/H5Bpkg.h | 1 + src/H5C.c | 53 ++++++++ src/H5Cprivate.h | 1 + src/H5Dchunk.c | 2 +- src/H5Dint.c | 79 +++++++---- tools/h5format_convert/h5fc_gentest.c | 149 +++++++++++++++++++++ tools/h5format_convert/h5format_convert.c | 2 +- tools/h5format_convert/testfiles/h5fc_err_level.h5 | Bin 0 -> 7294 bytes tools/h5format_convert/testfiles/h5fc_v_err.ddl | 13 ++ tools/h5format_convert/testh5fc.sh.in | 7 + 14 files changed, 324 insertions(+), 26 deletions(-) create mode 100644 tools/h5format_convert/testfiles/h5fc_err_level.h5 create mode 100644 tools/h5format_convert/testfiles/h5fc_v_err.ddl diff --git a/MANIFEST b/MANIFEST index 6dd890e..cf77e96 100644 --- a/MANIFEST +++ b/MANIFEST @@ -1247,6 +1247,7 @@ ./tools/h5format_convert/h5format_convert.c ./tools/h5format_convert/testfiles/h5fc_v_n_all.ddl ./tools/h5format_convert/testfiles/h5fc_v_bt1.ddl +./tools/h5format_convert/testfiles/h5fc_v_err.ddl ./tools/h5format_convert/testfiles/h5fc_v_non_chunked.ddl ./tools/h5format_convert/testfiles/h5fc_d_file.ddl ./tools/h5format_convert/testfiles/h5fc_v_ndata_bt1.ddl @@ -1259,6 +1260,7 @@ ./tools/h5format_convert/testfiles/h5fc_nonexistfile.ddl ./tools/h5format_convert/testfiles/h5fc_non_v3.h5 ./tools/h5format_convert/testfiles/h5fc_edge_v3.h5 +./tools/h5format_convert/testfiles/h5fc_err_level.h5 ./tools/h5format_convert/testfiles/h5fc_ext1_f.h5 ./tools/h5format_convert/testfiles/h5fc_ext1_i.h5 ./tools/h5format_convert/testfiles/h5fc_ext1_s.h5 diff --git a/src/H5AC.c b/src/H5AC.c index c0c6604..42f328e 100644 --- a/src/H5AC.c +++ b/src/H5AC.c @@ -2464,6 +2464,41 @@ done: } /* H5AC_flush_tagged_metadata */ + +/*------------------------------------------------------------------------------ + * Function: H5AC_expunge_tag_type_metadata() + * + * Purpose: Wrapper for cache level function which expunge entries with + * a specific tag and type id. + * + * Return: SUCCEED on success, FAIL otherwise. + * + * Programmer: Vailin Choi; May 2016 + * + *------------------------------------------------------------------------------ + */ +herr_t +H5AC_expunge_tag_type_metadata(H5F_t *f, hid_t dxpl_id, haddr_t tag, int type_id, unsigned flags) +{ + /* Variable Declarations */ + herr_t ret_value = SUCCEED; + + /* Function Enter Macro */ + FUNC_ENTER_NOAPI(FAIL) + + /* Assertions */ + HDassert(f); + HDassert(f->shared); + + /* Call cache level function to expunge entries with specified tag and type id */ + if(H5C_expunge_tag_type_metadata(f, dxpl_id, tag, type_id, flags)<0) + HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Cannot expunge tagged type entries") + +done: + FUNC_LEAVE_NOAPI(ret_value) + +} /* H5AC_expunge_tag_type_metadata*/ + #if H5AC_DO_TAGGING_SANITY_CHECKS /*------------------------------------------------------------------------- diff --git a/src/H5ACprivate.h b/src/H5ACprivate.h index 5b871ff..23b909f 100644 --- a/src/H5ACprivate.h +++ b/src/H5ACprivate.h @@ -365,6 +365,7 @@ H5_DLL herr_t H5AC_get_entry_ring(const H5F_t *f, haddr_t addr, H5AC_ring_t *rin H5_DLL herr_t H5AC_set_ring(hid_t dxpl_id, H5AC_ring_t ring, H5P_genplist_t **dxpl, H5AC_ring_t *orig_ring); H5_DLL herr_t H5AC_reset_ring(H5P_genplist_t *dxpl, H5AC_ring_t orig_ring); +H5_DLL herr_t H5AC_expunge_tag_type_metadata(H5F_t *f, hid_t dxpl_id, haddr_t tag, int type_id, unsigned flags); #ifdef H5_HAVE_PARALLEL H5_DLL herr_t H5AC_add_candidate(H5AC_t * cache_ptr, haddr_t addr); diff --git a/src/H5Bcache.c b/src/H5Bcache.c index 747e4c4..8354e8e 100644 --- a/src/H5Bcache.c +++ b/src/H5Bcache.c @@ -312,6 +312,11 @@ H5B__serialize(const H5F_t *f, void *_image, size_t H5_ATTR_UNUSED len, /* node type and level */ *image++ = (uint8_t)shared->type->id; + + /* 2^8 limit: only 1 byte is used to store node level */ + if(bt->level >= HDpow(2, LEVEL_BITS)) + HGOTO_ERROR(H5E_BTREE, H5E_CANTENCODE, FAIL, "unable to encode node level") + H5_CHECK_OVERFLOW(bt->level, unsigned, uint8_t); *image++ = (uint8_t)bt->level; diff --git a/src/H5Bpkg.h b/src/H5Bpkg.h index e645626..41e0951 100644 --- a/src/H5Bpkg.h +++ b/src/H5Bpkg.h @@ -42,6 +42,7 @@ /* Get the native key at a given index */ #define H5B_NKEY(b, shared, idx) ((b)->native + (shared)->nkey[(idx)]) +#define LEVEL_BITS 8 /* # of bits for node level: 1 byte */ /****************************/ diff --git a/src/H5C.c b/src/H5C.c index 0082a98..cd42512 100644 --- a/src/H5C.c +++ b/src/H5C.c @@ -9902,6 +9902,59 @@ H5C_retag_entries(H5C_t * cache_ptr, haddr_t src_tag, haddr_t dest_tag) /*------------------------------------------------------------------------- + * + * Function: H5C_expunge_tag_type_metadata + * + * Purpose: Search and expunge from the cache entries associated + * with 'tag' and type id. + * + * Return: FAIL if error is detected, SUCCEED otherwise. + * + * Programmer: Vailin Choi; May 2016 + * + *------------------------------------------------------------------------- + */ +herr_t +H5C_expunge_tag_type_metadata(H5F_t *f, hid_t dxpl_id, haddr_t tag, int type_id, unsigned flags) +{ + unsigned u; /* Local index variable */ + H5C_t *cache_ptr = NULL; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Sanity check */ + HDassert(f); + HDassert(f->shared); + HDassert(f->shared->cache); + HDassert(f->shared->cache->magic == H5C__H5C_T_MAGIC); + + /* Get cache pointer */ + cache_ptr = f->shared->cache; + + /* Iterate through hash table entries, expunge those with specified tag and type id */ + for(u = 0; u < H5C__HASH_TABLE_LEN; u++) { + H5C_cache_entry_t *entry_ptr; /* Entry pointer */ + + entry_ptr = cache_ptr->index[u]; + while(entry_ptr != NULL) { + /* Found one with the same tag and type id */ + if(entry_ptr->tag == tag && entry_ptr->type->id == type_id) { + + if(H5C_expunge_entry(f, dxpl_id, entry_ptr->type, entry_ptr->addr, flags) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_CANTEXPUNGE, FAIL, "H5C_expunge_entry() failed.") + } /* end if */ + + entry_ptr = entry_ptr->ht_next; + } /* end while */ + } /* end for */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5C_expunge_tag_type_metadata */ + + +/*------------------------------------------------------------------------- * Function: H5C_get_entry_ring * * Purpose: Given a file address, retrieve the ring for an entry at that diff --git a/src/H5Cprivate.h b/src/H5Cprivate.h index d43c845..fb04d84 100644 --- a/src/H5Cprivate.h +++ b/src/H5Cprivate.h @@ -1970,6 +1970,7 @@ H5_DLL herr_t H5C_expunge_entry(H5F_t *f, hid_t dxpl_id, const H5C_class_t *type, haddr_t addr, unsigned flags); H5_DLL herr_t H5C_flush_cache(H5F_t *f, hid_t dxpl_id, unsigned flags); H5_DLL herr_t H5C_flush_tagged_entries(H5F_t * f, hid_t dxpl_id, haddr_t tag); +H5_DLL herr_t H5C_expunge_tag_type_metadata(H5F_t *f, hid_t dxpl_id, haddr_t tag, int type_id, unsigned flags); #if H5C_DO_TAGGING_SANITY_CHECKS herr_t H5C_verify_tag(int id, haddr_t tag, H5C_tag_globality_t globality); #endif diff --git a/src/H5Dchunk.c b/src/H5Dchunk.c index f4f9104..8cf86ac 100644 --- a/src/H5Dchunk.c +++ b/src/H5Dchunk.c @@ -6471,7 +6471,7 @@ H5D__chunk_format_convert(H5D_t *dset, H5D_chk_idx_info_t *idx_info, H5D_chk_idx udata.dset_dims = dset->shared->curr_dims; /* terate over the chunks in the current index and insert the chunk addresses into version 1 B-tree index */ - if((dset->shared->layout.storage.u.chunk.ops->iterate)(idx_info, H5D__chunk_format_convert_cb, &udata) < 0) + if((idx_info->storage->ops->iterate)(idx_info, H5D__chunk_format_convert_cb, &udata) < 0) HGOTO_ERROR(H5E_DATASET, H5E_BADITER, FAIL, "unable to iterate over chunk index to chunk info") done: diff --git a/src/H5Dint.c b/src/H5Dint.c index 322776b..c68a355 100644 --- a/src/H5Dint.c +++ b/src/H5Dint.c @@ -2848,10 +2848,12 @@ done: herr_t H5D__format_convert(H5D_t *dataset, hid_t dxpl_id) { - H5O_t *oh = NULL; /* Pointer to dataset's object header */ H5D_chk_idx_info_t new_idx_info; /* Index info for the new layout */ H5D_chk_idx_info_t idx_info; /* Index info for the current layout */ H5O_layout_t newlayout; /* The new layout */ + hbool_t init_new_index = FALSE; /* Indicate that the new chunk index is initialized */ + hbool_t delete_old_layout = FALSE; /* Indicate that the old layout message is deleted */ + hbool_t add_new_layout = FALSE; /* Indicate that the new layout message is added */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE_TAG(dxpl_id, dataset->oloc.addr, FAIL) @@ -2888,37 +2890,42 @@ H5D__format_convert(H5D_t *dataset, hid_t dxpl_id) new_idx_info.storage = &newlayout.storage.u.chunk; /* Initialize version 1 B-tree */ - if(newlayout.storage.u.chunk.ops->init && (newlayout.storage.u.chunk.ops->init)(&new_idx_info, dataset->shared->space, dataset->oloc.addr) < 0) + if(new_idx_info.storage->ops->init && + (new_idx_info.storage->ops->init)(&new_idx_info, dataset->shared->space, dataset->oloc.addr) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't initialize indexing information") - + init_new_index = TRUE; + /* If the current chunk index exists */ - if(H5F_addr_defined(dataset->shared->layout.storage.u.chunk.idx_addr)) { + if(H5F_addr_defined(idx_info.storage->idx_addr)) { + /* Create v1 B-tree chunk index */ - if((newlayout.storage.u.chunk.ops->create)(&new_idx_info) < 0) + if((new_idx_info.storage->ops->create)(&new_idx_info) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't create chunk index") /* Iterate over the chunks in the current index and insert the chunk addresses * into the version 1 B-tree chunk index */ if(H5D__chunk_format_convert(dataset, &idx_info, &new_idx_info) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_BADITER, FAIL, "unable to iterate over chunk index to chunk info") + HGOTO_ERROR(H5E_DATASET, H5E_BADITER, FAIL, "unable to iterate/convert chunk index") } /* end if */ - /* Release the old (i.e. current) chunk index */ - if(dataset->shared->layout.storage.u.chunk.ops->dest && (dataset->shared->layout.storage.u.chunk.ops->dest)(&idx_info) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "unable to release chunk index info") - - /* Delete the "layout" message */ - if(H5O_msg_remove(&dataset->oloc, H5O_LAYOUT_ID, H5O_ALL, TRUE, dxpl_id) < 0) + /* Delete the old "current" layout message */ + if(H5O_msg_remove(&dataset->oloc, H5O_LAYOUT_ID, H5O_ALL, FALSE, dxpl_id) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTDELETE, FAIL, "unable to delete layout message") - HDmemcpy(&dataset->shared->layout, &newlayout, sizeof(H5O_layout_t)); - - if(NULL == (oh = H5O_pin(&dataset->oloc, dxpl_id))) - HGOTO_ERROR(H5E_DATASET, H5E_CANTPIN, FAIL, "unable to pin dataset object header") + delete_old_layout = TRUE; /* Append the new layout message to the object header */ - if(H5O_msg_append_oh(dataset->oloc.file, dxpl_id, oh, H5O_LAYOUT_ID, 0, H5O_UPDATE_TIME, &newlayout) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update old fill value header message") + if(H5O_msg_create(&dataset->oloc, H5O_LAYOUT_ID, 0, H5O_UPDATE_TIME, &newlayout, dxpl_id) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update layout header message") + + add_new_layout = TRUE; + + /* Release the old (current) chunk index */ + if(idx_info.storage->ops->dest && (idx_info.storage->ops->dest)(&idx_info) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "unable to release chunk index info") + + /* Copy the new layout to the dataset's layout */ + HDmemcpy(&dataset->shared->layout, &newlayout, sizeof(H5O_layout_t)); break; @@ -2935,17 +2942,41 @@ H5D__format_convert(H5D_t *dataset, hid_t dxpl_id) case H5D_LAYOUT_ERROR: case H5D_NLAYOUTS: - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid dataset layout type") - + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid dataset layout type") + default: HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "unknown dataset layout type") } /* end switch */ done: - /* Release pointer to object header */ - if(oh != NULL) - if(H5O_unpin(oh) < 0) - HDONE_ERROR(H5E_DATASET, H5E_CANTUNPIN, FAIL, "unable to unpin dataset object header") + if(ret_value < 0 && dataset->shared->layout.type == H5D_CHUNKED) { + /* Remove new layout message */ + if(add_new_layout) + if(H5O_msg_remove(&dataset->oloc, H5O_LAYOUT_ID, H5O_ALL, FALSE, dxpl_id) < 0) + HDONE_ERROR(H5E_SYM, H5E_CANTDELETE, FAIL, "unable to delete layout message") + + /* Add back old layout message */ + if(delete_old_layout) + if(H5O_msg_create(&dataset->oloc, H5O_LAYOUT_ID, 0, H5O_UPDATE_TIME, &dataset->shared->layout, dxpl_id) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to add layout header message") + + /* Clean up v1 b-tree chunk index */ + if(init_new_index) { + if(H5F_addr_defined(new_idx_info.storage->idx_addr)) { + /* Check for valid address i.e. tag */ + if(!H5F_addr_defined(dataset->oloc.addr)) + HDONE_ERROR(H5E_DATASET, H5E_BADVALUE, FAIL, "address undefined") + + /* Expunge from cache all v1 B-tree type entries associated with tag */ + if(H5AC_expunge_tag_type_metadata(dataset->oloc.file, dxpl_id, dataset->oloc.addr, H5AC_BT_ID, H5AC__NO_FLAGS_SET)) + HDONE_ERROR(H5E_DATASET, H5E_CANTEXPUNGE, FAIL, "unable to expunge index metadata") + } /* end if */ + + /* Delete v1 B-tree chunk index */ + if(new_idx_info.storage->ops->dest && (new_idx_info.storage->ops->dest)(&new_idx_info) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "unable to release chunk index info") + } /* end if */ + } /* end if */ FUNC_LEAVE_NOAPI_TAG(ret_value, FAIL) } /* end H5D__format_convert() */ diff --git a/tools/h5format_convert/h5fc_gentest.c b/tools/h5format_convert/h5fc_gentest.c index dae57fb..1b167e4 100644 --- a/tools/h5format_convert/h5fc_gentest.c +++ b/tools/h5format_convert/h5fc_gentest.c @@ -28,6 +28,7 @@ #define NON_V3_FILE "h5fc_non_v3.h5" #define EDGE_V3_FILE "h5fc_edge_v3.h5" +#define ERR_LEVEL_FILE "h5fc_err_level.h5" const char *FILENAME[] = { "h5fc_ext1_i.h5", /* 0 */ @@ -56,8 +57,13 @@ const char *FILENAME[] = { #define DSET_NDATA_NONE "DSET_NDATA_NONE" #define DSET_EDGE "DSET_EDGE" +#define DSET_ERR "DSET_ERR" #define ISTORE_IK 64 +#define ISTORE_ERR 1 + +#define NUM 500 + /* * Function: gen_non() @@ -378,6 +384,146 @@ error: /* + * Function: gen_err_level() + * + * Generate a file to test the situtation described in HDFFV-9434: + * Exceed the limit of v1-btree level + * + * Create a file with H5Pset_istore_k(fcpl, 1). + * Create a chunked dataset with extensible array chunk index and + * appends many chunks to the dataset. + * + * When h5format_convert tries to convert the dataset with + * extensive array index in the file to v1-btree chunk index, + * it will insert the dataset chunks to the v1-btree chunk index. + * The tree will split quickly due to the 'K' value of 1 and the + * tree level will eventually hit the maximum: 2^8(256). + */ +static void +gen_err_level(const char *fname) +{ + hid_t fid = -1; /* file ID */ + hid_t fapl = -1; /* file access property list */ + hid_t fcpl = -1; /* file creation property list */ + hid_t sid = -1; /* dataspace id */ + hid_t dcpl = -1; /* dataset creation property list */ + hid_t did = -1; /* dataset ID */ + hid_t fsid = -1; /* file dataspace ID */ + hid_t msid = -1; /* memory dataspace ID */ + unsigned char *buf = NULL; /* buffer for data */ + hsize_t dims[2] = {0, 1}; /* dataset dimension sizes */ + hsize_t max_dims[2] = {1, H5S_UNLIMITED}; /* dataset maximum dimension sizes */ + hsize_t chunk_dims[2] = {1, 1}; /* chunk dimension sizes */ + int n = 0; /* local index variable */ + + /* Create a new format file */ + if((fapl = H5Pcreate(H5P_FILE_ACCESS)) < 0) + goto error; + if(H5Pset_libver_bounds(fapl, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST) < 0) + goto error; + + /* Set 'K' value to 1 in file creation property list */ + if((fcpl = H5Pcreate(H5P_FILE_CREATE)) < 0) + goto error; + if(H5Pset_istore_k(fcpl, ISTORE_ERR) < 0) + goto error; + + /* Initialize data buffer */ + buf = (unsigned char *)HDmalloc(NUM * sizeof(unsigned char *)); + HDmemset(buf, 42, NUM * sizeof(unsigned char)); + + /* Create the test file */ + if((fid = H5Fcreate(fname, H5F_ACC_TRUNC, fcpl, fapl)) < 0) + goto error; + + /* Create a chunked dataset with extensible array chunk index */ + if((sid = H5Screate_simple(2, dims, max_dims)) < 0) + goto error; + if((dcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0) + goto error; + if(H5Pset_chunk(dcpl, 2, chunk_dims) < 0) + goto error; + if((did = H5Dcreate2(fid, DSET_ERR, H5T_NATIVE_UCHAR, sid, H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0) + goto error; + + /* Closing */ + if(H5Pclose(dcpl) < 0) + goto error; + if(H5Sclose(sid) < 0) + goto error; + if(H5Dclose(did) < 0) + goto error; + if(H5Fclose(fid) < 0) + goto error; + + /* Re-open the file */ + if((fid = H5Fopen(fname, H5F_ACC_RDWR, fapl)) < 0) + goto error; + + /* Open the dataset */ + if((did = H5Dopen2(fid, DSET_ERR, H5P_DEFAULT)) < 0) + goto error; + + /* Loop through appending 1 element at a time */ + for(n = 0; n < NUM; n++) { + hsize_t start[2] = {0, 0}; + hsize_t count[2] = {1, 1}; + hsize_t extent[2] = {0, 0}; + + start[0] = 0; + start[1] = n; + extent[0] = 1; + extent[1] = n+1; + + /* Set current dimension sizes for the dataset */ + if(H5Dset_extent(did, extent) < 0) + goto error; + + /* Set up memory dataspace */ + if((msid = H5Screate_simple(2, count, NULL)) < 0) + goto error; + + /* Get file dataspace */ + if((fsid = H5Dget_space(did)) < 0) + goto error; + + if((H5Sselect_hyperslab(fsid, H5S_SELECT_SET, start, NULL, count, NULL)) < 0) + goto error; + + /* Write to the dataset */ + if(H5Dwrite(did, H5T_NATIVE_UCHAR, msid, fsid, H5P_DEFAULT, buf) < 0) + goto error; + + if(H5Sclose(fsid) < 0) + goto error; + if(H5Sclose(msid) < 0) + goto error; + } + + /* Closing */ + if(H5Dclose(did) < 0) + goto error; + if(H5Fclose(fid) < 0) + goto error; + if(H5Pclose(fapl) < 0) + goto error; + if(buf) free(buf); + +error: + H5E_BEGIN_TRY { + H5Pclose(dcpl); + H5Sclose(sid); + H5Dclose(did); + H5Sclose(msid); + H5Sclose(fsid); + H5Fclose(fid); + H5Pclose(fapl); + H5Pclose(fcpl); + } H5E_END_TRY; + +} /* gen_err_level() */ + +/* * Function: gen_ext() * * Create a file with/without latest format with: @@ -642,6 +788,9 @@ int main(void) /* Generate a new format file with a no-filter-edge-chunk dataset */ gen_edge(EDGE_V3_FILE); + /* Generate a new format file with 'K' value of 1 in H5Pset_istore_k() */ + gen_err_level(ERR_LEVEL_FILE); + /* Generate old/new format file with/without messages in the superblock extension */ for(latest = FALSE; latest <= TRUE; latest++) { for(i = 0; i < 8; i++) { diff --git a/tools/h5format_convert/h5format_convert.c b/tools/h5format_convert/h5format_convert.c index 1098d35..dadfd99 100644 --- a/tools/h5format_convert/h5format_convert.c +++ b/tools/h5format_convert/h5format_convert.c @@ -310,7 +310,7 @@ convert(hid_t fid, const char *dname) /* Downgrade the dataset */ if(H5Dformat_convert(did) < 0) { - error_msg("unable to downgrade dataset for \"%s\"\n", dname); + error_msg("unable to downgrade dataset \"%s\"\n", dname); h5tools_setstatus(EXIT_FAILURE); goto error; } else if(verbose_g) diff --git a/tools/h5format_convert/testfiles/h5fc_err_level.h5 b/tools/h5format_convert/testfiles/h5fc_err_level.h5 new file mode 100644 index 0000000..a10e8a4 Binary files /dev/null and b/tools/h5format_convert/testfiles/h5fc_err_level.h5 differ diff --git a/tools/h5format_convert/testfiles/h5fc_v_err.ddl b/tools/h5format_convert/testfiles/h5fc_v_err.ddl new file mode 100644 index 0000000..4a728e8 --- /dev/null +++ b/tools/h5format_convert/testfiles/h5fc_v_err.ddl @@ -0,0 +1,13 @@ +Process command line options +Open the file tmp.h5 +Processing all datasets in the file... +Going to process dataset:/DSET_ERR... +Open the dataset +Retrieve the dataset's layout +Dataset is a chunked dataset +Retrieve the dataset's chunk indexing type +Dataset's chunk indexing type is not version 1 B-tree +Converting the dataset... +Error encountered +Close the file +h5format_convert error: unable to downgrade dataset "/DSET_ERR" diff --git a/tools/h5format_convert/testh5fc.sh.in b/tools/h5format_convert/testh5fc.sh.in index f712434..000425b 100644 --- a/tools/h5format_convert/testh5fc.sh.in +++ b/tools/h5format_convert/testh5fc.sh.in @@ -99,6 +99,7 @@ $SRC_H5FORMCONV_TESTFILES/old_h5fc_ext2_if.h5 $SRC_H5FORMCONV_TESTFILES/old_h5fc_ext2_is.h5 $SRC_H5FORMCONV_TESTFILES/old_h5fc_ext2_sf.h5 $SRC_H5FORMCONV_TESTFILES/old_h5fc_ext3_isf.h5 +$SRC_H5FORMCONV_TESTFILES/h5fc_err_level.h5 " LIST_OTHER_TEST_FILES=" @@ -128,6 +129,7 @@ $SRC_H5FORMCONV_TESTFILES/old_h5fc_ext2_if.ddl $SRC_H5FORMCONV_TESTFILES/old_h5fc_ext2_is.ddl $SRC_H5FORMCONV_TESTFILES/old_h5fc_ext2_sf.ddl $SRC_H5FORMCONV_TESTFILES/old_h5fc_ext3_isf.ddl +$SRC_H5FORMCONV_TESTFILES/h5fc_v_err.ddl " # @@ -369,6 +371,11 @@ TOOLTEST_OUT h5fc_v_n_all.ddl h5fc_non_v3.h5 -v -n # # # +# h5format_convert -v h5fc_err_level.h5 (error encountered in converting the dataset) +TOOLTEST_OUT h5fc_v_err.ddl h5fc_err_level.h5 -v +# +# +# # No output from tests # 1) Use the tool to convert the dataset # 2) Verify the chunk indexing type is correct -- cgit v0.12