diff options
Diffstat (limited to 'test/cache2_jnl_file_marking.c')
-rw-r--r-- | test/cache2_jnl_file_marking.c | 3600 |
1 files changed, 3600 insertions, 0 deletions
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 <test> <op> [verbose]\n", + "\n", + "where:\n", + "\n", + " <test> ::= ( 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", + " <op> :: ( 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() */ + |