summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn Mainzer <mainzer@hdfgroup.org>2008-05-31 10:48:52 (GMT)
committerJohn Mainzer <mainzer@hdfgroup.org>2008-05-31 10:48:52 (GMT)
commitbb57e9a9406dec8c3ae44fbcc6fa6e4e8f716c4a (patch)
tree7f8ae8fb465d8d31e33bee0780ba7649d04cbda2
parent06af1e93904ef055947df07069e4267489c85c91 (diff)
downloadhdf5-bb57e9a9406dec8c3ae44fbcc6fa6e4e8f716c4a.zip
hdf5-bb57e9a9406dec8c3ae44fbcc6fa6e4e8f716c4a.tar.gz
hdf5-bb57e9a9406dec8c3ae44fbcc6fa6e4e8f716c4a.tar.bz2
[svn-r15113] This checkin contains:
* Updates to test opening of a file created with journaling, along with associated debugging modifications. (Mike M. To get journal deletion to work correctly, I had to modify H5C2_jb__init() to allocate a buffer for the journal file name and copy it into the buffer. Similarly, I had to modify to H5C2_jb__takedown() to free the buffer. The fix was hurried, and should be reviewed. Also, a similar fix is probably in order for the HDF5 file name.) * Fix for the bug Albert reported on Linew. * An attempt to apply the changes Quincey requested to the loc_id parameters to the FUNC_ENTER_API_META macro calls in: H5Gmove2(), (src_loc_id --> dst_loc_id) H5Lcopy(), (src_loc_id --> dst_loc_id) H5Lmove(), (src_loc_id --> dst_loc_id) H5Glink2(), (cur_loc_id --> new_loc_id) H5Lmove() (cur_loc_id --> new_loc_id) However, with the exception of the requested change to H5Gmove2(), all these chages caused us to fail the regression tests. Thus only the H5Gmove2() change is made. Several caviats and warnings: * If you build and test this checkin, it will fail on the on the test for trecover. This showed up after I updated my project, so initially I thought I had broken something. However, after examining the problem for a while, I thought to checkout the version prior to this checkin, and test to see if the problem appeared. It did (under serial on phoenix, and parallel on Kagiso), so I am going ahead with this checkin regardless under the assumption that it is orthoginal to my changes. * Low level testing for the journaling feature of the metadata cache is not complete. The coverage of the existing tests is good enough that I don't expect anything major, but don't be surprised if you run into problems around the edges. In particular, enabling and disabling journaling while the file is open has not been tested at all. Suggest we stay away from this until it gets at least a once over. * The metadata journaling smoke check tests in cache2_journal.c are still configured to generate the architype files used to check journal output. This can be turned off any time, but given Quincey's constaints on test file size, I have to write code to skip the tests if the architype files are missing, and then put compressed versions of the architype files in svn before I do so. Unfortunately, there is no time before I leave. * I left a good bit of debugging code in both the journaling code proper, and the associated test code. It should all be #if 0'ed out at present, but if you run into it, you know what is going on. Needless to say, I'll delete it when I finish testing. * I was not able to reproduce the bug Albert observed on RedStorm locally, so I don't have a fix for it. That said, I touched some things that could have caused it, so it is possible that I fixed it by accident. Testing: Before I updated, I was able to build and test serial on Phoenix and Linew, and parallel on Kagiso without errors in the regression tests. As discussed above, after the update, I failed in the test for trecover in a serial build and test on Phoenix, and parallel build and test on Kagiso. Linew is slow, so I didn't attempt a test there. Since the same failures appear in the verion prior to this checkin, I am going ahead with the checkin regardless on the assumption that the problem is orthoginal to my changes.
-rw-r--r--src/H5C2journal.c167
-rw-r--r--src/H5F.c10
-rw-r--r--src/H5Fprivate.h2
-rw-r--r--src/H5Gdeprec.c2
-rw-r--r--test/cache2_journal.c431
5 files changed, 547 insertions, 65 deletions
diff --git a/src/H5C2journal.c b/src/H5C2journal.c
index 41bbc84..dbf78ce 100644
--- a/src/H5C2journal.c
+++ b/src/H5C2journal.c
@@ -337,44 +337,44 @@ H5C2_end_journaling(H5F_t * f,
HDassert( f != NULL );
HDassert( cache_ptr != NULL );
HDassert( cache_ptr->magic == H5C2__H5C2_T_MAGIC );
- /* HDassert( cache_ptr->mdj_enabled == TRUE ); */
- HDassert( cache_ptr->trans_in_progress == FALSE );
- HDassert( cache_ptr->tl_len == 0 );
- HDassert( cache_ptr->tl_size == 0 );
- HDassert( cache_ptr->tl_head_ptr == NULL );
- HDassert( cache_ptr->tl_tail_ptr == NULL );
- if ( ! cache_ptr->mdj_enabled ) {
+ if ( cache_ptr->mdj_enabled ) {
- HGOTO_ERROR(H5E_CACHE, H5E_CANTJOURNAL, FAIL, \
- "metadata journaling not enabled on entry.")
- }
+ HDassert( cache_ptr->mdj_enabled );
+ HDassert( cache_ptr->trans_in_progress == FALSE );
+ HDassert( cache_ptr->tl_len == 0 );
+ HDassert( cache_ptr->tl_size == 0 );
+ HDassert( cache_ptr->tl_head_ptr == NULL );
+ HDassert( cache_ptr->tl_tail_ptr == NULL );
- result = H5C2_flush_cache(f, dxpl_id, H5C2__NO_FLAGS_SET);
+ result = H5C2_flush_cache(f, dxpl_id, H5C2__NO_FLAGS_SET);
- if ( result < 0 ) {
+ if ( result < 0 ) {
- HGOTO_ERROR(H5E_CACHE, H5E_CANTJOURNAL, FAIL, \
- "H5C2_flush_cache() failed.")
- }
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTJOURNAL, FAIL, \
+ "H5C2_flush_cache() failed.")
+ }
- result = H5C2_unmark_journaling_in_progress(f, dxpl_id, cache_ptr);
+ HDassert( cache_ptr->mdj_enabled );
- if ( result < 0 ) {
+ result = H5C2_unmark_journaling_in_progress(f, dxpl_id, cache_ptr);
- HGOTO_ERROR(H5E_CACHE, H5E_CANTJOURNAL, FAIL, \
- "H5C2_unmark_journaling_in_progress() failed.")
- }
+ if ( result < 0 ) {
- result = H5C2_jb__takedown(&(cache_ptr->mdj_jbrb));
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTJOURNAL, FAIL, \
+ "H5C2_unmark_journaling_in_progress() failed.")
+ }
- if ( result < 0 ) {
+ result = H5C2_jb__takedown(&(cache_ptr->mdj_jbrb));
- HGOTO_ERROR(H5E_CACHE, H5E_CANTJOURNAL, FAIL, \
- "H5C2_jb__takedown() failed.")
- }
+ if ( result < 0 ) {
+
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTJOURNAL, FAIL, \
+ "H5C2_jb__takedown() failed.")
+ }
- cache_ptr->mdj_enabled = FALSE;
+ cache_ptr->mdj_enabled = FALSE;
+ }
done:
@@ -1957,6 +1957,7 @@ H5C2_unmark_journaling_in_progress(H5F_t * f,
HDassert( f != NULL );
HDassert( f->shared != NULL );
HDassert( f->shared->mdc_jrnl_enabled );
+ HDassert( f->shared->cache2 == cache_ptr );
HDassert( cache_ptr );
HDassert( cache_ptr->magic == H5C2__H5C2_T_MAGIC );
HDassert( cache_ptr->mdj_conf_block_addr != HADDR_UNDEF );
@@ -2024,9 +2025,9 @@ H5C2_unmark_journaling_in_progress(H5F_t * f,
* files -- a point we haven't discussed. We should do so.
*/
- if ( H5Fflush(f->file_id, H5F_SCOPE_GLOBAL) < 0 ) {
+ if ( H5F_flush(f, dxpl_id, H5F_SCOPE_GLOBAL, H5F_FLUSH_NONE) < 0 ) {
- HGOTO_ERROR(H5E_CACHE, H5E_CANTJOURNAL, FAIL, "H5Fflush() failed.")
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTJOURNAL, FAIL, "H5F_flush() failed.")
}
done:
@@ -2060,10 +2061,13 @@ done:
herr_t
H5C2_jb__flush_full_buffers(H5C2_jbrb_t * struct_ptr)
{
+ hbool_t verbose = FALSE;
int result;
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI(H5C2_jb__flush_full_buffers, FAIL)
+
+ if ( verbose ) { HDfprintf(stdout, "%s: entering.\n", FUNC); }
/* this asserts that at least one buffer is in use */
HDassert(struct_ptr->bufs_in_use > 0);
@@ -2077,9 +2081,16 @@ H5C2_jb__flush_full_buffers(H5C2_jbrb_t * struct_ptr)
/* can write solid chunk from get up to, but not
* including, put
*/
- HDwrite(struct_ptr->journal_file_fd,
- (*struct_ptr->buf)[struct_ptr->get],
- (struct_ptr->put - struct_ptr->get) * struct_ptr->buf_size);
+ result = HDwrite(struct_ptr->journal_file_fd,
+ (*struct_ptr->buf)[struct_ptr->get],
+ (struct_ptr->put - struct_ptr->get) * struct_ptr->buf_size);
+
+ if ( result == -1 ) {
+
+ if ( verbose ) { HDfprintf(stdout, "%s: write failed 1.\n", FUNC); }
+ HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, \
+ "Journal file write failed (1).")
+ }
struct_ptr->bufs_in_use -= (struct_ptr->put - struct_ptr->get);
struct_ptr->rb_free_space += (struct_ptr->put - struct_ptr->get) * struct_ptr->buf_size;
@@ -2095,8 +2106,9 @@ H5C2_jb__flush_full_buffers(H5C2_jbrb_t * struct_ptr)
if ( result == -1 ) {
+ if ( verbose ) { HDfprintf(stdout, "%s: write failed 2.\n", FUNC); }
HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, \
- "Journal file write failed.")
+ "Journal file write failed (2).")
}
struct_ptr->bufs_in_use -= (struct_ptr->num_bufs - struct_ptr->get);
@@ -2114,8 +2126,11 @@ H5C2_jb__flush_full_buffers(H5C2_jbrb_t * struct_ptr)
if ( result == -1 ) {
+ if ( verbose ) {
+ HDfprintf(stdout, "%s: write failed 3.\n", FUNC);
+ }
HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, \
- "Journal file write failed.")
+ "Journal file write failed(3).")
} /* end if */
struct_ptr->rb_free_space += (struct_ptr->put * struct_ptr->buf_size);
@@ -2145,6 +2160,8 @@ H5C2_jb__flush_full_buffers(H5C2_jbrb_t * struct_ptr)
done:
+ if ( verbose ) { HDfprintf(stdout, "%s: exiting.\n", FUNC); }
+
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5C2_jb__flush_full_buffers */
@@ -2169,12 +2186,15 @@ done:
herr_t
H5C2_jb__flush(H5C2_jbrb_t * struct_ptr)
{
+ hbool_t verbose = FALSE;
int result;
int i;
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI(H5C2_jb__flush, FAIL)
+ if ( verbose ) { HDfprintf(stdout, "%s: entering.\n", FUNC); }
+
/* Check Arguments */
HDassert(struct_ptr);
HDassert(struct_ptr->magic == H5C2__H5C2_JBRB_T_MAGIC);
@@ -2183,6 +2203,7 @@ H5C2_jb__flush(H5C2_jbrb_t * struct_ptr)
if (struct_ptr->trans_in_prog != FALSE) {
+ if ( verbose ) { HDfprintf(stdout, "%s: trans in progress.\n", FUNC); }
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
"Attempt to flush buffers with transaction in progress.")
} /* end if */
@@ -2196,8 +2217,9 @@ H5C2_jb__flush(H5C2_jbrb_t * struct_ptr)
if ( result == -1 ) {
+ if ( verbose ) { HDfprintf(stdout, "%s: write failed 1.\n", FUNC); }
HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, \
- "Journal file write failed.")
+ "Journal file write failed(1).")
}
struct_ptr->bufs_in_use -= (struct_ptr->num_bufs - struct_ptr->get);
@@ -2215,8 +2237,9 @@ H5C2_jb__flush(H5C2_jbrb_t * struct_ptr)
if ( result == -1 ) {
+ if ( verbose ) { HDfprintf(stdout, "%s: write failed 2.\n", FUNC); }
HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, \
- "Journal file write failed.")
+ "Journal file write failed (2).")
}
struct_ptr->bufs_in_use -= (struct_ptr->put - struct_ptr->get);
@@ -2234,8 +2257,9 @@ H5C2_jb__flush(H5C2_jbrb_t * struct_ptr)
if ( result == -1 ) {
+ if ( verbose ) { HDfprintf(stdout, "%s: write failed 3.\n", FUNC); }
HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, \
- "Journal file write failed.")
+ "Journal file write failed (3).")
}
struct_ptr->bufs_in_use--;
@@ -2251,6 +2275,10 @@ H5C2_jb__flush(H5C2_jbrb_t * struct_ptr)
fsync is being used. */
if ( fsync(struct_ptr->journal_file_fd) != 0 ) {
+ if ( verbose ) {
+ HDfprintf(stdout, "%s: fsync() failed. errno = %d (%s)\n",
+ FUNC, errno, strerror(errno));
+ }
HGOTO_ERROR(H5E_IO, H5E_SYNCFAIL, FAIL, "Journal file sync failed.")
} /* end if */
@@ -2279,6 +2307,8 @@ H5C2_jb__flush(H5C2_jbrb_t * struct_ptr)
done:
+ if ( verbose ) { HDfprintf(stdout, "%s: exiting.\n", FUNC); }
+
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5C2_jb__flush */
@@ -2615,7 +2645,15 @@ H5C2_jb__init(H5C2_jbrb_t * struct_ptr,
} /* end if */
/* Initialize Fields of H5C2_jbrb_t structure */
+#if 0 /* JRM */ /* initial version */
struct_ptr->jname = journal_file_name;
+#else /* JRM */ /* revised version */
+ /* this should be modified to check error returns, etc. Also, should
+ * probably do the same with the HDF5 file name.
+ */
+ struct_ptr->jname = (char *)H5MM_malloc(strlen(journal_file_name) + 1);
+ HDstrcpy(struct_ptr->jname, journal_file_name);
+#endif /* JRM */
struct_ptr->hdf5_file_name = HDF5_file_name;
struct_ptr->buf_size = buf_size;
struct_ptr->num_bufs = num_bufs;
@@ -3245,9 +3283,15 @@ H5C2_jb__takedown(H5C2_jbrb_t * struct_ptr)
{
herr_t ret_value = SUCCEED;
+ hbool_t verbose = FALSE;
FUNC_ENTER_NOAPI(H5C2_jb__takedown, FAIL)
+ if ( verbose ) {
+
+ HDfprintf(stdout, "%s: entering.\n", FUNC);
+ }
+
/* Check Arguments */
HDassert(struct_ptr);
HDassert(struct_ptr->magic == H5C2__H5C2_JBRB_T_MAGIC);
@@ -3255,6 +3299,10 @@ H5C2_jb__takedown(H5C2_jbrb_t * struct_ptr)
/* Verify that the journal buffers are empty */
if ( struct_ptr->bufs_in_use != 0 ) {
+ if ( verbose ) {
+ HDfprintf(stdout, "%s: Attempt to takedown with non-empty buffers.\n",
+ FUNC);
+ }
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
"Attempt to takedown with non-empty buffers.")
} /* end if */
@@ -3262,6 +3310,11 @@ H5C2_jb__takedown(H5C2_jbrb_t * struct_ptr)
/* Verify that the journal file has been truncated */
if (struct_ptr->journal_is_empty != TRUE) {
+ if ( verbose ) {
+ HDfprintf(stdout,
+ "%s: Attempt to takedown with journal file not truncated.\n",
+ FUNC);
+ }
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
"Attempt to takedown with journal file not truncated.")
} /* end if */
@@ -3269,21 +3322,47 @@ H5C2_jb__takedown(H5C2_jbrb_t * struct_ptr)
/* Close and delete the journal file associated with struct_ptr */
if ( HDclose(struct_ptr->journal_file_fd) < 0 ) {
+ if ( verbose ) {
+ HDfprintf(stdout,
+ "%s: journal file close failed. errno = %d(%s), fd = %d.\n",
+ FUNC, errno, strerror(errno), struct_ptr->journal_file_fd);
+ }
HGOTO_ERROR(H5E_IO, H5E_CLOSEERROR, FAIL, "Jounal file close failed.")
} /* end if */
- if (remove(struct_ptr->jname) < 0) {
+ if ( HDremove(struct_ptr->jname) < 0) {
+ if ( verbose ) {
+ HDfprintf(stdout,
+ "%s: journal file remove failed. errno = %d(%s).\n",
+ FUNC, errno, strerror(errno));
+ }
HGOTO_ERROR(H5E_IO, H5E_REMOVEFAIL, FAIL, "Jounal file close failed.")
} /* end if */
/* Free all memory associated with struct_ptr */
+ if ( struct_ptr->jname != NULL ) {
+
+ struct_ptr->jname = H5MM_xfree(struct_ptr->jname);
+ if ( struct_ptr->jname != NULL ) {
+
+ if ( verbose ) {
+ HDfprintf(stdout, "%s: free of jname failed.\n", FUNC);
+ }
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, FAIL, \
+ "free of jname failed.");
+ }
+ }
+
if ( (*struct_ptr->buf)[0] != NULL ) {
(*struct_ptr->buf)[0] = H5MM_xfree((*struct_ptr->buf)[0]);
if ( (*struct_ptr->buf)[0] != NULL ) {
+ if ( verbose ) {
+ HDfprintf(stdout, "%s: free of buffers failed.\n", FUNC);
+ }
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, FAIL, \
"free of buffers failed.");
}
@@ -3294,6 +3373,10 @@ H5C2_jb__takedown(H5C2_jbrb_t * struct_ptr)
struct_ptr->buf = H5MM_xfree(struct_ptr->buf);
if ( struct_ptr->buf != NULL ) {
+ if ( verbose ) {
+ HDfprintf(stdout, "%s: free of buffer ptr array faileid.\n",
+ FUNC);
+ }
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, FAIL, \
"free of buffer pointer array failed.");
}
@@ -3304,6 +3387,10 @@ H5C2_jb__takedown(H5C2_jbrb_t * struct_ptr)
struct_ptr->trans_tracking = H5MM_xfree(struct_ptr->trans_tracking);
if ( struct_ptr->trans_tracking != NULL ) {
+ if ( verbose ) {
+ HDfprintf(stdout, "%s: free of trans tracking array faileid.\n",
+ FUNC);
+ }
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, FAIL, \
"free of transaction tracking array failed.");
}
@@ -3311,6 +3398,12 @@ H5C2_jb__takedown(H5C2_jbrb_t * struct_ptr)
done:
+ if ( verbose ) {
+
+ HDfprintf(stdout, "%s: exiting.\n", FUNC);
+ fflush(stdout);
+ }
+
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5C2_jb__takedown */
diff --git a/src/H5F.c b/src/H5F.c
index e5b191d..21991cb 100644
--- a/src/H5F.c
+++ b/src/H5F.c
@@ -71,7 +71,6 @@ static herr_t H5F_get_vfd_handle(const H5F_t *file, hid_t fapl, void** file_hand
static H5F_t *H5F_new(H5F_file_t *shared, hid_t fcpl_id, hid_t fapl_id,
H5FD_t *lf);
static herr_t H5F_dest(H5F_t *f, hid_t dxpl_id);
-static herr_t H5F_flush(H5F_t *f, hid_t dxpl_id, H5F_scope_t scope, unsigned flags);
static herr_t H5F_close(H5F_t *f);
/* Declare a free list to manage the H5F_t struct */
@@ -1012,6 +1011,13 @@ H5F_dest(H5F_t *f, hid_t dxpl_id)
H5AC_stats(f);
#endif /* H5AC_DUMP_STATS_ON_CLOSE */
+ /* shut down metadata journaling if it is enabled. */
+ if ( H5C2_end_journaling(f, dxpl_id, f->shared->cache2) != SUCCEED ) {
+ /* Push error, but keep going*/
+ HDONE_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, \
+ "unable to shutdown metadata journaling")
+ }
+
/* Flush and invalidate all caches */
if(H5F_flush(f, dxpl_id, H5F_SCOPE_LOCAL, H5F_FLUSH_INVALIDATE | H5F_FLUSH_CLOSING) < 0)
/* Push error, but keep going*/
@@ -1683,7 +1689,7 @@ done:
*
*-------------------------------------------------------------------------
*/
-static herr_t
+herr_t
H5F_flush(H5F_t *f, hid_t dxpl_id, H5F_scope_t scope, unsigned flags)
{
unsigned nerrors = 0; /* Errors from nested flushes */
diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h
index 4b45481..7b38d7b 100644
--- a/src/H5Fprivate.h
+++ b/src/H5Fprivate.h
@@ -411,6 +411,8 @@ struct H5B_class_t;
struct H5RC_t;
/* Private functions */
+H5_DLL herr_t H5F_flush(H5F_t *f, hid_t dxpl_id, H5F_scope_t scope,
+ unsigned flags);
H5_DLL H5F_t *H5F_open(const char *name, unsigned flags, hid_t fcpl_id,
hid_t fapl_id, hid_t dxpl_id);
H5_DLL herr_t H5F_try_close(H5F_t *f);
diff --git a/src/H5Gdeprec.c b/src/H5Gdeprec.c
index 07de86a..bc635be 100644
--- a/src/H5Gdeprec.c
+++ b/src/H5Gdeprec.c
@@ -500,7 +500,7 @@ H5Gmove2(hid_t src_loc_id, const char *src_name, hid_t dst_loc_id,
{
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_API_META(H5Gmove2, src_loc_id, FAIL)
+ FUNC_ENTER_API_META(H5Gmove2, dst_loc_id, FAIL)
H5TRACE4("e", "i*si*s", src_loc_id, src_name, dst_loc_id, dst_name);
/* Call common routine to move the link */
diff --git a/test/cache2_journal.c b/test/cache2_journal.c
index 27902e1..b4a651b 100644
--- a/test/cache2_journal.c
+++ b/test/cache2_journal.c
@@ -123,19 +123,30 @@ static void jrnl_row_major_scan_forward2(H5F_t * file_ptr,
int dirty_unprotects,
uint64_t trans_num);
#endif /* JRM */
+static void open_exiting_file_for_journaling(const char * hdf_file_name,
+ const char * journal_file_name,
+ hid_t * file_id_ptr,
+ H5F_t ** file_ptr_ptr,
+ H5C2_t ** cache_ptr_ptr,
+ hbool_t use_core_driver_if_avail);
+
static void setup_cache_for_journaling(const char * hdf_file_name,
const char * journal_file_name,
hid_t * file_id_ptr,
H5F_t ** file_ptr_ptr,
- H5C2_t ** cache_ptr_ptr);
+ H5C2_t ** cache_ptr_ptr,
+ hbool_t use_core_driver_if_avail);
static void takedown_cache_after_journaling(hid_t file_id,
const char * filename,
- const char * journal_filename);
+ const char * journal_filename,
+ hbool_t use_core_driver_if_avail);
static void verify_journal_contents(const char * journal_file_path_ptr,
const char * expected_file_path_ptr);
+static void verify_journal_deleted(const char * journal_file_path_ptr);
+
static void verify_journal_empty(const char * journal_file_path_ptr);
/* test functions */
@@ -279,7 +290,7 @@ copy_file(const char * input_file,
ssize_t result;
int input_file_fd = -1;
int output_file_fd = -1;
- struct stat buf;
+ h5_stat_t buf;
if ( pass2 ) {
@@ -1547,6 +1558,233 @@ jrnl_row_major_scan_forward2(H5F_t * file_ptr,
/*-------------------------------------------------------------------------
+ * Function: open_existing_file_for_journaling()
+ *
+ * Purpose: If pass2 is true on entry, open the specified a HDF5 file
+ * with journaling enabled and journal file with the specified
+ * name. Return pointers to the cache data structure and file
+ * data structures, and verify that it contains the expected data.
+ *
+ * On failure, set pass2 to FALSE, and set failure_mssg2
+ * to point to an appropriate failure message.
+ *
+ * Do nothing if pass2 is FALSE on entry.
+ *
+ * Return: void
+ *
+ * Programmer: John Mainzer
+ * 5/13/08
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+
+static void
+open_exiting_file_for_journaling(const char * hdf_file_name,
+ const char * journal_file_name,
+ hid_t * file_id_ptr,
+ H5F_t ** file_ptr_ptr,
+ H5C2_t ** cache_ptr_ptr,
+ hbool_t use_core_driver_if_avail)
+{
+ const char * fcn_name = "open_exiting_file_for_journaling()";
+ hbool_t show_progress = FALSE;
+ hbool_t verbose = FALSE;
+ int cp = 0;
+ herr_t result;
+ H5AC2_cache_config_t mdj_config;
+ hid_t fapl_id = -1;
+ hid_t file_id;
+ H5F_t * file_ptr;
+ H5C2_t * cache_ptr;
+
+ if ( pass2 )
+ {
+ if ( ( hdf_file_name == NULL ) ||
+ ( journal_file_name == NULL ) ||
+ ( file_id_ptr == NULL ) ||
+ ( file_ptr_ptr == NULL ) ||
+ ( cache_ptr_ptr == NULL ) ) {
+
+ failure_mssg2 =
+ "Bad param(s) on entry to open_exiting_file_for_journaling().\n";
+ pass2 = FALSE;
+ }
+ else if ( strlen(journal_file_name) > H5AC2__MAX_JOURNAL_FILE_NAME_LEN ) {
+
+ failure_mssg2 = "journal file name too long.\n";
+ pass2 = FALSE;
+
+ } else {
+
+ strcpy(mdj_config.journal_file_path, journal_file_name);
+
+ if ( verbose ) {
+
+ HDfprintf(stdout, "%s: HDF file name = \"%s\".\n",
+ fcn_name, hdf_file_name);
+ HDfprintf(stdout, "%s: journal file name = \"%s\".\n",
+ fcn_name, journal_file_name);
+ }
+ }
+ }
+
+ if ( show_progress ) HDfprintf(stdout, "%s: cp = %d.\n", fcn_name, cp++);
+
+ /* create a file access propertly list. */
+ if ( pass2 ) {
+
+ fapl_id = H5Pcreate(H5P_FILE_ACCESS);
+
+ if ( fapl_id < 0 ) {
+
+ pass2 = FALSE;
+ failure_mssg2 = "H5Pcreate() failed.\n";
+ }
+ }
+
+ if ( show_progress ) HDfprintf(stdout, "%s: cp = %d.\n", fcn_name, cp++);
+
+ /* call H5Pset_latest_format() on the fapl_id */
+ if ( pass2 ) {
+
+ if ( H5Pset_latest_format(fapl_id, TRUE) < 0 ) {
+
+ pass2 = FALSE;
+ failure_mssg2 = "H5Pset_latest_format() failed.\n";
+ }
+ }
+
+ if ( show_progress ) HDfprintf(stdout, "%s: cp = %d.\n", fcn_name, cp++);
+
+ if ( pass2 ) {
+
+ mdj_config.version = H5C2__CURR_AUTO_SIZE_CTL_VER;
+
+ result = H5Pget_mdc_config(fapl_id, (H5AC_cache_config_t *)&mdj_config);
+
+ if ( result < 0 ) {
+
+ pass2 = FALSE;
+ failure_mssg2 = "H5Pset_mdc_config() failed.\n";
+ }
+
+ /* set journaling config fields to taste */
+ mdj_config.enable_journaling = TRUE;
+
+ strcpy(mdj_config.journal_file_path, journal_file_name);
+
+ mdj_config.journal_recovered = FALSE;
+ mdj_config.jbrb_buf_size = (8 * 1024);
+ mdj_config.jbrb_num_bufs = 2;
+ mdj_config.jbrb_use_aio = FALSE;
+ mdj_config.jbrb_human_readable = TRUE;
+ }
+
+ if ( show_progress ) HDfprintf(stdout, "%s: cp = %d.\n", fcn_name, cp++);
+
+ if ( pass2 ) {
+
+ result = H5Pset_mdc_config(fapl_id, (H5AC_cache_config_t *)&mdj_config);
+
+ if ( result < 0 ) {
+
+ pass2 = FALSE;
+ failure_mssg2 = "H5Pset_mdc_config() failed.\n";
+ }
+ }
+
+ if ( show_progress ) HDfprintf(stdout, "%s: cp = %d.\n", fcn_name, cp++);
+
+#if USE_CORE_DRIVER
+ if ( ( pass2 ) && ( use_core_driver_if_avail ) ) {
+
+ if ( H5Pset_fapl_core(fapl_id, 64 * 1024 * 1024, FALSE) < 0 ) {
+
+ pass2 = FALSE;
+ failure_mssg2 = "H5P_set_fapl_core() failed.\n";
+ }
+ }
+#endif /* USE_CORE_DRIVER */
+
+ if ( show_progress ) HDfprintf(stdout, "%s: cp = %d.\n", fcn_name, cp++);
+
+
+ /**************************************/
+ /* open the file with the fapl above. */
+ /**************************************/
+
+ /* open the file using fapl_id */
+ if ( pass2 ) {
+
+ file_id = H5Fopen(hdf_file_name, H5F_ACC_RDWR, fapl_id);
+
+ if ( file_id < 0 ) {
+
+ pass2 = FALSE;
+ failure_mssg2 = "H5Fopen() failed.\n";
+
+ } else {
+
+ file_ptr = H5I_object_verify(file_id, H5I_FILE);
+
+ if ( file_ptr == NULL ) {
+
+ pass2 = FALSE;
+ failure_mssg2 = "Can't get file_ptr.";
+
+ if ( verbose ) {
+ HDfprintf(stdout, "%s: Can't get file_ptr.\n", fcn_name);
+ }
+ }
+ }
+ }
+
+ /* At least within the context of the cache2 test code, there should be
+ * no need to allocate space for test entries since we are re-opening
+ * the file, and any needed space allocation should have been done at
+ * file creation.
+ */
+
+
+ if ( show_progress ) HDfprintf(stdout, "%s: cp = %d.\n", fcn_name, cp++);
+
+ /* get a pointer to the files internal data structure and then
+ * to the cache structure
+ */
+ if ( pass2 ) {
+
+ if ( file_ptr->shared->cache2 == NULL ) {
+
+ pass2 = FALSE;
+ failure_mssg2 = "can't get cache2 pointer(1).\n";
+
+ } else {
+
+ cache_ptr = file_ptr->shared->cache2;
+ }
+ }
+
+
+ if ( show_progress ) HDfprintf(stdout, "%s: cp = %d.\n", fcn_name, cp++);
+
+ if ( pass2 ) {
+
+ *file_id_ptr = file_id;
+ *file_ptr_ptr = file_ptr;
+ *cache_ptr_ptr = cache_ptr;
+ }
+
+ if ( show_progress )
+ HDfprintf(stdout, "%s: cp = %d -- exiting.\n", fcn_name, cp++);
+
+ return;
+
+} /* open_existing_file_for_journaling() */
+
+
+/*-------------------------------------------------------------------------
* Function: setup_cache_for_journaling()
*
* Purpose: If pass2 is true on entry, create a HDF5 file with
@@ -1574,7 +1812,8 @@ setup_cache_for_journaling(const char * hdf_file_name,
const char * journal_file_name,
hid_t * file_id_ptr,
H5F_t ** file_ptr_ptr,
- H5C2_t ** cache_ptr_ptr)
+ H5C2_t ** cache_ptr_ptr,
+ hbool_t use_core_driver_if_avail)
{
const char * fcn_name = "setup_cache_for_journaling()";
hbool_t show_progress = FALSE;
@@ -1700,7 +1939,7 @@ setup_cache_for_journaling(const char * hdf_file_name,
if ( show_progress ) HDfprintf(stdout, "%s: cp = %d.\n", fcn_name, cp++);
#if USE_CORE_DRIVER
- if ( pass2 ) {
+ if ( ( pass2 ) && ( use_core_driver_if_avail ) ) {
if ( H5Pset_fapl_core(fapl_id, 64 * 1024 * 1024, FALSE) < 0 ) {
@@ -1817,7 +2056,7 @@ setup_cache_for_journaling(const char * hdf_file_name,
* Function: takedown_cache_after_journaling()
*
* Purpose: If file_id >= 0, close the associated file, and then delete
- * it and the associated journal file (if it exists).
+ * it. Verify that they journal file has been deleted.
*
* Return: void
*
@@ -1832,7 +2071,9 @@ setup_cache_for_journaling(const char * hdf_file_name,
static void
takedown_cache_after_journaling(hid_t file_id,
const char * filename,
- const char * journal_filename)
+ const char * journal_filename,
+ hbool_t
+ use_core_driver_if_avail)
{
hbool_t verbose = TRUE;
int error;
@@ -1846,8 +2087,8 @@ takedown_cache_after_journaling(hid_t file_id,
pass2 = FALSE;
failure_mssg2 = "file close failed.";
}
-#if ! USE_CORE_DRIVER
- } else if ( (error = HDremove(filename)) != 0 ) {
+ } else if ( ( ( ! USE_CORE_DRIVER ) || ( ! use_core_driver_if_avail ) ) &&
+ ( ( error = HDremove(filename) ) != 0 ) ) {
if ( verbose ) {
HDfprintf(stdout,
@@ -1860,17 +2101,11 @@ takedown_cache_after_journaling(hid_t file_id,
pass2 = FALSE;
failure_mssg2 = "HDremove() failed (1).\n";
}
-#endif
- } else if ( HDremove(journal_filename) != 0 ) {
-
- if ( pass2 ) {
-
- pass2 = FALSE;
- failure_mssg2 = "HDremove() failed (2).\n";
- }
}
}
+ verify_journal_deleted(journal_filename);
+
return;
} /* takedown_cache_after_journaling() */
@@ -1916,7 +2151,7 @@ verify_journal_contents(const char * journal_file_path_ptr,
ssize_t read_result;
int journal_file_fd = -1;
int expected_file_fd = -1;
- struct stat buf;
+ h5_stat_t buf;
if ( pass2 ) {
@@ -2211,6 +2446,76 @@ verify_journal_contents(const char * journal_file_path_ptr,
/*-------------------------------------------------------------------------
+ * Function: verify_journal_deleted()
+ *
+ * Purpose: If pass2 is true on entry, stat the target journal file,
+ * and verify that it does not exist. If it does, set
+ * pass2 to FALSE, and set failure_mssg2 to point to an
+ * appropriate failure message. Similarly, if any errors
+ * are detected in this process, set pass2 to FALSE and set
+ * failure_mssg2 to point to an appropriate error message.
+ *
+ * Do nothing if pass2 is FALSE on entry.
+ *
+ * Return: void
+ *
+ * Programmer: John Mainzer
+ * 5//08
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+
+static void
+verify_journal_deleted(const char * journal_file_path_ptr)
+{
+ const char * fcn_name = "verify_journal_deleted()";
+ hbool_t verbose = FALSE;
+ h5_stat_t buf;
+
+ if ( pass2 ) {
+
+ if ( journal_file_path_ptr == NULL ) {
+
+ failure_mssg2 = "journal_file_path_ptr NULL on entry?!?",
+ pass2 = FALSE;
+ }
+ }
+
+ if ( pass2 ) {
+
+ if ( HDstat(journal_file_path_ptr, &buf) == 0 ) {
+
+ if ( verbose ) {
+
+ HDfprintf(stdout, "%s: HDstat(%s) succeeded.\n", fcn_name,
+ journal_file_path_ptr);
+ }
+
+ failure_mssg2 = "journal file not deleted(1).";
+ pass2 = FALSE;
+
+ } else if ( errno != ENOENT ) {
+
+ if ( verbose ) {
+
+ HDfprintf(stdout,
+ "%s: HDstat() failed with unexpected errno = %d.\n",
+ fcn_name, errno);
+ }
+ failure_mssg2 = "journal file not deleted(2).";
+ pass2 = FALSE;
+
+ }
+ }
+
+ return;
+
+} /* verify_journal_deleted() */
+
+
+/*-------------------------------------------------------------------------
* Function: verify_journal_empty()
*
* Purpose: If pass2 is true on entry, stat the target journal file,
@@ -2237,7 +2542,7 @@ verify_journal_empty(const char * journal_file_path_ptr)
{
const char * fcn_name = "verify_journal_empty()";
hbool_t verbose = FALSE;
- struct stat buf;
+ h5_stat_t buf;
if ( pass2 ) {
@@ -2292,7 +2597,13 @@ verify_journal_empty(const char * journal_file_path_ptr)
* Verify that these transactions are reflected correctly
* in the journal.
*
- * 3) Close and delete the file.
+ * 3) Close the hdf5 file, and verify that the journal file
+ * is deleted. Re-open the file with journaling, and
+ * do a transaction or two just to verify that the
+ * journaling is working.
+ *
+ * 4) Close the file, and verify that the journal is deleted.
+ * Then delete the file.
*
* Return: void
*
@@ -2327,6 +2638,7 @@ mdj_smoke_check_00(void)
"testfiles/cache2_journal_sc00_014.jnl",
"testfiles/cache2_journal_sc00_015.jnl",
"testfiles/cache2_journal_sc00_016.jnl",
+ "testfiles/cache2_journal_sc00_017.jnl",
NULL
};
char filename[512];
@@ -2391,7 +2703,7 @@ mdj_smoke_check_00(void)
}
setup_cache_for_journaling(filename, journal_filename, &file_id,
- &file_ptr, &cache_ptr);
+ &file_ptr, &cache_ptr, FALSE);
if ( show_progress )
HDfprintf(stdout, "%s:%d cp = %d.\n", fcn_name, pass2, cp++);
@@ -3168,12 +3480,81 @@ mdj_smoke_check_00(void)
verify_journal_contents(journal_filename, testfiles[16]);
+ if ( show_progress )
+ HDfprintf(stdout, "%s:%d cp = %d.\n", fcn_name, pass2, cp++);
+
+
+ /************************************************************/
+ /* 3) Close the hdf5 file, and verify that the journal file */
+ /* is deleted. Re-open the file with journaling, and */
+ /* do a transaction or two just to verify that the */
+ /* journaling is working. */
+ /************************************************************/
+
+ /* a) Close the hdf5 file. */
+ if ( pass2 ) {
+
+ if ( H5Fclose(file_id) < 0 ) {
+
+ pass2 = FALSE;
+ failure_mssg2 = "temporary H5Fclose() failed.\n";
+
+ } else {
+ file_id = -1;
+ file_ptr = NULL;
+ cache_ptr = NULL;
+ }
+ }
+
+ if ( show_progress )
+ HDfprintf(stdout, "%s:%d cp = %d.\n", fcn_name, pass2, cp++);
+
+
+ /* b) Verify that the journal file has been deleted. */
+ verify_journal_deleted(journal_filename);
+
+ if ( show_progress )
+ HDfprintf(stdout, "%s:%d cp = %d.\n", fcn_name, pass2, cp++);
+
+
+ /* c) Re-open the hdf5 file. */
+ open_exiting_file_for_journaling(filename, journal_filename, &file_id,
+ &file_ptr, &cache_ptr, FALSE);
+
+ if ( show_progress )
+ HDfprintf(stdout, "%s:%d cp = %d.\n", fcn_name, pass2, cp++);
+
+
+ /* d) do a transaction or to to verify that journaling is working. */
+
+ begin_trans(cache_ptr, verbose, (uint64_t)1, "transaction 1.5");
+
+ insert_entry2(file_ptr, 0, 1, FALSE, H5C2__NO_FLAGS_SET);
+ protect_entry2(file_ptr, 0, 0);
+ unprotect_entry2(file_ptr, 0, 0, TRUE, H5C2__NO_FLAGS_SET);
+
+ end_trans(file_ptr, cache_ptr, verbose, (uint64_t)1, "transaction 1.5");
+
+ flush_journal(cache_ptr);
+
+ if ( update_architypes ) {
+
+ copy_file(journal_filename, testfiles[17]);
+ }
+
+ verify_journal_contents(journal_filename, testfiles[17]);
+
+ flush_cache2(file_ptr, FALSE, FALSE, FALSE); /* resets transaction number */
+
+ if ( show_progress )
+ HDfprintf(stdout, "%s:%d cp = %d.\n", fcn_name, pass2, cp++);
+
/*******************************************************/
- /* 3) Close and discard the file and the journal file. */
+ /* 4) Close and discard the file and the journal file. */
/*******************************************************/
- takedown_cache_after_journaling(file_id, filename, journal_filename);
+ takedown_cache_after_journaling(file_id, filename, journal_filename, FALSE);
if ( show_progress )
HDfprintf(stdout, "%s:%d cp = %d.\n", fcn_name, pass2, cp++);
@@ -3290,7 +3671,7 @@ mdj_smoke_check_01(void)
}
setup_cache_for_journaling(filename, journal_filename, &file_id,
- &file_ptr, &cache_ptr);
+ &file_ptr, &cache_ptr, TRUE);
if ( show_progress )
HDfprintf(stdout, "%s:%d cp = %d.\n", fcn_name, pass2, cp++);
@@ -3480,7 +3861,7 @@ mdj_smoke_check_01(void)
/* Close and discard the file and the journal file. */
/****************************************************/
- takedown_cache_after_journaling(file_id, filename, journal_filename);
+ takedown_cache_after_journaling(file_id, filename, journal_filename, TRUE);
if ( show_progress )
HDfprintf(stdout, "%s:%d cp = %d.\n", fcn_name, pass2, cp++);