From d3396a79532601bf22e385f94b12e55dfb2c3bd0 Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Tue, 14 Jun 2016 18:07:03 -0500 Subject: [svn-r30075] Description: Bring object/dataset/group/named datatype features from revise_chunks branch to trunk. Also CMake support for h5format_convert and a bunch of misc. cleanups. Tested on: MacOSX/64 10.11.5 (amazon) w/serial, parallel & production (h5committest forthcoming) --- MANIFEST | 2 + hl/test/test_ds.c | 18 +- hl/test/test_image.c | 55 ++- java/src/hdf/hdf5lib/H5.java | 105 +++++ java/src/jni/h5dImp.c | 27 ++ java/src/jni/h5dImp.h | 18 + java/src/jni/h5gImp.c | 27 ++ java/src/jni/h5gImp.h | 18 + java/src/jni/h5oImp.c | 27 ++ java/src/jni/h5oImp.h | 18 + java/src/jni/h5tImp.c | 25 ++ java/src/jni/h5tImp.h | 18 + java/test/JUnit-interface.txt | 10 +- java/test/TestH5Dparams.java | 10 + java/test/TestH5Gbasic.java | 10 + java/test/TestH5Oparams.java | 10 + java/test/TestH5Tparams.java | 10 + src/H5AC.c | 34 ++ src/H5ACpkg.h | 10 +- src/H5ACprivate.h | 1 + src/H5Cprivate.h | 1 + src/H5Ctag.c | 111 +++++ src/H5D.c | 34 ++ src/H5Dint.c | 187 ++++++++ src/H5Dpkg.h | 10 + src/H5Dprivate.h | 2 + src/H5Dpublic.h | 1 + src/H5Dvirtual.c | 220 ++++++++++ src/H5Fint.c | 2 +- src/H5Fio.c | 38 ++ src/H5Fpkg.h | 2 +- src/H5Fprivate.h | 1 + src/H5Fsuper.c | 24 +- src/H5I.c | 67 +++ src/H5Iprivate.h | 1 + src/H5Oflush.c | 255 +++++++++++ src/H5Oprivate.h | 3 + src/H5Opublic.h | 1 + test/cork.c | 8 + testpar/t_cache.c | 7 - testpar/t_shapesame.c | 2 +- tools/CMakeLists.txt | 3 + tools/h5format_convert/CMakeLists.txt | 59 +++ tools/h5format_convert/CMakeTests.cmake | 473 +++++++++++++++++++++ tools/h5format_convert/h5format_convert.c | 10 +- tools/h5format_convert/testfiles/h5fc_d_file.ddl | 10 +- tools/h5format_convert/testfiles/h5fc_dname.ddl | 10 +- tools/h5format_convert/testfiles/h5fc_help.ddl | 10 +- tools/h5format_convert/testfiles/h5fc_nooption.ddl | 10 +- tools/h5jam/h5jam.c | 35 +- tools/h5jam/h5jamgentest.c | 27 +- tools/h5repack/h5repack_main.c | 44 +- tools/lib/h5diff.c | 13 +- tools/lib/h5diff_attr.c | 14 +- tools/perform/iopipe.c | 9 +- 55 files changed, 2054 insertions(+), 103 deletions(-) create mode 100644 tools/h5format_convert/CMakeLists.txt create mode 100644 tools/h5format_convert/CMakeTests.cmake diff --git a/MANIFEST b/MANIFEST index 1096880..e3b0195 100644 --- a/MANIFEST +++ b/MANIFEST @@ -2939,6 +2939,8 @@ ./tools/h5dump/CMakeTestsPBITS.cmake ./tools/h5dump/CMakeTestsXML.cmake ./tools/h5dump/CMakeTestsVDS.cmake +./tools/h5format_convert/CMakeLists.txt +./tools/h5format_convert/CMakeTests.cmake ./tools/h5import/CMakeLists.txt ./tools/h5import/CMakeTests.cmake ./tools/h5jam/CMakeLists.txt diff --git a/hl/test/test_ds.c b/hl/test/test_ds.c index 7b6fb82..47929e6 100644 --- a/hl/test/test_ds.c +++ b/hl/test/test_ds.c @@ -4870,8 +4870,16 @@ static int read_data( const char* fname, } for(i=0, nelms=1; i < ndims; i++) { - fscanf( f, "%s %u", str, &j); - fscanf( f, "%d",&n ); + if(fscanf( f, "%s %u", str, &j) && HDferror(f)) { + printf( "fscanf error in file %s\n", data_file ); + HDfclose(f); + return -1; + } /* end if */ + if(fscanf( f, "%d",&n ) < 0 && HDferror(f)) { + printf( "fscanf error in file %s\n", data_file ); + HDfclose(f); + return -1; + } /* end if */ dims[i] = (hsize_t)n; nelms *= (size_t)n; } @@ -4885,7 +4893,11 @@ static int read_data( const char* fname, } for(j = 0; j < nelms; j++) { - fscanf( f, "%f",&val ); + if(fscanf( f, "%f",&val ) < 0 && HDferror(f)) { + printf( "fscanf error in file %s\n", data_file ); + HDfclose(f); + return -1; + } /* end if */ (*buf)[j] = val; } HDfclose(f); diff --git a/hl/test/test_image.c b/hl/test/test_image.c index 8ba0083..8bc6f95 100644 --- a/hl/test/test_image.c +++ b/hl/test/test_image.c @@ -603,8 +603,14 @@ static int test_generate(void) */ - fscanf( f, "%d %d %d", &imax, &jmax, &kmax ); - fscanf( f, "%f %f %f", &valex, &xmin, &xmax ); + if(fscanf( f, "%d %d %d", &imax, &jmax, &kmax ) < 0 && HDferror(f)) { + printf( "fscanf error in file %s.\n", data_file ); + goto out; + } /* end if */ + if(fscanf( f, "%f %f %f", &valex, &xmin, &xmax ) < 0 && HDferror(f)) { + printf( "fscanf error in file %s.\n", data_file ); + goto out; + } /* end if */ /* Sanity check on scanned-in values */ if(imax < 1 || jmax < 1 || kmax < 1) @@ -633,7 +639,10 @@ static int test_generate(void) for ( i = 0; i < n_elements; i++ ) { - fscanf( f, "%f ", &value ); + if(fscanf( f, "%f ", &value ) < 0 && HDferror(f)) { + printf( "fscanf error in file %s.\n", data_file ); + goto out; + } /* end if */ data[i] = value; } HDfclose(f); @@ -794,12 +803,35 @@ static int read_data(const char* fname, /*IN*/ goto out; } - fscanf(f, "%s", str); - fscanf(f, "%d", &color_planes); - fscanf(f, "%s", str); - fscanf(f, "%d", &h); - fscanf(f, "%s", str); - fscanf(f, "%d", &w); + if(fscanf(f, "%s", str) < 0 && HDferror(f)) { + printf( "fscanf error in file %s.\n", data_file ); + goto out; + } /* end if */ + + if(fscanf(f, "%d", &color_planes) < 0 && HDferror(f)) { + printf( "fscanf error in file %s.\n", data_file ); + goto out; + } /* end if */ + + if(fscanf(f, "%s", str) < 0 && HDferror(f)) { + printf( "fscanf error in file %s.\n", data_file ); + goto out; + } /* end if */ + + if(fscanf(f, "%d", &h) < 0 && HDferror(f)) { + printf( "fscanf error in file %s.\n", data_file ); + goto out; + } /* end if */ + + if(fscanf(f, "%s", str) < 0 && HDferror(f)) { + printf( "fscanf error in file %s.\n", data_file ); + goto out; + } /* end if */ + + if(fscanf(f, "%d", &w) < 0 && HDferror(f)) { + printf( "fscanf error in file %s.\n", data_file ); + goto out; + } /* end if */ /* Check product for overflow */ if(w < 1 || h < 1 || color_planes < 1) @@ -830,7 +862,10 @@ static int read_data(const char* fname, /*IN*/ /* Read data elements */ for(i = 0; i < n_elements; i++) { - fscanf(f, "%d",&n); + if(fscanf(f, "%d", &n) < 0 && HDferror(f)) { + printf( "fscanf error in file %s.\n", data_file ); + goto out; + } /* end if */ image_data[i] = (unsigned char)n; } /* end for */ diff --git a/java/src/hdf/hdf5lib/H5.java b/java/src/hdf/hdf5lib/H5.java index e7f5fe8..e555a4f 100644 --- a/java/src/hdf/hdf5lib/H5.java +++ b/java/src/hdf/hdf5lib/H5.java @@ -2072,6 +2072,31 @@ public class H5 implements java.io.Serializable { public synchronized static native int H5Dwrite_VLStrings(long dataset_id, long mem_type_id, long mem_space_id, long file_space_id, long xfer_plist_id, Object[] buf) throws HDF5LibraryException, NullPointerException; + /** + * H5Dflush causes all buffers associated with a dataset to be immediately flushed to disk without removing the + * data from the cache. + * + * @param dset_id + * IN: Identifier of the dataset to be flushed. + * + * @exception HDF5LibraryException + * - Error from the HDF-5 Library. + **/ + public synchronized static native void H5Dflush(long dset_id) throws HDF5LibraryException; + + /** + * H5Drefresh causes all buffers associated with a dataset to be cleared and immediately re-loaded with updated + * contents from disk. This function essentially closes the dataset, evicts all metadata associated with it + * from the cache, and then re-opens the dataset. The reopened dataset is automatically re-registered with the same ID. + * + * @param dset_id + * IN: Identifier of the dataset to be refreshed. + * + * @exception HDF5LibraryException + * - Error from the HDF-5 Library. + **/ + public synchronized static native void H5Drefresh(long dset_id) throws HDF5LibraryException; + // /////// unimplemented //////// // H5_DLL herr_t H5Ddebug(hid_t dset_id); // herr_t H5Dgather(hid_t src_space_id, const void *src_buf, hid_t type_id, @@ -3289,6 +3314,32 @@ public class H5 implements java.io.Serializable { private synchronized static native long _H5Gopen2(long loc_id, String name, long gapl_id) throws HDF5LibraryException, NullPointerException; + /** + * H5Gflush causes all buffers associated with a group to be immediately flushed to disk without + * removing the data from the cache. + * + * @param group_id + * IN: Identifier of the group to be flushed. + * + * @exception HDF5LibraryException + * - Error from the HDF-5 Library. + **/ + public synchronized static native void H5Gflush(long group_id) throws HDF5LibraryException; + + /** + * H5Grefresh causes all buffers associated with a group to be cleared and immediately re-loaded + * with updated contents from disk. This function essentially closes the group, evicts all metadata + * associated with it from the cache, and then re-opens the group. The reopened group is automatically + * re-registered with the same ID. + * + * @param group_id + * IN: Identifier of the group to be refreshed. + * + * @exception HDF5LibraryException + * - Error from the HDF-5 Library. + **/ + public synchronized static native void H5Grefresh(long group_id) throws HDF5LibraryException; + // //////////////////////////////////////////////////////////// // // // H5I: HDF5 1.8 Identifier Interface API Functions // @@ -4290,6 +4341,34 @@ public class H5 implements java.io.Serializable { public synchronized static native long _H5Oopen_by_idx(long loc_id, String group_name, int idx_type, int order, long n, long lapl_id) throws HDF5LibraryException, NullPointerException; + /** + * H5Oflush causes all buffers associated with an object to be immediately flushed to disk without removing + * the data from the cache. object_id can be any named object associated with an HDF5 file including a + * dataset, a group, or a committed datatype. + * + * @param object_id + * IN: Identifier of the object to be flushed. + * + * @exception HDF5LibraryException + * - Error from the HDF-5 Library. + **/ + public synchronized static native void H5Oflush(long object_id) throws HDF5LibraryException; + + /** + * H5Orefresh causes all buffers associated with an object to be cleared and immediately re-loaded with + * updated contents from disk. This function essentially closes the object, evicts all metadata associated + * with it from the cache, and then re-opens the object. The reopened object is automatically re-registered + * with the same ID. object_id can be any named object associated with an HDF5 file including a + * dataset, a group, or a committed datatype. + * + * @param object_id + * IN: Identifier of the object to be refreshed. + * + * @exception HDF5LibraryException + * - Error from the HDF-5 Library. + **/ + public synchronized static native void H5Orefresh(long object_id) throws HDF5LibraryException; + // /////// unimplemented //////// // //////////////////////////////////////////////////////////// @@ -9155,6 +9234,32 @@ public class H5 implements java.io.Serializable { private synchronized static native long _H5Tvlen_create(long base_id) throws HDF5LibraryException; + /** + * H5Tflush causes all buffers associated with a committed datatype to be immediately flushed to disk + * without removing the data from the cache. + * + * @param dtype_id + * IN: Identifier of the committed datatype to be flushed. + * + * @exception HDF5LibraryException + * - Error from the HDF-5 Library. + **/ + public synchronized static native void H5Tflush(long dtype_id) throws HDF5LibraryException; + + /** + * H5Trefresh causes all buffers associated with a committed datatype to be cleared and immediately + * re-loaded with updated contents from disk. This function essentially closes the datatype, evicts + * all metadata associated with it from the cache, and then re-opens the datatype. The reopened datatype + * is automatically re-registered with the same ID. + * + * @param dtype_id + * IN: Identifier of the committed datatype to be refreshed. + * + * @exception HDF5LibraryException + * - Error from the HDF-5 Library. + **/ + public synchronized static native void H5Trefresh(long dtype_id) throws HDF5LibraryException; + // /////// unimplemented //////// // H5T_conv_t H5Tfind(int src_id, int dst_id, H5T_cdata_t *pcdata); diff --git a/java/src/jni/h5dImp.c b/java/src/jni/h5dImp.c index 330752b..9bcbd5f 100644 --- a/java/src/jni/h5dImp.c +++ b/java/src/jni/h5dImp.c @@ -1779,6 +1779,33 @@ Java_hdf_hdf5lib_H5_H5Diterate return (jint)status; } /* end Java_hdf_hdf5lib_H5_H5Diterate */ +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Dflush + * Signature: (J)V + */ +JNIEXPORT void JNICALL +Java_hdf_hdf5lib_H5_H5Dflush + (JNIEnv *env, jclass clss, jlong loc_id) +{ + if (H5Dflush((hid_t)loc_id) < 0) + h5libraryError(env); +} + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Drefresh + * Signature: (J)V + */ +JNIEXPORT void JNICALL +Java_hdf_hdf5lib_H5_H5Drefresh + (JNIEnv *env, jclass clss, jlong loc_id) +{ + if (H5Drefresh((hid_t)loc_id) < 0) + h5libraryError(env); +} + + #ifdef __cplusplus } /* end extern "C" */ diff --git a/java/src/jni/h5dImp.h b/java/src/jni/h5dImp.h index a44d465..2a91334 100644 --- a/java/src/jni/h5dImp.h +++ b/java/src/jni/h5dImp.h @@ -348,6 +348,24 @@ JNIEXPORT jint JNICALL Java_hdf_hdf5lib_H5_H5Diterate (JNIEnv*, jclass, jbyteArray, jlong, jlong, jobject, jobject); +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Dflush + * Signature: (J)V + */ +JNIEXPORT void JNICALL +Java_hdf_hdf5lib_H5_H5Dflush + (JNIEnv*, jclass, jlong); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Drefresh + * Signature: (J)V + */ +JNIEXPORT void JNICALL +Java_hdf_hdf5lib_H5_H5Drefresh + (JNIEnv*, jclass, jlong); + #ifdef __cplusplus } /* end extern "C" */ #endif /* __cplusplus */ diff --git a/java/src/jni/h5gImp.c b/java/src/jni/h5gImp.c index 649ddde1..a2c0de0 100644 --- a/java/src/jni/h5gImp.c +++ b/java/src/jni/h5gImp.c @@ -260,6 +260,33 @@ Java_hdf_hdf5lib_H5_H5Gget_1info_1by_1idx return create_H5G_info_t(env, group_info); } /* end Java_hdf_hdf5lib_H5_H5Gget_1info_1by_1idx */ +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Gflush + * Signature: (J)V + */ +JNIEXPORT void JNICALL +Java_hdf_hdf5lib_H5_H5Gflush + (JNIEnv *env, jclass clss, jlong loc_id) +{ + if (H5Gflush((hid_t)loc_id) < 0) + h5libraryError(env); +} /* end Java_hdf_hdf5lib_H5_H5Gflush */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Grefresh + * Signature: (J)V + */ +JNIEXPORT void JNICALL +Java_hdf_hdf5lib_H5_H5Grefresh + (JNIEnv *env, jclass clss, jlong loc_id) +{ + if (H5Grefresh((hid_t)loc_id) < 0) + h5libraryError(env); +} /* end Java_hdf_hdf5lib_H5_H5Grefresh */ + + #ifdef __cplusplus } /* end extern "C" */ diff --git a/java/src/jni/h5gImp.h b/java/src/jni/h5gImp.h index 05c1e39..3113689 100644 --- a/java/src/jni/h5gImp.h +++ b/java/src/jni/h5gImp.h @@ -97,6 +97,24 @@ JNIEXPORT jobject JNICALL Java_hdf_hdf5lib_H5_H5Gget_1info_1by_1idx (JNIEnv*, jclass, jlong, jstring, jint, jint, jlong, jlong); +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Gflush + * Signature: (J)V + */ +JNIEXPORT void JNICALL +Java_hdf_hdf5lib_H5_H5Gflush + (JNIEnv*, jclass, jlong); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Grefresh + * Signature: (J)V + */ +JNIEXPORT void JNICALL +Java_hdf_hdf5lib_H5_H5Grefresh + (JNIEnv*, jclass, jlong); + #ifdef __cplusplus } /* end extern "C" */ #endif /* __cplusplus */ diff --git a/java/src/jni/h5oImp.c b/java/src/jni/h5oImp.c index 21723b8..872bb4c 100644 --- a/java/src/jni/h5oImp.c +++ b/java/src/jni/h5oImp.c @@ -779,6 +779,33 @@ Java_hdf_hdf5lib_H5__1H5Oopen_1by_1idx return (jlong)retVal; } /* end Java_hdf_hdf5lib_H5__1H5Oopen_1by_1idx */ +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Oflush + * Signature: (J)V + */ +JNIEXPORT void JNICALL +Java_hdf_hdf5lib_H5_H5Oflush + (JNIEnv *env, jclass clss, jlong loc_id) +{ + if (H5Oflush((hid_t)loc_id) < 0) + h5libraryError(env); +} /* end Java_hdf_hdf5lib_H5_H5Oflush */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Orefresh + * Signature: (J)V + */ +JNIEXPORT void JNICALL +Java_hdf_hdf5lib_H5_H5Orefresh + (JNIEnv *env, jclass clss, jlong loc_id) +{ + if (H5Orefresh((hid_t)loc_id) < 0) + h5libraryError(env); +} /* end Java_hdf_hdf5lib_H5_H5Orefresh */ + + #ifdef __cplusplus } /* end extern "C" */ diff --git a/java/src/jni/h5oImp.h b/java/src/jni/h5oImp.h index 29e08e9..293dc2e 100644 --- a/java/src/jni/h5oImp.h +++ b/java/src/jni/h5oImp.h @@ -186,6 +186,24 @@ JNIEXPORT jlong JNICALL Java_hdf_hdf5lib_H5__1H5Oopen_1by_1idx (JNIEnv*, jclass, jlong, jstring, jint, jint, jlong, jlong); +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Oflush + * Signature: (J)V + */ +JNIEXPORT void JNICALL +Java_hdf_hdf5lib_H5_H5Oflush + (JNIEnv*, jclass, jlong); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Orefresh + * Signature: (J)V + */ +JNIEXPORT void JNICALL +Java_hdf_hdf5lib_H5_H5Orefresh + (JNIEnv*, jclass, jlong); + #ifdef __cplusplus } /* end extern "C" */ #endif /* __cplusplus */ diff --git a/java/src/jni/h5tImp.c b/java/src/jni/h5tImp.c index dc052bc..55e16f8 100644 --- a/java/src/jni/h5tImp.c +++ b/java/src/jni/h5tImp.c @@ -1640,6 +1640,31 @@ Java_hdf_hdf5lib_H5_H5Tconvert } /* end else */ } /* end Java_hdf_hdf5lib_H5_H5Tconvert */ +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Tflush + * Signature: (J)V + */ +JNIEXPORT void JNICALL +Java_hdf_hdf5lib_H5_H5Tflush(JNIEnv *env, jclass clss, jlong loc_id) +{ + if (H5Tflush((hid_t)loc_id) < 0) + h5libraryError(env); +} + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Trefresh + * Signature: (J)V + */ +JNIEXPORT void JNICALL +Java_hdf_hdf5lib_H5_H5Trefresh(JNIEnv *env, jclass clss, jlong loc_id) +{ + if (H5Trefresh((hid_t)loc_id) < 0) + h5libraryError(env); +} + + #ifdef __cplusplus } /* end extern "C" */ diff --git a/java/src/jni/h5tImp.h b/java/src/jni/h5tImp.h index 9e6779d..e614082 100644 --- a/java/src/jni/h5tImp.h +++ b/java/src/jni/h5tImp.h @@ -608,6 +608,24 @@ JNIEXPORT void JNICALL Java_hdf_hdf5lib_H5_H5Tconvert (JNIEnv *, jclass, jlong, jlong, jlong, jbyteArray, jbyteArray, jlong); +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Tflush + * Signature: (J)V + */ +JNIEXPORT void JNICALL +Java_hdf_hdf5lib_H5_H5Tflush + (JNIEnv*, jclass, jlong); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Trefresh + * Signature: (J)V + */ +JNIEXPORT void JNICALL +Java_hdf_hdf5lib_H5_H5Trefresh + (JNIEnv*, jclass, jlong); + #ifdef __cplusplus } /* end extern "C" */ #endif /* __cplusplus */ diff --git a/java/test/JUnit-interface.txt b/java/test/JUnit-interface.txt index 12e67ad..cbd93e0 100644 --- a/java/test/JUnit-interface.txt +++ b/java/test/JUnit-interface.txt @@ -105,7 +105,9 @@ JUnit version 4.11 .testH5Gcreate_null .testH5Gget_info_by_idx_fileid .testH5Gclose_invalid +.testH5Gflush_invalid .testH5Gopen_invalid +.testH5Grefresh_invalid .testH5Gget_info_invalid .testH5Gcreate_invalid .testH5Gcreate_exists @@ -232,9 +234,11 @@ JUnit version 4.11 .testH5Tget_nmembers_invalid .testH5Tarray_create_value_null .testH5Tset_size_invalid +.testH5Tflush_invalid .testH5Tenum_insert_invalid .testH5Tget_array_dims_null .testH5Tget_member_index_null +.testH5Trefresh_invalid .testH5Tset_sign_invalid .testH5Tenum_insert_name_null .testH5Tequal_not @@ -270,6 +274,8 @@ JUnit version 4.11 .testH5Dvlen_reclaim_invalid .testH5Dopen_invalid .testH5Dclose_invalid +.testH5Dflush_invalid +.testH5Drefresh_invalid .testH5Dget_storage_size_invalid .testH5Dget_space_invalid .testH5Dopen_null @@ -564,7 +570,9 @@ JUnit version 4.11 .testH5Oset_comment_by_name_invalid .testH5Oopen_null .testH5Oclose_invalid +.testH5Oflush_invalid .testH5Oget_comment_by_name_invalid +.testH5Orefresh_invalid .testH5Ocopy_null_dest .testH5Olink_invalid .testH5Oget_info_by_idx_invalid @@ -626,7 +634,7 @@ JUnit version 4.11 Time: XXXX -OK (624 tests) +OK (632 tests) HDF5-DIAG: Error detected in HDF5 (version (number)) thread (IDs): #000: (file name) line (number) in H5Fopen(): can't set access and transfer property lists diff --git a/java/test/TestH5Dparams.java b/java/test/TestH5Dparams.java index f056027..2cdd121 100644 --- a/java/test/TestH5Dparams.java +++ b/java/test/TestH5Dparams.java @@ -131,4 +131,14 @@ public class TestH5Dparams { H5.H5Dget_storage_size(-1); } + @Test(expected = HDF5LibraryException.class) + public void testH5Dflush_invalid() throws Throwable { + H5.H5Dflush(-1); + } + + @Test(expected = HDF5LibraryException.class) + public void testH5Drefresh_invalid() throws Throwable { + H5.H5Drefresh(-1); + } + } diff --git a/java/test/TestH5Gbasic.java b/java/test/TestH5Gbasic.java index 70acef4..b049e15 100644 --- a/java/test/TestH5Gbasic.java +++ b/java/test/TestH5Gbasic.java @@ -368,4 +368,14 @@ public class TestH5Gbasic { assertNotNull(info); } + @Test(expected = HDF5LibraryException.class) + public void testH5Gflush_invalid() throws Throwable { + H5.H5Gflush(-1); + } + + @Test(expected = HDF5LibraryException.class) + public void testH5Grefresh_invalid() throws Throwable { + H5.H5Grefresh(-1); + } + } diff --git a/java/test/TestH5Oparams.java b/java/test/TestH5Oparams.java index ced66f5..9398940 100644 --- a/java/test/TestH5Oparams.java +++ b/java/test/TestH5Oparams.java @@ -151,4 +151,14 @@ public class TestH5Oparams { H5.H5Oget_comment_by_name(-1, null, -1); } + @Test(expected = HDF5LibraryException.class) + public void testH5Oflush_invalid() throws Throwable { + H5.H5Oflush(-1); + } + + @Test(expected = HDF5LibraryException.class) + public void testH5Orefresh_invalid() throws Throwable { + H5.H5Orefresh(-1); + } + } diff --git a/java/test/TestH5Tparams.java b/java/test/TestH5Tparams.java index 15cc6af..4ebeea7 100644 --- a/java/test/TestH5Tparams.java +++ b/java/test/TestH5Tparams.java @@ -386,4 +386,14 @@ public class TestH5Tparams { H5.H5Tget_native_type(-1); } + @Test(expected = HDF5LibraryException.class) + public void testH5Tflush_invalid() throws Throwable { + H5.H5Tflush(-1); + } + + @Test(expected = HDF5LibraryException.class) + public void testH5Trefresh_invalid() throws Throwable { + H5.H5Trefresh(-1); + } + } diff --git a/src/H5AC.c b/src/H5AC.c index 118fc1b..2dfb7de 100644 --- a/src/H5AC.c +++ b/src/H5AC.c @@ -2473,6 +2473,40 @@ done: } /* H5AC_flush_tagged_metadata */ +/*------------------------------------------------------------------------------ + * Function: H5AC_evict_tagged_metadata() + * + * Purpose: Wrapper for cache level function which flushes all metadata + * that contains the specific tag. + * + * Return: SUCCEED on success, FAIL otherwise. + * + * Programmer: Mike McGreevy + * May 19, 2010 + * + *------------------------------------------------------------------------------ + */ +herr_t +H5AC_evict_tagged_metadata(H5F_t * f, haddr_t metadata_tag, hid_t dxpl_id) +{ + /* 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 evict metadata entries with specified tag */ + if(H5C_evict_tagged_entries(f, dxpl_id, metadata_tag) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Cannot evict metadata") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5AC_evict_tagged_metadata() */ + /*------------------------------------------------------------------------------ * Function: H5AC_expunge_tag_type_metadata() diff --git a/src/H5ACpkg.h b/src/H5ACpkg.h index 1051373..6b964d6 100644 --- a/src/H5ACpkg.h +++ b/src/H5ACpkg.h @@ -402,8 +402,15 @@ typedef struct H5AC_aux_t void (* sync_point_done)(int num_writes, haddr_t * written_entries_tbl); } H5AC_aux_t; /* struct H5AC_aux_t */ +#endif /* H5_HAVE_PARALLEL */ + + +/******************************/ +/* Package Private Prototypes */ +/******************************/ -/* Package scoped functions */ +#ifdef H5_HAVE_PARALLEL +/* Parallel I/O routines */ H5_DLL herr_t H5AC__log_deleted_entry(const H5AC_info_t *entry_ptr); H5_DLL herr_t H5AC__log_dirtied_entry(const H5AC_info_t *entry_ptr); H5_DLL herr_t H5AC__log_flushed_entry(H5C_t *cache_ptr, haddr_t addr, @@ -417,7 +424,6 @@ H5_DLL herr_t H5AC__set_sync_point_done_callback(H5C_t *cache_ptr, void (*sync_point_done)(int num_writes, haddr_t *written_entries_tbl)); H5_DLL herr_t H5AC__set_write_done_callback(H5C_t * cache_ptr, void (* write_done)(void)); - #endif /* H5_HAVE_PARALLEL */ #endif /* _H5ACpkg_H */ diff --git a/src/H5ACprivate.h b/src/H5ACprivate.h index 4d78938..be20bef 100644 --- a/src/H5ACprivate.h +++ b/src/H5ACprivate.h @@ -363,6 +363,7 @@ H5_DLL herr_t H5AC_validate_config(H5AC_cache_config_t *config_ptr); /* Tag & Ring routines */ H5_DLL herr_t H5AC_tag(hid_t dxpl_id, haddr_t metadata_tag, haddr_t *prev_tag); H5_DLL herr_t H5AC_flush_tagged_metadata(H5F_t * f, haddr_t metadata_tag, hid_t dxpl_id); +H5_DLL herr_t H5AC_evict_tagged_metadata(H5F_t * f, haddr_t metadata_tag, hid_t dxpl_id); H5_DLL herr_t H5AC_retag_copied_metadata(const H5F_t *f, haddr_t metadata_tag); H5_DLL herr_t H5AC_ignore_tags(const H5F_t *f); H5_DLL herr_t H5AC_cork(H5F_t *f, haddr_t obj_addr, unsigned action, hbool_t *corked); diff --git a/src/H5Cprivate.h b/src/H5Cprivate.h index 0974384..066977f 100644 --- a/src/H5Cprivate.h +++ b/src/H5Cprivate.h @@ -1979,6 +1979,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_evict_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); diff --git a/src/H5Ctag.c b/src/H5Ctag.c index 4748156..d560e25 100644 --- a/src/H5Ctag.c +++ b/src/H5Ctag.c @@ -54,6 +54,14 @@ /* Local Typedefs */ /******************/ +/* Typedef for tagged entry iterator callback context - evict tagged entries */ +typedef struct { + H5F_t * f; /* File pointer for evicting entry */ + hid_t dxpl_id; /* DXPL for evicting entry */ + hbool_t evicted_entries_last_pass; /* Flag to indicate that an entry was evicted when iterating over cache */ + hbool_t pinned_entries_need_evicted; /* Flag to indicate that a pinned entry was attempted to be evicted */ +} H5C_tag_iter_evict_ctx_t; + /* Typedef for tagged entry iterator callback context - retag tagged entries */ typedef struct { haddr_t dest_tag; /* New tag value for matching entries */ @@ -285,6 +293,109 @@ done: /*------------------------------------------------------------------------- * + * Function: H5C__evict_tagged_entries_cb + * + * Purpose: Callback for evicting tagged entries + * + * Return: H5_ITER_ERROR if error is detected, H5_ITER_CONT otherwise. + * + * Programmer: Mike McGreevy + * August 19, 2010 + * + *------------------------------------------------------------------------- + */ +static int +H5C__evict_tagged_entries_cb(H5C_cache_entry_t *entry, void *_ctx) +{ + H5C_tag_iter_evict_ctx_t *ctx = (H5C_tag_iter_evict_ctx_t *)_ctx; /* Get pointer to iterator context */ + int ret_value = H5_ITER_CONT; /* Return value */ + + /* Function enter macro */ + FUNC_ENTER_STATIC + + /* Santify checks */ + HDassert(entry); + HDassert(ctx); + + /* Attempt to evict entry */ + if(entry->is_protected) + HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, H5_ITER_ERROR, "Cannot evict protected entry") + else if(entry->is_dirty) + HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, H5_ITER_ERROR, "Cannot evict dirty entry") + else if(entry->is_pinned) + /* Can't evict at this time, but let's note that we hit a pinned + entry and we'll loop back around again (as evicting other + entries will hopefully unpin this entry) */ + ctx->pinned_entries_need_evicted = TRUE; + else + /* Evict the Entry */ + if(H5C__flush_single_entry(ctx->f, ctx->dxpl_id, entry, H5C__FLUSH_INVALIDATE_FLAG | H5C__FLUSH_CLEAR_ONLY_FLAG | H5C__DEL_FROM_SLIST_ON_DESTROY_FLAG, NULL, NULL) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, H5_ITER_ERROR, "Entry eviction failed.") + ctx->evicted_entries_last_pass = TRUE; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5C__evict_tagged_entries_cb() */ + + +/*------------------------------------------------------------------------- + * + * Function: H5C_evict_tagged_entries + * + * Purpose: Evicts all entries with the specified tag from cache + * + * Return: FAIL if error is detected, SUCCEED otherwise. + * + * Programmer: Mike McGreevy + * August 19, 2010 + * + *------------------------------------------------------------------------- + */ +herr_t +H5C_evict_tagged_entries(H5F_t * f, hid_t dxpl_id, haddr_t tag) +{ + H5C_t *cache; /* Pointer to cache structure */ + H5C_tag_iter_evict_ctx_t ctx; /* Context for iterator callback */ + herr_t ret_value = SUCCEED; /* Return value */ + + /* Function enter macro */ + FUNC_ENTER_NOAPI(FAIL) + + /* Sanity checks */ + HDassert(f); + HDassert(f->shared); + cache = f->shared->cache; /* Get cache pointer */ + HDassert(cache != NULL); + HDassert(cache->magic == H5C__H5C_T_MAGIC); + + /* Construct context for iterator callbacks */ + ctx.f = f; + ctx.dxpl_id = dxpl_id; + + /* Start evicting entries */ + do { + /* Reset pinned/evicted tracking flags */ + ctx.pinned_entries_need_evicted = FALSE; + ctx.evicted_entries_last_pass = FALSE; + + /* Iterate through entries in the cache */ + if(H5C__iter_tagged_entries(cache, tag, TRUE, H5C__evict_tagged_entries_cb, &ctx) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_BADITER, FAIL, "Iteration of tagged entries failed") + + /* Keep doing this until we have stopped evicted entries */ + } while(TRUE == ctx.evicted_entries_last_pass); + + /* Fail if we have finished evicting entries and pinned entries still need evicted */ + if(ctx.pinned_entries_need_evicted) + HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Pinned entries still need evicted?!") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5C_evict_tagged_entries() */ + + +/*------------------------------------------------------------------------- + * * Function: H5C__mark_tagged_entries_cb * * Purpose: Callback to set the flush marker on dirty entries in the cache diff --git a/src/H5D.c b/src/H5D.c index aa932b1..23397ad 100644 --- a/src/H5D.c +++ b/src/H5D.c @@ -957,6 +957,40 @@ done: /*------------------------------------------------------------------------- + * Function: H5Drefresh + * + * Purpose: Refreshes all buffers associated with a dataset. + * + * Return: Non-negative on success, negative on failure + * + * Programmer: Mike McGreevy + * July 21, 2010 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Drefresh(hid_t dset_id) +{ + H5D_t *dset; /* Dataset to refresh */ + herr_t ret_value = SUCCEED; /* return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE1("e", "i", dset_id); + + /* Check args */ + if(NULL == (dset = (H5D_t *)H5I_object_verify(dset_id, H5I_DATASET))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset") + + /* Call private function to refresh the dataset object */ + if((H5D__refresh(dset_id, dset, H5AC_ind_read_dxpl_id)) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTLOAD, FAIL, "unable to refresh dataset") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Drefresh() */ + + +/*------------------------------------------------------------------------- * Function: H5Dformat_convert (Internal) * * Purpose: For chunked: diff --git a/src/H5Dint.c b/src/H5Dint.c index a324873..6f088af 100644 --- a/src/H5Dint.c +++ b/src/H5Dint.c @@ -1955,6 +1955,139 @@ done: /*------------------------------------------------------------------------- + * Function: H5D_mult_refresh_close + * + * Purpose: Closing down the needed information when the dataset has + * multiple opens. (From H5O_refresh_metadata_close()) + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Vailin Choi + * 12/24/15 + * + *------------------------------------------------------------------------- + */ +herr_t +H5D_mult_refresh_close(hid_t dset_id, hid_t dxpl_id) +{ + H5D_t *dataset; /* Dataset to refresh */ + herr_t ret_value = SUCCEED; /* return value */ + + FUNC_ENTER_NOAPI(FAIL) + + if(NULL == (dataset = (H5D_t *)H5I_object_verify(dset_id, H5I_DATASET))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset") + + /* check args */ + HDassert(dataset && dataset->oloc.file && dataset->shared); + HDassert(dataset->shared->fo_count > 0); + + if(dataset->shared->fo_count > 1) { + /* Free cached information for each kind of dataset */ + switch(dataset->shared->layout.type) { + case H5D_CONTIGUOUS: + /* Free the data sieve buffer, if it's been allocated */ + if(dataset->shared->cache.contig.sieve_buf) + dataset->shared->cache.contig.sieve_buf = (unsigned char *)H5FL_BLK_FREE(sieve_buf,dataset->shared->cache.contig.sieve_buf); + break; + + case H5D_CHUNKED: + /* Check for skip list for iterating over chunks during I/O to close */ + if(dataset->shared->cache.chunk.sel_chunks) { + HDassert(H5SL_count(dataset->shared->cache.chunk.sel_chunks) == 0); + H5SL_close(dataset->shared->cache.chunk.sel_chunks); + dataset->shared->cache.chunk.sel_chunks = NULL; + } /* end if */ + + /* Check for cached single chunk dataspace */ + if(dataset->shared->cache.chunk.single_space) { + (void)H5S_close(dataset->shared->cache.chunk.single_space); + dataset->shared->cache.chunk.single_space = NULL; + } /* end if */ + + /* Check for cached single element chunk info */ + if(dataset->shared->cache.chunk.single_chunk_info) { + dataset->shared->cache.chunk.single_chunk_info = H5FL_FREE(H5D_chunk_info_t, dataset->shared->cache.chunk.single_chunk_info); + dataset->shared->cache.chunk.single_chunk_info = NULL; + } /* end if */ + break; + + case H5D_COMPACT: + case H5D_VIRTUAL: + /* Nothing special to do (info freed in the layout destroy) */ + break; + + case H5D_LAYOUT_ERROR: + case H5D_NLAYOUTS: + default: + HDassert("not implemented yet" && 0); +#ifdef NDEBUG + HGOTO_ERROR(H5E_IO, H5E_UNSUPPORTED, FAIL, "unsupported storage layout") +#endif /* NDEBUG */ + } /* end switch */ /*lint !e788 All appropriate cases are covered */ + + /* Destroy any cached layout information for the dataset */ + if(dataset->shared->layout.ops->dest && (dataset->shared->layout.ops->dest)(dataset, dxpl_id) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTRELEASE, FAIL, "unable to destroy layout info") + } /* end if */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5D_mult_refresh_close() */ + + +/*------------------------------------------------------------------------- + * Function: H5D_mult_refresh_reopen + * + * Purpose: Re-initialize the needed info when the dataset has multiple + * opens. (From H5O_refresh_metadata_reopen()) + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Vailin Choi + * 12/24/15 + * + *------------------------------------------------------------------------- + */ +herr_t +H5D_mult_refresh_reopen(H5D_t *dataset, hid_t dxpl_id) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* check args */ + HDassert(dataset && dataset->oloc.file && dataset->shared); + HDassert(dataset->shared->fo_count > 0); + + if(dataset->shared->fo_count > 1) { + /* Release dataspace info */ + if(H5S_close(dataset->shared->space) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTRELEASE, FAIL, "unable to release dataspace") + + /* Re-load dataspace info */ + if(NULL == (dataset->shared->space = H5S_read(&(dataset->oloc), dxpl_id))) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to load dataspace info from dataset header") + + /* Cache the dataset's dataspace info */ + if(H5D__cache_dataspace_info(dataset) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "can't cache dataspace info") + + /* Release layout info */ + if(H5O_msg_reset(H5O_LAYOUT_ID, &dataset->shared->layout) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTRESET, FAIL, "unable to reset layout info") + + /* Re-load layout message info */ + if(NULL == H5O_msg_read(&(dataset->oloc), H5O_LAYOUT_ID, &(dataset->shared->layout), dxpl_id)) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to read data layout message") + } /* end if */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5D_mult_refresh_reopen() */ + + +/*------------------------------------------------------------------------- * Function: H5D_oloc * * Purpose: Returns a pointer to the object location for a dataset. @@ -3475,3 +3608,57 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5D_get_type() */ + +/*------------------------------------------------------------------------- + * Function: H5D__refresh + * + * Purpose: Refreshes all buffers associated with a dataset. + * + * Return: SUCCEED/FAIL + * + * Programmer: Dana Robinson + * November 2015 + * + *------------------------------------------------------------------------- + */ +herr_t +H5D__refresh(hid_t dset_id, H5D_t *dset, hid_t dxpl_id) +{ + H5D_virtual_held_file_t *head = NULL; /* Pointer to list of files held open */ + hbool_t virt_dsets_held = FALSE; /* Whether virtual datasets' files are held open */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + HDassert(dset); + + /* If the layout is virtual... */ + if(dset->shared->layout.type == H5D_VIRTUAL) { + /* Hold open the source datasets' files */ + if(H5D__virtual_hold_source_dset_files(dset, &head) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINC, FAIL, "unable to hold VDS source files open") + virt_dsets_held = TRUE; + + /* Refresh source datasets for virtual dataset */ + if(H5D__virtual_refresh_source_dsets(dset, dxpl_id) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTFLUSH, FAIL, "unable to refresh VDS source datasets") + } /* end if */ + + /* Refresh dataset object */ + if((H5O_refresh_metadata(dset_id, dset->oloc, dxpl_id)) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTFLUSH, FAIL, "unable to refresh dataset") + +done: + /* Release hold on virtual datasets' files */ + if(virt_dsets_held) { + /* Sanity check */ + HDassert(dset->shared->layout.type == H5D_VIRTUAL); + + /* Release the hold on source datasets' files */ + if(H5D__virtual_release_source_dset_files(head) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CANTDEC, FAIL, "can't release VDS source files held open") + } /* end if */ + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5D__refresh() */ + diff --git a/src/H5Dpkg.h b/src/H5Dpkg.h index 3b2727f..05f49d1 100644 --- a/src/H5Dpkg.h +++ b/src/H5Dpkg.h @@ -394,6 +394,12 @@ typedef struct H5D_chunk_cached_t { unsigned filter_mask; /*excluded filters */ } H5D_chunk_cached_t; +/* List of files held open during refresh operations */ +typedef struct H5D_virtual_held_file_t { + H5F_t *file; /* Pointer to file held open */ + struct H5D_virtual_held_file_t *next; /* Pointer to next node in list */ +} H5D_virtual_held_file_t; + /* The raw data chunk cache */ struct H5D_rdcc_ent_t; /* Forward declaration of struct used below */ typedef struct H5D_rdcc_t { @@ -579,6 +585,7 @@ H5_DLL herr_t H5D__get_dxpl_cache(hid_t dxpl_id, H5D_dxpl_cache_t **cache); H5_DLL herr_t H5D__flush_sieve_buf(H5D_t *dataset, hid_t dxpl_id); H5_DLL herr_t H5D__flush_real(H5D_t *dataset, hid_t dxpl_id); H5_DLL herr_t H5D__mark(const H5D_t *dataset, hid_t dxpl_id, unsigned flags); +H5_DLL herr_t H5D__refresh(hid_t dset_id, H5D_t *dataset, hid_t dxpl_id); #ifdef H5_DEBUG_BUILD H5_DLL herr_t H5D_set_io_info_dxpls(H5D_io_info_t *io_info, hid_t dxpl_id); #endif /* H5_DEBUG_BUILD */ @@ -696,6 +703,9 @@ H5_DLL herr_t H5D__virtual_copy(H5F_t *f_src, H5O_layout_t *layout_dst, H5_DLL herr_t H5D__virtual_init(H5F_t *f, hid_t dxpl_id, const H5D_t *dset, hid_t dapl_id); H5_DLL hbool_t H5D__virtual_is_space_alloc(const H5O_storage_t *storage); +H5_DLL herr_t H5D__virtual_hold_source_dset_files(const H5D_t *dset, H5D_virtual_held_file_t **head); +H5_DLL herr_t H5D__virtual_refresh_source_dsets(H5D_t *dset, hid_t dxpl_id); +H5_DLL herr_t H5D__virtual_release_source_dset_files(H5D_virtual_held_file_t *head); /* Functions that operate on EFL (External File List)*/ H5_DLL hbool_t H5D__efl_is_space_alloc(const H5O_storage_t *storage); diff --git a/src/H5Dprivate.h b/src/H5Dprivate.h index d1468dd..ea2b8c8 100644 --- a/src/H5Dprivate.h +++ b/src/H5Dprivate.h @@ -173,6 +173,8 @@ typedef struct H5D_append_flush_t { H5_DLL herr_t H5D_init(void); H5_DLL H5D_t *H5D_open(const H5G_loc_t *loc, hid_t dapl_id, hid_t dxpl_id); H5_DLL herr_t H5D_close(H5D_t *dataset); +H5_DLL herr_t H5D_mult_refresh_close(hid_t dset_id, hid_t dxpl_id); +H5_DLL herr_t H5D_mult_refresh_reopen(H5D_t *dataset, hid_t dxpl_id); H5_DLL H5O_loc_t *H5D_oloc(H5D_t *dataset); H5_DLL H5G_name_t *H5D_nameof(H5D_t *dataset); H5_DLL H5T_t *H5D_typeof(const H5D_t *dset); diff --git a/src/H5Dpublic.h b/src/H5Dpublic.h index 831e811..81ae67d 100644 --- a/src/H5Dpublic.h +++ b/src/H5Dpublic.h @@ -161,6 +161,7 @@ H5_DLL herr_t H5Dfill(const void *fill, hid_t fill_type, void *buf, hid_t buf_type, hid_t space); H5_DLL herr_t H5Dset_extent(hid_t dset_id, const hsize_t size[]); H5_DLL herr_t H5Dflush(hid_t dset_id); +H5_DLL herr_t H5Drefresh(hid_t dset_id); H5_DLL herr_t H5Dscatter(H5D_scatter_func_t op, void *op_data, hid_t type_id, hid_t dst_space_id, void *dst_buf); H5_DLL herr_t H5Dgather(hid_t src_space_id, const void *src_buf, hid_t type_id, diff --git a/src/H5Dvirtual.c b/src/H5Dvirtual.c index c516c58..9a90fa7 100644 --- a/src/H5Dvirtual.c +++ b/src/H5Dvirtual.c @@ -144,6 +144,9 @@ const H5D_layout_ops_t H5D_LOPS_VIRTUAL[1] = {{ /* Declare a free list to manage the H5O_storage_virtual_name_seg_t struct */ H5FL_DEFINE(H5O_storage_virtual_name_seg_t); +/* Declare a static free list to manage H5D_virtual_file_list_t structs */ +H5FL_DEFINE_STATIC(H5D_virtual_held_file_t); + /*------------------------------------------------------------------------- @@ -2725,3 +2728,220 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5D__virtual_flush() */ + +/*------------------------------------------------------------------------- + * Function: H5D__virtual_hold_source_dset_files + * + * Purpose: Hold open the source files that are open, during a refresh event + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * November 7, 2015 + * + *------------------------------------------------------------------------- + */ +herr_t +H5D__virtual_hold_source_dset_files(const H5D_t *dset, H5D_virtual_held_file_t **head) +{ + H5O_storage_virtual_t *storage; /* Convenient pointer into layout struct */ + H5D_virtual_held_file_t *tmp; /* Temporary held file node */ + size_t i; /* Local index variable */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_PACKAGE + + /* Sanity check */ + HDassert(dset); + HDassert(head && NULL == *head); + + /* Set the convenience pointer */ + storage = &dset->shared->layout.storage.u.virt; + + /* Hold only files for open datasets */ + for(i = 0; i < storage->list_nused; i++) + /* Check for "printf" source dataset resolution */ + if(storage->list[i].psfn_nsubs || storage->list[i].psdn_nsubs) { + size_t j; /* Local index variable */ + + /* Iterate over sub-source dsets */ + for(j = 0; j < storage->list[i].sub_dset_nused; j++) + if(storage->list[i].sub_dset[j].dset) { + /* Hold open the file */ + H5F_INCR_NOPEN_OBJS(storage->list[i].sub_dset[j].dset->oloc.file); + + /* Allocate a node for this file */ + if(NULL == (tmp = H5FL_MALLOC(H5D_virtual_held_file_t))) + HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "can't allocate held file node") + + /* Set up node & connect to list */ + tmp->file = storage->list[i].sub_dset[j].dset->oloc.file; + tmp->next = *head; + *head = tmp; + } /* end if */ + } /* end if */ + else + if(storage->list[i].source_dset.dset) { + /* Hold open the file */ + H5F_INCR_NOPEN_OBJS(storage->list[i].source_dset.dset->oloc.file); + + /* Allocate a node for this file */ + if(NULL == (tmp = H5FL_MALLOC(H5D_virtual_held_file_t))) + HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "can't allocate held file node") + + /* Set up node & connect to list */ + tmp->file = storage->list[i].source_dset.dset->oloc.file; + tmp->next = *head; + *head = tmp; + } /* end if */ + +done: + if(ret_value < 0) { + /* Release hold on files and delete list on error */ + if(*head) + if(H5D__virtual_release_source_dset_files(*head) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "can't release source datasets' files held open") + } /* end if */ + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5D__virtual_hold_source_dset_files() */ + + +/*------------------------------------------------------------------------- + * Function: H5D__virtual_refresh_source_dset + * + * Purpose: Refresh a source dataset + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * November 7, 2015 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5D__virtual_refresh_source_dset(H5D_t **dset, hid_t dxpl_id) +{ + hid_t dset_id; /* Temporary dataset identifier */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + /* Sanity check */ + HDassert(dset && *dset); + + /* Get a temporary identifier for this source dataset */ + if((dset_id = H5I_register(H5I_DATASET, *dset, FALSE)) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTREGISTER, FAIL, "can't register source dataset ID") + + /* Refresh source dataset */ + if(H5D__refresh(dset_id, *dset, dxpl_id) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTFLUSH, FAIL, "unable to refresh source dataset") + + /* Discard the identifier & replace the dataset */ + if(NULL == (*dset = (H5D_t *)H5I_remove(dset_id))) + HGOTO_ERROR(H5E_DATASET, H5E_CANTREMOVE, FAIL, "can't unregister source dataset ID") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5D__virtual_refresh_source_dsets() */ + + +/*------------------------------------------------------------------------- + * Function: H5D__virtual_refresh_source_dsets + * + * Purpose: Refresh the source datasets + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Dana Robinson + * November, 2015 + * + *------------------------------------------------------------------------- + */ +herr_t +H5D__virtual_refresh_source_dsets(H5D_t *dset, hid_t dxpl_id) +{ + H5O_storage_virtual_t *storage; /* Convenient pointer into layout struct */ + size_t i; /* Local index variable */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_PACKAGE + + /* Sanity check */ + HDassert(dset); + + /* Set convenience pointer */ + storage = &dset->shared->layout.storage.u.virt; + + /* Refresh only open datasets */ + for(i = 0; i < storage->list_nused; i++) + /* Check for "printf" source dataset resolution */ + if(storage->list[i].psfn_nsubs || storage->list[i].psdn_nsubs) { + size_t j; /* Local index variable */ + + /* Iterate over sub-source datasets */ + for(j = 0; j < storage->list[i].sub_dset_nused; j++) + /* Check if sub-source dataset is open */ + if(storage->list[i].sub_dset[j].dset) + /* Refresh sub-source dataset */ + if(H5D__virtual_refresh_source_dset(&storage->list[i].sub_dset[j].dset, dxpl_id) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTFLUSH, FAIL, "unable to refresh source dataset") + } /* end if */ + else + /* Check if source dataset is open */ + if(storage->list[i].source_dset.dset) + /* Refresh source dataset */ + if(H5D__virtual_refresh_source_dset(&storage->list[i].source_dset.dset, dxpl_id) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTFLUSH, FAIL, "unable to refresh source dataset") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5D__virtual_refresh_source_dsets() */ + + +/*------------------------------------------------------------------------- + * Function: H5D__virtual_release_source_dset_files + * + * Purpose: Release the hold on source files that are open, during a refresh event + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * November 7, 2015 + * + *------------------------------------------------------------------------- + */ +herr_t +H5D__virtual_release_source_dset_files(H5D_virtual_held_file_t *head) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_PACKAGE + + /* Release hold on files and delete list */ + while(head) { + H5D_virtual_held_file_t *tmp = head->next; /* Temporary pointer to next node */ + + /* Release hold on file */ + H5F_DECR_NOPEN_OBJS(head->file); + + /* Attempt to close the file */ + /* (Should always succeed, since the 'top' source file pointer is + * essentially "private" to the virtual dataset, since it wasn't + * opened through an API routine -QAK) + */ + if(H5F_try_close(head->file) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCLOSEFILE, FAIL, "problem attempting file close") + + /* Delete node */ + (void)H5FL_FREE(H5D_virtual_held_file_t, head); + + /* Advance to next node */ + head = tmp; + } /* end while */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5D__virtual_release_source_dset_files() */ + diff --git a/src/H5Fint.c b/src/H5Fint.c index 9ca472d..80c593b 100644 --- a/src/H5Fint.c +++ b/src/H5Fint.c @@ -1085,7 +1085,7 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, } else if (1 == shared->nrefs) { /* Read the superblock if it hasn't been read before. */ - if(H5F__super_read(file, dxpl_id) < 0) + if(H5F__super_read(file, dxpl_id, TRUE) < 0) HGOTO_ERROR(H5E_FILE, H5E_READERROR, NULL, "unable to read superblock") /* Open the root group */ diff --git a/src/H5Fio.c b/src/H5Fio.c index 1fb3459..b9bd354 100644 --- a/src/H5Fio.c +++ b/src/H5Fio.c @@ -244,3 +244,41 @@ done: FUNC_LEAVE_NOAPI(ret_value); } /* end H5F_flush_tagged_metadata */ + +/*------------------------------------------------------------------------- + * Function: H5F_evict_tagged_metadata + * + * Purpose: Evicts metadata from the cache with specified tag. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Mike McGreevy + * September 9, 2010 + * + *------------------------------------------------------------------------- + */ +herr_t +H5F_evict_tagged_metadata(H5F_t * f, haddr_t tag, hid_t dxpl_id) +{ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(FAIL) + + /* Unpin the superblock, as this will be marked for eviction and it can't + be pinned. */ + if(H5AC_unpin_entry(f->shared->sblock) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_CANTUNPIN, FAIL, "unable to unpin superblock") + f->shared->sblock = NULL; + + /* Evict the object's metadata */ + if(H5AC_evict_tagged_metadata(f, tag, dxpl_id)<0) + HGOTO_ERROR(H5E_CACHE, H5E_CANTEXPUNGE, FAIL, "unable to evict tagged metadata") + + /* Re-read the superblock. */ + if(H5F__super_read(f, dxpl_id, FALSE) < 0) + HGOTO_ERROR(H5E_FILE, H5E_READERROR, FAIL, "unable to read superblock") + +done: + FUNC_LEAVE_NOAPI(ret_value); +} /* end H5F_evict_tagged_metadata */ + diff --git a/src/H5Fpkg.h b/src/H5Fpkg.h index e2874d1..c5aed3b 100644 --- a/src/H5Fpkg.h +++ b/src/H5Fpkg.h @@ -356,7 +356,7 @@ H5_DLL herr_t H5F_mount_count_ids(H5F_t *f, unsigned *nopen_files, unsigned *nop /* Superblock related routines */ H5_DLL herr_t H5F__super_init(H5F_t *f, hid_t dxpl_id); -H5_DLL herr_t H5F__super_read(H5F_t *f, hid_t dxpl_id); +H5_DLL herr_t H5F__super_read(H5F_t *f, hid_t dxpl_id, hbool_t initial_read); H5_DLL herr_t H5F__super_size(H5F_t *f, hid_t dxpl_id, hsize_t *super_size, hsize_t *super_ext_size); H5_DLL herr_t H5F__super_free(H5F_super_t *sblock); diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h index 7d45ed9..34a5277 100644 --- a/src/H5Fprivate.h +++ b/src/H5Fprivate.h @@ -698,6 +698,7 @@ H5_DLL herr_t H5F_block_write(const H5F_t *f, H5FD_mem_t type, haddr_t addr, /* Functions that flush or evict */ H5_DLL herr_t H5F_flush_tagged_metadata(H5F_t * f, haddr_t tag, hid_t dxpl_id); +H5_DLL herr_t H5F_evict_tagged_metadata(H5F_t * f, haddr_t tag, hid_t dxpl_id); /* Routine to invoke callback function upon object flush */ H5_DLL herr_t H5F_object_flush_cb(H5F_t *f, hid_t obj_id); diff --git a/src/H5Fsuper.c b/src/H5Fsuper.c index 4aca221..23b7f78 100644 --- a/src/H5Fsuper.c +++ b/src/H5Fsuper.c @@ -239,7 +239,7 @@ done: *------------------------------------------------------------------------- */ herr_t -H5F__super_read(H5F_t *f, hid_t dxpl_id) +H5F__super_read(H5F_t *f, hid_t dxpl_id, hbool_t initial_read) { H5P_genplist_t *dxpl = NULL; /* DXPL object */ H5AC_ring_t ring, orig_ring = H5AC_RING_INV; @@ -400,12 +400,24 @@ H5F__super_read(H5F_t *f, hid_t dxpl_id) * possible is if the first file of a family of files was opened * individually. */ - if(HADDR_UNDEF == (eof = H5FD_get_eof(f->shared->lf, H5FD_MEM_DEFAULT))) - HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to determine file size") + /* Can skip this test when it is not the initial file open-- + * H5F_super_read() call from H5F_evict_tagged_metadata() for + * refreshing object. + * When flushing file buffers and fractal heap is involved, + * the library will allocate actual space for tmp addresses + * via the file layer. The aggregator allocates a block, + * thus the eoa might be greater than eof. + * Note: the aggregator is changed again after being reset + * earlier before H5AC_flush due to allocation of tmp addresses. + */ + if(initial_read) { + if(HADDR_UNDEF == (eof = H5FD_get_eof(f->shared->lf, H5FD_MEM_DEFAULT))) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to determine file size") - /* (Account for the stored EOA being absolute offset -QAK) */ - if((eof + sblock->base_addr) < udata.stored_eof) - HGOTO_ERROR(H5E_FILE, H5E_TRUNCATED, FAIL, "truncated file: eof = %llu, sblock->base_addr = %llu, stored_eoa = %llu", (unsigned long long)eof, (unsigned long long)sblock->base_addr, (unsigned long long)udata.stored_eof) + /* (Account for the stored EOA being absolute offset -QAK) */ + if((eof + sblock->base_addr) < udata.stored_eof) + HGOTO_ERROR(H5E_FILE, H5E_TRUNCATED, FAIL, "truncated file: eof = %llu, sblock->base_addr = %llu, stored_eof = %llu", (unsigned long long)eof, (unsigned long long)sblock->base_addr, (unsigned long long)udata.stored_eof) + } /* end if */ /* * Tell the file driver how much address space has already been diff --git a/src/H5I.c b/src/H5I.c index a53b13b..0fe9782 100644 --- a/src/H5I.c +++ b/src/H5I.c @@ -789,6 +789,73 @@ done: /*------------------------------------------------------------------------- + * Function: H5I_register_with_id + * + * Purpose: Registers an OBJECT in a TYPE with the supplied ID for it. + * This routine will check to ensure the supplied ID is not already + * in use, and ensure that it is a valid ID for the given type, + * but will NOT check to ensure the OBJECT is not already + * registered (thus, it is possible to register one object under + * multiple IDs). + * + * Return: Success: 0 + * Failure: -1 + * + * Programmer: Mike McGreevy + * Wednesday, July 21, 2010 + * + *------------------------------------------------------------------------- + */ +herr_t +H5I_register_with_id(H5I_type_t type, const void *object, hbool_t app_ref, hid_t id) +{ + H5I_id_type_t *type_ptr; /*ptr to the type */ + H5I_id_info_t *id_ptr; /*ptr to the new ID information */ + herr_t ret_value = SUCCEED; /*return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Check arguments */ + + /* Make sure ID is not already in use */ + if(NULL != (id_ptr = H5I__find_id(id))) + HGOTO_ERROR(H5E_ATOM, H5E_BADRANGE, FAIL, "ID already in use?!") + + /* Make sure type number is valid */ + if(type <= H5I_BADID || type >= H5I_next_type) + HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid type number") + + /* Get type pointer from list of types */ + type_ptr = H5I_id_type_list_g[type]; + + if(NULL == type_ptr || type_ptr->init_count <= 0) + HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "invalid type") + + /* Make sure requested ID belongs to object's type */ + if(H5I_TYPE(id) != type) + HGOTO_ERROR(H5E_ATOM, H5E_BADRANGE, FAIL, "invalid type for provided ID") + + /* Allocate new structure to house this ID */ + if(NULL == (id_ptr = H5FL_MALLOC(H5I_id_info_t))) + HGOTO_ERROR(H5E_ATOM, H5E_NOSPACE, FAIL, "memory allocation failed") + + /* Create the struct & insert requested ID */ + id_ptr->id = id; + id_ptr->count = 1; /*initial reference count*/ + id_ptr->app_count = !!app_ref; + id_ptr->obj_ptr = object; + + /* Insert into the type */ + if(H5SL_insert(type_ptr->ids, id_ptr, &id_ptr->id) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTINSERT, FAIL, "can't insert ID node into skip list") + type_ptr->id_count++; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5I_register_with_id() */ + + +/*------------------------------------------------------------------------- * Function: H5I_subst * * Purpose: Substitute a new object pointer for the specified ID. diff --git a/src/H5Iprivate.h b/src/H5Iprivate.h index f438581..c916f31 100644 --- a/src/H5Iprivate.h +++ b/src/H5Iprivate.h @@ -69,6 +69,7 @@ H5_DLL herr_t H5I_register_type(const H5I_class_t *cls); H5_DLL int64_t H5I_nmembers(H5I_type_t type); H5_DLL herr_t H5I_clear_type(H5I_type_t type, hbool_t force, hbool_t app_ref); H5_DLL hid_t H5I_register(H5I_type_t type, const void *object, hbool_t app_ref); +H5_DLL herr_t H5I_register_with_id(H5I_type_t type, const void *object, hbool_t app_ref, hid_t id); H5_DLL void *H5I_subst(hid_t id, const void *new_object); H5_DLL void *H5I_object(hid_t id); H5_DLL void *H5I_object_verify(hid_t id, H5I_type_t id_type); diff --git a/src/H5Oflush.c b/src/H5Oflush.c index 0bec096..6484dfd 100644 --- a/src/H5Oflush.c +++ b/src/H5Oflush.c @@ -54,6 +54,53 @@ static herr_t H5O_oh_tag(const H5O_loc_t *oloc, hid_t dxpl_id, haddr_t *tag); /*------------------------------------------------------------------------- + * Function: H5Oflush + * + * Purpose: Flushes all buffers associated with an object to disk. + * + * Return: Non-negative on success, negative on failure + * + * Programmer: Mike McGreevy + * May 19, 2010 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Oflush(hid_t obj_id) +{ + H5O_loc_t *oloc; /* object location */ + void *obj_ptr; /* Pointer to object */ + const H5O_obj_class_t *obj_class = NULL; /* Class of object */ + herr_t ret_value = SUCCEED; /* return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE1("e", "i", obj_id); + + /* Check args */ + if(NULL == (oloc = H5O_get_loc(obj_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an object") + + /* Get the object pointer */ + if(NULL == (obj_ptr = H5I_object(obj_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier") + + /* Get the object class */ + if(NULL == (obj_class = H5O_obj_class(oloc, H5AC_ind_read_dxpl_id))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to determine object class") + + /* Flush the object of this class */ + if(obj_class->flush && obj_class->flush(obj_ptr, H5AC_ind_read_dxpl_id) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTFLUSH, FAIL, "unable to flush object") + + /* Flush the object metadata and invoke flush callback */ + if(H5O_flush_common(oloc, obj_id, H5AC_ind_read_dxpl_id) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTFLUSH, FAIL, "unable to flush object and object flush callback") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Oflush() */ + +/*------------------------------------------------------------------------- * Function: H5O_flush_common * * Purpose: Flushes the object's metadata @@ -130,3 +177,211 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5O_oh_tag() */ + + +/*------------------------------------------------------------------------- + * Function: H5O_refresh_metadata + * + * Purpose: Refreshes all buffers associated with an object. + * + * Note: This is based on the original H5O_refresh_metadata() but + * is split into 2 routines. + * This is done so that H5Fstart_swmr_write() can use these + * 2 routines to refresh opened objects. This may be + * restored back to the original code when H5Fstart_swmr_write() + * uses a different approach to handle issues with opened objects. + * H5Fstart_swmr_write() no longer calls the 1st routine. (12/24/15) + * + * Return: Non-negative on success, negative on failure + * + * Programmer: Mike McGreevy/Vailin Choi + * July 28, 2010/Feb 2014 + * + *------------------------------------------------------------------------- + */ +herr_t +H5O_refresh_metadata(hid_t oid, H5O_loc_t oloc, hid_t dxpl_id) +{ + hbool_t objs_incr = FALSE; /* Whether the object count in the file was incremented */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* If the file is opened with write access, no need to perform refresh actions. */ + if(!(H5F_INTENT(oloc.file) & H5F_ACC_RDWR)) { + H5G_loc_t obj_loc; + H5O_loc_t obj_oloc; + H5G_name_t obj_path; + + /* Create empty object location */ + obj_loc.oloc = &obj_oloc; + obj_loc.path = &obj_path; + H5G_loc_reset(&obj_loc); + + /* "Fake" another open object in the file, so that it doesn't get closed + * if this object is the only thing holding the file open. + */ + H5F_incr_nopen_objs(oloc.file); + objs_incr = TRUE; + + /* Close object & evict its metadata */ + if((H5O_refresh_metadata_close(oid, oloc, &obj_loc, dxpl_id)) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to refresh object") + + /* Re-open the object, re-fetching its metadata */ + if((H5O_refresh_metadata_reopen(oid, &obj_loc, dxpl_id)) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to refresh object") + } /* end if */ + +done: + if(objs_incr) + H5F_decr_nopen_objs(oloc.file); + + FUNC_LEAVE_NOAPI(ret_value); +} /* end H5O_refresh_metadata() */ + + +/*------------------------------------------------------------------------- + * Function: H5O_refresh_metadata_close + * + * Purpose: This is the first part of the original routine H5O_refresh_metadata(). + * (1) Save object location information. + * (2) Handle multiple dataset opens + * (3) Get object cork status + * (4) Close the object + * (5) Flush and evict object metadata + * (6) Re-cork the object if needed + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Mike McGreevy/Vailin Choi + * July 28, 2010/Feb 2014 + * + *------------------------------------------------------------------------- + */ +herr_t +H5O_refresh_metadata_close(hid_t oid, H5O_loc_t oloc, H5G_loc_t *obj_loc, hid_t dxpl_id) +{ + haddr_t tag = 0; /* Tag for object */ + hbool_t corked = FALSE; /* Whether object's metadata is corked */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Make deep local copy of object's location information */ + if(obj_loc) { + H5G_loc_t tmp_loc; + + H5G_loc(oid, &tmp_loc); + H5G_loc_copy(obj_loc, &tmp_loc, H5_COPY_DEEP); + } /* end if */ + + /* Get object's type */ + if(H5I_get_type(oid) == H5I_DATASET) + if(H5D_mult_refresh_close(oid, dxpl_id) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTOPENOBJ, FAIL, "unable to prepare refresh for dataset") + + /* Retrieve tag for object */ + if(H5O_oh_tag(&oloc, dxpl_id, &tag) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTFLUSH, FAIL, "unable to get object header address") + + /* Get cork status of the object with tag */ + if(H5AC_cork(oloc.file, tag, H5AC__GET_CORKED, &corked) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_SYSTEM, FAIL, "unable to retrieve an object's cork status") + + /* Close the object */ + if(H5I_dec_ref(oid) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to close object") + + /* Flush metadata based on tag value of the object */ + if(H5F_flush_tagged_metadata(oloc.file, tag, dxpl_id) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to flush tagged metadata") + + /* Evict the object's tagged metadata */ + if(H5F_evict_tagged_metadata(oloc.file, tag, dxpl_id) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to evict metadata") + + /* Re-cork object with tag */ + if(corked) + if(H5AC_cork(oloc.file, tag, H5AC__SET_CORK, &corked) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_SYSTEM, FAIL, "unable to cork the object") + +done: + FUNC_LEAVE_NOAPI(ret_value); +} /* end H5O_refresh_metadata_close() */ + + +/*------------------------------------------------------------------------- + * Function: H5O_refresh_metadata_reopen + * + * Purpose: This is the second part of the original routine H5O_refresh_metadata(). + * (1) Re-open object with the saved object location information. + * (2) Re-register object ID with the re-opened object. + * + * Return: SUCCEED/FAIL + * + * Programmer: Mike McGreevy/Vailin Choi + * July 28, 2010/Feb 2014 + * + *------------------------------------------------------------------------- + */ +herr_t +H5O_refresh_metadata_reopen(hid_t oid, H5G_loc_t *obj_loc, hid_t dxpl_id) +{ + void *object = NULL; /* Dataset for this operation */ + H5I_type_t type; /* Type of object for the ID */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Get object's type */ + type = H5I_get_type(oid); + + switch(type) { + case(H5I_GROUP): + /* Re-open the group */ + if(NULL == (object = H5G_open(obj_loc, dxpl_id))) + HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open group") + break; + + case(H5I_DATATYPE): + /* Re-open the named datatype */ + if(NULL == (object = H5T_open(obj_loc, dxpl_id))) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTOPENOBJ, FAIL, "unable to open named datatype") + break; + + case(H5I_DATASET): + /* Re-open the dataset */ + if(NULL == (object = H5D_open(obj_loc, H5P_DATASET_ACCESS_DEFAULT, dxpl_id))) + HGOTO_ERROR(H5E_DATASET, H5E_CANTOPENOBJ, FAIL, "unable to open dataset") + if(H5D_mult_refresh_reopen((H5D_t *)object, dxpl_id) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTOPENOBJ, FAIL, "unable to finish refresh for dataset") + break; + + case(H5I_UNINIT): + case(H5I_BADID): + case(H5I_FILE): + case(H5I_DATASPACE): + case(H5I_ATTR): + case(H5I_REFERENCE): + case(H5I_VFL): + case(H5I_GENPROP_CLS): + case(H5I_GENPROP_LST): + case(H5I_ERROR_CLASS): + case(H5I_ERROR_MSG): + case(H5I_ERROR_STACK): + case(H5I_NTYPES): + default: + HGOTO_ERROR(H5E_ARGS, H5E_CANTRELEASE, FAIL, "not a valid file object ID (dataset, group, or datatype)") + break; + } /* end switch */ + + /* Re-register ID for the object */ + if((H5I_register_with_id(type, object, TRUE, oid)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to re-register object atom") + +done: + FUNC_LEAVE_NOAPI(ret_value); +} /* end H5O_refresh_metadata_reopen() */ + diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h index 9ad8662..44b4998 100644 --- a/src/H5Oprivate.h +++ b/src/H5Oprivate.h @@ -904,6 +904,9 @@ H5_DLL herr_t H5O_msg_unlock(const H5O_loc_t *loc, unsigned type_id, hid_t dxpl_ /* Object metadata flush/refresh routines */ H5_DLL herr_t H5O_flush_common(H5O_loc_t *oloc, hid_t obj_id, hid_t dxpl_id); +H5_DLL herr_t H5O_refresh_metadata(hid_t oid, H5O_loc_t oloc, hid_t dxpl_id); +H5_DLL herr_t H5O_refresh_metadata_close(hid_t oid, H5O_loc_t oloc, H5G_loc_t *obj_loc, hid_t dxpl_id); +H5_DLL herr_t H5O_refresh_metadata_reopen(hid_t oid, H5G_loc_t *obj_loc, hid_t dxpl_id); /* Object copying routines */ H5_DLL herr_t H5O_copy_header_map(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */, diff --git a/src/H5Opublic.h b/src/H5Opublic.h index 9debdbc..1d2ab7b 100644 --- a/src/H5Opublic.h +++ b/src/H5Opublic.h @@ -182,6 +182,7 @@ H5_DLL herr_t H5Ovisit_by_name(hid_t loc_id, const char *obj_name, H5_index_t idx_type, H5_iter_order_t order, H5O_iterate_t op, void *op_data, hid_t lapl_id); H5_DLL herr_t H5Oclose(hid_t object_id); +H5_DLL herr_t H5Oflush(hid_t obj_id); H5_DLL herr_t H5Odisable_mdc_flushes(hid_t object_id); H5_DLL herr_t H5Oenable_mdc_flushes(hid_t object_id); H5_DLL herr_t H5Oare_mdc_flushes_disabled(hid_t object_id, hbool_t *are_disabled); diff --git a/test/cork.c b/test/cork.c index 8a2fc8f..95f08b5 100644 --- a/test/cork.c +++ b/test/cork.c @@ -1859,6 +1859,10 @@ test_dset_cork(hbool_t new_format) if(H5Dwrite(did1, tid1, sid, sid, H5P_DEFAULT, data) < 0) TEST_ERROR + /* Flush the dataset */ + if(H5Oflush(did1) < 0) + TEST_ERROR + /* Check cork status of the dataset */ if(H5Oare_mdc_flushes_disabled(did1, &corked) < 0) TEST_ERROR @@ -1919,6 +1923,10 @@ test_dset_cork(hbool_t new_format) if(H5Dwrite(did1, tid1, sid, sid, H5P_DEFAULT, data) < 0) TEST_ERROR + /* Refresh the dataset */ + if(H5Drefresh(did1) < 0) + TEST_ERROR + /* Check cork status of the dataset */ if(H5Oare_mdc_flushes_disabled(did1, &corked) < 0) TEST_ERROR diff --git a/testpar/t_cache.c b/testpar/t_cache.c index 9138395..7e32d51 100644 --- a/testpar/t_cache.c +++ b/testpar/t_cache.c @@ -7163,10 +7163,6 @@ smoke_check_6(int metadata_write_strategy) hbool_t success = TRUE; int i; int max_nerrors; - int min_count; - int max_count; - int min_idx; - int max_idx; hid_t fid = -1; H5F_t * file_ptr = NULL; H5C_t * cache_ptr = NULL; @@ -7225,9 +7221,6 @@ smoke_check_6(int metadata_write_strategy) } } - min_count = 100 / ((file_mpi_rank + 1) * (file_mpi_rank + 1)); - max_count = min_count + 50; - temp = virt_num_data_entries; virt_num_data_entries = NUM_DATA_ENTRIES; diff --git a/testpar/t_shapesame.c b/testpar/t_shapesame.c index ec46904..e66eaa7 100644 --- a/testpar/t_shapesame.c +++ b/testpar/t_shapesame.c @@ -4764,7 +4764,7 @@ void pause_proc(void) } printf("waiting(%ds) for file %s ...\n", time_int, greenlight); fflush(stdout); - HDsleep(time_int); + HDsleep(time_int); } MPI_Barrier(MPI_COMM_WORLD); } diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index fd47379..0b6faa8 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -45,5 +45,8 @@ add_subdirectory (${HDF5_TOOLS_SOURCE_DIR}/h5stat) #-- Add the h5dump and test executables add_subdirectory (${HDF5_TOOLS_SOURCE_DIR}/h5dump) +#-- Add the h5dump and test executables +add_subdirectory (${HDF5_TOOLS_SOURCE_DIR}/h5format_convert) + #-- Add the perform and test executables add_subdirectory (${HDF5_TOOLS_SOURCE_DIR}/perform) diff --git a/tools/h5format_convert/CMakeLists.txt b/tools/h5format_convert/CMakeLists.txt new file mode 100644 index 0000000..4f6fdea --- /dev/null +++ b/tools/h5format_convert/CMakeLists.txt @@ -0,0 +1,59 @@ +cmake_minimum_required (VERSION 3.1.0) +PROJECT (HDF5_TOOLS_H5FC) + +#----------------------------------------------------------------------------- +# Setup include Directories +#----------------------------------------------------------------------------- +INCLUDE_DIRECTORIES (${HDF5_TOOLS_DIR}/lib) + +# -------------------------------------------------------------------- +# Add the h5format_convert executables +# -------------------------------------------------------------------- +add_executable (h5format_convert ${HDF5_TOOLS_H5FC_SOURCE_DIR}/h5format_convert.c) +TARGET_NAMING (h5format_convert STATIC) +TARGET_C_PROPERTIES (h5format_convert STATIC " " " ") +target_link_libraries (h5format_convert ${HDF5_TOOLS_LIB_TARGET} ${HDF5_LIB_TARGET}) +set_target_properties (h5format_convert PROPERTIES FOLDER tools) + +set (H5_DEP_EXECUTABLES h5format_convert) + +if (BUILD_TESTING) + # -------------------------------------------------------------------- + # Add the h5format_convert test executables + # -------------------------------------------------------------------- + add_executable (h5fc_chk_idx ${HDF5_TOOLS_H5FC_SOURCE_DIR}/h5fc_chk_idx.c) + TARGET_NAMING (h5fc_chk_idx STATIC) + TARGET_C_PROPERTIES (h5fc_chk_idx STATIC " " " ") + target_link_libraries (h5fc_chk_idx ${HDF5_LIB_TARGET} ${HDF5_TOOLS_LIB_TARGET}) + set_target_properties (h5fc_chk_idx PROPERTIES FOLDER tools) + + if (HDF5_BUILD_GENERATORS) + add_executable (h5fc_gentest ${HDF5_TOOLS_H5FC_SOURCE_DIR}/h5fc_gentest.c) + TARGET_NAMING (h5fc_gentest STATIC) + TARGET_C_PROPERTIES (h5fc_gentest STATIC " " " ") + target_link_libraries (h5fc_gentest ${HDF5_LIB_TARGET} ${HDF5_TOOLS_LIB_TARGET}) + set_target_properties (h5fc_gentest PROPERTIES FOLDER generator/tools) + + #add_test (NAME h5fc_gentest COMMAND $) + endif (HDF5_BUILD_GENERATORS) + + include (CMakeTests.cmake) +endif (BUILD_TESTING) + +############################################################################## +############################################################################## +### I N S T A L L A T I O N ### +############################################################################## +############################################################################## + +#----------------------------------------------------------------------------- +# Rules for Installation of tools using make Install target +#----------------------------------------------------------------------------- + +#INSTALL_PROGRAM_PDB (h5format_convert ${HDF5_INSTALL_BIN_DIR} toolsapplications) + +install ( + TARGETS + h5format_convert + RUNTIME DESTINATION ${HDF5_INSTALL_BIN_DIR} COMPONENT toolsapplications +) diff --git a/tools/h5format_convert/CMakeTests.cmake b/tools/h5format_convert/CMakeTests.cmake new file mode 100644 index 0000000..0621b30 --- /dev/null +++ b/tools/h5format_convert/CMakeTests.cmake @@ -0,0 +1,473 @@ + +############################################################################## +############################################################################## +### T E S T I N G ### +############################################################################## +############################################################################## + + # -------------------------------------------------------------------- + # Copy all the HDF5 files from the test directory into the source directory + # -------------------------------------------------------------------- + set (HDF5_REFERENCE_FILES + h5fc_help.ddl + h5fc_nooption.ddl + h5fc_nonexistfile.ddl + h5fc_d_file.ddl + h5fc_dname.ddl + h5fc_nonexistdset_file.ddl + h5fc_v_non_chunked.ddl + h5fc_v_bt1.ddl + h5fc_v_ndata_bt1.ddl + h5fc_v_all.ddl + h5fc_v_n_1d.ddl + h5fc_v_n_all.ddl + h5fc_ext1_i.ddl + h5fc_ext1_s.ddl + h5fc_ext1_f.ddl + h5fc_ext2_if.ddl + h5fc_ext2_is.ddl + h5fc_ext2_sf.ddl + h5fc_ext3_isf.ddl + old_h5fc_ext1_i.ddl + old_h5fc_ext1_s.ddl + old_h5fc_ext1_f.ddl + old_h5fc_ext2_if.ddl + old_h5fc_ext2_is.ddl + old_h5fc_ext2_sf.ddl + old_h5fc_ext3_isf.ddl + h5fc_v_err.ddl + ) + set (HDF5_REFERENCE_TEST_FILES + h5fc_non_v3.h5 + h5fc_edge_v3.h5 + h5fc_ext_none.h5 + old_h5fc_ext_none.h5 + h5fc_ext1_i.h5 + h5fc_ext1_s.h5 + h5fc_ext1_f.h5 + h5fc_ext2_if.h5 + h5fc_ext2_is.h5 + h5fc_ext2_sf.h5 + h5fc_ext3_isf.h5 + old_h5fc_ext1_i.h5 + old_h5fc_ext1_s.h5 + old_h5fc_ext1_f.h5 + old_h5fc_ext2_if.h5 + old_h5fc_ext2_is.h5 + old_h5fc_ext2_sf.h5 + old_h5fc_ext3_isf.h5 + h5fc_err_level.h5 + ) + + file (MAKE_DIRECTORY "${PROJECT_BINARY_DIR}/testfiles") + add_custom_target(h5fc-files ALL COMMENT "Copying files needed by h5fc tests") + + foreach (ddl_file ${HDF5_REFERENCE_FILES}) + set (ddldest "${PROJECT_BINARY_DIR}/testfiles/${ddl_file}") + #message (STATUS " Translating ${ddl_file}") + add_custom_command ( + TARGET h5fc-files + POST_BUILD + COMMAND ${CMAKE_COMMAND} + ARGS -E copy_if_different ${HDF5_TOOLS_H5FC_SOURCE_DIR}/testfiles/${ddl_file} ${ddldest} + ) + endforeach (ddl_file ${HDF5_REFERENCE_FILES}) + + foreach (h5_file ${HDF5_REFERENCE_TEST_FILES}) + set (dest "${PROJECT_BINARY_DIR}/testfiles/${h5_file}") + #message (STATUS " Copying ${h5_file}") + add_custom_command ( + TARGET h5fc-files + POST_BUILD + COMMAND ${CMAKE_COMMAND} + ARGS -E copy_if_different ${HDF5_TOOLS_H5FC_SOURCE_DIR}/testfiles/${h5_file} ${dest} + ) + endforeach (h5_file ${HDF5_REFERENCE_TEST_FILES}) + +############################################################################## +############################################################################## +### T H E T E S T S M A C R O S ### +############################################################################## +############################################################################## + + MACRO (ADD_H5_OUTPUT testname resultfile resultcode testfile) + # If using memchecker add tests without using scripts + if (NOT HDF5_ENABLE_USING_MEMCHECKER) + add_test ( + NAME H5FC-${testname}-clear-objects + COMMAND ${CMAKE_COMMAND} + -E remove ./testfiles/${testname}.out ./testfiles/${testname}.out.err ./testfiles/outtmp.h5 + ) + if (NOT "${last_test}" STREQUAL "") + set_tests_properties (H5FC-${testname}-clear-objects PROPERTIES DEPENDS ${last_test}) + endif (NOT "${last_test}" STREQUAL "") + if (NOT "${testfile}" STREQUAL "") + add_test ( + NAME H5FC-${testname}-${testfile}-tmpfile + COMMAND ${CMAKE_COMMAND} + -E copy_if_different ${HDF5_TOOLS_H5FC_SOURCE_DIR}/testfiles/${testfile} ./testfiles/outtmp.h5 + ) + set_tests_properties (H5FC-${testname}-${testfile}-tmpfile PROPERTIES DEPENDS "H5FC-${testname}-clear-objects") + add_test ( + NAME H5FC-${testname}-${testfile} + COMMAND "${CMAKE_COMMAND}" + -D "TEST_PROGRAM=$" + -D "TEST_ARGS=${ARGN};outtmp.h5" + -D "TEST_FOLDER=${PROJECT_BINARY_DIR}/testfiles" + -D "TEST_OUTPUT=${testname}.out" + -D "TEST_EXPECT=${resultcode}" + -D "TEST_REFERENCE=${resultfile}" + -P "${HDF_RESOURCES_EXT_DIR}/runTest.cmake" + ) + set_tests_properties (H5FC-${testname}-${testfile} PROPERTIES DEPENDS "H5FC-${testname}-${testfile}-tmpfile") + set (last_test "H5FC-${testname}-${testfile}") + else (NOT "${testfile}" STREQUAL "") + add_test ( + NAME H5FC-${testname}-NA + COMMAND "${CMAKE_COMMAND}" + -D "TEST_PROGRAM=$" + -D "TEST_ARGS=${ARGN}" + -D "TEST_FOLDER=${PROJECT_BINARY_DIR}/testfiles" + -D "TEST_OUTPUT=${testname}.out" + -D "TEST_EXPECT=${resultcode}" + -D "TEST_REFERENCE=${resultfile}" + -P "${HDF_RESOURCES_EXT_DIR}/runTest.cmake" + ) + set_tests_properties (H5FC-${testname}-NA PROPERTIES DEPENDS "H5FC-${testname}-clear-objects") + set (last_test "H5FC-${testname}-NA") + endif (NOT "${testfile}" STREQUAL "") + endif (NOT HDF5_ENABLE_USING_MEMCHECKER) + ENDMACRO (ADD_H5_OUTPUT) + + MACRO (ADD_H5_TEST testname resultcode testfile) + # If using memchecker add tests without using scripts + if (NOT HDF5_ENABLE_USING_MEMCHECKER) + add_test ( + NAME H5FC-${testname}-clear-objects + COMMAND ${CMAKE_COMMAND} + -E remove ./testfiles/${testname}.out ./testfiles/${testname}.out.err ./testfiles/tmp.h5 + ) + if (NOT "${last_test}" STREQUAL "") + set_tests_properties (H5FC-${testname}-clear-objects PROPERTIES DEPENDS ${last_test}) + endif (NOT "${last_test}" STREQUAL "") + add_test ( + NAME H5FC-${testname}-tmpfile + COMMAND ${CMAKE_COMMAND} + -E copy_if_different ${HDF5_TOOLS_H5FC_SOURCE_DIR}/testfiles/${testfile} testfiles/tmp.h5 + ) + set_tests_properties (H5FC-${testname}-tmpfile PROPERTIES DEPENDS "H5FC-${testname}-clear-objects") + add_test ( + NAME H5FC-${testname} + COMMAND "${CMAKE_COMMAND}" + -D "TEST_PROGRAM=$" + -D "TEST_ARGS=${ARGN};./testfiles/tmp.h5" + -D "TEST_FOLDER=${PROJECT_BINARY_DIR}" + -D "TEST_OUTPUT=testfiles/${testname}.out" + -D "TEST_SKIP_COMPARE=TRUE" + -D "TEST_EXPECT=${resultcode}" + -P "${HDF_RESOURCES_EXT_DIR}/runTest.cmake" + ) + set_tests_properties (H5FC-${testname} PROPERTIES DEPENDS "H5FC-${testname}-tmpfile") + set (last_test "H5FC-${testname}") + endif (NOT HDF5_ENABLE_USING_MEMCHECKER) + ENDMACRO (ADD_H5_TEST) + + MACRO (ADD_H5_CHECK_IDX dependtest testname) + # If using memchecker add tests without using scripts + if (NOT HDF5_ENABLE_USING_MEMCHECKER) + add_test ( + NAME H5FC_CHECK_IDX-${testname} + COMMAND "$" "./testfiles/tmp.h5" "${ARGN}" + ) + set_tests_properties (H5FC_CHECK_IDX-${testname} PROPERTIES DEPENDS "H5FC-${dependtest}") + endif (NOT HDF5_ENABLE_USING_MEMCHECKER) + ENDMACRO (ADD_H5_CHECK_IDX) + + MACRO (ADD_H5_TEST_CHECK_IDX testname resultcode testfile) + # If using memchecker add tests without using scripts + if (NOT HDF5_ENABLE_USING_MEMCHECKER) + add_test ( + NAME H5FC-${testname}-clear-objects + COMMAND ${CMAKE_COMMAND} + -E remove ./testfiles/${testname}.out ./testfiles/${testname}.out.err ./testfiles/chktmp.h5 + ) + if (NOT "${last_test}" STREQUAL "") + set_tests_properties (H5FC-${testname}-clear-objects PROPERTIES DEPENDS ${last_test}) + endif (NOT "${last_test}" STREQUAL "") + add_test ( + NAME H5FC-${testname}-tmpfile + COMMAND ${CMAKE_COMMAND} + -E copy_if_different ${HDF5_TOOLS_H5FC_SOURCE_DIR}/testfiles/${testfile} testfiles/chktmp.h5 + ) + set_tests_properties (H5FC-${testname}-tmpfile PROPERTIES DEPENDS "H5FC-${testname}-clear-objects") + add_test ( + NAME H5FC-${testname} + COMMAND "${CMAKE_COMMAND}" + -D "TEST_PROGRAM=$" + -D "TEST_ARGS=-d;${ARGN};./testfiles/chktmp.h5" + -D "TEST_FOLDER=${PROJECT_BINARY_DIR}" + -D "TEST_OUTPUT=testfiles/${testname}.out" + -D "TEST_SKIP_COMPARE=TRUE" + -D "TEST_EXPECT=${resultcode}" + -P "${HDF_RESOURCES_EXT_DIR}/runTest.cmake" + ) + set_tests_properties (H5FC-${testname} PROPERTIES DEPENDS "H5FC-${testname}-tmpfile") + add_test ( + NAME H5FC_CHECK_IDX-${testname} + COMMAND "$" "./testfiles/chktmp.h5" "${ARGN}" + ) + set_tests_properties (H5FC_CHECK_IDX-${testname} PROPERTIES DEPENDS "H5FC-${testname}") + set (last_test "H5FC_CHECK_IDX-${testname}") + endif (NOT HDF5_ENABLE_USING_MEMCHECKER) + ENDMACRO (ADD_H5_TEST_CHECK_IDX) + + MACRO (ADD_H5_H5DUMP_CHECK testname) + # If using memchecker add tests without using scripts + if (NOT HDF5_ENABLE_USING_MEMCHECKER) + add_test ( + NAME H5FC-${testname}-clear-objects + COMMAND ${CMAKE_COMMAND} + -E remove ./testfiles/${testname}.out ./testfiles/${testname}.out.err ./testfiles/dmptmp.h5 + ) + if (NOT "${last_test}" STREQUAL "") + set_tests_properties (H5FC-${testname}-clear-objects PROPERTIES DEPENDS ${last_test}) + endif (NOT "${last_test}" STREQUAL "") + add_test ( + NAME H5FC-${testname}-tmpfile + COMMAND ${CMAKE_COMMAND} + -E copy_if_different ${HDF5_TOOLS_H5FC_SOURCE_DIR}/testfiles/${testname}.h5 testfiles/dmptmp.h5 + ) + set_tests_properties (H5FC-${testname}-tmpfile PROPERTIES DEPENDS "H5FC-${testname}-clear-objects") + add_test ( + NAME H5FC-${testname} + COMMAND "${CMAKE_COMMAND}" + -D "TEST_PROGRAM=$" + -D "TEST_ARGS=${ARGN};./testfiles/dmptmp.h5" + -D "TEST_FOLDER=${PROJECT_BINARY_DIR}" + -D "TEST_OUTPUT=testfiles/${testname}.out" + -D "TEST_SKIP_COMPARE=TRUE" + -D "TEST_EXPECT=0" + -P "${HDF_RESOURCES_EXT_DIR}/runTest.cmake" + ) + set_tests_properties (H5FC-${testname} PROPERTIES DEPENDS "H5FC-${testname}-tmpfile") + add_test ( + NAME H5FC_CHECK_DUMP-${testname} + COMMAND "${CMAKE_COMMAND}" + -D "TEST_PROGRAM=$" + -D "TEST_ARGS:STRING=-BH;./testfiles/dmptmp.h5" + -D "TEST_FOLDER=${PROJECT_BINARY_DIR}" + -D "TEST_OUTPUT=testfiles/${testname}.out" + -D "TEST_EXPECT=0" + -D "TEST_REFERENCE=testfiles/${testname}.ddl" + -P "${HDF_RESOURCES_EXT_DIR}/runTest.cmake" + ) + set_tests_properties (H5FC_CHECK_DUMP-${testname} PROPERTIES DEPENDS "H5FC-${testname}") + set (last_test "H5FC_CHECK_DUMP-${testname}") + endif (NOT HDF5_ENABLE_USING_MEMCHECKER) + ENDMACRO (ADD_H5_H5DUMP_CHECK) + +############################################################################## +############################################################################## +### T H E T E S T S ### +############################################################################## +############################################################################## + + if (HDF5_ENABLE_USING_MEMCHECKER) + # Remove any output file left over from previous test run + add_test ( + NAME H5FC-clearall-objects + COMMAND ${CMAKE_COMMAND} + -E remove + h5fc_help.out + h5fc_help.out.err + h5fc_nooption.out + h5fc_nooption.out.err + h5fc_nonexistfile.out + h5fc_nonexistfile.out.err + h5fc_d_file.out + h5fc_d_file.out.err + h5fc_d_file-d.out + h5fc_d_file-d.out.err + h5fc_dname.out + h5fc_dname.out.err + h5fc_nonexistdset_file.out + h5fc_nonexistdset_file.out.err + h5fc_v_non_chunked.out + h5fc_v_non_chunked.out.err + h5fc_v_bt1.out + h5fc_v_bt1.out.err + h5fc_v_ndata_bt1.out + h5fc_v_ndata_bt1.out.err + h5fc_v_all.out + h5fc_v_all.out.err + h5fc_v_n_1d.out + h5fc_v_n_1d.out.err + h5fc_v_n_all.out + h5fc_v_n_all.out.err + h5fc_ext1_i.out + h5fc_ext1_i.out.err + h5fc_ext1_s.out + h5fc_ext1_s.out.err + h5fc_ext1_f.out + h5fc_ext1_f.out.err + h5fc_ext2_if.out + h5fc_ext2_if.out.err + h5fc_ext2_is.out + h5fc_ext2_is.out.err + h5fc_ext2_sf.out + h5fc_ext2_sf.out.err + h5fc_ext3_isf.out + h5fc_ext3_isf.out.err + old_h5fc_ext1_i.out + old_h5fc_ext1_i.out.err + old_h5fc_ext1_s.out + old_h5fc_ext1_s.out.err + old_h5fc_ext1_f.out + old_h5fc_ext1_f.out.err + old_h5fc_ext2_if.out + old_h5fc_ext2_is.out.err + old_h5fc_ext2_is.out + old_h5fc_ext2_sf.out.err + old_h5fc_ext3_isf.out + old_h5fc_ext3_isf.out.err + outtmp.h5 + tmp.h5 + chktmp.h5 + dmptmp.h5 + ) + if (NOT "${last_test}" STREQUAL "") + set_tests_properties (H5FC-clearall-objects PROPERTIES DEPENDS ${last_test}) + endif (NOT "${last_test}" STREQUAL "") + set (last_test "H5FC-clearall-objects") + endif (HDF5_ENABLE_USING_MEMCHECKER) + +# h5format_convert --help +# h5format_convert (no options) +# h5format_convert nonexist.h5 (no options, file does not exist) + ADD_H5_OUTPUT (h5fc_help h5fc_help.ddl 0 "" --help) + ADD_H5_OUTPUT (h5fc_nooption h5fc_nooption.ddl 1 "") + ADD_H5_OUTPUT (h5fc_nonexistfile h5fc_nonexistfile.ddl 1 "" nonexist.h5) +# +# +# h5format_convert -d old_h5fc_ext_none.h5 (just -d option, file exists) +# h5format_convert --dname old_h5fc_ext_none.h5 (just --dname option, file exists) +# h5format_convert --dname (just --dname option) +# h5format_convert --dname=nonexist old_h5fc_ext_none.h5 (dataset does not exist, file exists) + ADD_H5_OUTPUT (h5fc_d_file-d h5fc_d_file.ddl 1 old_h5fc_ext_none.h5 -d) + ADD_H5_OUTPUT (h5fc_d_file h5fc_d_file.ddl 1 old_h5fc_ext_none.h5 --dname) + ADD_H5_OUTPUT (h5fc_dname h5fc_dname.ddl 1 "" --dname) + ADD_H5_OUTPUT (h5fc_nonexistdset_file h5fc_nonexistdset_file.ddl 1 old_h5fc_ext_none.h5 --dname=nonexist) +# +# +# +# h5format_convert -d /DSET_CONTIGUOUS -v old_h5fc_ext_none.h5 (verbose, contiguous dataset) +# h5format_convert -d /GROUP/DSET_BT2 --verbose old_h5fc_ext_none.h5 (verbose, bt1 dataset) +# h5format_convert -d /DSET_NDATA_BT2 -v -n old_h5fc_ext_none.h5 (verbose, noop, bt1+nodata dataset) +# h5format_convert -v old_h5fc_ext_none.h5 (verbose, all datasets) + ADD_H5_OUTPUT (h5fc_v_non_chunked h5fc_v_non_chunked.ddl 0 old_h5fc_ext_none.h5 -d /DSET_CONTIGUOUS -v) + ADD_H5_OUTPUT (h5fc_v_bt1 h5fc_v_bt1.ddl 0 old_h5fc_ext_none.h5 -d /GROUP/DSET_BT2 --verbose) + ADD_H5_OUTPUT (h5fc_v_ndata_bt1 h5fc_v_ndata_bt1.ddl 0 old_h5fc_ext_none.h5 -d /DSET_NDATA_BT2 -v -n) + ADD_H5_OUTPUT (h5fc_v_all h5fc_v_all.ddl 0 old_h5fc_ext_none.h5 -v) +# +# +# +# h5format_convert -d /DSET_EA -v -n h5fc_ext_none.h5 (verbose, noop, one ea dataset) +# h5format_convert -v -n h5fc_non_v3.h5 (verbose, noop, all datasets) + ADD_H5_OUTPUT (h5fc_v_n_1d h5fc_v_n_1d.ddl 0 h5fc_ext_none.h5 -d /DSET_EA -v -n) + ADD_H5_OUTPUT (h5fc_v_n_all h5fc_v_n_all.ddl 0 h5fc_non_v3.h5 -v -n) +# +# +# +# h5format_convert -v h5fc_err_level.h5 (error encountered in converting the dataset) + ADD_H5_OUTPUT (h5fc_v_err h5fc_v_err.ddl 1 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 +# h5format_convert -d /DSET_EA h5fc_ext_none.h5 +# h5format_convert -d /GROUP/DSET_NDATA_EA h5fc_ext_none.h5 +# h5format_convert -d /GROUP/DSET_BT2 h5fc_ext_none.h5 +# h5format_convert -d /DSET_NDATA_BT2 h5fc_ext_none.h5 +# h5format_convert -d /DSET_FA h5fc_ext_none.h5 +# h5format_convert -d /GROUP/DSET_FA h5fc_ext_none.h5 +# h5format_convert -d /DSET_NONE h5fc_ext_none.h5 +# h5format_convert -d /GROUP/DSET_NDATA_NONE h5fc_ext_none.h5 + ADD_H5_TEST_CHECK_IDX (h5fc_ext_none_EA 0 h5fc_ext_none.h5 /DSET_EA) +# + ADD_H5_TEST_CHECK_IDX (h5fc_ext_none_ND_EA 0 h5fc_ext_none.h5 /GROUP/DSET_NDATA_EA) +# + ADD_H5_TEST_CHECK_IDX (h5fc_ext_none_BT 0 h5fc_ext_none.h5 /GROUP/DSET_BT2) +# + ADD_H5_TEST_CHECK_IDX (h5fc_ext_none_ND_BT 0 h5fc_ext_none.h5 /DSET_NDATA_BT2) +# + ADD_H5_TEST_CHECK_IDX (h5fc_ext_none_FA 0 h5fc_ext_none.h5 /DSET_FA) +# + ADD_H5_TEST_CHECK_IDX (h5fc_ext_none_ND_FA 0 h5fc_ext_none.h5 /GROUP/DSET_NDATA_FA) +# + ADD_H5_TEST_CHECK_IDX (h5fc_ext_none_NONE 0 h5fc_ext_none.h5 /DSET_NONE) +# + ADD_H5_TEST_CHECK_IDX (h5fc_ext_none_ND_NONE 0 h5fc_ext_none.h5 /GROUP/DSET_NDATA_NONE) +# +# +# +# No output from tests: just check exit code +# h5format_convert -d /DSET_NDATA_BT2 old_h5fc_ext_none.h5 (v1-btree dataset) +# h5format_convert -d /DSET_CONTIGUOUS h5fc_non_v3.h5 (non-chunked dataset) + ADD_H5_TEST (old_h5fc_ext_none 0 old_h5fc_ext_none.h5 -d /DSET_NDATA_BT2) + ADD_H5_TEST (old_h5fc_ext_none_CONT 0 h5fc_non_v3.h5 -d /DSET_CONTIGUOUS) +# +# +# +# No output from tests: just check exit code +# h5format_convert -d /GROUP/DSET_BT2 -n h5fc_non_v3.h5 (noop, one dataset) +# h5format_convert -n h5fc_non_v3.h5 (noop, all datasets) + ADD_H5_TEST (h5fc_non_v3_BT 0 h5fc_non_v3.h5 -d /GROUP/DSET_BT2 -n) + ADD_H5_TEST (h5fc_non_v3-n 0 h5fc_non_v3.h5 -n) +# +# +# +# No output from tests: just check exit code +# h5format_convert h5fc_non_v3.h5 +# 1) convert all datasets +# 2) verify indexing types + ADD_H5_TEST (h5fc_non_v3 0 h5fc_non_v3.h5) + ADD_H5_CHECK_IDX (h5fc_non_v3 h5fc_non_v3-NEA /DSET_NDATA_EA) + ADD_H5_CHECK_IDX (h5fc_non_v3 h5fc_non_v3-NBT /DSET_NDATA_BT2) + ADD_H5_CHECK_IDX (h5fc_non_v3 h5fc_non_v3-BT /GROUP/DSET_BT2) + ADD_H5_CHECK_IDX (h5fc_non_v3 h5fc_non_v3-EA /GROUP/DSET_EA) +# +# +# +# No output from test: just check exit code +# h5format_convert h5fc_edge_v3.h5 +# 1) convert the chunked dataset (filter, no-filter-edge-chunk) +# 2) verify the indexing type + ADD_H5_TEST_CHECK_IDX (h5fc_edge_v3 0 h5fc_edge_v3.h5 /DSET_EDGE) +# +# + +# The following test files have messages in the superblock extension. +# Verify h5dump output for correctness after conversion + ADD_H5_H5DUMP_CHECK (h5fc_ext1_i) + ADD_H5_H5DUMP_CHECK (h5fc_ext1_s) + ADD_H5_H5DUMP_CHECK (h5fc_ext1_f) +# + ADD_H5_H5DUMP_CHECK (h5fc_ext2_if) + ADD_H5_H5DUMP_CHECK (h5fc_ext2_is) + ADD_H5_H5DUMP_CHECK (h5fc_ext2_sf) +# + ADD_H5_H5DUMP_CHECK (h5fc_ext3_isf) +# +# +# + ADD_H5_H5DUMP_CHECK (old_h5fc_ext1_i) + ADD_H5_H5DUMP_CHECK (old_h5fc_ext1_s) + ADD_H5_H5DUMP_CHECK (old_h5fc_ext1_f) +# + ADD_H5_H5DUMP_CHECK (old_h5fc_ext2_if) + ADD_H5_H5DUMP_CHECK (old_h5fc_ext2_is) + ADD_H5_H5DUMP_CHECK (old_h5fc_ext2_sf) +# + ADD_H5_H5DUMP_CHECK (old_h5fc_ext3_isf) diff --git a/tools/h5format_convert/h5format_convert.c b/tools/h5format_convert/h5format_convert.c index dadfd99..8ce28dd 100644 --- a/tools/h5format_convert/h5format_convert.c +++ b/tools/h5format_convert/h5format_convert.c @@ -79,11 +79,11 @@ static void usage(const char *prog) { HDfprintf(stdout, "usage: %s [OPTIONS] file_name\n", prog); HDfprintf(stdout, " OPTIONS\n"); - HDfprintf(stdout, " -h, --help Print a usage message and exit\n"); - HDfprintf(stdout, " -V, --version Print version number and exit\n"); - HDfprintf(stdout, " -v, --verbose Turn on verbose mode\n"); - HDfprintf(stdout, " -d dname, --dname=dataset_name Pathname for the dataset\n"); - HDfprintf(stdout, " -n, --noop Perform all the steps except the actual conversion\n"); + HDfprintf(stdout, " -h, --help Print a usage message and exit\n"); + HDfprintf(stdout, " -V, --version Print version number and exit\n"); + HDfprintf(stdout, " -v, --verbose Turn on verbose mode\n"); + HDfprintf(stdout, " -d dname, --dname=dataset_name Pathname for the dataset\n"); + HDfprintf(stdout, " -n, --noop Perform all the steps except the actual conversion\n"); HDfprintf(stdout, "\n"); HDfprintf(stdout, "Examples of use:\n"); HDfprintf(stdout, "\n"); diff --git a/tools/h5format_convert/testfiles/h5fc_d_file.ddl b/tools/h5format_convert/testfiles/h5fc_d_file.ddl index ad7a2f4..38fc432 100644 --- a/tools/h5format_convert/testfiles/h5fc_d_file.ddl +++ b/tools/h5format_convert/testfiles/h5fc_d_file.ddl @@ -1,10 +1,10 @@ usage: h5format_convert [OPTIONS] file_name OPTIONS - -h, --help Print a usage message and exit - -V, --version Print version number and exit - -v, --verbose Turn on verbose mode - -d dname, --dname=dataset_name Pathname for the dataset - -n, --noop Perform all the steps except the actual conversion + -h, --help Print a usage message and exit + -V, --version Print version number and exit + -v, --verbose Turn on verbose mode + -d dname, --dname=dataset_name Pathname for the dataset + -n, --noop Perform all the steps except the actual conversion Examples of use: diff --git a/tools/h5format_convert/testfiles/h5fc_dname.ddl b/tools/h5format_convert/testfiles/h5fc_dname.ddl index 0de42cb..48564b7 100644 --- a/tools/h5format_convert/testfiles/h5fc_dname.ddl +++ b/tools/h5format_convert/testfiles/h5fc_dname.ddl @@ -1,10 +1,10 @@ usage: h5format_convert [OPTIONS] file_name OPTIONS - -h, --help Print a usage message and exit - -V, --version Print version number and exit - -v, --verbose Turn on verbose mode - -d dname, --dname=dataset_name Pathname for the dataset - -n, --noop Perform all the steps except the actual conversion + -h, --help Print a usage message and exit + -V, --version Print version number and exit + -v, --verbose Turn on verbose mode + -d dname, --dname=dataset_name Pathname for the dataset + -n, --noop Perform all the steps except the actual conversion Examples of use: diff --git a/tools/h5format_convert/testfiles/h5fc_help.ddl b/tools/h5format_convert/testfiles/h5fc_help.ddl index aef8c63..bc0229c 100644 --- a/tools/h5format_convert/testfiles/h5fc_help.ddl +++ b/tools/h5format_convert/testfiles/h5fc_help.ddl @@ -1,10 +1,10 @@ usage: h5format_convert [OPTIONS] file_name OPTIONS - -h, --help Print a usage message and exit - -V, --version Print version number and exit - -v, --verbose Turn on verbose mode - -d dname, --dname=dataset_name Pathname for the dataset - -n, --noop Perform all the steps except the actual conversion + -h, --help Print a usage message and exit + -V, --version Print version number and exit + -v, --verbose Turn on verbose mode + -d dname, --dname=dataset_name Pathname for the dataset + -n, --noop Perform all the steps except the actual conversion Examples of use: diff --git a/tools/h5format_convert/testfiles/h5fc_nooption.ddl b/tools/h5format_convert/testfiles/h5fc_nooption.ddl index aef8c63..bc0229c 100644 --- a/tools/h5format_convert/testfiles/h5fc_nooption.ddl +++ b/tools/h5format_convert/testfiles/h5fc_nooption.ddl @@ -1,10 +1,10 @@ usage: h5format_convert [OPTIONS] file_name OPTIONS - -h, --help Print a usage message and exit - -V, --version Print version number and exit - -v, --verbose Turn on verbose mode - -d dname, --dname=dataset_name Pathname for the dataset - -n, --noop Perform all the steps except the actual conversion + -h, --help Print a usage message and exit + -V, --version Print version number and exit + -v, --verbose Turn on verbose mode + -d dname, --dname=dataset_name Pathname for the dataset + -n, --noop Perform all the steps except the actual conversion Examples of use: diff --git a/tools/h5jam/h5jam.c b/tools/h5jam/h5jam.c index 4509734..ae45714 100644 --- a/tools/h5jam/h5jam.c +++ b/tools/h5jam/h5jam.c @@ -21,7 +21,7 @@ /* Name of tool */ #define PROGRAMNAME "h5jam" -hsize_t write_pad (int, hsize_t); +herr_t write_pad(int ofile, hsize_t old_where, hsize_t *new_where); hsize_t compute_user_block_size (hsize_t); hsize_t copy_some_to_file (int, int, hsize_t, hsize_t, ssize_t); void parse_command_line (int, const char *[]); @@ -380,7 +380,13 @@ main (int argc, const char *argv[]) where = copy_some_to_file (ufid, ofid, (hsize_t) 0, startub, (ssize_t) - 1); /* pad the ub */ - where = write_pad (ofid, where); + if(write_pad(ofid, where, &where) < 0) { + error_msg("Can't pad file \"%s\"\n", output_file); + HDclose (h5fid); + HDclose (ufid); + HDclose (ofid); + leave (EXIT_FAILURE); + } /* end if */ if(ub_file) HDfree (ub_file); @@ -534,25 +540,32 @@ compute_user_block_size(hsize_t ublock_size) /* * Write zeroes to fill the file from 'where' to 512, 1024, etc. bytes. * - * Returns the size of the padded file. + * Sets new_where to the size of the padded file and + * returns SUCCEED/FAIL. */ -hsize_t -write_pad(int ofile, hsize_t where) +herr_t +write_pad(int ofile, hsize_t old_where, hsize_t *new_where) { unsigned int i; char buf[1]; hsize_t psize; + HDassert(new_where); + buf[0] = '\0'; - HDlseek(ofile, (off_t) where, SEEK_SET); + HDlseek(ofile, (off_t)old_where, SEEK_SET); - psize = compute_user_block_size (where); - psize -= where; + psize = compute_user_block_size(old_where); + psize -= old_where; for(i = 0; i < psize; i++) - HDwrite (ofile, buf, 1); + if(HDwrite(ofile, buf, 1) < 0) + return FAIL; - return(where + psize); /* the new size of the file. */ -} + /* Set the new size of the file. */ + *new_where = old_where + psize; + + return SUCCEED; +} /* end write_pad() */ diff --git a/tools/h5jam/h5jamgentest.c b/tools/h5jam/h5jamgentest.c index d3166b5..7ae3169 100644 --- a/tools/h5jam/h5jamgentest.c +++ b/tools/h5jam/h5jamgentest.c @@ -275,20 +275,23 @@ gent_ub(const char * filename, size_t ub_size, size_t ub_fill) /* If a user block is being used, write to it here */ if(ub_size > 0) { - HDassert(ub_size <= BUF_SIZE); + ssize_t nbytes; - fd = HDopen(filename, O_RDWR, 0); - HDassert(fd >= 0); + HDassert(ub_size <= BUF_SIZE); - /* fill buf with pattern */ - HDmemset(buf, '\0', ub_size); - bp = buf; - for (u = 0; u < ub_fill; u++) - *bp++ = pattern[u % 10]; + fd = HDopen(filename, O_RDWR, 0); + HDassert(fd >= 0); - HDwrite(fd, buf, ub_size); + /* fill buf with pattern */ + HDmemset(buf, '\0', ub_size); + bp = buf; + for (u = 0; u < ub_fill; u++) + *bp++ = pattern[u % 10]; - HDclose(fd); + nbytes = HDwrite(fd, buf, ub_size); + HDassert(nbytes >= 0); + + HDclose(fd); } } @@ -299,6 +302,7 @@ create_textfile(const char *name, size_t size) int fd; size_t i; char *bp; + ssize_t nbytes; fd = HDcreat(name,0777); HDassert(fd >= 0); @@ -310,7 +314,8 @@ create_textfile(const char *name, size_t size) for(i = 0; i < size; i++) *bp++ = pattern[i % 10]; - HDwrite(fd, buf, size); + nbytes = HDwrite(fd, buf, size); + HDassert(nbytes >= 0); HDfree(buf); diff --git a/tools/h5repack/h5repack_main.c b/tools/h5repack/h5repack_main.c index 7745860..e903435 100644 --- a/tools/h5repack/h5repack_main.c +++ b/tools/h5repack/h5repack_main.c @@ -264,14 +264,24 @@ int read_info(const char *filename, pack_opt_t *options) { i = 0; c = '0'; while (c != ' ') { - fscanf(fp, "%c", &c); + if(fscanf(fp, "%c", &c) < 0 && HDferror(fp)) { + error_msg("fscanf error\n"); + h5tools_setstatus(EXIT_FAILURE); + ret_value = EXIT_FAILURE; + goto done; + } /* end if */ if (HDfeof(fp)) break; } c = '0'; /* go until end */ while (c != ' ') { - fscanf(fp, "%c", &c); + if(fscanf(fp, "%c", &c) < 0 && HDferror(fp)) { + error_msg("fscanf error\n"); + h5tools_setstatus(EXIT_FAILURE); + ret_value = EXIT_FAILURE; + goto done; + } /* end if */ comp_info[i] = c; i++; if (HDfeof(fp)) @@ -282,10 +292,10 @@ int read_info(const char *filename, pack_opt_t *options) { comp_info[i - 1] = '\0'; /*cut the last " */ if (h5repack_addfilter(comp_info, options) == -1) { - error_msg("could not add compression option\n"); - h5tools_setstatus(EXIT_FAILURE); - ret_value = EXIT_FAILURE; - goto done; + error_msg("could not add compression option\n"); + h5tools_setstatus(EXIT_FAILURE); + ret_value = EXIT_FAILURE; + goto done; } } /*------------------------------------------------------------------------- @@ -298,14 +308,24 @@ int read_info(const char *filename, pack_opt_t *options) { i = 0; c = '0'; while (c != ' ') { - fscanf(fp, "%c", &c); + if(fscanf(fp, "%c", &c) < 0 && HDferror(fp)) { + error_msg("fscanf error\n"); + h5tools_setstatus(EXIT_FAILURE); + ret_value = EXIT_FAILURE; + goto done; + } /* end if */ if (HDfeof(fp)) break; } c = '0'; /* go until end */ while (c != ' ') { - fscanf(fp, "%c", &c); + if(fscanf(fp, "%c", &c) < 0 && HDferror(fp)) { + error_msg("fscanf error\n"); + h5tools_setstatus(EXIT_FAILURE); + ret_value = EXIT_FAILURE; + goto done; + } /* end if */ comp_info[i] = c; i++; if (HDfeof(fp)) @@ -316,10 +336,10 @@ int read_info(const char *filename, pack_opt_t *options) { comp_info[i - 1] = '\0'; /*cut the last " */ if (h5repack_addlayout(comp_info, options) == -1) { - error_msg("could not add chunck option\n"); - h5tools_setstatus(EXIT_FAILURE); - ret_value = EXIT_FAILURE; - goto done; + error_msg("could not add chunck option\n"); + h5tools_setstatus(EXIT_FAILURE); + ret_value = EXIT_FAILURE; + goto done; } } /*------------------------------------------------------------------------- diff --git a/tools/lib/h5diff.c b/tools/lib/h5diff.c index 46dcf6f..b1637a8 100644 --- a/tools/lib/h5diff.c +++ b/tools/lib/h5diff.c @@ -663,7 +663,8 @@ hsize_t h5diff(const char *fname1, { #ifdef H5_HAVE_ASPRINTF /* Use the asprintf() routine, since it does what we're trying to do below */ - HDasprintf(&obj1fullname, "/%s", objname1); + if(HDasprintf(&obj1fullname, "/%s", objname1) < 0) + goto out; #else /* H5_HAVE_ASPRINTF */ /* (malloc 2 more for "/" and end-of-line) */ obj1fullname = (char*)HDmalloc(HDstrlen(objname1) + 2); @@ -679,7 +680,8 @@ hsize_t h5diff(const char *fname1, { #ifdef H5_HAVE_ASPRINTF /* Use the asprintf() routine, since it does what we're trying to do below */ - HDasprintf(&obj2fullname, "/%s", objname2); + if(HDasprintf(&obj2fullname, "/%s", objname2) < 0) + goto out; #else /* H5_HAVE_ASPRINTF */ /* (malloc 2 more for "/" and end-of-line) */ obj2fullname = (char*)HDmalloc(HDstrlen(objname2) + 2); @@ -1186,7 +1188,8 @@ hsize_t diff_match(hid_t file1_id, const char *grp1, trav_info_t *info1, /* make full path for obj1 */ #ifdef H5_HAVE_ASPRINTF /* Use the asprintf() routine, since it does what we're trying to do below */ - HDasprintf(&obj1_fullpath, "%s%s", grp1_path, table->objs[i].name); + if(HDasprintf(&obj1_fullpath, "%s%s", grp1_path, table->objs[i].name) < 0) + goto out; #else /* H5_HAVE_ASPRINTF */ obj1_fullpath = (char*)HDmalloc(HDstrlen(grp1_path) + HDstrlen(table->objs[i].name) + 1); HDstrcpy(obj1_fullpath, grp1_path); @@ -1196,7 +1199,8 @@ hsize_t diff_match(hid_t file1_id, const char *grp1, trav_info_t *info1, /* make full path for obj2 */ #ifdef H5_HAVE_ASPRINTF /* Use the asprintf() routine, since it does what we're trying to do below */ - HDasprintf(&obj2_fullpath, "%s%s", grp2_path, table->objs[i].name); + if(HDasprintf(&obj2_fullpath, "%s%s", grp2_path, table->objs[i].name) < 0) + goto out; #else /* H5_HAVE_ASPRINTF */ obj2_fullpath = (char*)HDmalloc(HDstrlen(grp2_path) + HDstrlen(table->objs[i].name) + 1); HDstrcpy(obj2_fullpath, grp2_path); @@ -1493,6 +1497,7 @@ hsize_t diff_match(hid_t file1_id, const char *grp1, trav_info_t *info1, } #endif /* H5_HAVE_PARALLEL */ +out: /* free table */ if (table) trav_table_free(table); diff --git a/tools/lib/h5diff_attr.c b/tools/lib/h5diff_attr.c index 2cda28c..2b6e080 100644 --- a/tools/lib/h5diff_attr.c +++ b/tools/lib/h5diff_attr.c @@ -75,12 +75,14 @@ static void table_attrs_free( table_attrs_t *table ) { unsigned int i; - if (table) { - if (table->attrs) { - for (i = 0; i < table->nattrs; i++) { - if (table->attrs[i].name) { - HDfree(table->attrs[i].name); - } + if (table) + { + if(table->attrs) + { + for(i = 0; i < table->nattrs; i++) + { + if(table->attrs[i].name) + HDfree(table->attrs[i].name ); } /* end for */ HDfree(table->attrs); table->attrs = NULL; diff --git a/tools/perform/iopipe.c b/tools/perform/iopipe.c index a04ef82..6ac7ccb 100644 --- a/tools/perform/iopipe.c +++ b/tools/perform/iopipe.c @@ -135,8 +135,13 @@ synchronize (void) #if defined(H5_HAVE_WIN32_API) && ! defined(__CYGWIN__) _flushall(); #else - HDsystem("sync"); - HDsystem("df >/dev/null"); + int status; + + status = HDsystem("sync"); + HDassert(status >= 0); + + status = HDsystem("df >/dev/null"); + HDassert(status >= 0); #endif #endif } -- cgit v0.12