From 63f71aca9177fa4642cda8298a7b7c5c1eb5761e Mon Sep 17 00:00:00 2001 From: John Mainzer Date: Fri, 10 Oct 2008 14:47:43 -0500 Subject: [svn-r15835] Refactored tests of code to mark and unmark the HDF5 file as having journaling in progress to avoid calls to fork(). Did this by creating cache2_jnl_file_marking (a program that sets up or checks the results of the specified file marking test depending on parameters passed to it) and test/testjnlfilemarking.sh (a shell script to call cache2_jnl_file_marking and report results). Also fixed an input validation bug in src/H5AC.c in passing. Tested on Phoenix (serial -- debug and production mode) Kagiso (parallel) Linew (serial) There was another checkin during these tests. As the changes looked orthoginal to mine, I updated and retested on Phoenix (serial / debug) only before this checkin. --- MANIFEST | 2 + src/H5AC.c | 1 + test/Makefile.am | 10 +- test/Makefile.in | 52 +- test/cache2_jnl_file_marking.c | 3600 ++++++++++++++++++++++++++++++++++++++++ test/cache2_journal.c | 2676 ++--------------------------- test/testjnlfilemarking.sh | 89 + 7 files changed, 3842 insertions(+), 2588 deletions(-) create mode 100644 test/cache2_jnl_file_marking.c create mode 100755 test/testjnlfilemarking.sh diff --git a/MANIFEST b/MANIFEST index e5e53ca..998dd7b 100644 --- a/MANIFEST +++ b/MANIFEST @@ -772,6 +772,7 @@ ./test/cache2_common.c ./test/cache_common.h ./test/cache2_common.h +./test/cache2_jnl_file_marking.c ./test/cache2_journal.c ./test/cmpd_dset.c ./test/cross_read.c @@ -848,6 +849,7 @@ ./test/testframe.c ./test/testhdf5.c ./test/testhdf5.h +./test/testjnlfilemarking.sh ./test/testmeta.c ./test/tfile.c ./test/tgenprop.c diff --git a/src/H5AC.c b/src/H5AC.c index e4639f3..b5f8af6 100644 --- a/src/H5AC.c +++ b/src/H5AC.c @@ -3130,6 +3130,7 @@ H5AC_validate_config(H5AC_cache_config_t * config_ptr) if ( ( config_ptr->evictions_enabled == FALSE ) && ( ( config_ptr->incr_mode != H5C_incr__off ) || + ( config_ptr->flash_incr_mode != H5C_flash_incr__off ) || ( config_ptr->incr_mode != H5C_decr__off ) ) ) { HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, \ diff --git a/test/Makefile.am b/test/Makefile.am index 7a4d3d0..50d0f1e 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -24,9 +24,10 @@ include $(top_srcdir)/config/commence.am INCLUDES=-I$(top_srcdir)/src -I$(top_builddir)/src # Test script for error_test and err_compat -TEST_SCRIPT = testerror.sh +TEST_SCRIPT = testerror.sh ${srcdir}/testjnlfilemarking.sh check_SCRIPTS = $(TEST_SCRIPT) -SCRIPT_DEPEND = error_test$(EXEEXT) err_compat$(EXEEXT) +SCRIPT_DEPEND = error_test$(EXEEXT) err_compat$(EXEEXT) \ + cache2_jnl_file_marking.c$(EXEEXT) # These are our main targets. They should be listed in the order to be @@ -49,7 +50,8 @@ TEST_PROG=testhdf5 lheap ohdr stab gheap cache cache_api cache2 cache2_api \ # 'make check' doesn't run them directly, so they are not included in TEST_PROG. # Also build testmeta, which is used for timings test. It builds quickly, # and this lets automake keep all its test programs in one place. -check_PROGRAMS=$(TEST_PROG) error_test err_compat testmeta +check_PROGRAMS=$(TEST_PROG) error_test err_compat testmeta \ + cache2_jnl_file_marking # These programs generate test files for the tests. They don't need to be @@ -129,6 +131,6 @@ testhdf5_SOURCES=testhdf5.c tarray.c tattr.c tchecksum.c tconfig.c tfile.c \ tvlstr.c tvltypes.c # Temporary files. -DISTCLEANFILES=testerror.sh +DISTCLEANFILES=testerror.sh include $(top_srcdir)/config/conclude.am diff --git a/test/Makefile.in b/test/Makefile.in index 2d24292..4a7658f 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -54,7 +54,8 @@ DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(srcdir)/testerror.sh.in $(top_srcdir)/config/commence.am \ $(top_srcdir)/config/conclude.am COPYING check_PROGRAMS = $(am__EXEEXT_1) error_test$(EXEEXT) \ - err_compat$(EXEEXT) testmeta$(EXEEXT) + err_compat$(EXEEXT) testmeta$(EXEEXT) \ + cache2_jnl_file_marking$(EXEEXT) @BUILD_ALL_CONDITIONAL_TRUE@noinst_PROGRAMS = $(am__EXEEXT_2) TESTS = $(check_PROGRAMS) $(check_SCRIPTS) subdir = test @@ -115,6 +116,10 @@ cache2_api_SOURCES = cache2_api.c cache2_api_OBJECTS = cache2_api.$(OBJEXT) cache2_api_LDADD = $(LDADD) cache2_api_DEPENDENCIES = libh5test.la $(LIBHDF5) +cache2_jnl_file_marking_SOURCES = cache2_jnl_file_marking.c +cache2_jnl_file_marking_OBJECTS = cache2_jnl_file_marking.$(OBJEXT) +cache2_jnl_file_marking_LDADD = $(LDADD) +cache2_jnl_file_marking_DEPENDENCIES = libh5test.la $(LIBHDF5) cache2_journal_SOURCES = cache2_journal.c cache2_journal_OBJECTS = cache2_journal.$(OBJEXT) cache2_journal_LDADD = $(LDADD) @@ -346,23 +351,24 @@ LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(libh5test_la_SOURCES) big.c bittests.c btree2.c cache.c \ - cache2.c cache2_api.c cache2_journal.c cache_api.c cmpd_dset.c \ - cross_read.c dangle.c dsets.c dt_arith.c dtransform.c dtypes.c \ - enum.c err_compat.c error_test.c extend.c external.c fheap.c \ - fillval.c flush1.c flush2.c gen_bad_ohdr.c gen_bogus.c \ - gen_cross.c gen_deflate.c gen_filters.c gen_new_array.c \ - gen_new_fill.c gen_new_group.c gen_new_mtime.c gen_new_super.c \ - gen_noencoder.c gen_nullspace.c gen_udlinks.c getname.c \ - gheap.c hyperslab.c istore.c lheap.c links.c mount.c mtime.c \ - ntypes.c objcopy.c ohdr.c pool.c reserved.c set_extent.c \ - space_overflow.c stab.c $(testhdf5_SOURCES) testmeta.c \ - $(ttsafe_SOURCES) unlink.c vfd.c + cache2.c cache2_api.c cache2_jnl_file_marking.c \ + cache2_journal.c cache_api.c cmpd_dset.c cross_read.c dangle.c \ + dsets.c dt_arith.c dtransform.c dtypes.c enum.c err_compat.c \ + error_test.c extend.c external.c fheap.c fillval.c flush1.c \ + flush2.c gen_bad_ohdr.c gen_bogus.c gen_cross.c gen_deflate.c \ + gen_filters.c gen_new_array.c gen_new_fill.c gen_new_group.c \ + gen_new_mtime.c gen_new_super.c gen_noencoder.c \ + gen_nullspace.c gen_udlinks.c getname.c gheap.c hyperslab.c \ + istore.c lheap.c links.c mount.c mtime.c ntypes.c objcopy.c \ + ohdr.c pool.c reserved.c set_extent.c space_overflow.c stab.c \ + $(testhdf5_SOURCES) testmeta.c $(ttsafe_SOURCES) unlink.c \ + vfd.c DIST_SOURCES = $(libh5test_la_SOURCES) big.c bittests.c btree2.c \ - cache.c cache2.c cache2_api.c cache2_journal.c cache_api.c \ - cmpd_dset.c cross_read.c dangle.c dsets.c dt_arith.c \ - dtransform.c dtypes.c enum.c err_compat.c error_test.c \ - extend.c external.c fheap.c fillval.c flush1.c flush2.c \ - gen_bad_ohdr.c gen_bogus.c gen_cross.c gen_deflate.c \ + cache.c cache2.c cache2_api.c cache2_jnl_file_marking.c \ + cache2_journal.c cache_api.c cmpd_dset.c cross_read.c dangle.c \ + dsets.c dt_arith.c dtransform.c dtypes.c enum.c err_compat.c \ + error_test.c extend.c external.c fheap.c fillval.c flush1.c \ + flush2.c gen_bad_ohdr.c gen_bogus.c gen_cross.c gen_deflate.c \ gen_filters.c gen_new_array.c gen_new_fill.c gen_new_group.c \ gen_new_mtime.c gen_new_super.c gen_noencoder.c \ gen_nullspace.c gen_udlinks.c getname.c gheap.c hyperslab.c \ @@ -648,9 +654,11 @@ CHECK_CLEANFILES = *.chkexe *.chklog *.clog cmpd_dset.h5 \ INCLUDES = -I$(top_srcdir)/src -I$(top_builddir)/src # Test script for error_test and err_compat -TEST_SCRIPT = testerror.sh +TEST_SCRIPT = testerror.sh ${srcdir}/testjnlfilemarking.sh check_SCRIPTS = $(TEST_SCRIPT) -SCRIPT_DEPEND = error_test$(EXEEXT) err_compat$(EXEEXT) +SCRIPT_DEPEND = error_test$(EXEEXT) err_compat$(EXEEXT) \ + cache2_jnl_file_marking.c$(EXEEXT) + # These are our main targets. They should be listed in the order to be # executed, generally most specific tests to least specific tests. @@ -702,7 +710,7 @@ testhdf5_SOURCES = testhdf5.c tarray.c tattr.c tchecksum.c tconfig.c tfile.c \ # Temporary files. -DISTCLEANFILES = testerror.sh +DISTCLEANFILES = testerror.sh # Automake needs to be taught how to build lib, progs, and tests targets. # These will be filled in automatically for the most part (e.g., @@ -797,6 +805,9 @@ cache2$(EXEEXT): $(cache2_OBJECTS) $(cache2_DEPENDENCIES) cache2_api$(EXEEXT): $(cache2_api_OBJECTS) $(cache2_api_DEPENDENCIES) @rm -f cache2_api$(EXEEXT) $(LINK) $(cache2_api_OBJECTS) $(cache2_api_LDADD) $(LIBS) +cache2_jnl_file_marking$(EXEEXT): $(cache2_jnl_file_marking_OBJECTS) $(cache2_jnl_file_marking_DEPENDENCIES) + @rm -f cache2_jnl_file_marking$(EXEEXT) + $(LINK) $(cache2_jnl_file_marking_OBJECTS) $(cache2_jnl_file_marking_LDADD) $(LIBS) cache2_journal$(EXEEXT): $(cache2_journal_OBJECTS) $(cache2_journal_DEPENDENCIES) @rm -f cache2_journal$(EXEEXT) $(LINK) $(cache2_journal_OBJECTS) $(cache2_journal_LDADD) $(LIBS) @@ -967,6 +978,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cache2.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cache2_api.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cache2_common.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cache2_jnl_file_marking.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cache2_journal.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cache_api.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cache_common.Plo@am__quote@ diff --git a/test/cache2_jnl_file_marking.c b/test/cache2_jnl_file_marking.c new file mode 100644 index 0000000..a9db658 --- /dev/null +++ b/test/cache2_jnl_file_marking.c @@ -0,0 +1,3600 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * Copyright by the Board of Trustees of the University of Illinois. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the files COPYING and Copyright.html. COPYING can be found at the root * + * of the source code distribution tree; Copyright.html can be found at the * + * root level of an installed copy of the electronic HDF5 document set and * + * is linked from the top-level documents page. It can also be found at * + * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* Programmer: John Mainzer + * 3/08 + * + * This file contains tests for the metadata journaling + * features implemented in H5C2.c and friends. + */ + +#define H5F_PACKAGE /*suppress error about including H5Fpkg */ + +#include "h5test.h" +#include "H5Eprivate.h" +#include "H5Iprivate.h" +#include "H5MMprivate.h" /* Memory management */ +#include "H5MFprivate.h" +#include "H5AC2private.h" +#include "cache2_common.h" +#include "H5Fpkg.h" + +#define HDF5_FILE_NAME "HDF5.file" + +/* global variable declarations: */ + +const char *FILENAMES[] = { + "cache_test", + "cache_journal_test", + "cache_sb_test", + "journal_file", + "test_in_progress", + NULL +}; + + +/* private function declarations: */ + +/* utility functions */ + +static void check_test_in_progress(const char * str); + +static hbool_t file_exists(const char * file_path_ptr); + +static void mark_test_in_progress(const char * str); + +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, + hbool_t use_core_driver_if_avail); + +static void usage(void); + +/* test functions */ + +static void setup_mdj_file_marking_after_open_test(hbool_t verbose); +static void check_mdj_file_marking_after_open_test(hbool_t verbose); + +static void setup_mdj_file_marking_on_create_test(hbool_t verbose); +static void check_mdj_file_marking_on_create_test(hbool_t verbose); + +static void setup_mdj_file_marking_on_open_test(hbool_t verbose); +static void check_mdj_file_marking_on_open_test(hbool_t verbose); + +static void setup_mdj_file_unmarking_on_file_close_test(hbool_t verbose); +static void check_mdj_file_unmarking_on_file_close_test(hbool_t verbose); + +static void setup_mdj_file_unmarking_on_journaling_shutdown_test(hbool_t verbose); +static void check_mdj_file_unmarking_on_journaling_shutdown_test(hbool_t verbose); + +static void setup_mdj_file_unmarking_on_recovery_test(hbool_t verbose); +static void check_mdj_file_unmarking_on_recovery_test(hbool_t verbose); + + +/**************************************************************************/ +/**************************************************************************/ +/********************************* tests: *********************************/ +/**************************************************************************/ +/**************************************************************************/ + +/*** metadata journaling test utility functions ***/ + +/*------------------------------------------------------------------------- + * Function: check_test_in_progress() + * + * Purpose: If pass2 is true on entry, test to see if the test in + * progress file exists. If it does not, set pass2 to FALSE + * and set a failure message. + * + * If the test in progress file does exist, check to see if + * its contents matches the supplied string. It it does not, + * set pass2 to FALSE and set the appropriate failure message. + * + * Do nothing if pass2 is FALSE on entry. + * + * Return: void + * + * Programmer: John Mainzer + * 10/9/08 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + +static void +check_test_in_progress(const char * str) + +{ + const char * fcn_name = "check_test_in_progress()"; + char buffer[512]; + char filename[512]; + hbool_t show_progress = FALSE; + hbool_t verbose = FALSE; + size_t input_len; + int cp = 0; + herr_t result; + int fd = -1; + h5_stat_t buf; + + if ( show_progress ) { + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, pass2, cp++); + HDfflush(stdout); + } + + if ( pass2 ) { + + if ( ( str == NULL ) || + ( strlen(str) <= 0 ) || + ( strlen(str) >= 512 ) ) { + + pass2 = FALSE; + failure_mssg2 = "bad str on entry to check_test_in_progress()."; + } + } + + if ( show_progress ) { + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, pass2, cp++); + HDfflush(stdout); + } + + /* setup the journal file name */ + if ( pass2 ) { + + if ( h5_fixname(FILENAMES[4], H5P_DEFAULT, filename, + sizeof(filename)) == NULL ) { + + pass2 = FALSE; + failure_mssg2 = "h5_fixname() failed.\n"; + } + else if ( strlen(filename) >= 512 ) { + + pass2 = FALSE; + failure_mssg2 = "test in progress file name too long.\n"; + } + } + + if ( show_progress ) { + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, pass2, cp++); + HDfflush(stdout); + } + + if ( verbose ) { + HDfprintf(stdout, "%s filename = \"%s\".\n", fcn_name, filename); + HDfflush(stdout); + } + + if ( ( pass2 ) && ( ! file_exists(filename) ) ) { + + pass2 = FALSE; + failure_mssg2 = "test not in progress?!?"; + } + + + /* get the length of the test in progress file */ + if ( pass2 ) { + + if ( HDstat(filename, &buf) != 0 ) { + + if ( verbose ) { + + HDfprintf(stdout, "%s: HDstat() failed with errno = %d.\n", + fcn_name, errno); + } + failure_mssg2 = "stat() failed on test in progress file."; + pass2 = FALSE; + + } else { + + if ( (buf.st_size) == 0 ) { + + failure_mssg2 = "test in progress file empty?!?"; + pass2 = FALSE; + + } else if ( (buf.st_size) >= 512 ) { + + failure_mssg2 = "test in progress file too big?!?"; + pass2 = FALSE; + + } else { + + input_len = (size_t)(buf.st_size); + + if ( verbose ) { + + HDfprintf(stdout, "%s: input_len = %d.\n", + fcn_name, (int)input_len); + } + } + } + } + + /* open the test in progress file */ + if ( pass2 ) { + + if ( (fd = HDopen(filename, O_RDONLY, 0777)) == -1 ) { + + if ( verbose ) { + + HDfprintf(stdout, "%s: HDopen(i) failed with errno = %d.\n", + fcn_name, errno); + } + failure_mssg2 = "Can't open test in progress file."; + pass2 = FALSE; + } + } + + /* read the contents of the test in progress file */ + if ( pass2 ) + { + result = HDread(fd, buffer, input_len); + + if ( result != (int)input_len ) { + + if ( verbose ) { + + HDfprintf(stdout, + "%s: HDread() failed. result = %d, errno = %d.\n", + fcn_name, (int)result, errno); + } + failure_mssg2 = "error reading test in progress file."; + pass2 = FALSE; + } + + buffer[input_len] = '\0'; + } + + if ( fd != -1 ) { + + if ( HDclose(fd) != 0 ) { + + if ( verbose ) { + + HDfprintf(stdout, "%s: HDclose() failed with errno = %d.\n", + fcn_name, errno); + } + + if ( pass2 ) { + + failure_mssg2 = "Can't close test in progress file."; + pass2 = FALSE; + } + } + } + + HDremove(filename); + + if ( pass2 ) { + + if ( strcmp(str, buffer) != 0 ) { + + if ( verbose ) { + + HDfprintf(stdout, + "%s: expected/actual test in progress = %s/%s\n", + fcn_name, str, buffer); + } + + pass2 = FALSE; + failure_mssg2 = "Unexpected test in progress?!?"; + } + } + + return; + +} /* check_test_in_progress() */ + + +/*------------------------------------------------------------------------- + * Function: file_exists() + * + * Purpose: If pass2 is true on entry, stat the target file, and + * return TRUE if it exists, and FALSE if it does not. + * + * 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 and return FALSE if pass2 is FALSE on entry. + * + * Return: void + * + * Programmer: John Mainzer + * 5//08 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + +static hbool_t +file_exists(const char * file_path_ptr) +{ + const char * fcn_name = "file_exists()"; + hbool_t ret_val = FALSE; /* will set to TRUE if necessary */ + hbool_t verbose = FALSE; + h5_stat_t buf; + + if ( pass2 ) { + + if ( file_path_ptr == NULL ) { + + failure_mssg2 = "file_path_ptr NULL on entry?!?", + pass2 = FALSE; + } + } + + if ( pass2 ) { + + if ( HDstat(file_path_ptr, &buf) == 0 ) { + + if ( verbose ) { + + HDfprintf(stdout, "%s: HDstat(%s) succeeded.\n", fcn_name, + file_path_ptr); + } + + ret_val = TRUE; + + } else if ( errno == ENOENT ) { + + if ( verbose ) { + + HDfprintf(stdout, "%s: HDstat(%s) failed with ENOENT\n", + fcn_name, file_path_ptr); + } + + } else { + + if ( verbose ) { + + HDfprintf(stdout, + "%s: HDstat() failed with unexpected errno = %d.\n", + fcn_name, errno); + } + + failure_mssg2 = "HDstat() returned unexpected value."; + pass2 = FALSE; + + } + } + + return(ret_val); + +} /* file_exists() */ + + +/*------------------------------------------------------------------------- + * Function: mark_test_in_progress() + * + * Purpose: If pass2 is true on entry, test to see if the test in + * progress file exists. If it does, set pass2 to FALSE + * and set a failure message. + * + * If the test in progress file doesn't exist, create it, + * open it, write the supplied string to it, and then close + * it. If any errors are detected, set pass2 to FALSE, and + * set the appropriate failure message. + * + * Do nothing if pass2 is FALSE on entry. + * + * Return: void + * + * Programmer: John Mainzer + * 10/9/08 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + +static void +mark_test_in_progress(const char * str) + +{ + const char * fcn_name = "mark_test_in_progress()"; + char filename[512]; + hbool_t show_progress = FALSE; + hbool_t verbose = FALSE; + int cp = 0; + herr_t result; + int fd = -1; + + if ( show_progress ) { + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, pass2, cp++); + HDfflush(stdout); + } + + if ( pass2 ) { + + if ( ( str == NULL ) || + ( strlen(str) >= 512 ) ) { + + pass2 = FALSE; + failure_mssg2 = "bad str on entry to mark_test_in_progress()."; + } + } + + if ( show_progress ) { + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, pass2, cp++); + HDfflush(stdout); + } + + /* setup the journal file name */ + if ( pass2 ) { + + if ( h5_fixname(FILENAMES[4], H5P_DEFAULT, filename, + sizeof(filename)) == NULL ) { + + pass2 = FALSE; + failure_mssg2 = "h5_fixname() failed.\n"; + } + else if ( strlen(filename) >= 512 ) { + + pass2 = FALSE; + failure_mssg2 = "test in progress file name too long.\n"; + } + } + + if ( show_progress ) { + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, pass2, cp++); + HDfflush(stdout); + } + + if ( verbose ) { + HDfprintf(stdout, "%s filename = \"%s\".\n", fcn_name, filename); + HDfflush(stdout); + } + + if ( ( pass2 ) && ( file_exists(filename) ) ) { + + pass2 = FALSE; + failure_mssg2 = "test already in progress?!?"; + } + + /* open the test in progress file */ + if ( pass2 ) { + + if ( (fd = HDopen(filename, O_WRONLY|O_CREAT|O_TRUNC, 0777)) + == -1 ) { + + if ( verbose ) { + + HDfprintf(stdout, "%s: HDopen(i) failed with errno = %d.\n", + fcn_name, errno); + } + failure_mssg2 = "Can't open test in progress file."; + pass2 = FALSE; + } + } + + if ( pass2 ) { + + result = HDwrite(fd, str, strlen(str)); + + if ( result != (int)strlen(str) ) { + + if ( verbose ) { + + HDfprintf(stdout, + "%s: HDwrite() failed. result = %d, errno = %d.\n", + fcn_name, (int)result, errno); + } + failure_mssg2 = "error writing test in progress file."; + pass2 = FALSE; + } + } + + if ( fd != -1 ) { + + if ( HDclose(fd) != 0 ) { + + if ( verbose ) { + + HDfprintf(stdout, "%s: HDclose() failed with errno = %d.\n", + fcn_name, errno); + } + + if ( pass2 ) { + + failure_mssg2 = "Can't close test in progress file."; + pass2 = FALSE; + } + } + } + + return; + +} /* mark_test_in_progress() */ + + +/*------------------------------------------------------------------------- + * Function: setup_cache_for_journaling() + * + * Purpose: If pass2 is true on entry, create 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 +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, +#if USE_CORE_DRIVER + hbool_t use_core_driver_if_avail) +#else /* USE_CORE_DRIVER */ + hbool_t UNUSED use_core_driver_if_avail) +#endif /* USE_CORE_DRIVER */ +{ + const char * fcn_name = "setup_cache_for_journaling()"; + hbool_t show_progress = FALSE; + hbool_t verbose = FALSE; + int cp = 0; + herr_t result; + H5AC2_cache_config_t mdj_config = + { + /* int version = */ H5C2__CURR_AUTO_SIZE_CTL_VER, + /* hbool_t rpt_fcn_enabled = */ FALSE, + /* hbool_t open_trace_file = */ FALSE, + /* hbool_t close_trace_file = */ FALSE, + /* char trace_file_name[] = */ "", + /* hbool_t evictions_enabled = */ TRUE, + /* hbool_t set_initial_size = */ TRUE, + /* size_t initial_size = */ ( 64 * 1024 ), + /* double min_clean_fraction = */ 0.5, + /* size_t max_size = */ (16 * 1024 * 1024 ), + /* size_t min_size = */ ( 8 * 1024 ), + /* long int epoch_length = */ 50000, + /* enum H5C2_cache_incr_mode incr_mode = */ H5C2_incr__off, + /* double lower_hr_threshold = */ 0.9, + /* double increment = */ 2.0, + /* hbool_t apply_max_increment = */ TRUE, + /* size_t max_increment = */ (4 * 1024 * 1024), + /* enum H5C2_cache_flash_incr_mode */ + /* flash_incr_mode = */ H5C2_flash_incr__off, + /* double flash_multiple = */ 1.0, + /* double flash_threshold = */ 0.25, + /* enum H5C2_cache_decr_mode decr_mode = */ H5C2_decr__off, + /* double upper_hr_threshold = */ 0.999, + /* double decrement = */ 0.9, + /* hbool_t apply_max_decrement = */ TRUE, + /* size_t max_decrement = */ (1 * 1024 * 1024), + /* int epochs_before_eviction = */ 3, + /* hbool_t apply_empty_reserve = */ TRUE, + /* double empty_reserve = */ 0.1, + /* int dirty_bytes_threshold = */ (8 * 1024) + }; + H5AC2_jnl_config_t jnl_config = + { + /* int version = */ H5AC2__CURR_JNL_CONFIG_VER, + /* hbool_t enable_journaling = */ TRUE, + /* char journal_file_path[] = */ "", + /* hbool_t journal_recovered = */ FALSE, + /* size_t jbrb_buf_size = */ (8 * 1024), + /* int jbrb_num_bufs = */ 2, + /* hbool_t jbrb_use_aio = */ FALSE, + /* hbool_t jbrb_human_readable = */ TRUE + }; + hid_t fapl_id = -1; + hid_t file_id = -1; + haddr_t actual_base_addr; + H5F_t * file_ptr = NULL; + H5C2_t * cache_ptr = NULL; + + 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 setup_cache_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(jnl_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_libver_bounds() on the fapl_id */ + if ( pass2 ) { + + if ( H5Pset_libver_bounds(fapl_id, H5F_LIBVER_LATEST, + H5F_LIBVER_LATEST) < 0 ) { + + pass2 = FALSE; + failure_mssg2 = "H5Pset_libver_bounds() failed.\n"; + } + } + + 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 ( pass2 ) { + + result = H5Pset_jnl_config(fapl_id, &jnl_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++); + + + /**************************************/ + /* Create a file with the fapl above. */ + /**************************************/ + + /* create the file using fapl_id */ + if ( pass2 ) { + + file_id = H5Fcreate(hdf_file_name, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id); + + if ( file_id < 0 ) { + + pass2 = FALSE; + failure_mssg2 = "H5Fcreate() failed.\n"; + + } else { + + file_ptr = (H5F_t *)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); + } + } + } + } + + if ( show_progress ) HDfprintf(stdout, "%s: cp = %d.\n", fcn_name, cp++); + + if ( pass2 ) { /* allocate space for test entries */ + + actual_base_addr = H5MF_alloc(file_ptr, H5FD_MEM_DEFAULT, H5P_DEFAULT, + (hsize_t)(ADDR_SPACE_SIZE + BASE_ADDR)); + + if ( actual_base_addr == HADDR_UNDEF ) { + + pass2 = FALSE; + failure_mssg2 = "H5MF_alloc() failed."; + + if ( verbose ) { + HDfprintf(stdout, "%s: H5MF_alloc() failed.\n", fcn_name); + } + + } else if ( actual_base_addr > BASE_ADDR ) { + + /* If this happens, must increase BASE_ADDR so that the + * actual_base_addr is <= BASE_ADDR. This should only happen + * if the size of the superblock is increase. + */ + pass2 = FALSE; + failure_mssg2 = "actual_base_addr > BASE_ADDR"; + + if ( verbose ) { + HDfprintf(stdout, "%s: actual_base_addr > BASE_ADDR.\n", + fcn_name); + } + } + } + + 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++); + + reset_entries2(); + + if ( show_progress ) HDfprintf(stdout, "%s: cp = %d.\n", fcn_name, cp++); + + /* close the fapl */ + if ( pass2 ) { + + if ( H5Pclose(fapl_id) < 0 ) { + + pass2 = FALSE; + failure_mssg2 = "error closing fapl.\n"; + } + } + + 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; + +} /* setup_cache_for_journaling() */ + + +/*************************************************************************** + * Function: setup_mdj_file_marking_on_create_test + * + * Purpose: Setup test to verify that HDF5 file is marked as having + * journaling in progress when journaling is enabled at file + * creation time. + * + * Do this by creating a test file with metadata journaling + * enabled, and then exiting without closing the file. + * + * Return: void + * + * Programmer: John Mainzer + * 10/8/08 + * + **************************************************************************/ + +static void +setup_mdj_file_marking_on_create_test(hbool_t verbose) +{ + const char * fcn_name = "setup_mdj_file_marking_on_create_test():"; + char filename[512]; + char journal_filename[H5AC2__MAX_JOURNAL_FILE_NAME_LEN + 1]; + hbool_t show_progress = FALSE; + int cp = 0; + uint64_t trans_num; + hid_t file_id = -1; + H5F_t * file_ptr = NULL; + H5C2_t * cache_ptr = NULL; + + /* setup the file name */ + if ( pass2 ) { + + if ( h5_fixname(FILENAMES[1], H5P_DEFAULT, filename, + sizeof(filename)) == NULL ) { + + pass2 = FALSE; + failure_mssg2 = "h5_fixname() failed (1).\n"; + } + } + + if ( show_progress ) { + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, pass2, cp++); + HDfflush(stdout); + } + + if ( verbose ) { + HDfprintf(stdout, "%s filename = \"%s\".\n", fcn_name, filename); + HDfflush(stdout); + } + + /* setup the journal file name */ + if ( pass2 ) { + + if ( h5_fixname(FILENAMES[3], H5P_DEFAULT, journal_filename, + sizeof(journal_filename)) == NULL ) { + + pass2 = FALSE; + failure_mssg2 = "h5_fixname() failed (2).\n"; + } + else if ( strlen(journal_filename) >= + H5AC2__MAX_JOURNAL_FILE_NAME_LEN ) { + + pass2 = FALSE; + failure_mssg2 = "journal file name too long.\n"; + } + } + + if ( show_progress ) { + + HDfprintf(stdout, "%s%d cp = %d.\n", + fcn_name, (int)pass2, cp++); + HDfflush(stdout); + } + + if ( verbose ) { + HDfprintf(stdout, "%s journal filename = \"%s\".\n", + fcn_name, journal_filename); + HDfflush(stdout); + } + + if ( pass2 ) { + + /* clean out any existing journal file */ + HDremove(journal_filename); + setup_cache_for_journaling(filename, journal_filename, &file_id, + &file_ptr, &cache_ptr, FALSE); + + if ( show_progress ) { + + HDfprintf(stdout, "%s%d: cp = %d.\n", fcn_name, (int)pass2, cp++); + HDfflush(stdout); + } + + /* run a dummy transaction to fource metadata journaling + * initialization. + */ + H5C2_begin_transaction(cache_ptr, &trans_num, "dummy"); + H5C2_end_transaction(file_ptr, H5AC2_dxpl_id, cache_ptr, + trans_num, "dummy"); + + if ( show_progress ) { + + HDfprintf(stdout, "%s%d: cp = %d.\n", fcn_name, (int)pass2, cp++); + HDfflush(stdout); + } + + if ( ( verbose ) && ( ! pass2 ) ) { + HDfprintf(stdout, "%s%d failure_mssg = \"%s\".\n", + fcn_name, pass2, failure_mssg2); + HDfflush(stdout); + } + + if ( show_progress ) { + + HDfprintf(stdout, "%s%d cp = %d child exiting.\n", + fcn_name, (int)pass2, cp++); + HDfflush(stdout); + } + + mark_test_in_progress("mdj_file_marking_on_create_test"); + + abort(); + + } + + return; + +} /* setup_mdj_file_marking_on_create_test() */ + + +/*************************************************************************** + * Function: check_mdj_file_marking_on_create_test + * + * Purpose: Check to see if a test to verify that a HDF5 file is marked + * as having journaling in progress when journaling is enabled + * at file creation time passes. + * + * Do this by trying to open the test file created by the + * associated setup function. Open should fail, as the file + * should be marked as journaling in progress. + * + * On either success or failure, clean up the test file and + * the associated journal file. + * + * Return: void + * + * Programmer: John Mainzer + * 10/8/08 + * + **************************************************************************/ + +static void +check_mdj_file_marking_on_create_test(hbool_t verbose) +{ + const char * fcn_name = "check_mdj_file_marking_on_create_test():"; + char filename[512]; + char journal_filename[H5AC2__MAX_JOURNAL_FILE_NAME_LEN + 1]; + hbool_t show_progress = FALSE; + int cp = 0; + hid_t file_id = -1; + hid_t fapl_id = -1; + + check_test_in_progress("mdj_file_marking_on_create_test"); + + /* setup the file name */ + if ( pass2 ) { + + if ( h5_fixname(FILENAMES[1], H5P_DEFAULT, filename, + sizeof(filename)) == NULL ) { + + pass2 = FALSE; + failure_mssg2 = "h5_fixname() failed (1).\n"; + } + } + + if ( show_progress ) { + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, pass2, cp++); + HDfflush(stdout); + } + + if ( verbose ) { + HDfprintf(stdout, "%s filename = \"%s\".\n", fcn_name, filename); + HDfflush(stdout); + } + + /* setup the journal file name */ + if ( pass2 ) { + + if ( h5_fixname(FILENAMES[3], H5P_DEFAULT, journal_filename, + sizeof(journal_filename)) == NULL ) { + + pass2 = FALSE; + failure_mssg2 = "h5_fixname() failed (2).\n"; + } + else if ( strlen(journal_filename) >= + H5AC2__MAX_JOURNAL_FILE_NAME_LEN ) { + + pass2 = FALSE; + failure_mssg2 = "journal file name too long.\n"; + } + } + + if ( show_progress ) { + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, (int)pass2, cp++); + HDfflush(stdout); + } + + if ( verbose ) { + HDfprintf(stdout, "%s journal filename = \"%s\".\n", + fcn_name, journal_filename); + HDfflush(stdout); + } + + if ( pass2 ) { + + if ( show_progress ) { + + HDfprintf(stdout, "%s:%d: cp = %d child exited as expected.\n", + fcn_name, (int)pass2, cp++); + HDfflush(stdout); + } + + /* 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:%d cp = %d.\n", fcn_name, (int)pass2, cp++); + HDfflush(stdout); + } + + /* call H5Pset_libver_bounds() on the fapl_id */ + if ( pass2 ) { + + if ( H5Pset_libver_bounds(fapl_id, H5F_LIBVER_LATEST, + H5F_LIBVER_LATEST) < 0 ) { + + pass2 = FALSE; + failure_mssg2 = "H5Pset_libver_bounds() failed.\n"; + } + } + + if ( show_progress ) { + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, (int)pass2, cp++); + HDfflush(stdout); + } + + /* attempt to open the file -- should fail as the child + * exited without closing the file properly, and thus + * the file should still be marked as having journaling + * in progress. + */ + + if ( pass2 ) { + + H5E_BEGIN_TRY { + + file_id = H5Fopen(filename, H5F_ACC_RDWR, fapl_id); + + } H5E_END_TRY; + + if ( file_id >= 0 ) { + + pass2 = FALSE; + failure_mssg2 = "H5Fopen() succeeded - 1."; + } + } + + if ( show_progress ) { + + HDfprintf(stdout, "%s%d: cp = %d.\n", fcn_name, (int)pass2, cp++); + HDfflush(stdout); + } + + /* delete the HDF5 file and journal file */ +#if 1 + HDremove(filename); + HDremove(journal_filename); +#endif + if ( show_progress ) { + + HDfprintf(stdout, "%s%d cp = %d parent done.\n", + fcn_name, (int)pass2, cp++); + HDfflush(stdout); + } + } + + return; + +} /* check_mdj_file_marking_on_create_test() */ + + +/*************************************************************************** + * Function: setup_mdj_file_marking_after_open_test + * + * Purpose: Setup a test to verify that a HDF5 file is marked as having + * journaling in progress when journaling is enabled on an + * open file. + * + * Do this by: + * + * 1) creating a test file, + * + * 2) writing some data to it, + * + * 3) enable journaling on the open file via a call to + * H5Fset_mdc_config() + * + * 4) exiting without closing the file. + * + * set pass2 to FALSE and set a failure message if errors + * are detected. + * + * Return: void + * + * Programmer: John Mainzer + * 10/8/08 + * + **************************************************************************/ + +static void +setup_mdj_file_marking_after_open_test(hbool_t verbose) +{ + const char * fcn_name = "setup_mdj_file_marking_after_open_test():"; + char filename[512]; + char journal_filename[H5AC2__MAX_JOURNAL_FILE_NAME_LEN + 1]; + hbool_t show_progress = FALSE; + herr_t result; + int cp = 0; + hid_t file_id = -1; + hid_t fapl_id = -1; + hid_t dataset_id = -1; + hid_t dataspace_id = -1; + hsize_t dims[2]; + H5AC2_jnl_config_t jnl_config; + + /* setup the file name */ + if ( pass2 ) { + + if ( h5_fixname(FILENAMES[1], H5P_DEFAULT, filename, + sizeof(filename)) == NULL ) { + + pass2 = FALSE; + failure_mssg2 = "h5_fixname() failed (1).\n"; + } + } + + if ( show_progress ) { + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, pass2, cp++); + HDfflush(stdout); + } + + if ( verbose ) { + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, pass2, cp++); + HDfflush(stdout); + } + + /* setup the journal file name */ + if ( pass2 ) { + + if ( h5_fixname(FILENAMES[3], H5P_DEFAULT, journal_filename, + sizeof(journal_filename)) == NULL ) { + + pass2 = FALSE; + failure_mssg2 = "h5_fixname() failed (2).\n"; + } + else if ( strlen(journal_filename) >= + H5AC2__MAX_JOURNAL_FILE_NAME_LEN ) { + + pass2 = FALSE; + failure_mssg2 = "journal file name too long.\n"; + } + } + + if ( show_progress ) { + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, (int)pass2, cp++); + HDfflush(stdout); + } + + if ( verbose ) { + HDfprintf(stdout, "%s journal filename = \"%s\".\n", + fcn_name, journal_filename); + HDfflush(stdout); + } + + if ( pass2 ) { + + /* 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%d cp = %d.\n", fcn_name, pass2, cp++); + HDfflush(stdout); + } + + /* call H5Pset_libver_bounds() on the fapl_id */ + if ( pass2 ) { + + if ( H5Pset_libver_bounds(fapl_id, H5F_LIBVER_LATEST, + H5F_LIBVER_LATEST) < 0 ) { + + pass2 = FALSE; + failure_mssg2 = "H5Pset_libver_bounds() failed.\n"; + } + } + + /* open the file with a fapl indicating latest version of + * the file format. + */ + if ( pass2 ) { + + file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id); + + if ( file_id < 0 ) { + + pass2 = FALSE; + failure_mssg2 = "H5Fcreate() failed.\n"; + } + } + + if ( show_progress ) { + + HDfprintf(stdout, "%s%d: cp = %d.\n", fcn_name, (int)pass2, cp++); + HDfflush(stdout); + } + + if ( pass2 ) { + + dims[0] = 4; + dims[1] = 6; + dataspace_id = H5Screate_simple(2, dims, NULL); + + if ( dataspace_id < 0 ) { + + pass2 = FALSE; + failure_mssg2 = "H5Screate_simple() failed."; + } + } + + if ( show_progress ) { + + HDfprintf(stdout, "%s%d: cp = %d.\n", fcn_name, (int)pass2, cp++); + HDfflush(stdout); + } + + if ( pass2 ) { + + /* Create the dataset. */ + dataset_id = H5Dcreate2(file_id, "/dset", H5T_STD_I32BE, + dataspace_id, H5P_DEFAULT, + H5P_DEFAULT, H5P_DEFAULT); + + if ( dataspace_id < 0 ) { + + pass2 = FALSE; + failure_mssg2 = "H5Dcreate2() failed."; + } + } + + if ( show_progress ) { + + HDfprintf(stdout, "%s%d: cp = %d.\n", fcn_name, (int)pass2, cp++); + HDfflush(stdout); + } + + /* now enable journaling */ + if ( pass2 ) { + + jnl_config.version = H5AC2__CURR_JNL_CONFIG_VER; + + result = H5Fget_jnl_config(file_id, &jnl_config); + + if ( result < 0 ) { + + pass2 = FALSE; + failure_mssg2 = "H5Fget_jnl_config() failed.\n"; + } + + /* set journaling config fields to taste */ + jnl_config.enable_journaling = TRUE; + + strcpy(jnl_config.journal_file_path, journal_filename); + + jnl_config.journal_recovered = FALSE; + jnl_config.jbrb_buf_size = (8 * 1024); + jnl_config.jbrb_num_bufs = 2; + jnl_config.jbrb_use_aio = FALSE; + jnl_config.jbrb_human_readable = TRUE; + } + + if ( show_progress ) { + + HDfprintf(stdout, "%s%d: cp = %d.\n", fcn_name, (int)pass2, cp++); + HDfflush(stdout); + } + + if ( pass2 ) { + + result = H5Fset_jnl_config(file_id, &jnl_config); + + if ( result < 0 ) { + + pass2 = FALSE; + failure_mssg2 = "H5Fset_jnl_config() failed.\n"; + } + } + + if ( show_progress ) { + + HDfprintf(stdout, "%s%d: cp = %d.\n", fcn_name, (int)pass2, cp++); + HDfflush(stdout); + } + + if ( ( verbose ) && ( ! pass2 ) ) { + HDfprintf(stdout, "%s%d failure_mssg = \"%s\".\n", + fcn_name, pass2, failure_mssg2); + HDfflush(stdout); + } + + if ( show_progress ) { + + HDfprintf(stdout, "%s%d cp = %d exiting.\n", + fcn_name, (int)pass2, cp++); + HDfflush(stdout); + } + + mark_test_in_progress("mdj_file_marking_after_open_test"); + + abort(); + + } + + return; + +} /* setup_mdj_file_marking_after_open_test() */ + + +/*************************************************************************** + * Function: check_mdj_file_marking_after_open_test + * + * Purpose: Check to see if the test to rvVerify that a HDF5 file is + * marked as having journaling in progress when journaling is + * enabled on an open file passed. + * + * Try to open the test file created by the associated setup + * function. Open should fail, as the file should be marked + * as journaling in progress. + * + * On either success or failure, clean up the test file and + * the associated journal file. + * + * Return: void + * + * Programmer: John Mainzer + * 10/8/08 + * + **************************************************************************/ + +static void +check_mdj_file_marking_after_open_test(hbool_t verbose) +{ + const char * fcn_name = "check_mdj_file_marking_after_open_test():"; + char filename[512]; + char journal_filename[H5AC2__MAX_JOURNAL_FILE_NAME_LEN + 1]; + hbool_t show_progress = FALSE; + int cp = 0; + hid_t file_id = -1; + hid_t fapl_id = -1; + + check_test_in_progress("mdj_file_marking_after_open_test"); + + /* setup the file name */ + if ( pass2 ) { + + if ( h5_fixname(FILENAMES[1], H5P_DEFAULT, filename, + sizeof(filename)) == NULL ) { + + pass2 = FALSE; + failure_mssg2 = "h5_fixname() failed (1).\n"; + } + } + + if ( show_progress ) { + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, pass2, cp++); + HDfflush(stdout); + } + + if ( verbose ) { + HDfprintf(stdout, "%s filename = \"%s\".\n", fcn_name, filename); + HDfflush(stdout); + } + + /* setup the journal file name */ + if ( pass2 ) { + + if ( h5_fixname(FILENAMES[3], H5P_DEFAULT, journal_filename, + sizeof(journal_filename)) == NULL ) { + + pass2 = FALSE; + failure_mssg2 = "h5_fixname() failed (2).\n"; + } + else if ( strlen(journal_filename) >= + H5AC2__MAX_JOURNAL_FILE_NAME_LEN ) { + + pass2 = FALSE; + failure_mssg2 = "journal file name too long.\n"; + } + } + + if ( show_progress ) { + + HDfprintf(stdout, "%s%d cp = %d.\n", + fcn_name, (int)pass2, cp++); + HDfflush(stdout); + } + + if ( verbose ) { + HDfprintf(stdout, "%s journal filename = \"%s\".\n", + fcn_name, journal_filename); + HDfflush(stdout); + } + + if ( pass2 ) { + + /* 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:%d cp = %d.\n", + fcn_name, (int)pass2, cp++); + HDfflush(stdout); + } + + /* call H5Pset_libver_bounds() on the fapl_id */ + if ( pass2 ) { + + if ( H5Pset_libver_bounds(fapl_id, H5F_LIBVER_LATEST, + H5F_LIBVER_LATEST) < 0 ) { + + pass2 = FALSE; + failure_mssg2 = "H5Pset_libver_bounds() failed.\n"; + } + } + + if ( show_progress ) { + HDfprintf(stdout, "%s%d cp = %d.\n", + fcn_name, (int)pass2, cp++); + HDfflush(stdout); + } + + /* attempt to open the file -- should fail as the setup program + * exited without closing the file properly, and thus + * the file should still be marked as having journaling + * in progress. + */ + + if ( pass2 ) { + + H5E_BEGIN_TRY { + + file_id = H5Fopen(filename, H5F_ACC_RDWR, fapl_id); + + } H5E_END_TRY; + + if ( file_id >= 0 ) { + + pass2 = FALSE; + failure_mssg2 = "H5Fopen() succeeded - 2."; + } + } + + if ( show_progress ) { + + HDfprintf(stdout, "%s%d: cp = %d.\n", + fcn_name, (int)pass2, cp++); + HDfflush(stdout); + } + + /* delete the HDF5 file and journal file */ +#if 1 + HDremove(filename); + HDremove(journal_filename); +#endif + if ( show_progress ) { + + HDfprintf(stdout, "%s%d cp = %d parent done.\n", + fcn_name, (int)pass2, cp++); + HDfflush(stdout); + } + } + + return; + +} /* check_mdj_file_marking_after_open_test() */ + + +/*************************************************************************** + * Function: setup_mdj_file_marking_on_open_test + * + * Purpose: Setup test to verify that a HDF5 file is marked as having + * journaling in progress when journaling is enabled at file + * open time. + * + * Do this by: + * + * 1) creating a test file in the child, + * + * 2) writing some data to it, + * + * 3) closing the test file. + * + * 4) re-openting the test file with metadata journaling + * enabled, and then + * + * 5) exiting from the child without closing the file. + * + * Return: void + * + * Programmer: John Mainzer + * 10/8/08 + * + **************************************************************************/ + +static void +setup_mdj_file_marking_on_open_test(hbool_t verbose) +{ + const char * fcn_name = "setup_mdj_file_marking_on_open_test():"; + char filename[512]; + char journal_filename[H5AC2__MAX_JOURNAL_FILE_NAME_LEN + 1]; + hbool_t show_progress = FALSE; + herr_t result; + int cp = 0; + hid_t file_id = -1; + hid_t fapl_id = -1; + hid_t dataset_id = -1; + hid_t dataspace_id = -1; + hsize_t dims[2]; + H5F_t * file_ptr = NULL; + H5AC2_jnl_config_t jnl_config; + + /* setup the file name */ + if ( pass2 ) { + + if ( h5_fixname(FILENAMES[1], H5P_DEFAULT, filename, + sizeof(filename)) == NULL ) { + + pass2 = FALSE; + failure_mssg2 = "h5_fixname() failed (1).\n"; + } + } + + if ( show_progress ) { + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, pass2, cp++); + HDfflush(stdout); + } + + if ( verbose ) { + HDfprintf(stdout, "%s filename = \"%s\".\n", fcn_name, filename); + HDfflush(stdout); + } + + /* setup the journal file name */ + if ( pass2 ) { + + if ( h5_fixname(FILENAMES[3], H5P_DEFAULT, journal_filename, + sizeof(journal_filename)) == NULL ) { + + pass2 = FALSE; + failure_mssg2 = "h5_fixname() failed (2).\n"; + } + else if ( strlen(journal_filename) >= + H5AC2__MAX_JOURNAL_FILE_NAME_LEN ) { + + pass2 = FALSE; + failure_mssg2 = "journal file name too long.\n"; + } + } + + if ( show_progress ) { + + HDfprintf(stdout, "%s%d cp = %d.\n", + fcn_name, (int)pass2, cp++); + HDfflush(stdout); + } + + if ( verbose ) { + HDfprintf(stdout, "%s journal filename = \"%s\".\n", + fcn_name, journal_filename); + HDfflush(stdout); + } + + if ( pass2 ) { + +#if 0 /* JRM */ + /* Quincey: + * + * It looks like we may have a bug here -- + * + * In the original version of this test, I: + * + * 1) created a file using the default FAPL, + * + * 2) added a data set to the file + * + * 3) closed it, + * + * 4) tried to re-open it using a FAPL that set the + * latest format, and enabled journaling. + * + * I hit an assertion failure on step 4. + * + * I then modified the above to select the latest file + * format on file create, and the problem went away. + * + * Is this as it should be, or do we have a bug here? + * + * JRM -- 7/9/08 + */ + + if ( pass2 ) { + + file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, + H5P_DEFAULT); + + if ( file_id < 0 ) { + + pass2 = FALSE; + failure_mssg2 = "H5Fcreate() failed.\n"; + } + } +#else /* JRM */ + + /* 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%d: cp = %d.\n", fcn_name, (int)pass2, cp++); + HDfflush(stdout); + } + + /* call H5Pset_libver_bounds() on the fapl_id */ + if ( pass2 ) { + + if ( H5Pset_libver_bounds(fapl_id, H5F_LIBVER_LATEST, + H5F_LIBVER_LATEST) < 0 ) { + + pass2 = FALSE; + failure_mssg2 = "H5Pset_libver_bounds() failed.\n"; + } + } + + /* open the file with a fapl indicating latest version of + * the file format. + */ + if ( pass2 ) { + + file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id); + + if ( file_id < 0 ) { + + pass2 = FALSE; + failure_mssg2 = "H5Fcreate() failed.\n"; + } + } +#endif /* JRM */ + if ( show_progress ) { + + HDfprintf(stdout, "%s%d: cp = %d.\n", fcn_name, (int)pass2, cp++); + HDfflush(stdout); + } + + if ( pass2 ) { + + dims[0] = 4; + dims[1] = 6; + dataspace_id = H5Screate_simple(2, dims, NULL); + + if ( dataspace_id < 0 ) { + + pass2 = FALSE; + failure_mssg2 = "H5Screate_simple() failed."; + } + } + + if ( show_progress ) { + + HDfprintf(stdout, "%s%d: cp = %d.\n", fcn_name, (int)pass2, cp++); + HDfflush(stdout); + } + + if ( pass2 ) { + + /* Create the dataset. */ + dataset_id = H5Dcreate2(file_id, "/dset", H5T_STD_I32BE, + dataspace_id, H5P_DEFAULT, + H5P_DEFAULT, H5P_DEFAULT); + + if ( dataspace_id < 0 ) { + + pass2 = FALSE; + failure_mssg2 = "H5Dcreate2() failed."; + } + } + + if ( show_progress ) { + + HDfprintf(stdout, "%s%d: cp = %d.\n", fcn_name, (int)pass2, cp++); + HDfflush(stdout); + } + + if ( pass2 ) { + + /* close the data set, the data space, and the file */ + if ( ( H5Dclose(dataset_id) < 0 ) || + ( H5Sclose(dataspace_id) < 0 ) || +#if 1 /* JRM */ + ( H5Pclose(fapl_id) < 0 ) || +#endif /* JRM */ + ( H5Fclose(file_id) < 0 ) ) { + + pass2 = FALSE; + failure_mssg2 = "data set, data space, or file close failed."; + } + } + + if ( show_progress ) { + + HDfprintf(stdout, "%s%d: cp = %d.\n", fcn_name, (int)pass2, cp++); + HDfflush(stdout); + } + + /* 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%d: cp = %d.\n", fcn_name, (int)pass2, cp++); + HDfflush(stdout); + } + + /* call H5Pset_libver_bounds() on the fapl_id */ + if ( pass2 ) { + + if ( H5Pset_libver_bounds(fapl_id, H5F_LIBVER_LATEST, + H5F_LIBVER_LATEST) < 0 ) { + + pass2 = FALSE; + failure_mssg2 = "H5Pset_libver_bounds() failed.\n"; + } + } + + if ( show_progress ) { + + HDfprintf(stdout, "%s%d: cp = %d.\n", fcn_name, (int)pass2, cp++); + HDfflush(stdout); + } + + if ( pass2 ) { + + jnl_config.version = H5AC2__CURR_JNL_CONFIG_VER; + + result = H5Pget_jnl_config(fapl_id, &jnl_config); + + if ( result < 0 ) { + + pass2 = FALSE; + failure_mssg2 = "H5Pget_jnl_config() failed.\n"; + } + + /* set journaling config fields to taste */ + jnl_config.enable_journaling = TRUE; + + strcpy(jnl_config.journal_file_path, journal_filename); + + jnl_config.journal_recovered = FALSE; + jnl_config.jbrb_buf_size = (8 * 1024); + jnl_config.jbrb_num_bufs = 2; + jnl_config.jbrb_use_aio = FALSE; + jnl_config.jbrb_human_readable = TRUE; + } + + if ( show_progress ) { + + HDfprintf(stdout, "%s%d: cp = %d.\n", fcn_name, (int)pass2, cp++); + HDfflush(stdout); + } + + if ( pass2 ) { + + result = H5Pset_jnl_config(fapl_id, &jnl_config); + + if ( result < 0 ) { + + pass2 = FALSE; + failure_mssg2 = "H5Pset_jnl_config() failed.\n"; + } + } + + if ( show_progress ) { + + HDfprintf(stdout, "%s%d: cp = %d.\n", fcn_name, (int)pass2, cp++); + HDfflush(stdout); + } + + /* open the file using fapl_id */ + if ( pass2 ) { + + file_id = H5Fopen(filename, H5F_ACC_RDWR, fapl_id); + + if ( file_id < 0 ) { + + pass2 = FALSE; + failure_mssg2 = "H5Fopen() failed (9).\n"; + + } else { + + file_ptr = (H5F_t *)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); + } + } + } + } + + if ( show_progress ) { + + HDfprintf(stdout, "%s%d: cp = %d.\n", fcn_name, (int)pass2, cp++); + HDfflush(stdout); + } + + if ( ( verbose ) && ( ! pass2 ) ) { + + HDfprintf(stdout, "%s%d failure_mssg = \"%s\".\n", + fcn_name, pass2, failure_mssg2); + HDfflush(stdout); + } + + if ( show_progress ) { + + HDfprintf(stdout, "%s%d cp = %d exiting.\n", + fcn_name, (int)pass2, cp++); + HDfflush(stdout); + } + + mark_test_in_progress("mdj_file_marking_on_open_test"); + + abort(); + } + + return; + +} /* setup_mdj_file_marking_on_open_test() */ + + +/*************************************************************************** + * Function: check_mdj_file_marking_on_open_test + * + * Purpose: Check to verify that a HDF5 file is marked as having + * journaling in progress when journaling is enabled at + * file open time. + * + * Do this by trying to open the test file created by the + * associated setup function. + * + * Open should fail, as the file should be marked as journaling + * in progress. + * + * On either success or failure, clean up the test file and + * the associated journal file. + * + * Return: void + * + * Programmer: John Mainzer + * 10/8/08 + * + **************************************************************************/ + +static void +check_mdj_file_marking_on_open_test(hbool_t verbose) +{ + const char * fcn_name = "check_mdj_file_marking_on_open_test():"; + char filename[512]; + char journal_filename[H5AC2__MAX_JOURNAL_FILE_NAME_LEN + 1]; + hbool_t show_progress = FALSE; + int cp = 0; + hid_t file_id = -1; + hid_t fapl_id = -1; + + check_test_in_progress("mdj_file_marking_on_open_test"); + + /* setup the file name */ + if ( pass2 ) { + + if ( h5_fixname(FILENAMES[1], H5P_DEFAULT, filename, + sizeof(filename)) == NULL ) { + + pass2 = FALSE; + failure_mssg2 = "h5_fixname() failed (1).\n"; + } + } + + if ( show_progress ) { + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, pass2, cp++); + HDfflush(stdout); + } + + if ( verbose ) { + HDfprintf(stdout, "%s filename = \"%s\".\n", fcn_name, filename); + HDfflush(stdout); + } + + /* setup the journal file name */ + if ( pass2 ) { + + if ( h5_fixname(FILENAMES[3], H5P_DEFAULT, journal_filename, + sizeof(journal_filename)) == NULL ) { + + pass2 = FALSE; + failure_mssg2 = "h5_fixname() failed (2).\n"; + } + else if ( strlen(journal_filename) >= + H5AC2__MAX_JOURNAL_FILE_NAME_LEN ) { + + pass2 = FALSE; + failure_mssg2 = "journal file name too long.\n"; + } + } + + if ( show_progress ) { + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, (int)pass2, cp++); + HDfflush(stdout); + } + + if ( verbose ) { + HDfprintf(stdout, "%s journal filename = \"%s\".\n", + fcn_name, journal_filename); + HDfflush(stdout); + } + + if ( pass2 ) { + + /* 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:%d cp = %d.\n", fcn_name, (int)pass2, cp++); + HDfflush(stdout); + } + + /* call H5Pset_libver_bounds() on the fapl_id */ + if ( pass2 ) { + + if ( H5Pset_libver_bounds(fapl_id, H5F_LIBVER_LATEST, + H5F_LIBVER_LATEST) < 0 ) { + + pass2 = FALSE; + failure_mssg2 = "H5Pset_libver_bounds() failed.\n"; + } + } + + if ( show_progress ) { + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, (int)pass2, cp++); + HDfflush(stdout); + } + + /* attempt to open the file -- should fail as the child + * exited without closing the file properly, and thus + * the file should still be marked as having journaling + * in progress. + */ + + if ( pass2 ) { + + H5E_BEGIN_TRY { + + file_id = H5Fopen(filename, H5F_ACC_RDWR, fapl_id); + + } H5E_END_TRY; + + if ( file_id >= 0 ) { + + pass2 = FALSE; + failure_mssg2 = "H5Fopen() succeeded - 3."; + } + } + + if ( show_progress ) { + + HDfprintf(stdout, "%s%d: cp = %d.\n", fcn_name, (int)pass2, cp++); + HDfflush(stdout); + } + + /* delete the HDF5 file and journal file */ +#if 1 + HDremove(filename); + HDremove(journal_filename); +#endif + if ( show_progress ) { + + HDfprintf(stdout, "%s%d cp = %d done.\n", + fcn_name, (int)pass2, cp++); + HDfflush(stdout); + } + } + + return; + +} /* check_mdj_file_marking_on_open_test() */ + + +/*************************************************************************** + * Function: setup_mdj_file_unmarking_on_file_close_test + * + * Purpose: Setup test to verify that a HDF5 file on which journaling + * is enabled is marked as having not having journaling in + * progress when the file is closed. + * + * Do this as follows: + * + * 1) create a test file with metadata journaling + * enabled, + * + * 2) perform some operation(s) that dirty metadata + * and result in journal activity. + * + * 3) close the file. + * + * Return: void + * + * Programmer: John Mainzer + * 10/8/08 + * + **************************************************************************/ + +static void +setup_mdj_file_unmarking_on_file_close_test(hbool_t verbose) +{ + const char * fcn_name = "setup_mdj_file_unmarking_on_file_close_test():"; + char filename[512]; + char journal_filename[H5AC2__MAX_JOURNAL_FILE_NAME_LEN + 1]; + hbool_t show_progress = FALSE; + int cp = 0; + hid_t file_id = -1; + hid_t dataset_id = -1; + hid_t dataspace_id = -1; + hsize_t dims[2]; + H5F_t * file_ptr = NULL; + H5C2_t * cache_ptr = NULL; + + if ( show_progress ) { + + HDfprintf(stdout, "%s%d cp = %d -- entering.\n", fcn_name, pass2, cp++); + HDfflush(stdout); + } + + /* setup the file name */ + if ( pass2 ) { + + if ( h5_fixname(FILENAMES[1], H5P_DEFAULT, filename, + sizeof(filename)) == NULL ) { + + pass2 = FALSE; + failure_mssg2 = "h5_fixname() failed (1).\n"; + } + } + + if ( show_progress ) { + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, pass2, cp++); + HDfflush(stdout); + } + + if ( verbose ) { + HDfprintf(stdout, "%s filename = \"%s\".\n", fcn_name, filename); + HDfflush(stdout); + } + + /* setup the journal file name */ + if ( pass2 ) { + + if ( h5_fixname(FILENAMES[3], H5P_DEFAULT, journal_filename, + sizeof(journal_filename)) == NULL ) { + + pass2 = FALSE; + failure_mssg2 = "h5_fixname() failed (2).\n"; + } + else if ( strlen(journal_filename) >= + H5AC2__MAX_JOURNAL_FILE_NAME_LEN ) { + + pass2 = FALSE; + failure_mssg2 = "journal file name too long.\n"; + } + } + + if ( show_progress ) { + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, (int)pass2, cp++); + HDfflush(stdout); + } + + if ( verbose ) { + HDfprintf(stdout, "%s journal filename = \"%s\".\n", + fcn_name, journal_filename); + HDfflush(stdout); + } + + if ( pass2 ) { + + /* clean out any existing journal file */ + setup_cache_for_journaling(filename, journal_filename, &file_id, + &file_ptr, &cache_ptr, FALSE); + } + + if ( show_progress ) { + + HDfprintf(stdout, "%s%d: cp = %d.\n", fcn_name, (int)pass2, cp++); + HDfflush(stdout); + } + + /* create a data set so as to force a bit of journaling */ + if ( pass2 ) { + + dims[0] = 4; + dims[1] = 6; + dataspace_id = H5Screate_simple(2, dims, NULL); + + if ( dataspace_id < 0 ) { + + pass2 = FALSE; + failure_mssg2 = "H5Screate_simple() failed."; + } + } + + if ( show_progress ) { + + HDfprintf(stdout, "%s%d: cp = %d.\n", fcn_name, (int)pass2, cp++); + HDfflush(stdout); + } + + if ( pass2 ) { + + /* Create the dataset. */ + dataset_id = H5Dcreate2(file_id, "/dset", H5T_STD_I32BE, + dataspace_id, H5P_DEFAULT, + H5P_DEFAULT, H5P_DEFAULT); + + if ( dataspace_id < 0 ) { + + pass2 = FALSE; + failure_mssg2 = "H5Dcreate2() failed."; + } + } + + if ( show_progress ) { + + HDfprintf(stdout, "%s%d: cp = %d.\n", fcn_name, (int)pass2, cp++); + HDfflush(stdout); + } + + /* now close the file... */ + + if ( pass2 ) { + + if ( ( H5Dclose(dataset_id) < 0 ) || + ( H5Sclose(dataspace_id) < 0 ) || + ( H5Fclose(file_id) < 0 ) ) { + + pass2 = FALSE; + failure_mssg2 = "dataset, dataspace, or file close failed."; + } + } + + if ( show_progress ) { + + HDfprintf(stdout, "%s%d: cp = %d.\n", fcn_name, (int)pass2, cp++); + HDfflush(stdout); + } + + mark_test_in_progress("mdj_file_unmarking_on_file_close_test"); + + return; + +} /* setup_mdj_file_unmarking_on_file_close_test() */ + + +/*************************************************************************** + * Function: check_mdj_file_unmarking_on_file_close_test + * + * Purpose: Check to verify that a HDF5 file on which journaling is + * enabled is marked as having not having journaling in + * progress when the file is closed. + * + * To do this, attempt to re-open the file created by the + * associated setup function. This should succeed. + * + * On either success or failure, clean up the test file and + * the associated journal file. + * + * Return: void + * + * Programmer: John Mainzer + * 10/8/08 + * + **************************************************************************/ + +static void +check_mdj_file_unmarking_on_file_close_test(hbool_t verbose) +{ + const char * fcn_name = "check_mdj_file_unmarking_on_file_close_test():"; + char filename[512]; + char journal_filename[H5AC2__MAX_JOURNAL_FILE_NAME_LEN + 1]; + hbool_t show_progress = FALSE; + int cp = 0; + hid_t fapl_id = -1; + hid_t file_id = -1; + + if ( show_progress ) { + + HDfprintf(stdout, "%s%d cp = %d -- entering.\n", fcn_name, pass2, cp++); + HDfflush(stdout); + } + + check_test_in_progress("mdj_file_unmarking_on_file_close_test"); + + /* setup the file name */ + if ( pass2 ) { + + if ( h5_fixname(FILENAMES[1], H5P_DEFAULT, filename, + sizeof(filename)) == NULL ) { + + pass2 = FALSE; + failure_mssg2 = "h5_fixname() failed (1).\n"; + } + } + + if ( show_progress ) { + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, pass2, cp++); + HDfflush(stdout); + } + + if ( verbose ) { + HDfprintf(stdout, "%s filename = \"%s\".\n", fcn_name, filename); + HDfflush(stdout); + } + + /* setup the journal file name */ + if ( pass2 ) { + + if ( h5_fixname(FILENAMES[3], H5P_DEFAULT, journal_filename, + sizeof(journal_filename)) == NULL ) { + + pass2 = FALSE; + failure_mssg2 = "h5_fixname() failed (2).\n"; + } + else if ( strlen(journal_filename) >= + H5AC2__MAX_JOURNAL_FILE_NAME_LEN ) { + + pass2 = FALSE; + failure_mssg2 = "journal file name too long.\n"; + } + } + + if ( show_progress ) { + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, (int)pass2, cp++); + HDfflush(stdout); + } + + if ( verbose ) { + HDfprintf(stdout, "%s journal filename = \"%s\".\n", + fcn_name, journal_filename); + HDfflush(stdout); + } + + /* attempt to re-open file created by setup. Should succeed */ + + /* 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%d: cp = %d.\n", fcn_name, (int)pass2, cp++); + HDfflush(stdout); + } + + /* call H5Pset_libver_bounds() on the fapl_id */ + if ( pass2 ) { + + if ( H5Pset_libver_bounds(fapl_id, H5F_LIBVER_LATEST, + H5F_LIBVER_LATEST) < 0 ) { + + pass2 = FALSE; + failure_mssg2 = "H5Pset_libver_bounds() failed.\n"; + } + } + + if ( show_progress ) { + + HDfprintf(stdout, "%s%d: cp = %d.\n", fcn_name, (int)pass2, cp++); + HDfflush(stdout); + } + + /* attempt to open the file -- should succeed as the close should + * shutdown journaling. + */ + + if ( pass2 ) { + + file_id = H5Fopen(filename, H5F_ACC_RDWR, fapl_id); + + if ( file_id < 0 ) { + + pass2 = FALSE; + failure_mssg2 = "H5Fopen() failed (10)."; + } + } + + if ( show_progress ) { + + HDfprintf(stdout, "%s%d: cp = %d.\n", fcn_name, (int)pass2, cp++); + HDfflush(stdout); + } + + /* close the file and fapl */ + + if ( pass2 ) { + + if ( ( H5Pclose(fapl_id) < 0 ) || + ( H5Fclose(file_id) < 0 ) ) { + + pass2 = FALSE; + failure_mssg2 = "fapl or file close failed."; + } + } + + if ( show_progress ) { + + HDfprintf(stdout, "%s%d: cp = %d.\n", fcn_name, (int)pass2, cp++); + HDfflush(stdout); + } + + /* delete the HDF5 file and journal file */ +#if 1 + HDremove(filename); + HDremove(journal_filename); +#endif + + if ( show_progress ) { + + HDfprintf(stdout, "%s%d: cp = %d.\n", fcn_name, (int)pass2, cp++); + HDfflush(stdout); + } + + return; + +} /* verify_mdj_file_unmarking_on_file_close() */ + + +/*************************************************************************** + * Function: setup_mdj_file_unmarking_on_journaling_shutdown_test + * + * Purpose: Setup test to verify that a HDF5 file on which journaling + * is enabled is marked as having not having journaling in + * progress when journaling is disabled via the + * H5Fset_mdc_config() API call. + * + * Do this by: + * + * 1) creating a test file in the child with metadata + * journaling enabled, + * + * 2) performing some operation(s) that dirty metadata + * and result in journal activity. + * + * 3) using the H5Fset_mdc_config() to disable journaling. + * + * 4) exiting from the child without closing the file. + * + * Return: void + * + * Programmer: John Mainzer + * 7/9/08 + * + **************************************************************************/ + +static void +setup_mdj_file_unmarking_on_journaling_shutdown_test(hbool_t verbose) +{ + const char * fcn_name = + "setup_mdj_file_unmarking_on_journaling_shutdown_test():"; + char filename[512]; + char journal_filename[H5AC2__MAX_JOURNAL_FILE_NAME_LEN + 1]; + hbool_t show_progress = FALSE; + herr_t result; + int cp = 0; + hid_t file_id = -1; + hid_t dataset_id = -1; + hid_t dataspace_id = -1; + hsize_t dims[2]; + H5F_t * file_ptr = NULL; + H5C2_t * cache_ptr = NULL; + H5AC2_jnl_config_t jnl_config; + + /* setup the file name */ + if ( pass2 ) { + + if ( h5_fixname(FILENAMES[1], H5P_DEFAULT, filename, + sizeof(filename)) == NULL ) { + + pass2 = FALSE; + failure_mssg2 = "h5_fixname() failed (1).\n"; + } + } + + if ( show_progress ) { + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, pass2, cp++); + HDfflush(stdout); + } + + if ( verbose ) { + HDfprintf(stdout, "%s filename = \"%s\".\n", fcn_name, filename); + HDfflush(stdout); + } + + /* setup the journal file name */ + if ( pass2 ) { + + if ( h5_fixname(FILENAMES[3], H5P_DEFAULT, journal_filename, + sizeof(journal_filename)) == NULL ) { + + pass2 = FALSE; + failure_mssg2 = "h5_fixname() failed (2).\n"; + } + else if ( strlen(journal_filename) >= + H5AC2__MAX_JOURNAL_FILE_NAME_LEN ) { + + pass2 = FALSE; + failure_mssg2 = "journal file name too long.\n"; + } + } + + if ( show_progress ) { + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, (int)pass2, cp++); + HDfflush(stdout); + } + + if ( verbose ) { + HDfprintf(stdout, "%s journal filename = \"%s\".\n", + fcn_name, journal_filename); + HDfflush(stdout); + } + + if ( pass2 ) { + + /* clean out any existing journal file */ + setup_cache_for_journaling(filename, journal_filename, &file_id, + &file_ptr, &cache_ptr, FALSE); + + if ( show_progress ) { + + HDfprintf(stdout, "%s%d: cp = %d.\n", fcn_name, (int)pass2, cp++); + HDfflush(stdout); + } + + /* create a data set so as to force a bit of journaling */ + if ( pass2 ) { + + dims[0] = 4; + dims[1] = 6; + dataspace_id = H5Screate_simple(2, dims, NULL); + + if ( dataspace_id < 0 ) { + + pass2 = FALSE; + failure_mssg2 = "H5Screate_simple() failed."; + } + } + + if ( show_progress ) { + + HDfprintf(stdout, "%s%d: cp = %d.\n", fcn_name, (int)pass2, cp++); + HDfflush(stdout); + } + + if ( pass2 ) { + + /* Create the dataset. */ + dataset_id = H5Dcreate2(file_id, "/dset", H5T_STD_I32BE, + dataspace_id, H5P_DEFAULT, + H5P_DEFAULT, H5P_DEFAULT); + + if ( dataspace_id < 0 ) { + + pass2 = FALSE; + failure_mssg2 = "H5Dcreate2() failed."; + } + } + + if ( show_progress ) { + + HDfprintf(stdout, "%s%d: cp = %d.\n", fcn_name, (int)pass2, cp++); + HDfflush(stdout); + } + + /* now dis-able journaling */ + if ( pass2 ) { + + jnl_config.version = H5AC2__CURR_JNL_CONFIG_VER; + + result = H5Fget_jnl_config(file_id, &jnl_config); + + if ( result < 0 ) { + + pass2 = FALSE; + failure_mssg2 = "H5Fget_jnl_config() failed.\n"; + } + + jnl_config.enable_journaling = FALSE; + } + + if ( show_progress ) { + + HDfprintf(stdout, "%s%d: cp = %d.\n", fcn_name, (int)pass2, cp++); + HDfflush(stdout); + } + + if ( pass2 ) { + + result = H5Fset_jnl_config(file_id, &jnl_config); + + if ( result < 0 ) { + + pass2 = FALSE; + failure_mssg2 = "H5Fset_jnl_config() failed.\n"; + } + } + + if ( show_progress ) { + + HDfprintf(stdout, "%s%d: cp = %d.\n", fcn_name, (int)pass2, cp++); + HDfflush(stdout); + } + + if ( ( verbose ) && ( ! pass2 ) ) { + HDfprintf(stdout, "%s%d failure_mssg = \"%s\".\n", + fcn_name, pass2, failure_mssg2); + HDfflush(stdout); + } + + if ( show_progress ) { + + HDfprintf(stdout, "%s%d cp = %d exiting.\n", + fcn_name, (int)pass2, cp++); + HDfflush(stdout); + } + + mark_test_in_progress("mdj_file_unmarking_on_journaling_shutdown_test"); + + abort(); + } + + return; + +} /* setup_mdj_file_unmarking_on_journaling_shutdown_test() */ + + +/*************************************************************************** + * Function: check_mdj_file_unmarking_on_journaling_shutdown_test + * + * Purpose: Check to verify that a HDF5 file on which journaling is + * enabled is marked as having not having journaling in + * progress when journaling is disabled via the + * H5Fset_mdc_config() API call. + * + * Do this by trying to open the test file created by the + * associated setup function. + * + * Open should succeed, as the file should be marked as + * journaling not in progress. + * + * Note that the file will be synced out as part of the + * journaling shutdown process, so the metadata should be + * in a consistant state. Strictly speaking, this is not + * necessary for this test, for as long as the the file is + * not marked as having journaling in progress, we should + * pass. However, testing this without using the HDF5 + * library to open the file would be inconvenient -- hence + * we make use of the sync on journal shutdown to make the + * test easier to implement. + * + * On either success or failure, clean up the test file and + * the associated journal file. + * + * Return: void + * + * Programmer: John Mainzer + * 10/8/08 + * + **************************************************************************/ + +static void +check_mdj_file_unmarking_on_journaling_shutdown_test(hbool_t verbose) +{ + const char * fcn_name = + "check_mdj_file_unmarking_on_journaling_shutdown_test():"; + char filename[512]; + char journal_filename[H5AC2__MAX_JOURNAL_FILE_NAME_LEN + 1]; + hbool_t show_progress = FALSE; + int cp = 0; + hid_t file_id = -1; + hid_t fapl_id = -1; + + check_test_in_progress("mdj_file_unmarking_on_journaling_shutdown_test"); + + /* setup the file name */ + if ( pass2 ) { + + if ( h5_fixname(FILENAMES[1], H5P_DEFAULT, filename, + sizeof(filename)) == NULL ) { + + pass2 = FALSE; + failure_mssg2 = "h5_fixname() failed (1).\n"; + } + } + + if ( show_progress ) { + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, pass2, cp++); + HDfflush(stdout); + } + + if ( verbose ) { + HDfprintf(stdout, "%s filename = \"%s\".\n", fcn_name, filename); + HDfflush(stdout); + } + + /* setup the journal file name */ + if ( pass2 ) { + + if ( h5_fixname(FILENAMES[3], H5P_DEFAULT, journal_filename, + sizeof(journal_filename)) == NULL ) { + + pass2 = FALSE; + failure_mssg2 = "h5_fixname() failed (2).\n"; + } + else if ( strlen(journal_filename) >= + H5AC2__MAX_JOURNAL_FILE_NAME_LEN ) { + + pass2 = FALSE; + failure_mssg2 = "journal file name too long.\n"; + } + } + + if ( show_progress ) { + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, (int)pass2, cp++); + HDfflush(stdout); + } + + if ( verbose ) { + HDfprintf(stdout, "%s journal filename = \"%s\".\n", + fcn_name, journal_filename); + HDfflush(stdout); + } + + if ( pass2 ) { + + /* 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:%d cp = %d.\n", fcn_name, (int)pass2, cp++); + HDfflush(stdout); + } + + /* call H5Pset_libver_bounds() on the fapl_id */ + if ( pass2 ) { + + if ( H5Pset_libver_bounds(fapl_id, H5F_LIBVER_LATEST, + H5F_LIBVER_LATEST) < 0 ) { + + pass2 = FALSE; + failure_mssg2 = "H5Pset_libver_bounds() failed.\n"; + } + } + + if ( show_progress ) { + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, (int)pass2, cp++); + HDfflush(stdout); + } + + /* attempt to open the file -- should succeed as the setup function + * disabled journaling just before exiting, which should have + * had the dual effect of marking the file as not having + * journaling in progress, and syncing the file out to disk. + */ + + file_id = H5Fopen(filename, H5F_ACC_RDWR, fapl_id); + + if ( file_id < 0 ) { + + pass2 = FALSE; + failure_mssg2 = "H5Fopen() failed (11)."; + } + + if ( show_progress ) { + + HDfprintf(stdout, "%s%d: cp = %d.\n", fcn_name, (int)pass2, cp++); + HDfflush(stdout); + } + + /* close the file and fapl */ + + if ( pass2 ) { + + if ( ( H5Pclose(fapl_id) < 0 ) || + ( H5Fclose(file_id) < 0 ) ) { + + pass2 = FALSE; + failure_mssg2 = "fapl or file close failed."; + } + } + + if ( show_progress ) { + + HDfprintf(stdout, "%s%d: cp = %d.\n", fcn_name, (int)pass2, cp++); + HDfflush(stdout); + } + + /* delete the HDF5 file and journal file */ +#if 1 + HDremove(filename); + HDremove(journal_filename); +#endif + if ( show_progress ) { + + HDfprintf(stdout, "%s%d cp = %d done.\n", + fcn_name, (int)pass2, cp++); + HDfflush(stdout); + } + } + + return; + +} /* check_mdj_file_unmarking_on_journaling_shutdown_test() */ + + +/*************************************************************************** + * Function: setup_mdj_file_unmarking_on_recovery_test + * + * Purpose: Setup test to verify that HDF5 file that is marked as as + * having journaling in progress is unmarked when the file + * is opened with the journal_recovered flag set in the + * cache configuration structure in the file access + * property list. + * + * Do this by creating a test file metadata journaling enabled, + * and then exiting without closing the file. Note that + * we must flush the file before exiting, as we want the file + * to be readable, but be marked as journaling in progress. + * + * Return: void + * + * Programmer: John Mainzer + * 7/14/08 + * + **************************************************************************/ + +static void +setup_mdj_file_unmarking_on_recovery_test(hbool_t verbose) +{ + const char * fcn_name = "setup_mdj_file_unmarking_on_recovery_test():"; + char filename[512]; + char journal_filename[H5AC2__MAX_JOURNAL_FILE_NAME_LEN + 1]; + hbool_t show_progress = FALSE; + int cp = 0; + uint64_t trans_num; + hid_t file_id = -1; + H5F_t * file_ptr = NULL; + H5C2_t * cache_ptr = NULL; + + /* setup the file name */ + if ( pass2 ) { + + if ( h5_fixname(FILENAMES[1], H5P_DEFAULT, filename, + sizeof(filename)) == NULL ) { + + pass2 = FALSE; + failure_mssg2 = "h5_fixname() failed (1).\n"; + } + } + + if ( show_progress ) { + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, pass2, cp++); + HDfflush(stdout); + } + + if ( verbose ) { + HDfprintf(stdout, "%s filename = \"%s\".\n", fcn_name, filename); + HDfflush(stdout); + } + + /* setup the journal file name */ + if ( pass2 ) { + + if ( h5_fixname(FILENAMES[3], H5P_DEFAULT, journal_filename, + sizeof(journal_filename)) == NULL ) { + + pass2 = FALSE; + failure_mssg2 = "h5_fixname() failed (2).\n"; + } + else if ( strlen(journal_filename) >= + H5AC2__MAX_JOURNAL_FILE_NAME_LEN ) { + + pass2 = FALSE; + failure_mssg2 = "journal file name too long.\n"; + } + } + + if ( show_progress ) { + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, (int)pass2, cp++); + HDfflush(stdout); + } + + if ( verbose ) { + HDfprintf(stdout, "%s journal filename = \"%s\".\n", + fcn_name, journal_filename); + HDfflush(stdout); + } + + if ( pass2 ) { + + /* clean out any existing journal file */ + HDremove(journal_filename); + setup_cache_for_journaling(filename, journal_filename, &file_id, + &file_ptr, &cache_ptr, FALSE); + + if ( show_progress ) { + + HDfprintf(stdout, "%s%d: cp = %d.\n", fcn_name, (int)pass2, cp++); + HDfflush(stdout); + } + + /* run a dummy transaction to fource metadata journaling + * initialization. + */ + H5C2_begin_transaction(cache_ptr, &trans_num, "dummy"); + H5C2_end_transaction(file_ptr, H5AC2_dxpl_id, cache_ptr, + trans_num, "dummy"); + + if ( show_progress ) { + + HDfprintf(stdout, "%s%d: cp = %d.\n", fcn_name, (int)pass2, cp++); + HDfflush(stdout); + } + + /* flush the file to ensure that it is in a readable state */ + if ( pass2 ) { + + if ( H5Fflush(file_id, H5F_SCOPE_GLOBAL) < 0 ) { + + if ( verbose ) { + + HDfprintf(stdout, "%s: H5Fflush() failed.\n", fcn_name); + HDfflush(stdout); + } + pass2 = FALSE; + failure_mssg2 = "H5Fflush() failed."; + } + } + + if ( ( verbose ) && ( ! pass2 ) ) { + HDfprintf(stdout, "%s%d failure_mssg = \"%s\".\n", + fcn_name, pass2, failure_mssg2); + HDfflush(stdout); + } + + if ( show_progress ) { + + HDfprintf(stdout, "%s%d cp = %d exiting.\n", + fcn_name, (int)pass2, cp++); + HDfflush(stdout); + } + + mark_test_in_progress("mdj_file_unmarking_on_recovery_test"); + + abort(); + } + + return; + +} /* setup_mdj_file_unmarking_on_recovery_test() */ + + +/*************************************************************************** + * Function: check_mdj_file_unmarking_on_recovery_test + * + * Purpose: Check to verify that a HDF5 file that is marked as as + * having journaling in progress is unmarked when the file + * is opened with the journal_recovered flag set in the + * cache configuration structure in the file access property + * list. + * + * Do this by trying to open the test file created by the + * assocated setup function. + * + * Open should fail, as the file should be marked as journaling + * in progress. + * + * Try to open again with the journal_recovered flag set. This + * should succeed. + * + * Close and open again without the journal recovered flag + * set to verify that the file is no longer marked as + * having journaling in progress. + * + * On either success or failure, clean up the test file and + * the associated journal file. + * + * Return: void + * + * Programmer: John Mainzer + * 10/8/08 + * + **************************************************************************/ + +static void +check_mdj_file_unmarking_on_recovery_test(hbool_t verbose) +{ + const char * fcn_name = "check_mdj_file_unmarking_on_recovery_test():"; + char filename[512]; + char journal_filename[H5AC2__MAX_JOURNAL_FILE_NAME_LEN + 1]; + hbool_t show_progress = FALSE; + herr_t result; + int cp = 0; + hid_t file_id = -1; + hid_t fapl_id = -1; + H5AC2_jnl_config_t jnl_config; + + check_test_in_progress("mdj_file_unmarking_on_recovery_test"); + + /* setup the file name */ + if ( pass2 ) { + + if ( h5_fixname(FILENAMES[1], H5P_DEFAULT, filename, + sizeof(filename)) == NULL ) { + + pass2 = FALSE; + failure_mssg2 = "h5_fixname() failed (1).\n"; + } + } + + if ( show_progress ) { + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, pass2, cp++); + HDfflush(stdout); + } + + if ( verbose ) { + HDfprintf(stdout, "%s filename = \"%s\".\n", fcn_name, filename); + HDfflush(stdout); + } + + /* setup the journal file name */ + if ( pass2 ) { + + if ( h5_fixname(FILENAMES[3], H5P_DEFAULT, journal_filename, + sizeof(journal_filename)) == NULL ) { + + pass2 = FALSE; + failure_mssg2 = "h5_fixname() failed (2).\n"; + } + else if ( strlen(journal_filename) >= + H5AC2__MAX_JOURNAL_FILE_NAME_LEN ) { + + pass2 = FALSE; + failure_mssg2 = "journal file name too long.\n"; + } + } + + if ( show_progress ) { + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, (int)pass2, cp++); + HDfflush(stdout); + } + + if ( verbose ) { + HDfprintf(stdout, "%s journal filename = \"%s\".\n", + fcn_name, journal_filename); + HDfflush(stdout); + } + + if ( pass2 ) { + + /* 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:%d cp = %d.\n", fcn_name, (int)pass2, cp++); + HDfflush(stdout); + } + + /* call H5Pset_libver_bounds() on the fapl_id */ + if ( pass2 ) { + + if ( H5Pset_libver_bounds(fapl_id, H5F_LIBVER_LATEST, + H5F_LIBVER_LATEST) < 0 ) { + + pass2 = FALSE; + failure_mssg2 = "H5Pset_libver_bounds() failed.\n"; + } + } + + if ( show_progress ) { + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, (int)pass2, cp++); + HDfflush(stdout); + } + + /* attempt to open the file -- should fail as the setup fcn + * exited without closing the file properly, and thus + * the file should still be marked as having journaling + * in progress. + */ + + if ( pass2 ) { + + H5E_BEGIN_TRY { + + file_id = H5Fopen(filename, H5F_ACC_RDWR, fapl_id); + + } H5E_END_TRY; + + if ( file_id >= 0 ) { + + pass2 = FALSE; + failure_mssg2 = "H5Fopen() succeeded - 4."; + } + } + + if ( show_progress ) { + + HDfprintf(stdout, "%s%d: cp = %d.\n", fcn_name, (int)pass2, cp++); + HDfflush(stdout); + } + + + /* now set the file recovered flag in the journal config + * structure in the fapl, and try to open again. Should + * succeed, and the file should not be marked as having + * journaling in progress. + */ + if ( pass2 ) { + + jnl_config.version = H5AC2__CURR_JNL_CONFIG_VER; + + result = H5Pget_jnl_config(fapl_id, &jnl_config); + + if ( result < 0 ) { + + pass2 = FALSE; + failure_mssg2 = "H5Pget_jnl_config() failed.\n"; + } + + jnl_config.journal_recovered = TRUE; + } + + if ( show_progress ) { + + HDfprintf(stdout, "%s%d: cp = %d.\n", fcn_name, (int)pass2, cp++); + HDfflush(stdout); + } + + if ( pass2 ) { + + result = H5Pset_jnl_config(fapl_id, &jnl_config); + + if ( result < 0 ) { + + pass2 = FALSE; + failure_mssg2 = "H5Pset_jnl_config() failed(1).\n"; + } + } + + if ( show_progress ) { + + HDfprintf(stdout, "%s%d: cp = %d.\n", fcn_name, (int)pass2, cp++); + HDfflush(stdout); + } + + if ( pass2 ) { + + file_id = H5Fopen(filename, H5F_ACC_RDWR, fapl_id); + + if ( file_id < 0 ) { + + pass2 = FALSE; + failure_mssg2 = "H5Fopen() failed (12)."; + } + } + + if ( show_progress ) { + + HDfprintf(stdout, "%s%d: cp = %d.\n", fcn_name, (int)pass2, cp++); + HDfflush(stdout); + } + + if ( pass2 ) { + + if ( H5Fclose(file_id) < 0 ) { + + pass2 = FALSE; + failure_mssg2 = "H5Fclose() failed(1)."; + } + } + + if ( show_progress ) { + + HDfprintf(stdout, "%s%d: cp = %d.\n", fcn_name, (int)pass2, cp++); + HDfflush(stdout); + } + + /* now, turn off the journal recovered flag, and try to + * open the file again. Should succeed. + */ + + if ( pass2 ) { + + jnl_config.journal_recovered = FALSE; + + result = H5Pset_jnl_config(fapl_id, &jnl_config); + + if ( result < 0 ) { + + pass2 = FALSE; + failure_mssg2 = "H5Pset_jnl_config() failed(2).\n"; + } + } + + if ( show_progress ) { + + HDfprintf(stdout, "%s%d: cp = %d.\n", fcn_name, (int)pass2, cp++); + HDfflush(stdout); + } + + if ( pass2 ) { + + file_id = H5Fopen(filename, H5F_ACC_RDWR, fapl_id); + + if ( file_id < 0 ) { + + pass2 = FALSE; + failure_mssg2 = "H5Fopen() failed (13)."; + } + } + + if ( show_progress ) { + + HDfprintf(stdout, "%s%d: cp = %d.\n", fcn_name, (int)pass2, cp++); + HDfflush(stdout); + } + + if ( pass2 ) { + + if ( ( H5Fclose(file_id) < 0 ) || + ( H5Pclose(fapl_id) < 0 ) ) { + + pass2 = FALSE; + failure_mssg2 = "H5Fclose() or H5Pclose() failed(2)."; + } + } + + if ( show_progress ) { + + HDfprintf(stdout, "%s%d: cp = %d.\n", fcn_name, (int)pass2, cp++); + HDfflush(stdout); + } + + /* delete the HDF5 file and journal file */ +#if 1 + HDremove(filename); + HDremove(journal_filename); +#endif + if ( show_progress ) { + + HDfprintf(stdout, "%s%d cp = %d done.\n", + fcn_name, (int)pass2, cp++); + HDfflush(stdout); + } + } + + return; + +} /* check_mdj_file_unmarking_on_recovery_test() */ + + +/*------------------------------------------------------------------------- + * Function: usage + * + * Purpose: Display a brief message describing the purpose and use + * of the program. + * + * Return: void + * + * Programmer: John Mainzer + * 10/8/08 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + +void +usage(void) + +{ + const char * s[] = + { + "\n", + "cache2_jnl_file_marking:\n", + "\n", + "Setup or check the results of the specified test.\n", + "\n", + "usage: cache2_jnl_file_marking [verbose]\n", + "\n", + "where:\n", + "\n", + " ::= ( file_marking_after_open |\n", + " file_marking_on_create |\n", + " file_marking_on_open |\n", + " file_unmarking_on_file_close |\n", + " file_unmarking_on_journaling_shutdown |\n", + " file_unmarking_on_recovery )\n", + "\n", + " :: ( setup | check )\n", + "\n", + "Returns 0 on success, 1 on failure.\n", + "\n", + NULL, + }; + int i = 0; + + while ( s[i] != NULL ) { + + HDfprintf(stdout, "%s", s[i]); + i++; + } + + return; + +} /* usage() */ + + +/*------------------------------------------------------------------------- + * Function: main + * + * Purpose: Run the specified setup or check of metadata journaling + * HDF5 file marking or unmarking. + * + * Return: Success: 0 + * + * Failure: A positive integer. + * + * Programmer: John Mainzer + * 10/8/08 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + +int +main(int argc, + char * argv[]) +{ + int express_test; + int result = 0; + hbool_t setup = FALSE; + hbool_t check = FALSE; + hbool_t verbose = FALSE; + + express_test = GetTestExpress(); + + pass2 = TRUE; + + if ( argc == 4 ) { + + if ( strcmp("verbose", argv[3]) == 0 ) { + + verbose = TRUE; + + } else { + + pass2 = FALSE; + usage(); + + } + + } else if ( argc != 3 ) { + + pass2 = FALSE; + usage(); + } + + if ( verbose ) { + + HDfprintf(stdout, "%s %s %s %s:\n", argv[0], argv[1], argv[2], argv[3]); + } + + if ( pass2 ) { + + if ( strcmp("setup", argv[2]) == 0 ) { + + setup = TRUE; + + } else if ( strcmp("check", argv[2]) == 0 ) { + + check = TRUE; + + } else { + + pass2 = FALSE; + usage(); + } + } + + if ( pass2 ) { + + H5open(); + + if ( strcmp("file_marking_after_open", argv[1]) == 0 ) { + + if ( setup ) { + + setup_mdj_file_marking_after_open_test(verbose); + + } else if ( check ) { + + check_mdj_file_marking_after_open_test(verbose); + + } else { + + pass2 = FALSE; + failure_mssg2 = "setup and check both FALSE?"; + } + + } else if ( strcmp("file_marking_on_create", argv[1]) == 0 ) { + + if ( setup ) { + + setup_mdj_file_marking_on_create_test(verbose); + + } else if ( check ) { + + check_mdj_file_marking_on_create_test(verbose); + + } else { + + pass2 = FALSE; + failure_mssg2 = "setup and check both FALSE?"; + } + + } else if ( strcmp("file_marking_on_open", argv[1]) == 0 ) { + + if ( setup ) { + + setup_mdj_file_marking_on_open_test(verbose); + + } else if ( check ) { + + check_mdj_file_marking_on_open_test(verbose); + + } else { + + pass2 = FALSE; + failure_mssg2 = "setup and check both FALSE?"; + } + + } else if ( strcmp("file_unmarking_on_file_close", argv[1]) == 0 ) { + + if ( setup ) { + + setup_mdj_file_unmarking_on_file_close_test(verbose); + + } else if ( check ) { + + check_mdj_file_unmarking_on_file_close_test(verbose); + + } else { + + pass2 = FALSE; + failure_mssg2 = "setup and check both FALSE?"; + } + + } else if ( strcmp("file_unmarking_on_journaling_shutdown", argv[1]) + == 0 ) { + + if ( setup ) { + + setup_mdj_file_unmarking_on_journaling_shutdown_test(verbose); + + } else if ( check ) { + + check_mdj_file_unmarking_on_journaling_shutdown_test(verbose); + + } else { + + pass2 = FALSE; + failure_mssg2 = "setup and check both FALSE?"; + } + + } else if ( strcmp("file_unmarking_on_recovery", argv[1]) == 0 ) { + + if ( setup ) { + + setup_mdj_file_unmarking_on_recovery_test(verbose); + + } else if ( check ) { + + check_mdj_file_unmarking_on_recovery_test(verbose); + + } else { + + pass2 = FALSE; + failure_mssg2 = "setup and check both FALSE?"; + } + + } else { + + pass2 = FALSE; + failure_mssg2 = "unknown test requested."; + usage(); + } + } + + if ( verbose ) { + + if ( pass2 ) { + + if ( setup ) { + + HDfprintf(stdout, "test setup succeeded.\n"); + + } else if ( check ) { + + HDfprintf(stdout, "test passed.\n"); + + } + } else { + + HDfprintf(stdout, "FAILED. Failure mssg = \"%s\"\n", + failure_mssg2); + } + } + + if ( ! pass2 ) { + + result = 1; + } + + return(result); + +} /* main() */ + diff --git a/test/cache2_journal.c b/test/cache2_journal.c index 1aaf58e..7fb60d6 100644 --- a/test/cache2_journal.c +++ b/test/cache2_journal.c @@ -171,20 +171,6 @@ static void write_noflush_verify(H5C2_jbrb_t * struct_ptr, static void check_mdj_config_block_IO(void); -static void check_mdj_file_marking(void); - -static void verify_mdj_file_marking_after_open(void); - -static void verify_mdj_file_marking_on_create(void); - -static void verify_mdj_file_marking_on_open(void); - -static void verify_mdj_file_unmarking_on_file_close(void); - -static void verify_mdj_file_unmarking_on_journaling_shutdown(void); - -static void verify_mdj_file_unmarking_on_recovery(void); - static void test_mdj_conf_blk_read_write_discard(H5F_t * file_ptr, const char * jrnl_file_path); @@ -6488,17 +6474,16 @@ check_superblock_extensions(void) } /* check_superblock_extensions() */ -/*** Check metadata journaling file marking ***/ - /*************************************************************************** - * Function: check_mdj_file_marking + * Function: check_mdjsc_callbacks() * - * Purpose: Verify that HDF5 file is marked as having journaling - * in progress when journaling is enabled, and that it is - * unmarked when journaling is shut down, or when the file - * is closed normally. + * Purpose: Verify that the registration and deregistration of + * metadata journaling status change registration/deregistraion + * works correctly. * - * Do nothing if pass2 is false on entry. + * Verify that the status change callbacks are called as + * they should be, and that the cache is clean when the + * callback is called. * * On failure, set pass2 to false, and failure_mssg2 to an * appropriate error string. @@ -6511,23 +6496,17 @@ check_superblock_extensions(void) **************************************************************************/ static void -check_mdj_file_marking(void) +check_mdjsc_callbacks(void) { - const char * fcn_name = "check_mdj_file_marking():"; - - TESTING("metadata journaling file marking"); - - verify_mdj_file_marking_on_create(); - - verify_mdj_file_marking_on_open(); + const char * fcn_name = "check_mdjsc_callbacks():"; - verify_mdj_file_marking_after_open(); + TESTING("metadata journaling status change callbacks"); - verify_mdj_file_unmarking_on_file_close(); + verify_mdjsc_callback_registration_deregistration(); - verify_mdj_file_unmarking_on_journaling_shutdown(); + verify_mdjsc_callback_execution(); - verify_mdj_file_unmarking_on_recovery(); + verify_mdjsc_callback_error_rejection(); if ( pass2 ) { PASSED(); } else { H5_FAILED(); } @@ -6540,2582 +6519,154 @@ check_mdj_file_marking(void) return; -} /* check_mdj_file_marking() */ +} /* check_mdjsc_callbacks() */ /*************************************************************************** - * Function: verify_mdj_file_marking_on_create - * - * Purpose: Verify that HDF5 file is marked as having journaling - * in progress when journaling is enabled at file creation - * time. - * - * Do this by forking a child process, creating a test file - * in the child with metadata journaling enabled, and then - * exiting from the child without closing the file. * - * When the child exits, try to open the child's test file. - * Open should fail, as the file should be marked as journaling - * in progress. + * Function: test_mdjsc_callback() * - * On either success or failure, clean up the test file and - * the associated journal file. + * Purpose: Test callback function used to test the metadata + * journaling status change callback facility. * * Return: void * * Programmer: John Mainzer - * 7/2/08 + * 8/15/08 * **************************************************************************/ +static H5C2_t * callback_test_cache_ptr = NULL; +static hbool_t callback_test_invalid_cache_ptr = FALSE; +static hbool_t callback_test_null_config_ptr = FALSE; +static hbool_t callback_test_invalid_config = FALSE; +static hbool_t callback_test_null_data_ptr = FALSE; +static hbool_t callback_test_cache_is_dirty = FALSE; +static int callback_test_null_data_ptr_count = 0; + static void -verify_mdj_file_marking_on_create(void) +test_mdjsc_callback(H5C2_mdj_config_t * config_ptr, + void * data_ptr) { - const char * fcn_name = "verify_mdj_file_marking_on_create():"; - const char * tag = "pre-fork:"; - char filename[512]; - char journal_filename[H5AC2__MAX_JOURNAL_FILE_NAME_LEN + 1]; - hbool_t child = FALSE; - hbool_t show_progress = FALSE; - hbool_t verbose = FALSE; - int cp = 0; - int wait_status; - uint64_t trans_num; - pid_t child_id; - pid_t wait_result; - hid_t file_id = -1; - hid_t fapl_id = -1; - H5F_t * file_ptr = NULL; - H5C2_t * cache_ptr = NULL; - - /* setup the file name */ - if ( pass2 ) { - - if ( h5_fixname(FILENAMES[1], H5P_DEFAULT, filename, - sizeof(filename)) == NULL ) { - - pass2 = FALSE; - failure_mssg2 = "h5_fixname() failed (1).\n"; - } + if ( config_ptr == NULL ) + { + callback_test_null_config_ptr = TRUE; } - - if ( show_progress ) { - - HDfprintf(stdout, "%s%s%d cp = %d.\n", fcn_name, tag, pass2, cp++); - HDfflush(stdout); + + if ( ( callback_test_cache_ptr == NULL ) || + ( callback_test_cache_ptr->magic != H5C2__H5C2_T_MAGIC ) ) + { + callback_test_invalid_cache_ptr = TRUE; } - - if ( verbose ) { - HDfprintf(stdout, "%s%s filename = \"%s\".\n", fcn_name, tag,filename); - HDfflush(stdout); + else if ( callback_test_cache_ptr->slist_len > 0 ) + { + callback_test_cache_is_dirty = TRUE; } - - /* setup the journal file name */ - if ( pass2 ) { - - if ( h5_fixname(FILENAMES[3], H5P_DEFAULT, journal_filename, - sizeof(journal_filename)) == NULL ) { - - pass2 = FALSE; - failure_mssg2 = "h5_fixname() failed (2).\n"; - } - else if ( strlen(journal_filename) >= - H5AC2__MAX_JOURNAL_FILE_NAME_LEN ) { - - pass2 = FALSE; - failure_mssg2 = "journal file name too long.\n"; - } + else if ( ( callback_test_cache_ptr != NULL ) && + ( callback_test_cache_ptr->mdj_enabled != + config_ptr->enable_journaling ) ) + { + callback_test_invalid_config = TRUE; } - if ( show_progress ) { - - HDfprintf(stdout, "%s%s%d cp = %d.\n", - fcn_name, tag, (int)pass2, cp++); - HDfflush(stdout); + if ( data_ptr == NULL ) + { + callback_test_null_data_ptr = TRUE; + callback_test_null_data_ptr_count++; } - - if ( verbose ) { - HDfprintf(stdout, "%s%s journal filename = \"%s\".\n", - fcn_name, tag, journal_filename); - HDfflush(stdout); + else + { + *((int *)data_ptr) += 1; } - if ( pass2 ) { - - child_id = HDfork(); - - if ( child_id == -1 ) { - - pass2 = FALSE; - failure_mssg2 = "H5fork() failed."; + return; - } else if ( child_id == 0 ) { +} /* test_mdjsc_callback() */ - child = TRUE; - tag = "child:"; + +/*************************************************************************** + * + * Function: deregister_mdjsc_callback() + * + * Purpose: Attempt to deregister the metadata journaling status change + * callback with the supplied index, and verify that the + * deregistration took place. + * + * If any error is detected, set pass2 t FALSE, and set the + * failure_mssg2 to the appropriate error message. + * + * Do nothing and return if pass2 is false on entry. + * + * Return: void + * + * Programmer: John Mainzer + * 8/15/08 + * + **************************************************************************/ - } else { +static void +deregister_mdjsc_callback(H5F_t * file_ptr, + H5C2_t * cache_ptr, + int32_t idx) +{ + herr_t result; - child = FALSE; - tag = "parent:"; + if ( pass2 ) + { + if ( ( file_ptr == NULL ) || + ( cache_ptr == NULL ) || + ( cache_ptr->magic != H5C2__H5C2_T_MAGIC ) ) + { + pass2 = FALSE; + failure_mssg2 = + "deregister_mdjsc_callback(): bad param(s) on entry."; } } - if ( pass2 ) { - - if ( show_progress ) { + if ( pass2 ) + { + result = H5AC2_deregister_mdjsc_callback(file_ptr, idx); - HDfprintf(stdout, "%s%s%d: cp = %d fork() succeeded.\n", - fcn_name, tag, (int)pass2, cp++); - HDfflush(stdout); + if ( result < 0 ) + { + pass2 = FALSE; + failure_mssg2 = "H5AC2_deregister_mdjsc_callback() failed."; } - if ( child ) { - - if ( show_progress ) { - - HDfprintf(stdout, "%s%s%d: cp = %d child starting.\n", - fcn_name, tag, (int)pass2, cp++); - HDfflush(stdout); - } - - /* clean out any existing journal file */ - HDremove(journal_filename); - setup_cache_for_journaling(filename, journal_filename, &file_id, - &file_ptr, &cache_ptr, FALSE); - - if ( show_progress ) { - - HDfprintf(stdout, "%s%s%d: cp = %d.\n", - fcn_name, tag, (int)pass2, cp++); - HDfflush(stdout); - } - - /* run a dummy transaction to fource metadata journaling - * initialization. - */ - H5C2_begin_transaction(cache_ptr, &trans_num, "dummy"); - H5C2_end_transaction(file_ptr, H5AC2_dxpl_id, cache_ptr, - trans_num, "dummy"); - - if ( show_progress ) { - - HDfprintf(stdout, "%s%s%d: cp = %d.\n", - fcn_name, tag, (int)pass2, cp++); - HDfflush(stdout); - } - - if ( ( verbose ) && ( ! pass2 ) ) { - HDfprintf(stdout, "%s%s%d failure_mssg = \"%s\".\n", - fcn_name, tag, pass2, failure_mssg2); - HDfflush(stdout); - } - - if ( show_progress ) { - - HDfprintf(stdout, "%s%s%d cp = %d child exiting.\n", - fcn_name, tag, (int)pass2, cp++); - HDfflush(stdout); - } - - abort(); - - } else { - - /* wait for the child to exit */ - wait_result = HDwaitpid(child_id, &wait_status, 0); - - HDsleep(3); - - if ( wait_result != child_id ) { - - pass2 = FALSE; - failure_mssg2 = "unexpected waitpid() result."; - - if ( show_progress ) { - - HDfprintf(stdout, - "%s%s:%d: wait_result = %ld, wait_status = %d.\n", - fcn_name, tag, (int)pass2, - (long)wait_result, wait_status); - HDfflush(stdout); - } - } else { - - if ( show_progress ) { - - HDfprintf(stdout, - "%s%s:%d: cp = %d child exited as expected.\n", - fcn_name, tag, (int)pass2, cp++); - HDfflush(stdout); - } - - /* 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%s:%d cp = %d.\n", - fcn_name, tag, (int)pass2, cp++); - HDfflush(stdout); - } - - /* call H5Pset_libver_bounds() on the fapl_id */ - if ( pass2 ) { - - if ( H5Pset_libver_bounds(fapl_id, H5F_LIBVER_LATEST, - H5F_LIBVER_LATEST) < 0 ) { - - pass2 = FALSE; - failure_mssg2 = "H5Pset_libver_bounds() failed.\n"; - } - } - - if ( show_progress ) { - HDfprintf(stdout, "%s%s%d cp = %d.\n", - fcn_name, tag, (int)pass2, cp++); - HDfflush(stdout); - } - - /* attempt to open the file -- should fail as the child - * exited without closing the file properly, and thus - * the file should still be marked as having journaling - * in progress. - */ - - if ( pass2 ) { - - H5E_BEGIN_TRY { - - file_id = H5Fopen(filename, H5F_ACC_RDWR, fapl_id); - - } H5E_END_TRY; - - if ( file_id >= 0 ) { - - pass2 = FALSE; - failure_mssg2 = "H5Fopen() succeeded - 1."; - } - } - - if ( show_progress ) { - - HDfprintf(stdout, "%s%s%d: cp = %d.\n", - fcn_name, tag, (int)pass2, cp++); - HDfflush(stdout); - } - - /* delete the HDF5 file and journal file */ -#if 1 - HDremove(filename); - HDremove(journal_filename); -#endif - if ( show_progress ) { - - HDfprintf(stdout, "%s%s%d cp = %d parent done.\n", - fcn_name, tag, (int)pass2, cp++); - HDfflush(stdout); - } - } - } - } + verify_mdjsc_callback_deregistered(cache_ptr, idx); + } return; -} /* verify_mdj_file_marking_on_create() */ +} /* deregister_mdjsc_callback() */ /*************************************************************************** - * Function: verify_mdj_file_marking_after_open - * - * Purpose: Verify that HDF5 file is marked as having journaling - * in progress when journaling is enabled on an open file. * - * Do this by forking a child process and: - * - * 1) creating a test file in the child, - * - * 2) writing some data to it, - * - * 3) enable journaling on the open file via a call to - * H5Fset_mdc_config() + * Function: register_mdjsc_callback() * - * 4) exiting from the child without closing the file. + * Purpose: Attempt to register the supplied metadata journaling + * status change callback, and verify that the registration + * took. * - * When the child exits, try to open the child's test file. - * Open should fail, as the file should be marked as journaling - * in progress. + * If any error is detected, set pass2 t FALSE, and set the + * failure_mssg2 to the appropriate error message. * - * On either success or failure, clean up the test file and - * the associated journal file. + * Do nothing and return if pass2 is false on entry. * * Return: void * * Programmer: John Mainzer - * 7/9/08 + * 8/15/08 * **************************************************************************/ -static void -verify_mdj_file_marking_after_open(void) -{ - const char * fcn_name = "verify_mdj_file_marking_after_open():"; - const char * tag = "pre-fork:"; - char filename[512]; - char journal_filename[H5AC2__MAX_JOURNAL_FILE_NAME_LEN + 1]; - hbool_t child = FALSE; - hbool_t show_progress = FALSE; - hbool_t verbose = FALSE; - herr_t result; - int cp = 0; - int wait_status; - pid_t child_id; - pid_t wait_result; - hid_t file_id = -1; - hid_t fapl_id = -1; - hid_t dataset_id = -1; - hid_t dataspace_id = -1; - hsize_t dims[2]; - H5AC2_jnl_config_t jnl_config; - - /* setup the file name */ - if ( pass2 ) { - - if ( h5_fixname(FILENAMES[1], H5P_DEFAULT, filename, - sizeof(filename)) == NULL ) { - - pass2 = FALSE; - failure_mssg2 = "h5_fixname() failed (1).\n"; - } - } - - if ( show_progress ) { - - HDfprintf(stdout, "%s%s%d cp = %d.\n", fcn_name, tag, pass2, cp++); - HDfflush(stdout); - } - - if ( verbose ) { - HDfprintf(stdout, "%s%s filename = \"%s\".\n", fcn_name, tag,filename); - HDfflush(stdout); - } - - /* setup the journal file name */ - if ( pass2 ) { - - if ( h5_fixname(FILENAMES[3], H5P_DEFAULT, journal_filename, - sizeof(journal_filename)) == NULL ) { - - pass2 = FALSE; - failure_mssg2 = "h5_fixname() failed (2).\n"; - } - else if ( strlen(journal_filename) >= - H5AC2__MAX_JOURNAL_FILE_NAME_LEN ) { - - pass2 = FALSE; - failure_mssg2 = "journal file name too long.\n"; - } - } - - if ( show_progress ) { - - HDfprintf(stdout, "%s%s%d cp = %d.\n", - fcn_name, tag, (int)pass2, cp++); - HDfflush(stdout); - } - - if ( verbose ) { - HDfprintf(stdout, "%s%s journal filename = \"%s\".\n", - fcn_name, tag, journal_filename); - HDfflush(stdout); - } - - if ( pass2 ) { - - child_id = HDfork(); - - if ( child_id == -1 ) { - - pass2 = FALSE; - failure_mssg2 = "H5fork() failed."; - - } else if ( child_id == 0 ) { - - child = TRUE; - tag = "child:"; - - } else { - - child = FALSE; - tag = "parent:"; - } - } - - if ( pass2 ) { - - /* reset the check point */ - cp = 0; - - if ( show_progress ) { - - HDfprintf(stdout, "%s%s%d: cp = %d fork() succeeded.\n", - fcn_name, tag, (int)pass2, cp++); - HDfflush(stdout); - } - - if ( child ) { - - if ( show_progress ) { - - HDfprintf(stdout, "%s%s%d: cp = %d child starting.\n", - fcn_name, tag, (int)pass2, cp++); - HDfflush(stdout); - } - - /* 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%s%d: cp = %d.\n", - fcn_name, tag, (int)pass2, cp++); - HDfflush(stdout); - } - - /* call H5Pset_libver_bounds() on the fapl_id */ - if ( pass2 ) { - - if ( H5Pset_libver_bounds(fapl_id, H5F_LIBVER_LATEST, - H5F_LIBVER_LATEST) < 0 ) { - - pass2 = FALSE; - failure_mssg2 = "H5Pset_libver_bounds() failed.\n"; - } - } - - /* open the file with a fapl indicating latest version of - * the file format. - */ - if ( pass2 ) { - - file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, - fapl_id); - - if ( file_id < 0 ) { - - pass2 = FALSE; - failure_mssg2 = "H5Fcreate() failed.\n"; - } - } - - if ( show_progress ) { - - HDfprintf(stdout, "%s%s%d: cp = %d.\n", - fcn_name, tag, (int)pass2, cp++); - HDfflush(stdout); - } - - if ( pass2 ) { - - dims[0] = 4; - dims[1] = 6; - dataspace_id = H5Screate_simple(2, dims, NULL); - - if ( dataspace_id < 0 ) { - - pass2 = FALSE; - failure_mssg2 = "H5Screate_simple() failed."; - } - } - - if ( show_progress ) { - - HDfprintf(stdout, "%s%s%d: cp = %d.\n", - fcn_name, tag, (int)pass2, cp++); - HDfflush(stdout); - } - - if ( pass2 ) { - - /* Create the dataset. */ - dataset_id = H5Dcreate2(file_id, "/dset", H5T_STD_I32BE, - dataspace_id, H5P_DEFAULT, - H5P_DEFAULT, H5P_DEFAULT); - - if ( dataspace_id < 0 ) { - - pass2 = FALSE; - failure_mssg2 = "H5Dcreate2() failed."; - } - } - - if ( show_progress ) { - - HDfprintf(stdout, "%s%s%d: cp = %d.\n", - fcn_name, tag, (int)pass2, cp++); - HDfflush(stdout); - } - - /* now enable journaling */ - if ( pass2 ) { - - jnl_config.version = H5AC2__CURR_JNL_CONFIG_VER; - - result = H5Fget_jnl_config(file_id, &jnl_config); - - if ( result < 0 ) { - - pass2 = FALSE; - failure_mssg2 = "H5Fget_jnl_config() failed.\n"; - } - - /* set journaling config fields to taste */ - jnl_config.enable_journaling = TRUE; - - strcpy(jnl_config.journal_file_path, journal_filename); - - jnl_config.journal_recovered = FALSE; - jnl_config.jbrb_buf_size = (8 * 1024); - jnl_config.jbrb_num_bufs = 2; - jnl_config.jbrb_use_aio = FALSE; - jnl_config.jbrb_human_readable = TRUE; - } - - if ( show_progress ) { - - HDfprintf(stdout, "%s%s%d: cp = %d.\n", - fcn_name, tag, (int)pass2, cp++); - HDfflush(stdout); - } - - if ( pass2 ) { - - result = H5Fset_jnl_config(file_id, &jnl_config); - - if ( result < 0 ) { - - pass2 = FALSE; - failure_mssg2 = "H5Fset_jnl_config() failed.\n"; - } - } - - if ( show_progress ) { - - HDfprintf(stdout, "%s%s%d: cp = %d.\n", - fcn_name, tag, (int)pass2, cp++); - HDfflush(stdout); - } - - if ( ( verbose ) && ( ! pass2 ) ) { - HDfprintf(stdout, "%s%s%d failure_mssg = \"%s\".\n", - fcn_name, tag, pass2, failure_mssg2); - HDfflush(stdout); - } - - if ( show_progress ) { - - HDfprintf(stdout, "%s%s%d cp = %d child exiting.\n", - fcn_name, tag, (int)pass2, cp++); - HDfflush(stdout); - } - - abort(); - - } else { - - /* wait for the child to exit */ - wait_result = HDwaitpid(child_id, &wait_status, 0); - - HDsleep(3); - - if ( wait_result != child_id ) { - - pass2 = FALSE; - failure_mssg2 = "unexpected waitpid() result."; - - if ( show_progress ) { - - HDfprintf(stdout, - "%s%s:%d: wait_result = %ld, wait_status = %d.\n", - fcn_name, tag, (int)pass2, - (long)wait_result, wait_status); - HDfflush(stdout); - } - } else { - - if ( show_progress ) { - - HDfprintf(stdout, - "%s%s:%d: cp = %d child exited as expected.\n", - fcn_name, tag, (int)pass2, cp++); - HDfflush(stdout); - } - - /* 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%s:%d cp = %d.\n", - fcn_name, tag, (int)pass2, cp++); - HDfflush(stdout); - } - - /* call H5Pset_libver_bounds() on the fapl_id */ - if ( pass2 ) { - - if ( H5Pset_libver_bounds(fapl_id, H5F_LIBVER_LATEST, - H5F_LIBVER_LATEST) < 0 ) { - - pass2 = FALSE; - failure_mssg2 = "H5Pset_libver_bounds() failed.\n"; - } - } - - if ( show_progress ) { - HDfprintf(stdout, "%s%s%d cp = %d.\n", - fcn_name, tag, (int)pass2, cp++); - HDfflush(stdout); - } - - /* attempt to open the file -- should fail as the child - * exited without closing the file properly, and thus - * the file should still be marked as having journaling - * in progress. - */ - - if ( pass2 ) { - - H5E_BEGIN_TRY { - - file_id = H5Fopen(filename, H5F_ACC_RDWR, fapl_id); - - } H5E_END_TRY; - - if ( file_id >= 0 ) { - - pass2 = FALSE; - failure_mssg2 = "H5Fopen() succeeded - 2."; - } - } - - if ( show_progress ) { - - HDfprintf(stdout, "%s%s%d: cp = %d.\n", - fcn_name, tag, (int)pass2, cp++); - HDfflush(stdout); - } - - /* delete the HDF5 file and journal file */ -#if 1 - HDremove(filename); - HDremove(journal_filename); -#endif - if ( show_progress ) { - - HDfprintf(stdout, "%s%s%d cp = %d parent done.\n", - fcn_name, tag, (int)pass2, cp++); - HDfflush(stdout); - } - } - } - } - - return; - -} /* verify_mdj_file_marking_after_open() */ - - -/*************************************************************************** - * Function: verify_mdj_file_marking_on_open - * - * Purpose: Verify that HDF5 file is marked as having journaling - * in progress when journaling is enabled at file open - * time. - * - * Do this by forking a child process and: - * - * 1) creating a test file in the child, - * - * 2) writing some data to it, - * - * 3) closing the test file. - * - * 4) re-openting the test file with metadata journaling - * enabled, and then - * - * 5) exiting from the child without closing the file. - * - * When the child exits, try to open the child's test file. - * Open should fail, as the file should be marked as journaling - * in progress. - * - * On either success or failure, clean up the test file and - * the associated journal file. - * - * Return: void - * - * Programmer: John Mainzer - * 7/2/08 - * - **************************************************************************/ - -static void -verify_mdj_file_marking_on_open(void) -{ - const char * fcn_name = "verify_mdj_file_marking_on_open():"; - const char * tag = "pre-fork:"; - char filename[512]; - char journal_filename[H5AC2__MAX_JOURNAL_FILE_NAME_LEN + 1]; - hbool_t child = FALSE; - hbool_t show_progress = FALSE; - hbool_t verbose = FALSE; - herr_t result; - int cp = 0; - int wait_status; - pid_t child_id; - pid_t wait_result; - hid_t file_id = -1; - hid_t fapl_id = -1; - hid_t dataset_id = -1; - hid_t dataspace_id = -1; - hsize_t dims[2]; - H5F_t * file_ptr = NULL; - H5AC2_jnl_config_t jnl_config; - - /* setup the file name */ - if ( pass2 ) { - - if ( h5_fixname(FILENAMES[1], H5P_DEFAULT, filename, - sizeof(filename)) == NULL ) { - - pass2 = FALSE; - failure_mssg2 = "h5_fixname() failed (1).\n"; - } - } - - if ( show_progress ) { - - HDfprintf(stdout, "%s%s%d cp = %d.\n", fcn_name, tag, pass2, cp++); - HDfflush(stdout); - } - - if ( verbose ) { - HDfprintf(stdout, "%s%s filename = \"%s\".\n", fcn_name, tag,filename); - HDfflush(stdout); - } - - /* setup the journal file name */ - if ( pass2 ) { - - if ( h5_fixname(FILENAMES[3], H5P_DEFAULT, journal_filename, - sizeof(journal_filename)) == NULL ) { - - pass2 = FALSE; - failure_mssg2 = "h5_fixname() failed (2).\n"; - } - else if ( strlen(journal_filename) >= - H5AC2__MAX_JOURNAL_FILE_NAME_LEN ) { - - pass2 = FALSE; - failure_mssg2 = "journal file name too long.\n"; - } - } - - if ( show_progress ) { - - HDfprintf(stdout, "%s%s%d cp = %d.\n", - fcn_name, tag, (int)pass2, cp++); - HDfflush(stdout); - } - - if ( verbose ) { - HDfprintf(stdout, "%s%s journal filename = \"%s\".\n", - fcn_name, tag, journal_filename); - HDfflush(stdout); - } - - if ( pass2 ) { - - child_id = HDfork(); - - if ( child_id == -1 ) { - - pass2 = FALSE; - failure_mssg2 = "H5fork() failed."; - - } else if ( child_id == 0 ) { - - child = TRUE; - tag = "child:"; - - } else { - - child = FALSE; - tag = "parent:"; - } - } - - if ( pass2 ) { - - /* reset the check point */ - cp = 0; - - if ( show_progress ) { - - HDfprintf(stdout, "%s%s%d: cp = %d fork() succeeded.\n", - fcn_name, tag, (int)pass2, cp++); - HDfflush(stdout); - } - - if ( child ) { - - if ( show_progress ) { - - HDfprintf(stdout, "%s%s%d: cp = %d child starting.\n", - fcn_name, tag, (int)pass2, cp++); - HDfflush(stdout); - } -#if 0 /* JRM */ - /* Quincey: - * - * It looks like we may have a bug here -- - * - * In the original version of this test, I: - * - * 1) created a file using the default FAPL, - * - * 2) added a data set to the file - * - * 3) closed it, - * - * 4) tried to re-open it using a FAPL that set the - * latest format, and enabled journaling. - * - * I hit an assertion failure on step 4. - * - * I then modified the above to select the latest file - * format on file create, and the problem went away. - * - * Is this as it should be, or do we have a bug here? - * - * JRM -- 7/9/08 - */ - - if ( pass2 ) { - - file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, - H5P_DEFAULT); - - if ( file_id < 0 ) { - - pass2 = FALSE; - failure_mssg2 = "H5Fcreate() failed.\n"; - } - } -#else /* JRM */ - - /* 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%s%d: cp = %d.\n", - fcn_name, tag, (int)pass2, cp++); - HDfflush(stdout); - } - - /* call H5Pset_libver_bounds() on the fapl_id */ - if ( pass2 ) { - - if ( H5Pset_libver_bounds(fapl_id, H5F_LIBVER_LATEST, - H5F_LIBVER_LATEST) < 0 ) { - - pass2 = FALSE; - failure_mssg2 = "H5Pset_libver_bounds() failed.\n"; - } - } - - /* open the file with a fapl indicating latest version of - * the file format. - */ - if ( pass2 ) { - - file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, - fapl_id); - - if ( file_id < 0 ) { - - pass2 = FALSE; - failure_mssg2 = "H5Fcreate() failed.\n"; - } - } -#endif /* JRM */ - if ( show_progress ) { - - HDfprintf(stdout, "%s%s%d: cp = %d.\n", - fcn_name, tag, (int)pass2, cp++); - HDfflush(stdout); - } - - if ( pass2 ) { - - dims[0] = 4; - dims[1] = 6; - dataspace_id = H5Screate_simple(2, dims, NULL); - - if ( dataspace_id < 0 ) { - - pass2 = FALSE; - failure_mssg2 = "H5Screate_simple() failed."; - } - } - - if ( show_progress ) { - - HDfprintf(stdout, "%s%s%d: cp = %d.\n", - fcn_name, tag, (int)pass2, cp++); - HDfflush(stdout); - } - - if ( pass2 ) { - - /* Create the dataset. */ - dataset_id = H5Dcreate2(file_id, "/dset", H5T_STD_I32BE, - dataspace_id, H5P_DEFAULT, - H5P_DEFAULT, H5P_DEFAULT); - - if ( dataspace_id < 0 ) { - - pass2 = FALSE; - failure_mssg2 = "H5Dcreate2() failed."; - } - } - - if ( show_progress ) { - - HDfprintf(stdout, "%s%s%d: cp = %d.\n", - fcn_name, tag, (int)pass2, cp++); - HDfflush(stdout); - } - - if ( pass2 ) { - - /* close the data set, the data space, and the file */ - if ( ( H5Dclose(dataset_id) < 0 ) || - ( H5Sclose(dataspace_id) < 0 ) || -#if 1 /* JRM */ - ( H5Pclose(fapl_id) < 0 ) || -#endif /* JRM */ - ( H5Fclose(file_id) < 0 ) ) { - - pass2 = FALSE; - failure_mssg2 = - "data set, data space, or file close failed."; - } - } - - if ( show_progress ) { - - HDfprintf(stdout, "%s%s%d: cp = %d.\n", - fcn_name, tag, (int)pass2, cp++); - HDfflush(stdout); - } - - /* 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%s%d: cp = %d.\n", - fcn_name, tag, (int)pass2, cp++); - HDfflush(stdout); - } - - /* call H5Pset_libver_bounds() on the fapl_id */ - if ( pass2 ) { - - if ( H5Pset_libver_bounds(fapl_id, H5F_LIBVER_LATEST, - H5F_LIBVER_LATEST) < 0 ) { - - pass2 = FALSE; - failure_mssg2 = "H5Pset_libver_bounds() failed.\n"; - } - } - - if ( show_progress ) { - - HDfprintf(stdout, "%s%s%d: cp = %d.\n", - fcn_name, tag, (int)pass2, cp++); - HDfflush(stdout); - } - - if ( pass2 ) { - - jnl_config.version = H5AC2__CURR_JNL_CONFIG_VER; - - result = H5Pget_jnl_config(fapl_id, &jnl_config); - - if ( result < 0 ) { - - pass2 = FALSE; - failure_mssg2 = "H5Pget_jnl_config() failed.\n"; - } - - /* set journaling config fields to taste */ - jnl_config.enable_journaling = TRUE; - - strcpy(jnl_config.journal_file_path, journal_filename); - - jnl_config.journal_recovered = FALSE; - jnl_config.jbrb_buf_size = (8 * 1024); - jnl_config.jbrb_num_bufs = 2; - jnl_config.jbrb_use_aio = FALSE; - jnl_config.jbrb_human_readable = TRUE; - } - - if ( show_progress ) { - - HDfprintf(stdout, "%s%s%d: cp = %d.\n", - fcn_name, tag, (int)pass2, cp++); - HDfflush(stdout); - } - - if ( pass2 ) { - - result = H5Pset_jnl_config(fapl_id, &jnl_config); - - if ( result < 0 ) { - - pass2 = FALSE; - failure_mssg2 = "H5Pset_jnl_config() failed.\n"; - } - } - - if ( show_progress ) { - - HDfprintf(stdout, "%s%s%d: cp = %d.\n", - fcn_name, tag, (int)pass2, cp++); - HDfflush(stdout); - } - - /* open the file using fapl_id */ - if ( pass2 ) { - - file_id = H5Fopen(filename, H5F_ACC_RDWR, fapl_id); - - if ( file_id < 0 ) { - - pass2 = FALSE; - failure_mssg2 = "H5Fopen() failed (9).\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); - } - } - } - } - - if ( show_progress ) { - - HDfprintf(stdout, "%s%s%d: cp = %d.\n", - fcn_name, tag, (int)pass2, cp++); - HDfflush(stdout); - } - - if ( ( verbose ) && ( ! pass2 ) ) { - HDfprintf(stdout, "%s%s%d failure_mssg = \"%s\".\n", - fcn_name, tag, pass2, failure_mssg2); - HDfflush(stdout); - } - - if ( show_progress ) { - - HDfprintf(stdout, "%s%s%d cp = %d child exiting.\n", - fcn_name, tag, (int)pass2, cp++); - HDfflush(stdout); - } - - abort(); - - } else { - - /* wait for the child to exit */ - wait_result = HDwaitpid(child_id, &wait_status, 0); - - HDsleep(3); - - if ( wait_result != child_id ) { - - pass2 = FALSE; - failure_mssg2 = "unexpected waitpid() result."; - - if ( show_progress ) { - - HDfprintf(stdout, - "%s%s:%d: wait_result = %ld, wait_status = %d.\n", - fcn_name, tag, (int)pass2, - (long)wait_result, wait_status); - HDfflush(stdout); - } - } else { - - if ( show_progress ) { - - HDfprintf(stdout, - "%s%s:%d: cp = %d child exited as expected.\n", - fcn_name, tag, (int)pass2, cp++); - HDfflush(stdout); - } - - /* 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%s:%d cp = %d.\n", - fcn_name, tag, (int)pass2, cp++); - HDfflush(stdout); - } - - /* call H5Pset_libver_bounds() on the fapl_id */ - if ( pass2 ) { - - if ( H5Pset_libver_bounds(fapl_id, H5F_LIBVER_LATEST, - H5F_LIBVER_LATEST) < 0 ) { - - pass2 = FALSE; - failure_mssg2 = "H5Pset_libver_bounds() failed.\n"; - } - } - - if ( show_progress ) { - HDfprintf(stdout, "%s%s%d cp = %d.\n", - fcn_name, tag, (int)pass2, cp++); - HDfflush(stdout); - } - - /* attempt to open the file -- should fail as the child - * exited without closing the file properly, and thus - * the file should still be marked as having journaling - * in progress. - */ - - if ( pass2 ) { - - H5E_BEGIN_TRY { - - file_id = H5Fopen(filename, H5F_ACC_RDWR, fapl_id); - - } H5E_END_TRY; - - if ( file_id >= 0 ) { - - pass2 = FALSE; - failure_mssg2 = "H5Fopen() succeeded - 3."; - } - } - - if ( show_progress ) { - - HDfprintf(stdout, "%s%s%d: cp = %d.\n", - fcn_name, tag, (int)pass2, cp++); - HDfflush(stdout); - } - - /* delete the HDF5 file and journal file */ -#if 1 - HDremove(filename); - HDremove(journal_filename); -#endif - if ( show_progress ) { - - HDfprintf(stdout, "%s%s%d cp = %d parent done.\n", - fcn_name, tag, (int)pass2, cp++); - HDfflush(stdout); - } - } - } - } - - return; - -} /* verify_mdj_file_marking_on_open() */ - - -/*************************************************************************** - * Function: verify_mdj_file_unmarking_on_file_close - * - * Purpose: Verify that HDF5 file on which journaling is enabled is - * marked as having not haveing journaling in progress when - * the file is closed. - * - * Do this as follows: - * - * 1) create a test file with metadata journaling - * enabled, - * - * 2) perform some operation(s) that dirty metadata - * and result in journal activity. - * - * 3) close the file. - * - * 4) attempt to re-open the file -- should succeed. - * - * On either success or failure, clean up the test file and - * the associated journal file. - * - * Return: void - * - * Programmer: John Mainzer - * 7/10/08 - * - **************************************************************************/ - -static void -verify_mdj_file_unmarking_on_file_close(void) -{ - const char * fcn_name = "verify_mdj_file_unmarking_on_file_close():"; - char filename[512]; - char journal_filename[H5AC2__MAX_JOURNAL_FILE_NAME_LEN + 1]; - hbool_t show_progress = FALSE; - hbool_t verbose = FALSE; - int cp = 0; - hid_t file_id = -1; - hid_t fapl_id = -1; - hid_t dataset_id = -1; - hid_t dataspace_id = -1; - hsize_t dims[2]; - H5F_t * file_ptr = NULL; - H5C2_t * cache_ptr = NULL; - - if ( show_progress ) { - - HDfprintf(stdout, "%s%d cp = %d -- entering.\n", fcn_name, pass2, cp++); - HDfflush(stdout); - } - - /* setup the file name */ - if ( pass2 ) { - - if ( h5_fixname(FILENAMES[1], H5P_DEFAULT, filename, - sizeof(filename)) == NULL ) { - - pass2 = FALSE; - failure_mssg2 = "h5_fixname() failed (1).\n"; - } - } - - if ( show_progress ) { - - HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, pass2, cp++); - HDfflush(stdout); - } - - if ( verbose ) { - HDfprintf(stdout, "%s filename = \"%s\".\n", fcn_name, filename); - HDfflush(stdout); - } - - /* setup the journal file name */ - if ( pass2 ) { - - if ( h5_fixname(FILENAMES[3], H5P_DEFAULT, journal_filename, - sizeof(journal_filename)) == NULL ) { - - pass2 = FALSE; - failure_mssg2 = "h5_fixname() failed (2).\n"; - } - else if ( strlen(journal_filename) >= - H5AC2__MAX_JOURNAL_FILE_NAME_LEN ) { - - pass2 = FALSE; - failure_mssg2 = "journal file name too long.\n"; - } - } - - if ( show_progress ) { - - HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, (int)pass2, cp++); - HDfflush(stdout); - } - - if ( verbose ) { - HDfprintf(stdout, "%s journal filename = \"%s\".\n", - fcn_name, journal_filename); - HDfflush(stdout); - } - - if ( pass2 ) { - - /* clean out any existing journal file */ - setup_cache_for_journaling(filename, journal_filename, &file_id, - &file_ptr, &cache_ptr, FALSE); - } - - if ( show_progress ) { - - HDfprintf(stdout, "%s%d: cp = %d.\n", fcn_name, (int)pass2, cp++); - HDfflush(stdout); - } - - /* create a data set so as to force a bit of journaling */ - if ( pass2 ) { - - dims[0] = 4; - dims[1] = 6; - dataspace_id = H5Screate_simple(2, dims, NULL); - - if ( dataspace_id < 0 ) { - - pass2 = FALSE; - failure_mssg2 = "H5Screate_simple() failed."; - } - } - - if ( show_progress ) { - - HDfprintf(stdout, "%s%d: cp = %d.\n", fcn_name, (int)pass2, cp++); - HDfflush(stdout); - } - - if ( pass2 ) { - - /* Create the dataset. */ - dataset_id = H5Dcreate2(file_id, "/dset", H5T_STD_I32BE, - dataspace_id, H5P_DEFAULT, - H5P_DEFAULT, H5P_DEFAULT); - - if ( dataspace_id < 0 ) { - - pass2 = FALSE; - failure_mssg2 = "H5Dcreate2() failed."; - } - } - - if ( show_progress ) { - - HDfprintf(stdout, "%s%d: cp = %d.\n", fcn_name, (int)pass2, cp++); - HDfflush(stdout); - } - - /* now close the file... */ - - if ( pass2 ) { - - if ( ( H5Dclose(dataset_id) < 0 ) || - ( H5Sclose(dataspace_id) < 0 ) || - ( H5Fclose(file_id) < 0 ) ) { - - pass2 = FALSE; - failure_mssg2 = "dataset, dataspace, or file close failed."; - } - } - - if ( show_progress ) { - - HDfprintf(stdout, "%s%d: cp = %d.\n", fcn_name, (int)pass2, cp++); - HDfflush(stdout); - } - - /* ... and attempt to re-open it. Should succeed */ - - /* 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%d: cp = %d.\n", fcn_name, (int)pass2, cp++); - HDfflush(stdout); - } - - /* call H5Pset_libver_bounds() on the fapl_id */ - if ( pass2 ) { - - if ( H5Pset_libver_bounds(fapl_id, H5F_LIBVER_LATEST, - H5F_LIBVER_LATEST) < 0 ) { - - pass2 = FALSE; - failure_mssg2 = "H5Pset_libver_bounds() failed.\n"; - } - } - - if ( show_progress ) { - - HDfprintf(stdout, "%s%d: cp = %d.\n", fcn_name, (int)pass2, cp++); - HDfflush(stdout); - } - - /* attempt to open the file -- should succeed as the close should - * shutdown journaling. - */ - - if ( pass2 ) { - - file_id = H5Fopen(filename, H5F_ACC_RDWR, fapl_id); - - if ( file_id < 0 ) { - - pass2 = FALSE; - failure_mssg2 = "H5Fopen() failed (10)."; - } - } - - if ( show_progress ) { - - HDfprintf(stdout, "%s%d: cp = %d.\n", fcn_name, (int)pass2, cp++); - HDfflush(stdout); - } - - /* close the file and fapl */ - - if ( pass2 ) { - - if ( ( H5Pclose(fapl_id) < 0 ) || - ( H5Fclose(file_id) < 0 ) ) { - - pass2 = FALSE; - failure_mssg2 = "fapl or file close failed."; - } - } - - if ( show_progress ) { - - HDfprintf(stdout, "%s%d: cp = %d.\n", fcn_name, (int)pass2, cp++); - HDfflush(stdout); - } - - /* delete the HDF5 file and journal file */ -#if 1 - HDremove(filename); - HDremove(journal_filename); -#endif - - if ( show_progress ) { - - HDfprintf(stdout, "%s%d: cp = %d.\n", fcn_name, (int)pass2, cp++); - HDfflush(stdout); - } - - return; - -} /* verify_mdj_file_unmarking_on_file_close() */ - - -/*************************************************************************** - * Function: verify_mdj_file_unmarking_on_journaling_shutdown - * - * Purpose: Verify that HDF5 file on which journaling is enabled is - * marked as having not haveing journaling in progress when - * journaling is disabled via the H5Fset_mdc_config() API - * call. - * - * Do this by: - * - * 1) forking a child process, - * - * 2) creating a test file in the child with metadata - * journaling enabled, - * - * 3) performing some operation(s) that dirty metadata - * and result in journal activity. - * - * 4) using the H5Fset_mdc_config() to disable journaling. - * - * 5) exiting from the child without closing the file. - * - * When the child exits, try to open the child's test file. - * Open should succeed, as the file should be marked as - * journaling not in progress. - * - * Note that the file will be synced out as part of the - * journaling shutdown process, so the metadata should be - * in a consistant state. Strictly speaking, this is not - * necessary for this test, for as long as the the file is - * not marked as having journaling in progress, we should - * pass. However, testing this without using the HDF5 - * library to open the file would be inconvenient -- hence - * we make use of the sync on journal shutdown to make the - * test easier to implement. - * - * On either success or failure, clean up the test file and - * the associated journal file. - * - * Return: void - * - * Programmer: John Mainzer - * 7/9/08 - * - **************************************************************************/ - -static void -verify_mdj_file_unmarking_on_journaling_shutdown(void) -{ - const char * fcn_name = - "verify_mdj_file_unmarking_on_journaling_shutdown():"; - const char * tag = "pre-fork:"; - char filename[512]; - char journal_filename[H5AC2__MAX_JOURNAL_FILE_NAME_LEN + 1]; - hbool_t child = FALSE; - hbool_t show_progress = FALSE; - hbool_t verbose = FALSE; - herr_t result; - int cp = 0; - int wait_status; - pid_t child_id; - pid_t wait_result; - hid_t file_id = -1; - hid_t fapl_id = -1; - hid_t dataset_id = -1; - hid_t dataspace_id = -1; - hsize_t dims[2]; - H5F_t * file_ptr = NULL; - H5C2_t * cache_ptr = NULL; - H5AC2_jnl_config_t jnl_config; - - /* setup the file name */ - if ( pass2 ) { - - if ( h5_fixname(FILENAMES[1], H5P_DEFAULT, filename, - sizeof(filename)) == NULL ) { - - pass2 = FALSE; - failure_mssg2 = "h5_fixname() failed (1).\n"; - } - } - - if ( show_progress ) { - - HDfprintf(stdout, "%s%s%d cp = %d.\n", fcn_name, tag, pass2, cp++); - HDfflush(stdout); - } - - if ( verbose ) { - HDfprintf(stdout, "%s%s filename = \"%s\".\n", fcn_name, tag,filename); - HDfflush(stdout); - } - - /* setup the journal file name */ - if ( pass2 ) { - - if ( h5_fixname(FILENAMES[3], H5P_DEFAULT, journal_filename, - sizeof(journal_filename)) == NULL ) { - - pass2 = FALSE; - failure_mssg2 = "h5_fixname() failed (2).\n"; - } - else if ( strlen(journal_filename) >= - H5AC2__MAX_JOURNAL_FILE_NAME_LEN ) { - - pass2 = FALSE; - failure_mssg2 = "journal file name too long.\n"; - } - } - - if ( show_progress ) { - - HDfprintf(stdout, "%s%s%d cp = %d.\n", - fcn_name, tag, (int)pass2, cp++); - HDfflush(stdout); - } - - if ( verbose ) { - HDfprintf(stdout, "%s%s journal filename = \"%s\".\n", - fcn_name, tag, journal_filename); - HDfflush(stdout); - } - - if ( pass2 ) { - - child_id = HDfork(); - - if ( child_id == -1 ) { - - pass2 = FALSE; - failure_mssg2 = "H5fork() failed."; - - } else if ( child_id == 0 ) { - - child = TRUE; - tag = "child:"; - - } else { - - child = FALSE; - tag = "parent:"; - } - } - - if ( pass2 ) { - - if ( show_progress ) { - - HDfprintf(stdout, "%s%s%d: cp = %d fork() succeeded.\n", - fcn_name, tag, (int)pass2, cp++); - HDfflush(stdout); - } - - if ( child ) { - - if ( show_progress ) { - - HDfprintf(stdout, "%s%s%d: cp = %d child starting.\n", - fcn_name, tag, (int)pass2, cp++); - HDfflush(stdout); - } - - /* clean out any existing journal file */ - setup_cache_for_journaling(filename, journal_filename, &file_id, - &file_ptr, &cache_ptr, FALSE); - - if ( show_progress ) { - - HDfprintf(stdout, "%s%s%d: cp = %d.\n", - fcn_name, tag, (int)pass2, cp++); - HDfflush(stdout); - } - - /* create a data set so as to force a bit of journaling */ - if ( pass2 ) { - - dims[0] = 4; - dims[1] = 6; - dataspace_id = H5Screate_simple(2, dims, NULL); - - if ( dataspace_id < 0 ) { - - pass2 = FALSE; - failure_mssg2 = "H5Screate_simple() failed."; - } - } - - if ( show_progress ) { - - HDfprintf(stdout, "%s%s%d: cp = %d.\n", - fcn_name, tag, (int)pass2, cp++); - HDfflush(stdout); - } - - if ( pass2 ) { - - /* Create the dataset. */ - dataset_id = H5Dcreate2(file_id, "/dset", H5T_STD_I32BE, - dataspace_id, H5P_DEFAULT, - H5P_DEFAULT, H5P_DEFAULT); - - if ( dataspace_id < 0 ) { - - pass2 = FALSE; - failure_mssg2 = "H5Dcreate2() failed."; - } - } - - if ( show_progress ) { - - HDfprintf(stdout, "%s%s%d: cp = %d.\n", - fcn_name, tag, (int)pass2, cp++); - HDfflush(stdout); - } - - /* now dis-able journaling */ - if ( pass2 ) { - - jnl_config.version = H5AC2__CURR_JNL_CONFIG_VER; - - result = H5Fget_jnl_config(file_id, &jnl_config); - - if ( result < 0 ) { - - pass2 = FALSE; - failure_mssg2 = "H5Fget_jnl_config() failed.\n"; - } - - jnl_config.enable_journaling = FALSE; - } - - if ( show_progress ) { - - HDfprintf(stdout, "%s%s%d: cp = %d.\n", - fcn_name, tag, (int)pass2, cp++); - HDfflush(stdout); - } - - if ( pass2 ) { - - result = H5Fset_jnl_config(file_id, &jnl_config); - - if ( result < 0 ) { - - pass2 = FALSE; - failure_mssg2 = "H5Fset_jnl_config() failed.\n"; - } - } - - if ( show_progress ) { - - HDfprintf(stdout, "%s%s%d: cp = %d.\n", - fcn_name, tag, (int)pass2, cp++); - HDfflush(stdout); - } - - if ( ( verbose ) && ( ! pass2 ) ) { - HDfprintf(stdout, "%s%s%d failure_mssg = \"%s\".\n", - fcn_name, tag, pass2, failure_mssg2); - HDfflush(stdout); - } - - if ( show_progress ) { - - HDfprintf(stdout, "%s%s%d cp = %d child exiting.\n", - fcn_name, tag, (int)pass2, cp++); - HDfflush(stdout); - } - - abort(); - - } else { - - /* wait for the child to exit */ - wait_result = HDwaitpid(child_id, &wait_status, 0); - - HDsleep(3); - - if ( wait_result != child_id ) { - - pass2 = FALSE; - failure_mssg2 = "unexpected waitpid() result."; - - if ( show_progress ) { - - HDfprintf(stdout, - "%s%s:%d: wait_result = %ld, wait_status = %d.\n", - fcn_name, tag, (int)pass2, - (long)wait_result, wait_status); - HDfflush(stdout); - } - } else { - - if ( show_progress ) { - - HDfprintf(stdout, - "%s%s:%d: cp = %d child exited as expected.\n", - fcn_name, tag, (int)pass2, cp++); - HDfflush(stdout); - } - - /* 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%s:%d cp = %d.\n", - fcn_name, tag, (int)pass2, cp++); - HDfflush(stdout); - } - - /* call H5Pset_libver_bounds() on the fapl_id */ - if ( pass2 ) { - - if ( H5Pset_libver_bounds(fapl_id, H5F_LIBVER_LATEST, - H5F_LIBVER_LATEST) < 0 ) { - - pass2 = FALSE; - failure_mssg2 = "H5Pset_libver_bounds() failed.\n"; - } - } - - if ( show_progress ) { - HDfprintf(stdout, "%s%s%d cp = %d.\n", - fcn_name, tag, (int)pass2, cp++); - HDfflush(stdout); - } - - /* attempt to open the file -- should succeed as the child - * disabled journaling just before exiting, which should have - * had the dual effect of marking the file as not having - * journaling in progress, and syncing the file out to disk. - */ - - file_id = H5Fopen(filename, H5F_ACC_RDWR, fapl_id); - - if ( file_id < 0 ) { - - pass2 = FALSE; - failure_mssg2 = "H5Fopen() failed (11)."; - } - - if ( show_progress ) { - - HDfprintf(stdout, "%s%s%d: cp = %d.\n", - fcn_name, tag, (int)pass2, cp++); - HDfflush(stdout); - } - - /* close the file and fapl */ - - if ( pass2 ) { - - if ( ( H5Pclose(fapl_id) < 0 ) || - ( H5Fclose(file_id) < 0 ) ) { - - pass2 = FALSE; - failure_mssg2 = "fapl or file close failed."; - } - } - - if ( show_progress ) { - - HDfprintf(stdout, "%s%s%d: cp = %d.\n", - fcn_name, tag, (int)pass2, cp++); - HDfflush(stdout); - } - - /* delete the HDF5 file and journal file */ -#if 1 - HDremove(filename); - HDremove(journal_filename); -#endif - if ( show_progress ) { - - HDfprintf(stdout, "%s%s%d cp = %d parent done.\n", - fcn_name, tag, (int)pass2, cp++); - HDfflush(stdout); - } - } - } - } - - return; - -} /* verify_mdj_file_unmarking_on_journaling_shutdown() */ - - -/*************************************************************************** - * Function: verify_mdj_file_unmarking_on_recovery - * - * Purpose: Verify that HDF5 file that is marked as as having journaling - * in progress is unmarked when the file is opened with the - * journal_recovered flag set in the cache configuration - * structure in the file access property list. - * - * Do this by forking a child process, creating a test file - * in the child with metadata journaling enabled, and then - * exiting from the child without closing the file. Note that - * we must flush the file before exiting, as we want the file - * to be readable, but be marked as journaling in progress. - * - * When the child exits, try to open the child's test file. - * Open should fail, as the file should be marked as journaling - * in progress. - * - * Try to open again with the journal_recovered flag set. This - * should succeed. Close and open again without the - * journal recovered flag set to verify that the file is - * no longer marked as having journaling in progress. - * - * On either success or failure, clean up the test file and - * the associated journal file. - * - * Return: void - * - * Programmer: John Mainzer - * 7/14/08 - * - **************************************************************************/ - -static void -verify_mdj_file_unmarking_on_recovery(void) -{ - const char * fcn_name = "verify_mdj_file_unmarking_on_recovery():"; - const char * tag = "pre-fork:"; - char filename[512]; - char journal_filename[H5AC2__MAX_JOURNAL_FILE_NAME_LEN + 1]; - hbool_t child = FALSE; - hbool_t show_progress = FALSE; - hbool_t verbose = FALSE; - herr_t result; - int cp = 0; - int wait_status; - uint64_t trans_num; - pid_t child_id; - pid_t wait_result; - hid_t file_id = -1; - hid_t fapl_id = -1; - H5F_t * file_ptr = NULL; - H5C2_t * cache_ptr = NULL; - H5AC2_jnl_config_t jnl_config; - - /* setup the file name */ - if ( pass2 ) { - - if ( h5_fixname(FILENAMES[1], H5P_DEFAULT, filename, - sizeof(filename)) == NULL ) { - - pass2 = FALSE; - failure_mssg2 = "h5_fixname() failed (1).\n"; - } - } - - if ( show_progress ) { - - HDfprintf(stdout, "%s%s%d cp = %d.\n", fcn_name, tag, pass2, cp++); - HDfflush(stdout); - } - - if ( verbose ) { - HDfprintf(stdout, "%s%s filename = \"%s\".\n", fcn_name, tag,filename); - HDfflush(stdout); - } - - /* setup the journal file name */ - if ( pass2 ) { - - if ( h5_fixname(FILENAMES[3], H5P_DEFAULT, journal_filename, - sizeof(journal_filename)) == NULL ) { - - pass2 = FALSE; - failure_mssg2 = "h5_fixname() failed (2).\n"; - } - else if ( strlen(journal_filename) >= - H5AC2__MAX_JOURNAL_FILE_NAME_LEN ) { - - pass2 = FALSE; - failure_mssg2 = "journal file name too long.\n"; - } - } - - if ( show_progress ) { - - HDfprintf(stdout, "%s%s%d cp = %d.\n", - fcn_name, tag, (int)pass2, cp++); - HDfflush(stdout); - } - - if ( verbose ) { - HDfprintf(stdout, "%s%s journal filename = \"%s\".\n", - fcn_name, tag, journal_filename); - HDfflush(stdout); - } - - if ( pass2 ) { - - child_id = HDfork(); - - if ( child_id == -1 ) { - - pass2 = FALSE; - failure_mssg2 = "H5fork() failed."; - - } else if ( child_id == 0 ) { - - child = TRUE; - tag = "child:"; - - } else { - - child = FALSE; - tag = "parent:"; - } - } - - if ( pass2 ) { - - if ( show_progress ) { - - HDfprintf(stdout, "%s%s%d: cp = %d fork() succeeded.\n", - fcn_name, tag, (int)pass2, cp++); - HDfflush(stdout); - } - - if ( child ) { - - if ( show_progress ) { - - HDfprintf(stdout, "%s%s%d: cp = %d child starting.\n", - fcn_name, tag, (int)pass2, cp++); - HDfflush(stdout); - } - - /* clean out any existing journal file */ - HDremove(journal_filename); - setup_cache_for_journaling(filename, journal_filename, &file_id, - &file_ptr, &cache_ptr, FALSE); - - if ( show_progress ) { - - HDfprintf(stdout, "%s%s%d: cp = %d.\n", - fcn_name, tag, (int)pass2, cp++); - HDfflush(stdout); - } - - /* run a dummy transaction to fource metadata journaling - * initialization. - */ - H5C2_begin_transaction(cache_ptr, &trans_num, "dummy"); - H5C2_end_transaction(file_ptr, H5AC2_dxpl_id, cache_ptr, - trans_num, "dummy"); - - if ( show_progress ) { - - HDfprintf(stdout, "%s%s%d: cp = %d.\n", - fcn_name, tag, (int)pass2, cp++); - HDfflush(stdout); - } - - /* flush the file to ensure that it is in a readable state */ - if ( pass2 ) { - - if ( H5Fflush(file_id, H5F_SCOPE_GLOBAL) < 0 ) { - - if ( verbose ) { - - HDfprintf(stdout, "%s:%s: H5Fflush() failed.\n", - fcn_name, tag); - HDfflush(stdout); - } - pass2 = FALSE; - failure_mssg2 = "H5Fflush() failed."; - } - } - - if ( ( verbose ) && ( ! pass2 ) ) { - HDfprintf(stdout, "%s%s%d failure_mssg = \"%s\".\n", - fcn_name, tag, pass2, failure_mssg2); - HDfflush(stdout); - } - - if ( show_progress ) { - - HDfprintf(stdout, "%s%s%d cp = %d child exiting.\n", - fcn_name, tag, (int)pass2, cp++); - HDfflush(stdout); - } - - abort(); - - } else { - - /* wait for the child to exit */ - wait_result = HDwaitpid(child_id, &wait_status, 0); - - HDsleep(3); - - if ( wait_result != child_id ) { - - pass2 = FALSE; - failure_mssg2 = "unexpected waitpid() result."; - - if ( show_progress ) { - - HDfprintf(stdout, - "%s%s:%d: wait_result = %ld, wait_status = %d.\n", - fcn_name, tag, (int)pass2, - (long)wait_result, wait_status); - HDfflush(stdout); - } - } else { - - if ( show_progress ) { - - HDfprintf(stdout, - "%s%s:%d: cp = %d child exited as expected.\n", - fcn_name, tag, (int)pass2, cp++); - HDfflush(stdout); - } - - /* 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%s:%d cp = %d.\n", - fcn_name, tag, (int)pass2, cp++); - HDfflush(stdout); - } - - /* call H5Pset_libver_bounds() on the fapl_id */ - if ( pass2 ) { - - if ( H5Pset_libver_bounds(fapl_id, H5F_LIBVER_LATEST, - H5F_LIBVER_LATEST) < 0 ) { - - pass2 = FALSE; - failure_mssg2 = "H5Pset_libver_bounds() failed.\n"; - } - } - - if ( show_progress ) { - HDfprintf(stdout, "%s%s%d cp = %d.\n", - fcn_name, tag, (int)pass2, cp++); - HDfflush(stdout); - } - - /* attempt to open the file -- should fail as the child - * exited without closing the file properly, and thus - * the file should still be marked as having journaling - * in progress. - */ - - if ( pass2 ) { - - H5E_BEGIN_TRY { - - file_id = H5Fopen(filename, H5F_ACC_RDWR, fapl_id); - - } H5E_END_TRY; - - if ( file_id >= 0 ) { - - pass2 = FALSE; - failure_mssg2 = "H5Fopen() succeeded - 4."; - } - } - - if ( show_progress ) { - - HDfprintf(stdout, "%s%s%d: cp = %d.\n", - fcn_name, tag, (int)pass2, cp++); - HDfflush(stdout); - } - - - /* now set the file recovered flag in the journal config - * structure in the fapl, and try to open again. Should - * succeed, and the file should not be marked as having - * journaling in progress. - */ - if ( pass2 ) { - - jnl_config.version = H5AC2__CURR_JNL_CONFIG_VER; - - result = H5Pget_jnl_config(fapl_id, &jnl_config); - - if ( result < 0 ) { - - pass2 = FALSE; - failure_mssg2 = "H5Pget_jnl_config() failed.\n"; - } - - jnl_config.journal_recovered = TRUE; - } - - if ( show_progress ) { - - HDfprintf(stdout, "%s%s%d: cp = %d.\n", - fcn_name, tag, (int)pass2, cp++); - HDfflush(stdout); - } - - if ( pass2 ) { - - result = H5Pset_jnl_config(fapl_id, &jnl_config); - - if ( result < 0 ) { - - pass2 = FALSE; - failure_mssg2 = "H5Pset_jnl_config() failed(1).\n"; - } - } - - if ( show_progress ) { - - HDfprintf(stdout, "%s%s%d: cp = %d.\n", - fcn_name, tag, (int)pass2, cp++); - HDfflush(stdout); - } - - if ( pass2 ) { - - file_id = H5Fopen(filename, H5F_ACC_RDWR, fapl_id); - - if ( file_id < 0 ) { - - pass2 = FALSE; - failure_mssg2 = "H5Fopen() failed (12)."; - } - } - - if ( show_progress ) { - - HDfprintf(stdout, "%s%s%d: cp = %d.\n", - fcn_name, tag, (int)pass2, cp++); - HDfflush(stdout); - } - - if ( pass2 ) { - - if ( H5Fclose(file_id) < 0 ) { - - pass2 = FALSE; - failure_mssg2 = "H5Fclose() failed(1)."; - } - } - - if ( show_progress ) { - - HDfprintf(stdout, "%s%s%d: cp = %d.\n", - fcn_name, tag, (int)pass2, cp++); - HDfflush(stdout); - } - - /* now, turn off the journal recovered flag, and try to - * open the file again. Should succeed. - */ - - if ( pass2 ) { - - jnl_config.journal_recovered = FALSE; - - result = H5Pset_jnl_config(fapl_id, &jnl_config); - - if ( result < 0 ) { - - pass2 = FALSE; - failure_mssg2 = "H5Pset_jnl_config() failed(2).\n"; - } - } - - if ( show_progress ) { - - HDfprintf(stdout, "%s%s%d: cp = %d.\n", - fcn_name, tag, (int)pass2, cp++); - HDfflush(stdout); - } - - if ( pass2 ) { - - file_id = H5Fopen(filename, H5F_ACC_RDWR, fapl_id); - - if ( file_id < 0 ) { - - pass2 = FALSE; - failure_mssg2 = "H5Fopen() failed (13)."; - } - } - - if ( show_progress ) { - - HDfprintf(stdout, "%s%s%d: cp = %d.\n", - fcn_name, tag, (int)pass2, cp++); - HDfflush(stdout); - } - - if ( pass2 ) { - - if ( ( H5Fclose(file_id) < 0 ) || - ( H5Pclose(fapl_id) < 0 ) ) { - - pass2 = FALSE; - failure_mssg2 = "H5Fclose() or H5Pclose() failed(2)."; - } - } - - if ( show_progress ) { - - HDfprintf(stdout, "%s%s%d: cp = %d.\n", - fcn_name, tag, (int)pass2, cp++); - HDfflush(stdout); - } - - /* delete the HDF5 file and journal file */ -#if 1 - HDremove(filename); - HDremove(journal_filename); -#endif - if ( show_progress ) { - - HDfprintf(stdout, "%s%s%d cp = %d parent done.\n", - fcn_name, tag, (int)pass2, cp++); - HDfflush(stdout); - } - } - } - } - - return; - -} /* verify_mdj_file_unmarking_on_recovery() */ - - -/*************************************************************************** - * Function: check_mdjsc_callbacks() - * - * Purpose: Verify that the registration and deregistration of - * metadata journaling status change registration/deregistraion - * works correctly. - * - * Verify that the status change callbacks are called as - * they should be, and that the cache is clean when the - * callback is called. - * - * On failure, set pass2 to false, and failure_mssg2 to an - * appropriate error string. - * - * Return: void - * - * Programmer: John Mainzer - * 7/2/08 - * - **************************************************************************/ - -static void -check_mdjsc_callbacks(void) -{ - const char * fcn_name = "check_mdjsc_callbacks():"; - - TESTING("metadata journaling status change callbacks"); - - verify_mdjsc_callback_registration_deregistration(); - - verify_mdjsc_callback_execution(); - - verify_mdjsc_callback_error_rejection(); - - if ( pass2 ) { PASSED(); } else { H5_FAILED(); } - - if ( ! pass2 ) { - - failures2++; - HDfprintf(stdout, "%s: failure_mssg2 = \"%s\".\n", - fcn_name, failure_mssg2); - } - - return; - -} /* check_mdjsc_callbacks() */ - - -/*************************************************************************** - * - * Function: test_mdjsc_callback() - * - * Purpose: Test callback function used to test the metadata - * journaling status change callback facility. - * - * Return: void - * - * Programmer: John Mainzer - * 8/15/08 - * - **************************************************************************/ - -static H5C2_t * callback_test_cache_ptr = NULL; -static hbool_t callback_test_invalid_cache_ptr = FALSE; -static hbool_t callback_test_null_config_ptr = FALSE; -static hbool_t callback_test_invalid_config = FALSE; -static hbool_t callback_test_null_data_ptr = FALSE; -static hbool_t callback_test_cache_is_dirty = FALSE; -static int callback_test_null_data_ptr_count = 0; - -static void -test_mdjsc_callback(H5C2_mdj_config_t * config_ptr, - void * data_ptr) -{ - if ( config_ptr == NULL ) - { - callback_test_null_config_ptr = TRUE; - } - - if ( ( callback_test_cache_ptr == NULL ) || - ( callback_test_cache_ptr->magic != H5C2__H5C2_T_MAGIC ) ) - { - callback_test_invalid_cache_ptr = TRUE; - } - else if ( callback_test_cache_ptr->slist_len > 0 ) - { - callback_test_cache_is_dirty = TRUE; - } - else if ( ( callback_test_cache_ptr != NULL ) && - ( callback_test_cache_ptr->mdj_enabled != - config_ptr->enable_journaling ) ) - { - callback_test_invalid_config = TRUE; - } - - if ( data_ptr == NULL ) - { - callback_test_null_data_ptr = TRUE; - callback_test_null_data_ptr_count++; - } - else - { - *((int *)data_ptr) += 1; - } - - return; - -} /* test_mdjsc_callback() */ - - -/*************************************************************************** - * - * Function: deregister_mdjsc_callback() - * - * Purpose: Attempt to deregister the metadata journaling status change - * callback with the supplied index, and verify that the - * deregistration took place. - * - * If any error is detected, set pass2 t FALSE, and set the - * failure_mssg2 to the appropriate error message. - * - * Do nothing and return if pass2 is false on entry. - * - * Return: void - * - * Programmer: John Mainzer - * 8/15/08 - * - **************************************************************************/ - -static void -deregister_mdjsc_callback(H5F_t * file_ptr, - H5C2_t * cache_ptr, - int32_t idx) -{ - herr_t result; - - if ( pass2 ) - { - if ( ( file_ptr == NULL ) || - ( cache_ptr == NULL ) || - ( cache_ptr->magic != H5C2__H5C2_T_MAGIC ) ) - { - pass2 = FALSE; - failure_mssg2 = - "deregister_mdjsc_callback(): bad param(s) on entry."; - } - } - - if ( pass2 ) - { - result = H5AC2_deregister_mdjsc_callback(file_ptr, idx); - - if ( result < 0 ) - { - pass2 = FALSE; - failure_mssg2 = "H5AC2_deregister_mdjsc_callback() failed."; - } - - verify_mdjsc_callback_deregistered(cache_ptr, idx); - } - - return; - -} /* deregister_mdjsc_callback() */ - - -/*************************************************************************** - * - * Function: register_mdjsc_callback() - * - * Purpose: Attempt to register the supplied metadata journaling - * status change callback, and verify that the registration - * took. - * - * If any error is detected, set pass2 t FALSE, and set the - * failure_mssg2 to the appropriate error message. - * - * Do nothing and return if pass2 is false on entry. - * - * Return: void - * - * Programmer: John Mainzer - * 8/15/08 - * - **************************************************************************/ - -static void -register_mdjsc_callback(H5F_t * file_ptr, - H5C2_t * cache_ptr, - H5C2_mdj_status_change_func_t fcn_ptr, - void * data_ptr, - int32_t * idx_ptr) +static void +register_mdjsc_callback(H5F_t * file_ptr, + H5C2_t * cache_ptr, + H5C2_mdj_status_change_func_t fcn_ptr, + void * data_ptr, + int32_t * idx_ptr) { herr_t result; H5C2_mdj_config_t init_config; @@ -14440,9 +11991,6 @@ main(void) check_mdj_config_block_IO(); #endif #if 1 - check_mdj_file_marking(); -#endif -#if 1 check_mdjsc_callbacks(); #endif diff --git a/test/testjnlfilemarking.sh b/test/testjnlfilemarking.sh new file mode 100755 index 0000000..2c278cb --- /dev/null +++ b/test/testjnlfilemarking.sh @@ -0,0 +1,89 @@ +#! /bin/sh +# +# Copyright by The HDF Group. +# Copyright by the Board of Trustees of the University of Illinois. +# All rights reserved. +# +# This file is part of HDF5. The full HDF5 copyright notice, including +# terms governing use, modification, and redistribution, is contained in +# the files COPYING and Copyright.html. COPYING can be found at the root +# of the source code distribution tree; Copyright.html can be found at the +# root level of an installed copy of the electronic HDF5 document set and +# is linked from the top-level documents page. It can also be found at +# http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have +# access to either file, you may request a copy from help@hdfgroup.org. +# +# Tests for journaling related marking and unmarking of HDF5 files. +# +# These tests used to be in cache2_journal.c, but had to be moved +# out as the tests require simulated crashes, and it is difficult to +# do this in a C program without using fork(). + +nerrors=0 + +# The build (current) directory might be different than the source directory. +if test -z "$srcdir"; then + srcdir=. +fi + +test -d ./testfiles || mkdir ./testfiles + +# Print a line-line message left justified in a field of 70 characters +# beginning with the word "Testing". +# +TESTING() { + SPACES=" " + echo "Testing $* $SPACES" | cut -c1-70 | tr -d '\012' +} + +# Run a test and print PASS or *FAIL*. If a test fails then increment +# the `nerrors' global variable. +# +TEST() { + TEST_ERR=$1 # The test name + TEST_ERR_BIN=`pwd`/$TEST_ERR # The path of the test binary + TEST_DESC=$2 + + #Run the test: + trap "" 6 + $RUNSERIAL $TEST_ERR_BIN $TEST_DESC setup + trap 6 + TESTING $TEST_DESC + $RUNSERIAL $TEST_ERR_BIN $TEST_DESC check + if [ $? -eq 0 ] + then + echo " PASSED" + else + echo "*FAILED*" + nerrors="`expr $nerrors + 1`" + fi +} + +# Print a "SKIP" message +SKIP() { + TESTING $@ + echo " -SKIP-" +} + +############################################################################## +############################################################################## +### T H E T E S T S ### +############################################################################## +############################################################################## + +echo "Tests to verify correct marking of journaling in progress status in a" +echo "HDF5 file under various conditions -- most involving abnormal exits." +echo "Thus the \"Aborted\" messages between tests are expected." + +TEST cache2_jnl_file_marking file_marking_after_open +TEST cache2_jnl_file_marking file_marking_on_create +TEST cache2_jnl_file_marking file_marking_on_open +TEST cache2_jnl_file_marking file_unmarking_on_file_close +TEST cache2_jnl_file_marking file_unmarking_on_journaling_shutdown +TEST cache2_jnl_file_marking file_unmarking_on_recovery + +if test $nerrors -eq 0 ; then + echo "All journaling file marking tests passed." +fi + +exit $nerrors -- cgit v0.12