diff options
37 files changed, 660 insertions, 276 deletions
@@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in Id: configure.in 15300 2008-06-30 19:05:39Z koziol . +# From configure.in Id: configure.in 15369 2008-07-15 22:03:33Z acheng . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.61 for HDF5 1.9.8-metadata_journaling1. # @@ -50520,6 +50520,15 @@ echo "$as_me: error: Removing old public API symbols not allowed when using them { (exit 1); exit 1; }; } fi +{ echo "$as_me:$LINENO: checking for and unzipping large test files" >&5 +echo $ECHO_N "checking for and unzipping large test files... $ECHO_C" >&6; } +for f in $srcdir/test/testfiles/*.gz; do + if test -f $f; then + gunzip -f $f + fi +done +{ echo "$as_me:$LINENO: result: done" >&5 +echo "${ECHO_T}done" >&6; } { echo "$as_me:$LINENO: checking Whether to perform strict file format checks" >&5 diff --git a/configure.in b/configure.in index 460b4da..c4166a3 100644 --- a/configure.in +++ b/configure.in @@ -3715,6 +3715,16 @@ if test "X${DEFAULT_API_VERSION}" != "Xv18" -a "X${DEPRECATED_SYMBOLS}" = "Xno" AC_MSG_ERROR([Removing old public API symbols not allowed when using them as default public API symbols]) fi +dnl ---------------------------------------------------------------------- +dnl Unzip large test files +dnl +AC_MSG_CHECKING([for and unzipping large test files]) +for f in $srcdir/test/testfiles/*.gz; do + if test -f $f; then + gunzip -f $f + fi +done +AC_MSG_RESULT([done]) dnl ---------------------------------------------------------------------- dnl Enable strict file format checks diff --git a/src/H5C2journal.c b/src/H5C2journal.c index 4eaab9e..5350d6d 100644 --- a/src/H5C2journal.c +++ b/src/H5C2journal.c @@ -788,7 +788,6 @@ H5C2_journal_transaction(H5F_t * f, void * new_image_ptr; void * thing; herr_t result; - haddr_t eoa; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5C2_journal_transaction, FAIL) @@ -973,13 +972,8 @@ H5C2_journal_transaction(H5F_t * f, */ if ( ( ! resized ) && ( ! renamed ) ) { - if(HADDR_UNDEF == (eoa = H5FDget_eoa(f->shared->lf, H5FD_MEM_DEFAULT))) - HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, \ - "file get eoa request failed") - result = H5C2_jb__journal_entry(&(cache_ptr->mdj_jbrb), cache_ptr->trans_num, - eoa, entry_ptr->addr, entry_ptr->size, entry_ptr->image_ptr); @@ -2768,7 +2762,6 @@ done: herr_t H5C2_jb__journal_entry(H5C2_jbrb_t * struct_ptr, uint64_t trans_num, - haddr_t eoa, haddr_t base_addr, size_t length, const uint8_t * body) @@ -2821,9 +2814,8 @@ H5C2_jb__journal_entry(H5C2_jbrb_t * struct_ptr, /* Write journal entry */ HDsnprintf(temp, (size_t)(length + 100), - "2 trans_num %llu eoa 0x%lx length %zu base_addr 0x%lx body ", + "2 trans_num %llu length %zu base_addr 0x%lx body ", trans_num, - (unsigned long)eoa, length, (unsigned long)base_addr); @@ -3065,6 +3057,86 @@ done: /****************************************************************************** * + * Function: H5C2_jb__eoa + * + * Programmer: Mike McGreevy <mamcgree@hdfgroup.org> + * July 29, 2008 + * + * Purpose: Insert the supplied EOA into the journal file. + * + * Returns: SUCCEED on success. + * + ******************************************************************************/ + +herr_t +H5C2_jb__eoa(H5C2_jbrb_t * struct_ptr, + haddr_t eoa) +{ + char temp[40]; + size_t temp_len = 40; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(H5C2_jb__eoa, FAIL) + + /* Check Arguments */ + HDassert(struct_ptr); + HDassert(struct_ptr->magic == H5C2__H5C2_JBRB_T_MAGIC); + HDassert(struct_ptr->hdf5_file_name); + + /* Verify that header message is present in journal file or ring buffer. + * If not, write it. + */ + if ( struct_ptr->header_present == FALSE ) { + + char buf[150]; + time_t current_date; + + /* Get the current date */ + current_date = time(NULL); + + HDsnprintf(buf, + (size_t)150, + "0 ver_num %ld target_file_name %s creation_date %10.10s human_readable %d\n", + struct_ptr->jvers, + struct_ptr->hdf5_file_name, + ctime(¤t_date), + struct_ptr->human_readable); + + if ( H5C2_jb__write_to_buffer(struct_ptr, HDstrlen(buf), buf, + FALSE, struct_ptr->cur_trans) < 0 ) { + + HGOTO_ERROR(H5E_CACHE, H5E_CANTJOURNAL, FAIL, \ + "H5C2_jb__write_to_buffer() failed.\n") + } /* end if */ + + struct_ptr->header_present = 1; + struct_ptr->journal_is_empty = 0; + } /* end if */ + + /* Write EOA message */ + HDsnprintf(temp, temp_len, "E eoa_value 0x%lx", eoa); + + if ( H5C2_jb__write_to_buffer(struct_ptr, HDstrlen(temp), temp, FALSE, struct_ptr->cur_trans ) < 0 ) { + + HGOTO_ERROR(H5E_CACHE, H5E_CANTJOURNAL, FAIL, \ + "H5C2_jb__write_to_buffer() failed.\n") + } /* end if */ + + if ( H5C2_jb__write_to_buffer(struct_ptr, 1, "\n", FALSE, struct_ptr->cur_trans ) < 0 ) { + + HGOTO_ERROR(H5E_CACHE, H5E_CANTJOURNAL, FAIL, \ + "H5C2_jb__write_to_buffer() failed.\n") + } /* end if */ + +done: + + FUNC_LEAVE_NOAPI(ret_value) + +} /* end H5C2_jb__eoa */ + + +/****************************************************************************** + * * Function: H5C2_jb__get_last_transaction_on_disk * * Programmer: Mike McGreevy <mcgreevy@hdfgroup.org> diff --git a/src/H5C2private.h b/src/H5C2private.h index 1e4dbb3..f25fe4f 100644 --- a/src/H5C2private.h +++ b/src/H5C2private.h @@ -1531,7 +1531,6 @@ H5_DLL herr_t H5C2_jb__start_transaction(H5C2_jbrb_t * struct_ptr, H5_DLL herr_t H5C2_jb__journal_entry(H5C2_jbrb_t * struct_ptr, uint64_t trans_num, - haddr_t eoa, haddr_t base_addr, size_t length, const uint8_t * body); @@ -1542,6 +1541,9 @@ H5_DLL herr_t H5C2_jb__end_transaction(H5C2_jbrb_t * struct_ptr, H5_DLL herr_t H5C2_jb__comment(H5C2_jbrb_t * struct_ptr, const char * comment_ptr); +H5_DLL herr_t H5C2_jb__eoa(H5C2_jbrb_t * struct_ptr, + haddr_t eoa); + H5_DLL herr_t H5C2_jb__get_last_transaction_on_disk(H5C2_jbrb_t * struct_ptr, uint64_t * trans_num_ptr); @@ -28,6 +28,7 @@ /* Module Setup */ /****************/ +#define H5C2_PACKAGE /*suppress error about including H5C2pkg */ #define H5F_PACKAGE /*suppress error about including H5Fpkg */ @@ -35,6 +36,7 @@ /* Headers */ /***********/ #include "H5private.h" /* Generic Functions */ +#include "H5C2pkg.h" /* Metadata cache */ #include "H5Eprivate.h" /* Error handling */ #include "H5Fpkg.h" /* File access */ #include "H5MFprivate.h" /* File memory management */ @@ -96,7 +98,8 @@ static hbool_t H5MF_alloc_overflow(const H5F_t *f, hsize_t size); haddr_t H5MF_alloc(const H5F_t *f, H5FD_mem_t type, hid_t dxpl_id, hsize_t size) { - haddr_t ret_value; + haddr_t ret_value, new_eoa; + herr_t result; FUNC_ENTER_NOAPI(H5MF_alloc, HADDR_UNDEF) @@ -111,6 +114,20 @@ H5MF_alloc(const H5F_t *f, H5FD_mem_t type, hid_t dxpl_id, hsize_t size) /* Allocate space from the virtual file layer */ if(HADDR_UNDEF == (ret_value = H5FD_alloc(f->shared->lf, type, dxpl_id, size))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, HADDR_UNDEF, "file allocation failed") + + /* Check for journaling in progress */ + if (f->shared->cache2->mdj_enabled == 1) { + + /* get updated EOA value */ + if (HADDR_UNDEF ==(new_eoa = H5FDget_eoa(f->shared->lf, H5FD_MEM_DEFAULT))) + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, \ + "file get eoa request failed") + + /* journal the updated EOA value */ + if(SUCCEED != H5C2_jb__eoa(&(f->shared->cache2->mdj_jbrb), new_eoa)) + HGOTO_ERROR(H5E_CACHE, H5E_CANTJOURNAL, FAIL, \ + "H5C2_jb__eoa() failed.") + } /* end if */ /* Convert absolute file address to relative file address */ HDassert(ret_value >= f->shared->base_addr); diff --git a/src/Makefile.in b/src/Makefile.in index b96bdb0..51417eb 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -102,10 +102,10 @@ am_libhdf5_la_OBJECTS = H5.lo H5checksum.lo H5dbg.lo H5system.lo \ H5I.lo H5L.lo H5Lexternal.lo H5MF.lo H5MM.lo H5MP.lo \ H5MPtest.lo H5O.lo H5Oainfo.lo H5Oalloc.lo H5Oattr.lo \ H5Oattribute.lo H5Obogus.lo H5Obtreek.lo H5Ocache.lo \ - H5Ochunk.lo H5Ocont.lo H5Ocopy.lo H5Odbg.lo H5Odrvinfo.lo H5Odtype.lo \ - H5Oefl.lo H5Ofill.lo H5Oginfo.lo H5Olayout.lo H5Olinfo.lo \ - H5Olink.lo H5Omdj_msg.lo H5Omessage.lo H5Omtime.lo H5Oname.lo \ - H5Onull.lo H5Opline.lo H5Orefcount.lo H5Osdspace.lo \ + H5Ochunk.lo H5Ocont.lo H5Ocopy.lo H5Odbg.lo H5Odrvinfo.lo \ + H5Odtype.lo H5Oefl.lo H5Ofill.lo H5Oginfo.lo H5Olayout.lo \ + H5Olinfo.lo H5Olink.lo H5Omdj_msg.lo H5Omessage.lo H5Omtime.lo \ + H5Oname.lo H5Onull.lo H5Opline.lo H5Orefcount.lo H5Osdspace.lo \ H5Oshared.lo H5Ostab.lo H5Oshmesg.lo H5Otest.lo H5Ounknown.lo \ H5P.lo H5Pacpl.lo H5Pdcpl.lo H5Pdeprec.lo H5Pdxpl.lo \ H5Pfapl.lo H5Pfcpl.lo H5Pfmpl.lo H5Pgcpl.lo H5Pint.lo \ diff --git a/test/cache2_journal.c b/test/cache2_journal.c index 633414e..fb199d5 100644 --- a/test/cache2_journal.c +++ b/test/cache2_journal.c @@ -9336,7 +9336,6 @@ check_message_format(void) if ( H5C2_jb__journal_entry(/* H5C2_jbrb_t */ &jbrb_struct, /* trans number */ (uint64_t)1, - /* eoa */ (haddr_t)1, /* base address */ (haddr_t)0, /* data length */ 1, /* data */ (const uint8_t *)"A") @@ -9358,7 +9357,6 @@ check_message_format(void) if ( H5C2_jb__journal_entry(/* H5C2_jbrb_t */ &jbrb_struct, /* trans number */ (uint64_t)1, - /* eoa */ (haddr_t)1, /* base address */ (haddr_t)1, /* data length */ 2, /* data */ (const uint8_t *)"AB") @@ -9380,7 +9378,6 @@ check_message_format(void) if ( H5C2_jb__journal_entry(/* H5C2_jbrb_t */ &jbrb_struct, /* trans number */ (uint64_t)1, - /* eoa */ (haddr_t)1, /* base address */ (haddr_t)3, /* data length */ 4, /* data */ (const uint8_t *)"CDEF") @@ -9437,7 +9434,6 @@ check_message_format(void) if ( H5C2_jb__journal_entry(/* H5C2_jbrb_t */ &jbrb_struct, /* trans number */ (uint64_t)2, - /* eoa */ (haddr_t)1, /* base address */ (haddr_t)285, /* data length */ 11, /* data */ (const uint8_t *)"Test Data?!") @@ -9493,12 +9489,12 @@ check_message_format(void) /* Fill out verify array with expected messages */ sprintf(verify[0], "0 ver_num 1 target_file_name HDF5.file creation_date %10.10s human_readable 1\n", ctime(¤t_date)); sprintf(verify[1], "1 bgn_trans 1\n"); - sprintf(verify[2], "2 trans_num 1 eoa 0x1 length 1 base_addr 0x0 body 41 \n"); - sprintf(verify[3], "2 trans_num 1 eoa 0x1 length 2 base_addr 0x1 body 41 42 \n"); - sprintf(verify[4], "2 trans_num 1 eoa 0x1 length 4 base_addr 0x3 body 43 44 45 46 \n"); + sprintf(verify[2], "2 trans_num 1 length 1 base_addr 0x0 body 41 \n"); + sprintf(verify[3], "2 trans_num 1 length 2 base_addr 0x1 body 41 42 \n"); + sprintf(verify[4], "2 trans_num 1 length 4 base_addr 0x3 body 43 44 45 46 \n"); sprintf(verify[5], "3 end_trans 1\n"); sprintf(verify[6], "1 bgn_trans 2\n"); - sprintf(verify[7], "2 trans_num 2 eoa 0x1 length 11 base_addr 0x11d body 54 65 73 74 20 44 61 74 61 3f 21 \n"); + sprintf(verify[7], "2 trans_num 2 length 11 base_addr 0x11d body 54 65 73 74 20 44 61 74 61 3f 21 \n"); sprintf(verify[8], "3 end_trans 2\n"); /* verify that messages in journal are same as expected */ @@ -9560,7 +9556,6 @@ check_message_format(void) if ( H5C2_jb__journal_entry(/* H5C2_jbrb_t */ &jbrb_struct, /* trans number */ (uint64_t)3, - /* eoa */ (haddr_t)1, /* base address */ (haddr_t)28591, /* data length */ 6, /* data */ (const uint8_t *)"#1nN`}") @@ -9650,7 +9645,7 @@ check_message_format(void) /* Fill out verify array with expected messages */ sprintf(verify[0], "0 ver_num 1 target_file_name HDF5.file creation_date %10.10s human_readable 1\n", ctime(¤t_date)); sprintf(verify[1], "1 bgn_trans 3\n"); - sprintf(verify[2], "2 trans_num 3 eoa 0x1 length 6 base_addr 0x6faf body 23 31 6e 4e 60 7d \n"); + sprintf(verify[2], "2 trans_num 3 length 6 base_addr 0x6faf body 23 31 6e 4e 60 7d \n"); sprintf(verify[3], "3 end_trans 3\n"); sprintf(verify[4], "C comment This is a comment!\n"); sprintf(verify[5], "C comment This is another comment!\n"); @@ -9840,7 +9835,6 @@ check_legal_calls(void) if ( H5C2_jb__journal_entry(/* H5C2_jbrb_t */ &jbrb_struct, /* Transaction # */ (uint64_t)1, - /* eoa */ (haddr_t)1, /* Base Address */ (haddr_t)123456789, /* Length */ 16, /* Body */ (const uint8_t *)"This should fail") @@ -9921,7 +9915,6 @@ check_legal_calls(void) if ( H5C2_jb__journal_entry(/* H5C2_jbrb_t */ &jbrb_struct, /* Transaction # */ (uint64_t)2, - /* eoa */ (haddr_t)1, /* Base Address */ (haddr_t)123456789, /* Length */ 16, /* Body */ (const uint8_t *)"This should fail") @@ -9943,7 +9936,6 @@ check_legal_calls(void) if ( H5C2_jb__journal_entry(/* H5C2_jbrb_t */ &jbrb_struct, /* Transaction # */ (uint64_t)1, - /* eoa */ (haddr_t)1, /* Base Address */ (haddr_t)123456789, /* Length */ 51, /* Body */ (const uint8_t *)"This is the first transaction during transaction 1.") @@ -10040,7 +10032,6 @@ check_legal_calls(void) if ( H5C2_jb__journal_entry(/* H5C2_jbrb_t */ &jbrb_struct, /* Transaction # */ (uint64_t)2, - /* eoa */ (haddr_t)1, /* Base Address */ (haddr_t)7465, /* Length */ 51, /* Body */ (const uint8_t *)"This is the first transaction during transaction 2!") @@ -10062,7 +10053,6 @@ check_legal_calls(void) if ( H5C2_jb__journal_entry(/* H5C2_jbrb_t */ &jbrb_struct, /* Transaction # */ (uint64_t)2, - /* eoa */ (haddr_t)1, /* Base Address */ (haddr_t)123456789, /* Length */ 60, /* Body */ (const uint8_t *)"... And here's your second transaction during transaction 2.") @@ -10812,10 +10802,9 @@ write_verify_trans_num(H5C2_jbrb_t * struct_ptr, if ( H5C2_jb__journal_entry(/* H5C2_jbrb_t */ struct_ptr, /* Transaction # */ trans_num, - /* eoa */ (haddr_t)16, /* Base Address */ (haddr_t)16, - /* Length */ 6, - /* Body */ (const uint8_t *)"XXXXXX") + /* Length */ 9, + /* Body */ (const uint8_t *)"XXXXXXXXX") != SUCCEED ) { pass2 = FALSE; @@ -10829,10 +10818,9 @@ write_verify_trans_num(H5C2_jbrb_t * struct_ptr, if ( H5C2_jb__journal_entry(/* H5C2_jbrb_t */ struct_ptr, /* Transaction # */ trans_num, - /* eoa */ (haddr_t)16, /* Base Address */ (haddr_t)16, - /* Length */ 5, - /* Body */ (const uint8_t *)"XXXXX") + /* Length */ 8, + /* Body */ (const uint8_t *)"XXXXXXXX") != SUCCEED ) { pass2 = FALSE; @@ -10846,10 +10834,9 @@ write_verify_trans_num(H5C2_jbrb_t * struct_ptr, if ( H5C2_jb__journal_entry(/* H5C2_jbrb_t */ struct_ptr, /* Transaction # */ trans_num, - /* eoa */ (haddr_t)16, /* Base Address */ (haddr_t)16, - /* Length */ 4, - /* Body */ (const uint8_t *)"XXXX") + /* Length */ 7, + /* Body */ (const uint8_t *)"XXXXXXX") != SUCCEED ) { pass2 = FALSE; diff --git a/test/testfiles/cache2_journal_sc00_000.jnl.gz b/test/testfiles/cache2_journal_sc00_000.jnl.gz Binary files differindex 5f4311e..2b1646d 100755 --- a/test/testfiles/cache2_journal_sc00_000.jnl.gz +++ b/test/testfiles/cache2_journal_sc00_000.jnl.gz diff --git a/test/testfiles/cache2_journal_sc00_001.jnl.gz b/test/testfiles/cache2_journal_sc00_001.jnl.gz Binary files differindex 7f711dc..4989b62 100755 --- a/test/testfiles/cache2_journal_sc00_001.jnl.gz +++ b/test/testfiles/cache2_journal_sc00_001.jnl.gz diff --git a/test/testfiles/cache2_journal_sc00_002.jnl.gz b/test/testfiles/cache2_journal_sc00_002.jnl.gz Binary files differindex 62d6929..ad81f72 100755 --- a/test/testfiles/cache2_journal_sc00_002.jnl.gz +++ b/test/testfiles/cache2_journal_sc00_002.jnl.gz diff --git a/test/testfiles/cache2_journal_sc00_003.jnl.gz b/test/testfiles/cache2_journal_sc00_003.jnl.gz Binary files differindex cd60e35..44512bb 100755 --- a/test/testfiles/cache2_journal_sc00_003.jnl.gz +++ b/test/testfiles/cache2_journal_sc00_003.jnl.gz diff --git a/test/testfiles/cache2_journal_sc00_004.jnl.gz b/test/testfiles/cache2_journal_sc00_004.jnl.gz Binary files differindex ffacdc0..87ae0f0 100755 --- a/test/testfiles/cache2_journal_sc00_004.jnl.gz +++ b/test/testfiles/cache2_journal_sc00_004.jnl.gz diff --git a/test/testfiles/cache2_journal_sc00_005.jnl.gz b/test/testfiles/cache2_journal_sc00_005.jnl.gz Binary files differindex e777a18..c1550f0 100755 --- a/test/testfiles/cache2_journal_sc00_005.jnl.gz +++ b/test/testfiles/cache2_journal_sc00_005.jnl.gz diff --git a/test/testfiles/cache2_journal_sc00_006.jnl.gz b/test/testfiles/cache2_journal_sc00_006.jnl.gz Binary files differindex bfab587..a845a4f 100755 --- a/test/testfiles/cache2_journal_sc00_006.jnl.gz +++ b/test/testfiles/cache2_journal_sc00_006.jnl.gz diff --git a/test/testfiles/cache2_journal_sc00_007.jnl.gz b/test/testfiles/cache2_journal_sc00_007.jnl.gz Binary files differindex d2d8e5f..02fbaff 100755 --- a/test/testfiles/cache2_journal_sc00_007.jnl.gz +++ b/test/testfiles/cache2_journal_sc00_007.jnl.gz diff --git a/test/testfiles/cache2_journal_sc00_008.jnl.gz b/test/testfiles/cache2_journal_sc00_008.jnl.gz Binary files differindex 8ea7164..97e2444 100755 --- a/test/testfiles/cache2_journal_sc00_008.jnl.gz +++ b/test/testfiles/cache2_journal_sc00_008.jnl.gz diff --git a/test/testfiles/cache2_journal_sc00_009.jnl.gz b/test/testfiles/cache2_journal_sc00_009.jnl.gz Binary files differindex f345dcb..b3c9be1 100755 --- a/test/testfiles/cache2_journal_sc00_009.jnl.gz +++ b/test/testfiles/cache2_journal_sc00_009.jnl.gz diff --git a/test/testfiles/cache2_journal_sc00_010.jnl.gz b/test/testfiles/cache2_journal_sc00_010.jnl.gz Binary files differindex d761163..f3134fc 100755 --- a/test/testfiles/cache2_journal_sc00_010.jnl.gz +++ b/test/testfiles/cache2_journal_sc00_010.jnl.gz diff --git a/test/testfiles/cache2_journal_sc00_011.jnl.gz b/test/testfiles/cache2_journal_sc00_011.jnl.gz Binary files differindex 176fc0c..bd2de80 100755 --- a/test/testfiles/cache2_journal_sc00_011.jnl.gz +++ b/test/testfiles/cache2_journal_sc00_011.jnl.gz diff --git a/test/testfiles/cache2_journal_sc00_012.jnl.gz b/test/testfiles/cache2_journal_sc00_012.jnl.gz Binary files differindex b8cf81a..a8ac645 100755 --- a/test/testfiles/cache2_journal_sc00_012.jnl.gz +++ b/test/testfiles/cache2_journal_sc00_012.jnl.gz diff --git a/test/testfiles/cache2_journal_sc00_013.jnl.gz b/test/testfiles/cache2_journal_sc00_013.jnl.gz Binary files differindex 7fb6958..9898d8c 100755 --- a/test/testfiles/cache2_journal_sc00_013.jnl.gz +++ b/test/testfiles/cache2_journal_sc00_013.jnl.gz diff --git a/test/testfiles/cache2_journal_sc00_014.jnl.gz b/test/testfiles/cache2_journal_sc00_014.jnl.gz Binary files differindex 6a6eb10..fcd6826 100755 --- a/test/testfiles/cache2_journal_sc00_014.jnl.gz +++ b/test/testfiles/cache2_journal_sc00_014.jnl.gz diff --git a/test/testfiles/cache2_journal_sc00_015.jnl.gz b/test/testfiles/cache2_journal_sc00_015.jnl.gz Binary files differindex 2af775b..fd8b45f 100755 --- a/test/testfiles/cache2_journal_sc00_015.jnl.gz +++ b/test/testfiles/cache2_journal_sc00_015.jnl.gz diff --git a/test/testfiles/cache2_journal_sc00_016.jnl.gz b/test/testfiles/cache2_journal_sc00_016.jnl.gz Binary files differindex 2de5c38..6f89ad1 100755 --- a/test/testfiles/cache2_journal_sc00_016.jnl.gz +++ b/test/testfiles/cache2_journal_sc00_016.jnl.gz diff --git a/test/testfiles/cache2_journal_sc00_017.jnl.gz b/test/testfiles/cache2_journal_sc00_017.jnl.gz Binary files differindex f60aed8..79a96ae 100755 --- a/test/testfiles/cache2_journal_sc00_017.jnl.gz +++ b/test/testfiles/cache2_journal_sc00_017.jnl.gz diff --git a/test/testfiles/cache2_journal_sc00_018.jnl.gz b/test/testfiles/cache2_journal_sc00_018.jnl.gz Binary files differindex c6f10ee..50c8dc3 100755 --- a/test/testfiles/cache2_journal_sc00_018.jnl.gz +++ b/test/testfiles/cache2_journal_sc00_018.jnl.gz diff --git a/test/testfiles/cache2_journal_sc01_000.jnl.gz b/test/testfiles/cache2_journal_sc01_000.jnl.gz Binary files differindex 5d37f04..3244641 100755 --- a/test/testfiles/cache2_journal_sc01_000.jnl.gz +++ b/test/testfiles/cache2_journal_sc01_000.jnl.gz diff --git a/test/testfiles/cache2_journal_sc01_001.jnl.gz b/test/testfiles/cache2_journal_sc01_001.jnl.gz Binary files differindex 669a307..9563e51 100755 --- a/test/testfiles/cache2_journal_sc01_001.jnl.gz +++ b/test/testfiles/cache2_journal_sc01_001.jnl.gz diff --git a/test/testfiles/cache2_journal_sc01_002.jnl.gz b/test/testfiles/cache2_journal_sc01_002.jnl.gz Binary files differindex a684d6d..cac45ff 100755 --- a/test/testfiles/cache2_journal_sc01_002.jnl.gz +++ b/test/testfiles/cache2_journal_sc01_002.jnl.gz diff --git a/test/testfiles/cache2_journal_sc01_003.jnl.gz b/test/testfiles/cache2_journal_sc01_003.jnl.gz Binary files differindex c9265ff..a3cfa45 100755 --- a/test/testfiles/cache2_journal_sc01_003.jnl.gz +++ b/test/testfiles/cache2_journal_sc01_003.jnl.gz diff --git a/test/testfiles/cache2_journal_sc01_004.jnl.gz b/test/testfiles/cache2_journal_sc01_004.jnl.gz Binary files differindex aacc153..9ce7738 100755 --- a/test/testfiles/cache2_journal_sc01_004.jnl.gz +++ b/test/testfiles/cache2_journal_sc01_004.jnl.gz diff --git a/test/testfiles/cache2_journal_sc02_000.jnl.gz b/test/testfiles/cache2_journal_sc02_000.jnl.gz Binary files differindex d5675ed..e3906ad 100755 --- a/test/testfiles/cache2_journal_sc02_000.jnl.gz +++ b/test/testfiles/cache2_journal_sc02_000.jnl.gz diff --git a/test/testfiles/cache2_journal_sc02_001.jnl.gz b/test/testfiles/cache2_journal_sc02_001.jnl.gz Binary files differindex 6a8fbf7..3990c93 100755 --- a/test/testfiles/cache2_journal_sc02_001.jnl.gz +++ b/test/testfiles/cache2_journal_sc02_001.jnl.gz diff --git a/test/testfiles/cache2_journal_sc02_002.jnl.gz b/test/testfiles/cache2_journal_sc02_002.jnl.gz Binary files differindex 121017e..5e0cd42 100755 --- a/test/testfiles/cache2_journal_sc02_002.jnl.gz +++ b/test/testfiles/cache2_journal_sc02_002.jnl.gz diff --git a/test/testfiles/cache2_journal_sc02_003.jnl.gz b/test/testfiles/cache2_journal_sc02_003.jnl.gz Binary files differindex b5dbf0a..ef6df83 100755 --- a/test/testfiles/cache2_journal_sc02_003.jnl.gz +++ b/test/testfiles/cache2_journal_sc02_003.jnl.gz diff --git a/test/testfiles/cache2_journal_sc02_004.jnl.gz b/test/testfiles/cache2_journal_sc02_004.jnl.gz Binary files differindex 6b16e37..833438e 100755 --- a/test/testfiles/cache2_journal_sc02_004.jnl.gz +++ b/test/testfiles/cache2_journal_sc02_004.jnl.gz diff --git a/tools/h5recover/h5recover.c b/tools/h5recover/h5recover.c index 692ba8b..bf6c1b7 100644 --- a/tools/h5recover/h5recover.c +++ b/tools/h5recover/h5recover.c @@ -26,6 +26,8 @@ #include <stdlib.h> #include "H5Fpkg.h" +#define H5F_MAX_SUPERBLOCK_SIZE 134 + const char * progname="h5recover"; int d_status; @@ -48,7 +50,7 @@ static struct long_options l_opts[] = { * * Return: void * - * Programmer: Mike McGreevy <mcgreevy@hdfgroup.org> + * Programmer: Mike McGreevy <mamcgree@hdfgroup.org> * Monday, March 10, 2008 * *------------------------------------------------------------------------- @@ -99,7 +101,7 @@ leave(int ret) * * Return: 0 on success * - * Programmer: Mike McGreevy <mcgreevy@hdfgroup.org> + * Programmer: Mike McGreevy <mamcgree@hdfgroup.org> * Monday, March 10, 2008 * *------------------------------------------------------------------------- @@ -159,15 +161,93 @@ file_copy(char * file_from, char * file_to) return 0; } +/*------------------------------------------------------------------------- + * Function: address_decode + * + * Purpose: Decodes an address from the buffer pointed to by *pp and + * updates the pointer to point to the next byte after the + * address. + * + * If the value read is all 1's, then the address is + * returned with an undefined value. + * + * Programmer: Mike McGreevy (utilizing code from Robb Matzke) + * Thursday, August 7, 2008 + * + *------------------------------------------------------------------------- + */ +void +address_decode(size_t sizeof_addr, const uint8_t **pp/*in,out*/, haddr_t *addr_p/*out*/) +{ + + unsigned i; + haddr_t tmp; + uint8_t c; + hbool_t all_zero = TRUE; + + assert(pp && *pp); + assert(addr_p); + + *addr_p = 0; + + for (i=0; i<sizeof_addr; i++) { + c = *(*pp)++; + if (c != 0xff) + all_zero = FALSE; + + if (i<sizeof(*addr_p)) { + tmp = c; + tmp <<= (i * 8); /*use tmp to get casting right */ + *addr_p |= tmp; + } else if (!all_zero) { + assert(0 == **pp); /*overflow */ + } + } + + if (all_zero) + *addr_p = HADDR_UNDEF; +} + +/*------------------------------------------------------------------------- + * Function: address_encode + * + * Purpose: Encodes an address into the buffer pointed to by *pp and + * then increments the pointer to the first byte after the + * address. An undefined value is stored as all 1's. + * + * Programmer: Mike McGreevy (utilizing code from Robb Matzke) + * Thursday, August 7, 2008 + * + *------------------------------------------------------------------------- + */ +void +address_encode(size_t sizeof_addr, uint8_t **pp/*in,out*/, haddr_t addr) +{ + unsigned u; + + HDassert(pp && *pp); + + for(u = 0; u < sizeof_addr; u++) { + *(*pp)++ = (uint8_t)(addr & 0xff); + addr >>= 8; + } /* end for */ + + assert("overflow" && 0 == addr); + +} /*------------------------------------------------------------------------- * Function: main() * * Purpose: main h5recover program. * - * Programmer: Mike McGreevy <mcgreevy@hdfgroup.org> + * Programmer: Mike McGreevy <mamcgree@hdfgroup.org> * Monday, March 10, 2008 * + * Modifications: + * Mike McGreevy, August 7, 2008 + * Parses superblock to update EOA value + * *------------------------------------------------------------------------- */ @@ -194,7 +274,8 @@ main (int argc, const char *argv[]) char * tok[11]; /* string tokens */ int i; /* iterator */ off_t address; /* address to write to */ - haddr_t eoa; /* end of address of file */ + haddr_t eoa = 0; /* end of address of file */ + haddr_t update_eoa = 0; /* new end of address */ uint8_t * body; /* body of journal entry */ size_t size; /* size of journal entry body */ size_t max_size; /* maximum size of journal entry body */ @@ -210,6 +291,24 @@ main (int argc, const char *argv[]) long pos_end; /* file descriptor position indicator */ char temp[100]; /* temporary buffer */ H5F_t * f; /* File pointer */ + hbool_t jrnl_has_transactions = TRUE; + + /* ================================================ */ + /* Variables needed for superblock parse and update */ + /* ================================================ */ + + int n; /* iterator */ + haddr_t sb_addr; /* address of superblock */ + uint8_t buf[H5F_SIGNATURE_LEN]; /* buf to get superblock signature */ + uint8_t sbuf[H5F_MAX_SUPERBLOCK_SIZE]; /* buf to store superblock */ + int super_vers = 0; /* superblock version number */ + int sizeof_addr = 0; /* size of addresses */ + haddr_t addr = NULL; /* address buffer to hold haddr_t values */ + uint8_t * p_front = NULL; /* reference pointer into superblock buffer */ + uint8_t * p_end = NULL; /* reference pointer into superblock buffer */ + haddr_t new_eoa; /* new value of EOA to be written into superblock */ + uint32_t chksum; /* calculated checksum value */ + uint32_t read_chksum; /* checksum value read from superblock */ /* ==================== */ /* Command Line Parsing */ @@ -297,51 +396,6 @@ main (int argc, const char *argv[]) } /* end if */ - /* ========================================== */ - /* Open HDF5 File with Journal Recovered Flag */ - /* ========================================== */ - - /* set up appropriate fapl */ - fapl = H5Pcreate(H5P_FILE_ACCESS); - - if ( fapl == -1 ) { - - error_msg(progname, "Could not create FAPL.\n"); - leave( EXIT_FAILURE ); - - } /* end if */ - - config.version = 1; /* should be H5C2__CURR_AUTO_SIZE_CTL_VER */ - - /* get H5AC_cache_config_t configuration from fapl */ - if ( H5Pget_jnl_config(fapl, &config) == -1) { - - error_msg(progname, "Could not get mdc config from FAPL.\n"); - leave( EXIT_FAILURE ); - - } - - /* make sure journal recovered field is set to TRUE in mdc_config */ - config.journal_recovered = TRUE; - - /* set H5AC_cache_config_t configuration with file recovered */ - if ( H5Pset_jnl_config(fapl, &config) == -1) { - - error_msg(progname, "Could not set jnl config on FAPL.\n"); - leave( EXIT_FAILURE ); - - } /* end if */ - - /* open HDF5 file with provided fapl */ - fid = H5Fopen(file_name, H5F_ACC_RDWR, fapl); - - if ( fid == -1 ) { - - error_msg(progname, "Could not open recovered HDF5 file.\n"); - leave( EXIT_FAILURE ); - - } /* end if */ - /* =============================== */ /* Make a Backup Copy of HDF5 File */ /* =============================== */ @@ -420,9 +474,9 @@ main (int argc, const char *argv[]) if (ftell(journal_fp) <= 1) { - error_msg(progname, "Journal has no complete transactions\n"); - usage(); - leave( EXIT_FAILURE ); + jrnl_has_transactions = FALSE; + printf("Journal file has no complete transactions. Nothing to recover!\n"); + break; } /* end if */ @@ -430,6 +484,8 @@ main (int argc, const char *argv[]) } /* end while */ + if (jrnl_has_transactions == FALSE) break; + if ( fgetc(journal_fp) == '3' ) { last_trans_found = 1; @@ -446,287 +502,517 @@ main (int argc, const char *argv[]) } /* end while */ - /* ======================================= */ - /* Determine Size of Biggest Journal Entry */ - /* ======================================= */ + /* ================================================================== */ + /* Only do the recovery procedure if there is something to recover in */ + /* the journal file. Otherwise, skip over these steps and mark */ + /* the file as recovered. */ + /* ================================================================== */ + + if (jrnl_has_transactions == TRUE) { - fseek(journal_fp, 0, SEEK_END); - pos_end = ftell(journal_fp); + /* ================================================================= */ + /* Pre-parse of journal file to pull information needed before doing */ + /* the recovery. */ + /* - max journal size (for buffer allocation) */ + /* - max EOA size (for superblock update, to preserve raw data) */ + /* ================================================================= */ + + fseek(journal_fp, 0, SEEK_END); + pos_end = ftell(journal_fp); - fseek(journal_fp, 0, SEEK_SET); + fseek(journal_fp, 0, SEEK_SET); - c_new = 0; - c_old = 0; - max_size = 0; + c_new = 0; + c_old = 0; + max_size = 0; - /* while journal is not at end of file */ - while (ftell(journal_fp) != pos_end) { + if ( verbose ) printf("Pre-parsing journal file to pull needed data ... \n"); - c_old = c_new; - c_new = fgetc(journal_fp); + /* while journal is not at end of file */ + while (ftell(journal_fp) != pos_end) { + + c_old = c_new; + c_new = fgetc(journal_fp); - /* if position is at the start of a line */ - if (c_old == '\n') { + /* if position is at the start of a line */ + if (c_old == '\n') { - /* if the line starts with a '2', find out size of entry */ - if (c_new == '2') { + /* ========================================================== */ + /* if the line is a journal entry, determine its size. update */ + /* max size value if needed. */ + /* ========================================================== */ + if (c_new == '2') { - pos = ftell(journal_fp); + pos = ftell(journal_fp); - fgets(temp, 100, journal_fp); - tok[0] = HDstrtok(temp, " "); - if (tok[0] == NULL) { + fgets(temp, 100, journal_fp); + tok[0] = HDstrtok(temp, " "); + if (tok[0] == NULL) { - error_msg(progname, "Could not tokenize entry\n"); - leave( EXIT_FAILURE); + error_msg(progname, "Could not tokenize entry\n"); + leave( EXIT_FAILURE); - } /* end if */ - for (i=1; i<8; i++) { + } /* end if */ + for (i=1; i<8; i++) { - tok[i] = HDstrtok(NULL, " "); - if (tok[i] == NULL) { + tok[i] = HDstrtok(NULL, " "); + if (tok[i] == NULL) { - error_msg(progname, "Could not tokenize entry\n"); - leave( EXIT_FAILURE); + error_msg(progname, "Could not tokenize entry\n"); + leave( EXIT_FAILURE); - } /* end if */ + } /* end if */ - } /* end for */ + } /* end for */ - size = HDstrtod(tok[3], NULL); + size = HDstrtod(tok[5], NULL); - if (max_size < size) { + if (max_size < size) { - max_size = size; + max_size = size; + + } /* end if */ + + /* jump back to start of line */ + fseek(journal_fp, pos, SEEK_SET); } /* end if */ - /* jump back to start of line */ - fseek(journal_fp, pos, SEEK_SET); + /* =========================================================== */ + /* If the line is an EOA entry, determine its value and update */ + /* if it exceeds the current max length */ + /* =========================================================== */ - } /* end if */ + if (c_new == 'E') { + + pos = ftell(journal_fp); - } /* end if */ + fgets(temp, 100, journal_fp); + p = &temp[11]; + + eoa = HDstrtod(p, NULL); + if (eoa == 0) { + + error_msg(progname, "Could not convert eoa to integer\n"); + leave( EXIT_FAILURE); - } /* end while */ + } /* end if */ + + if (update_eoa < eoa) { - /* ================================================= */ - /* Tokenize each journal entry in order to grab data */ - /* ================================================= */ + update_eoa = eoa; - max_size = max_size * 3 + 200; + } /* end if */ - /* allocate space large enough to hold largest journal entry */ - readback = HDmalloc( max_size ); - if (readback == NULL) { + /* jump back to start of line */ + fseek(journal_fp, pos, SEEK_SET); - error_msg(progname, "Could not allocate space to hold entries\n"); - leave( EXIT_FAILURE); + } /* end if */ - } /* end if */ + } /* end if */ - /* read through journal file. recover any journal entries found, up - * through the last transaction number */ - fseek(journal_fp, 0, SEEK_SET); + } /* end while */ + + if ( verbose ) printf(" - Maximum journal entry size = %d\n", max_size); + if ( verbose ) printf(" - Journaled EOA value = 0x%llx\n", update_eoa); + + /* =================================== */ + /* Update EOA value in HDF5 superblock */ + /* =================================== */ + + if (update_eoa != 0) { - while ( fgets(readback, max_size, journal_fp) != NULL ) { + if ( verbose ) printf("\nLooking for HDF5 superblock ... \n"); + /* Jump through possible locations of superblock */ + for(n = 8; n < 16; n++) { + + sb_addr = (8 == n) ? 0 : 1 << n; + + /* read from HDF5 file */ + pread(hdf5_fd, buf, H5F_SIGNATURE_LEN, sb_addr); + + /* Check to see if superblock has been found. */ + if(!HDmemcmp(buf, H5F_SIGNATURE, (size_t)H5F_SIGNATURE_LEN)) { + + if ( verbose ) printf(" - Superblock signature found at location %d\n", sb_addr); - if (HDstrcmp(readback, last_trans_msg) == 0) { + if ( verbose ) printf(" - Reading in entire superblock\n"); - /* done reading from file */ - break; + /* Read in entire superblock */ + pread(hdf5_fd, sbuf, H5F_MAX_SUPERBLOCK_SIZE, sb_addr/* + H5F_SIGNATURE_LEN */); + + /* Use p as a pointer into superblock buffer */ + p = sbuf; + + /* Skip over signature */ + p += H5F_SIGNATURE_LEN; - } /* end if */ + /* Get superblock version number */ + super_vers = *p++; - if ( readback[0] == '2') { /* journal entry found */ + /* add printfs to verbose */ + if ( verbose ) printf(" - Superblock version number = %d\n", super_vers); + + /* ==================================== */ + /* Point to EOA value in the superblock */ + /* ==================================== */ + + /* First part of superblock may be of differing versions */ + if(super_vers < 2) { + /* skip over unneeded data */ + p += 1 + /* freespace version */ + 1 + /* root group version */ + 1 + /* reserved byte */ + 1; /* shared header version */ + + sizeof_addr = *p++; /* size of file addresses */ + + p += 1 + /* size of file sizes */ + 1 + /* reserved byte */ + 2 + /* 1/2 rank for symtable leaf nodes */ + 2 + /* 1/2 rank for btree internal nodes */ + 4 + /* file status flags */ + 2; /* b-tree internal k value */ + + if (super_vers == 1) + p += 2; /* reserved bytes */ + + } /* end if */ - if ( verbose ) printf("Journal entry found.\n"); - if ( verbose ) printf("Tokenizing journal entry.\n"); + /* Superblock version number > 2 */ + else { + + sizeof_addr = *p++; /* size of file addresses */ + + p += 1 + /* size of file sizes */ + 1; /* file status flags */ + + p_front = p; + p_end = p; + + } /* end else */ + + /* Skip over various variable portions of superblock */ + address_decode(sizeof_addr, &p_end, &addr); /* base address */ + address_decode(sizeof_addr, &p_end, &addr); /* extension address */ - /* divide the journal entry into tokens */ - tok[0] = HDstrtok(readback, " "); - if (tok[0] == NULL) { + /* ============================ */ + /* Update EOA in the superblock */ + /* ============================ */ - error_msg(progname, "Could not tokenize journal entry\n"); - leave( EXIT_FAILURE); - - } /* end if */ + p_front = p_end; - if ( verbose ) printf(" token[0] : <%s>\n", tok[0]); + /* Decode the EOA address */ + address_decode(sizeof_addr, &p_end, &addr); - for (i=1; i<10; i++) { + if ( verbose ) printf(" - Current value of EOA in superblock is 0x%llx\n", addr); + + /* Set the EOA to the address pulled from the journal */ + addr = (haddr_t)update_eoa; + p_end = p_front; - tok[i] = HDstrtok(NULL, " "); - if (tok[i] == NULL) { + /* encode new EOA value into superblock buffer */ + address_encode(sizeof_addr, &p_end, addr); - error_msg(progname, "Could not tokenize journal entry\n"); - leave( EXIT_FAILURE); + if ( verbose ) printf(" - EOA value has been updated to 0x%llx in superblock\n", update_eoa); - } /* end if */ + /* skip over root group object header */ + address_decode(sizeof_addr, &p_end, &addr); /* root group object header */ - if ( verbose ) printf(" token[%d] : <%s>\n", i, tok[i]); + p_front = p_end; + if ( verbose ) printf(" - Updating checksum value of superblock\n"); + + /* decode checksum */ + read_chksum = 0; + UINT32DECODE(p_end, read_chksum); + + p_end = p_front; + + /* Update the CHECKSUM VALUE */ + /* Compute superblock checksum */ + chksum = H5_checksum_metadata(sbuf, (size_t)(p_end - sbuf), 0); + + /* Superblock checksum */ + UINT32ENCODE(p_end, chksum); + + new_eoa = (haddr_t)update_eoa; + + /* verify new EOA value in buffer is correct */ + address_decode(sizeof_addr, &p_front, &addr); + + /* Extend file to be EOA bytes */ + HDftruncate(hdf5_fd, new_eoa); + + /* Write out new updated superblock to the file */ + status = pwrite(hdf5_fd, sbuf, (size_t)H5F_MAX_SUPERBLOCK_SIZE, sb_addr /*+ H5F_SIGNATURE_LEN */); + + if (status == -1) { + error_msg(progname, "pwrite failed when trying to update superblock\n"); + leave( EXIT_FAILURE ); + } + + if (status == 0) { + error_msg(progname, "pwrite did not write anything to superblock!\n"); + leave( EXIT_FAILURE); + } + + if ( verbose ) printf(" - New superblock written to HDF5 file\n"); + + } /* end if */ + } /* end for */ - /* put all remaining data into last token. */ - /* This contains all of the journal entry body */ - tok[10] = HDstrtok(NULL, "\n"); - if (tok[10] == NULL) { + } /* end if (update_eoa != 0)*/ - error_msg(progname, "Could not tokenize journal entry\n"); - leave( EXIT_FAILURE); + if ( verbose ) printf("\nBeginning recovery process ... \n\n"); - } /* end if */ + /* ==================================================================== */ + /* Main Recovery Procedure: */ + /* Read through the journal file and recover any journal entries found. */ + /* ==================================================================== */ + + max_size = max_size * 3 + 200; - if ( verbose ) printf(" token[8] : <hexadecimal body data>\n"); + /* allocate space large enough to hold largest journal entry */ + readback = HDmalloc( max_size ); + if (readback == NULL) { - /* ================================== */ - /* Convert Items from Character Array */ - /* ================================== */ + error_msg(progname, "Could not allocate space to hold entries\n"); + leave( EXIT_FAILURE); + + } /* end if */ - if ( verbose ) printf("Converting data from character strings.\n"); + /* read through journal file. recover any journal entries found, up + * through the last transaction number */ + fseek(journal_fp, 0, SEEK_SET); - /* convert address from character character string */ - address = HDstrtod(tok[8], NULL); - if (address == 0) { + while ( fgets(readback, max_size, journal_fp) != NULL ) { - error_msg(progname, "Could not convert address to integer\n"); - leave( EXIT_FAILURE); + if (HDstrcmp(readback, last_trans_msg) == 0) { + + /* done reading from file */ + break; } /* end if */ + + /* ===================================================== */ + /* If journal entry is found, write entry into HDF5 file */ + /* ===================================================== */ - if ( verbose ) printf(" address : %llx\n", address); + if ( readback[0] == '2') { /* journal entry found */ - /* convert size from character string*/ - size = HDstrtod(tok[6], NULL); - if (size == 0) { + if ( verbose ) printf("Journal entry found.\n"); + if ( verbose ) printf("Tokenizing journal entry.\n"); - error_msg(progname, "Could not convert size to double\n"); - leave( EXIT_FAILURE); + /* ================================================= */ + /* Tokenize the journal entry in order to grab data */ + /* ================================================= */ - } /* end if */ + /* divide the journal entry into tokens */ + tok[0] = HDstrtok(readback, " "); + if (tok[0] == NULL) { - /* convert eoa from character character string */ - eoa = HDstrtod(tok[4], NULL); - if (eoa == 0) { + error_msg(progname, "Could not tokenize journal entry\n"); + leave( EXIT_FAILURE); - error_msg(progname, "Could not convert eoa to integer\n"); - leave( EXIT_FAILURE); + } /* end if */ - } /* end if */ + if ( verbose ) printf(" token[0] : <%s>\n", tok[0]); + + for (i=1; i<8; i++) { + + tok[i] = HDstrtok(NULL, " "); + if (tok[i] == NULL) { - if ( verbose ) printf(" length : %d\n", size); + error_msg(progname, "Could not tokenize journal entry\n"); + leave( EXIT_FAILURE); - /* transform body out of hexadecimal character string */ - body = HDmalloc(size + 1); - if (body == NULL) { + } /* end if */ - error_msg(progname, "Could not allocate space for body\n"); - leave( EXIT_FAILURE); + if ( verbose ) printf(" token[%d] : <%s>\n", i, tok[i]); - } /* end if */ + } /* end for */ + + /* put all remaining data into last token. */ + /* This contains all of the journal entry body */ + tok[8] = HDstrtok(NULL, "\n"); + if (tok[8] == NULL) { + + error_msg(progname, "Could not tokenize journal entry\n"); + leave( EXIT_FAILURE); + + } /* end if */ + + if ( verbose ) printf(" token[8] : <hexadecimal body data>\n"); + + /* =================================== */ + /* Convert Items from Character Arrays */ + /* =================================== */ + + if ( verbose ) printf("Converting data from character strings.\n"); + + /* convert address from character character string */ + address = HDstrtod(tok[6], NULL); + if (address == 0) { + + error_msg(progname, "Could not convert address to integer\n"); + leave( EXIT_FAILURE); + + } /* end if */ + + if ( verbose ) printf(" address : %llx\n", address); + + /* convert size from character string*/ + size = HDstrtod(tok[4], NULL); + if (size == 0) { + + error_msg(progname, "Could not convert size to double\n"); + leave( EXIT_FAILURE); + + } /* end if */ + + if ( verbose ) printf(" length : %d\n", size); + + /* transform body out of hexadecimal character string */ + body = HDmalloc(size + 1); + if (body == NULL) { + + error_msg(progname, "Could not allocate space for body\n"); + leave( EXIT_FAILURE); + + } /* end if */ - p = &(tok[10])[0]; + p = &(tok[8])[0]; - for (i = 0; i < size; i++) { + for (i = 0; i < size; i++) { - body[i] = HDstrtoul(p, NULL, 16); - p = &p[3]; + body[i] = HDstrtoul(p, NULL, 16); + p = &p[3]; - } /* end for */ + } /* end for */ - body[i] = 0; + body[i] = 0; - if ( verbose ) printf(" body : binary body data\n"); + if ( verbose ) printf(" body : binary body data\n"); - /* ================================================ */ - /* Write into HDF5 file the recovered journal entry */ - /* ================================================ */ + /* ================================================ */ + /* Write into HDF5 file the recovered journal entry */ + /* ================================================ */ - if ( verbose ) printf("Writing entry to HDF5 file.\n"); - - /* perform a write */ - status = pwrite(hdf5_fd, body, size, address); + if ( verbose ) printf("Writing entry to HDF5 file.\n"); + + /* perform a write */ + status = pwrite(hdf5_fd, body, size, address); - if (status == -1) { - error_msg(progname, "pwrite failed\n"); - leave( EXIT_FAILURE ); - } - - if (status == 0) { - error_msg(progname, "pwrite did not write anything!\n"); - leave( EXIT_FAILURE); - } + if (status == -1) { + error_msg(progname, "pwrite failed\n"); + leave( EXIT_FAILURE ); + } - /* Verify that write occurred correctly */ - if ( check_file == 1) { + if (status == 0) { + error_msg(progname, "pwrite did not write anything!\n"); + leave( EXIT_FAILURE); + } - if ( verbose ) printf("Verifying success of write"); + /* Verify that write occurred correctly */ + if ( check_file == 1) { + + if ( verbose ) printf("Verifying success of write"); - compare_buf = HDmalloc(size + 1); + compare_buf = HDmalloc(size + 1); - if (compare_buf == NULL) { - error_msg(progname, "Could not allocate space\n"); - leave( EXIT_FAILURE); - } /* end if */ + if (compare_buf == NULL) { + error_msg(progname, "Could not allocate space\n"); + leave( EXIT_FAILURE); + } /* end if */ - pread(hdf5_fd, compare_buf, size, address); - - /* do a quick string compare on two items */ - if (HDstrcmp((const char *)body, (const char *)compare_buf) != 0) { - error_msg(progname, "Entry incorrectly written into HDF5 file. Exiting.\n"); - printf("Address %llx:\n", (unsigned long_long)address); - printf(" -- from journal: '%s'\n", body); - printf(" -- from HDF5 file: '%s'\n", compare_buf); - leave( EXIT_FAILURE ); - } /* end if */ + pread(hdf5_fd, compare_buf, size, address); - /* compare each individual value of entry */ - for (i=0; i<size; i++) { - if (body[i] != compare_buf[i]) { + /* do a quick string compare on two items */ + if (HDstrcmp((const char *)body, (const char *)compare_buf) != 0) { error_msg(progname, "Entry incorrectly written into HDF5 file. Exiting.\n"); - printf("Address %llx\n", (unsigned long_long)(address + i)); - printf(" -- from journal: %d\n", body[i]); - printf(" -- from HDF5 file: %d\n", compare_buf[i]); + printf("Address %llx:\n", (unsigned long_long)address); + printf(" -- from journal: '%s'\n", body); + printf(" -- from HDF5 file: '%s'\n", compare_buf); leave( EXIT_FAILURE ); + } /* end if */ + + /* compare each individual value of entry */ + for (i=0; i<size; i++) { + if (body[i] != compare_buf[i]) { + error_msg(progname, "Entry incorrectly written into HDF5 file. Exiting.\n"); + printf("Address %llx\n", (unsigned long_long)(address + i)); + printf(" -- from journal: %d\n", body[i]); + printf(" -- from HDF5 file: %d\n", compare_buf[i]); + leave( EXIT_FAILURE ); + } } + + if ( verbose ) printf(" .... SUCCESS!\n\n"); + free(compare_buf); + } - if ( verbose ) printf(" .... SUCCESS!\n\n"); - free(compare_buf); + free(body); - } + } /* end if */ - free(body); + } /* end while */ - } /* end if */ + free(readback); - } /* end while */ + } /* end if jrnl_has_transactions */ fclose(journal_fp); close(hdf5_fd); free(last_trans_msg); - free(readback); free(journal_name); + if (file_name_backup != NULL) HDfree(file_name_backup); - /* =========================================== */ - /* Set EOA Value and Close Recovered HDF5 File */ - /* =========================================== */ - - /* obtain H5F_t pointer */ - if (NULL == (f = H5I_object(fid))) { + /* =========================== */ + /* Mark HDF5 File as Recovered */ + /* =========================== */ - error_msg(progname, "Could not obtain H5F_t pointer from file id"); + /* set up appropriate fapl */ + fapl = H5Pcreate(H5P_FILE_ACCESS); + + if ( fapl == -1 ) { + + error_msg(progname, "Could not create FAPL.\n"); leave( EXIT_FAILURE ); - + } /* end if */ - - /* set the correct value of the eoa */ - if (H5FDset_eoa(f->shared->lf, H5FD_MEM_DEFAULT, eoa) == -1) { - - error_msg(progname, "Driver set eoa request failed"); + + config.version = 1; /* should be H5C2__CURR_AUTO_SIZE_CTL_VER */ + + /* get H5AC_cache_config_t configuration from fapl */ + if ( H5Pget_jnl_config(fapl, &config) == -1) { + + error_msg(progname, "Could not get mdc config from FAPL.\n"); leave( EXIT_FAILURE ); + + } + + /* make sure journal recovered field is set to TRUE in mdc_config */ + config.journal_recovered = TRUE; + + /* set H5AC_cache_config_t configuration with file recovered */ + if ( H5Pset_jnl_config(fapl, &config) == -1) { + + error_msg(progname, "Could not set mdc config on FAPL.\n"); + leave( EXIT_FAILURE ); + + } /* end if */ + /* open HDF5 file with provided fapl */ + fid = H5Fopen(file_name, H5F_ACC_RDWR, fapl); + + if ( fid == -1 ) { + + error_msg(progname, "Could not open recovered HDF5 file.\n"); + leave( EXIT_FAILURE ); + } /* end if */ /* close HDF5 file */ @@ -736,15 +1022,16 @@ main (int argc, const char *argv[]) leave( EXIT_FAILURE ); } /* end if */ - + /* ================ */ /* Cleanup and Exit */ /* ================ */ - - /* MIKE: Should I remove journal file here, or should that happen - on file close? */ - printf("HDF5 file successfuly recovered.\n"); + if (jrnl_has_transactions == TRUE) + printf("HDF5 file successfuly recovered.\n"); + else + printf("File marked as recovered.\n"); + if ( verbose ) printf("==============================================\n\n"); free(file_name); |