summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xconfigure11
-rw-r--r--configure.in10
-rw-r--r--src/H5C2journal.c90
-rw-r--r--src/H5C2private.h4
-rw-r--r--src/H5MF.c19
-rw-r--r--src/Makefile.in8
-rw-r--r--test/cache2_journal.c35
-rwxr-xr-xtest/testfiles/cache2_journal_sc00_000.jnl.gzbin218 -> 222 bytes
-rwxr-xr-xtest/testfiles/cache2_journal_sc00_001.jnl.gzbin250 -> 237 bytes
-rwxr-xr-xtest/testfiles/cache2_journal_sc00_002.jnl.gzbin249 -> 239 bytes
-rwxr-xr-xtest/testfiles/cache2_journal_sc00_003.jnl.gzbin284 -> 274 bytes
-rwxr-xr-xtest/testfiles/cache2_journal_sc00_004.jnl.gzbin317 -> 309 bytes
-rwxr-xr-xtest/testfiles/cache2_journal_sc00_005.jnl.gzbin374 -> 364 bytes
-rwxr-xr-xtest/testfiles/cache2_journal_sc00_006.jnl.gzbin392 -> 383 bytes
-rwxr-xr-xtest/testfiles/cache2_journal_sc00_007.jnl.gzbin646 -> 630 bytes
-rwxr-xr-xtest/testfiles/cache2_journal_sc00_008.jnl.gzbin1026 -> 1012 bytes
-rwxr-xr-xtest/testfiles/cache2_journal_sc00_009.jnl.gzbin1431 -> 1414 bytes
-rwxr-xr-xtest/testfiles/cache2_journal_sc00_010.jnl.gzbin1823 -> 1805 bytes
-rwxr-xr-xtest/testfiles/cache2_journal_sc00_011.jnl.gzbin345 -> 331 bytes
-rwxr-xr-xtest/testfiles/cache2_journal_sc00_012.jnl.gzbin417 -> 404 bytes
-rwxr-xr-xtest/testfiles/cache2_journal_sc00_013.jnl.gzbin533 -> 522 bytes
-rwxr-xr-xtest/testfiles/cache2_journal_sc00_014.jnl.gzbin780 -> 767 bytes
-rwxr-xr-xtest/testfiles/cache2_journal_sc00_015.jnl.gzbin223 -> 210 bytes
-rwxr-xr-xtest/testfiles/cache2_journal_sc00_016.jnl.gzbin241 -> 231 bytes
-rwxr-xr-xtest/testfiles/cache2_journal_sc00_017.jnl.gzbin217 -> 204 bytes
-rwxr-xr-xtest/testfiles/cache2_journal_sc00_018.jnl.gzbin218 -> 209 bytes
-rwxr-xr-xtest/testfiles/cache2_journal_sc01_000.jnl.gzbin9610 -> 9227 bytes
-rwxr-xr-xtest/testfiles/cache2_journal_sc01_001.jnl.gzbin9608 -> 9207 bytes
-rwxr-xr-xtest/testfiles/cache2_journal_sc01_002.jnl.gzbin9124 -> 8721 bytes
-rwxr-xr-xtest/testfiles/cache2_journal_sc01_003.jnl.gzbin27070 -> 25997 bytes
-rwxr-xr-xtest/testfiles/cache2_journal_sc01_004.jnl.gzbin25108 -> 24104 bytes
-rwxr-xr-xtest/testfiles/cache2_journal_sc02_000.jnl.gzbin13594 -> 13030 bytes
-rwxr-xr-xtest/testfiles/cache2_journal_sc02_001.jnl.gzbin24175 -> 23080 bytes
-rwxr-xr-xtest/testfiles/cache2_journal_sc02_002.jnl.gzbin24519 -> 23449 bytes
-rwxr-xr-xtest/testfiles/cache2_journal_sc02_003.jnl.gzbin103469 -> 99109 bytes
-rwxr-xr-xtest/testfiles/cache2_journal_sc02_004.jnl.gzbin100534 -> 96391 bytes
-rw-r--r--tools/h5recover/h5recover.c759
37 files changed, 660 insertions, 276 deletions
diff --git a/configure b/configure
index 3f9b53b..34360c3 100755
--- a/configure
+++ b/configure
@@ -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(&current_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);
diff --git a/src/H5MF.c b/src/H5MF.c
index df4531e..953726a 100644
--- a/src/H5MF.c
+++ b/src/H5MF.c
@@ -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(&current_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(&current_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
index 5f4311e..2b1646d 100755
--- a/test/testfiles/cache2_journal_sc00_000.jnl.gz
+++ b/test/testfiles/cache2_journal_sc00_000.jnl.gz
Binary files differ
diff --git a/test/testfiles/cache2_journal_sc00_001.jnl.gz b/test/testfiles/cache2_journal_sc00_001.jnl.gz
index 7f711dc..4989b62 100755
--- a/test/testfiles/cache2_journal_sc00_001.jnl.gz
+++ b/test/testfiles/cache2_journal_sc00_001.jnl.gz
Binary files differ
diff --git a/test/testfiles/cache2_journal_sc00_002.jnl.gz b/test/testfiles/cache2_journal_sc00_002.jnl.gz
index 62d6929..ad81f72 100755
--- a/test/testfiles/cache2_journal_sc00_002.jnl.gz
+++ b/test/testfiles/cache2_journal_sc00_002.jnl.gz
Binary files differ
diff --git a/test/testfiles/cache2_journal_sc00_003.jnl.gz b/test/testfiles/cache2_journal_sc00_003.jnl.gz
index cd60e35..44512bb 100755
--- a/test/testfiles/cache2_journal_sc00_003.jnl.gz
+++ b/test/testfiles/cache2_journal_sc00_003.jnl.gz
Binary files differ
diff --git a/test/testfiles/cache2_journal_sc00_004.jnl.gz b/test/testfiles/cache2_journal_sc00_004.jnl.gz
index ffacdc0..87ae0f0 100755
--- a/test/testfiles/cache2_journal_sc00_004.jnl.gz
+++ b/test/testfiles/cache2_journal_sc00_004.jnl.gz
Binary files differ
diff --git a/test/testfiles/cache2_journal_sc00_005.jnl.gz b/test/testfiles/cache2_journal_sc00_005.jnl.gz
index e777a18..c1550f0 100755
--- a/test/testfiles/cache2_journal_sc00_005.jnl.gz
+++ b/test/testfiles/cache2_journal_sc00_005.jnl.gz
Binary files differ
diff --git a/test/testfiles/cache2_journal_sc00_006.jnl.gz b/test/testfiles/cache2_journal_sc00_006.jnl.gz
index bfab587..a845a4f 100755
--- a/test/testfiles/cache2_journal_sc00_006.jnl.gz
+++ b/test/testfiles/cache2_journal_sc00_006.jnl.gz
Binary files differ
diff --git a/test/testfiles/cache2_journal_sc00_007.jnl.gz b/test/testfiles/cache2_journal_sc00_007.jnl.gz
index d2d8e5f..02fbaff 100755
--- a/test/testfiles/cache2_journal_sc00_007.jnl.gz
+++ b/test/testfiles/cache2_journal_sc00_007.jnl.gz
Binary files differ
diff --git a/test/testfiles/cache2_journal_sc00_008.jnl.gz b/test/testfiles/cache2_journal_sc00_008.jnl.gz
index 8ea7164..97e2444 100755
--- a/test/testfiles/cache2_journal_sc00_008.jnl.gz
+++ b/test/testfiles/cache2_journal_sc00_008.jnl.gz
Binary files differ
diff --git a/test/testfiles/cache2_journal_sc00_009.jnl.gz b/test/testfiles/cache2_journal_sc00_009.jnl.gz
index f345dcb..b3c9be1 100755
--- a/test/testfiles/cache2_journal_sc00_009.jnl.gz
+++ b/test/testfiles/cache2_journal_sc00_009.jnl.gz
Binary files differ
diff --git a/test/testfiles/cache2_journal_sc00_010.jnl.gz b/test/testfiles/cache2_journal_sc00_010.jnl.gz
index d761163..f3134fc 100755
--- a/test/testfiles/cache2_journal_sc00_010.jnl.gz
+++ b/test/testfiles/cache2_journal_sc00_010.jnl.gz
Binary files differ
diff --git a/test/testfiles/cache2_journal_sc00_011.jnl.gz b/test/testfiles/cache2_journal_sc00_011.jnl.gz
index 176fc0c..bd2de80 100755
--- a/test/testfiles/cache2_journal_sc00_011.jnl.gz
+++ b/test/testfiles/cache2_journal_sc00_011.jnl.gz
Binary files differ
diff --git a/test/testfiles/cache2_journal_sc00_012.jnl.gz b/test/testfiles/cache2_journal_sc00_012.jnl.gz
index b8cf81a..a8ac645 100755
--- a/test/testfiles/cache2_journal_sc00_012.jnl.gz
+++ b/test/testfiles/cache2_journal_sc00_012.jnl.gz
Binary files differ
diff --git a/test/testfiles/cache2_journal_sc00_013.jnl.gz b/test/testfiles/cache2_journal_sc00_013.jnl.gz
index 7fb6958..9898d8c 100755
--- a/test/testfiles/cache2_journal_sc00_013.jnl.gz
+++ b/test/testfiles/cache2_journal_sc00_013.jnl.gz
Binary files differ
diff --git a/test/testfiles/cache2_journal_sc00_014.jnl.gz b/test/testfiles/cache2_journal_sc00_014.jnl.gz
index 6a6eb10..fcd6826 100755
--- a/test/testfiles/cache2_journal_sc00_014.jnl.gz
+++ b/test/testfiles/cache2_journal_sc00_014.jnl.gz
Binary files differ
diff --git a/test/testfiles/cache2_journal_sc00_015.jnl.gz b/test/testfiles/cache2_journal_sc00_015.jnl.gz
index 2af775b..fd8b45f 100755
--- a/test/testfiles/cache2_journal_sc00_015.jnl.gz
+++ b/test/testfiles/cache2_journal_sc00_015.jnl.gz
Binary files differ
diff --git a/test/testfiles/cache2_journal_sc00_016.jnl.gz b/test/testfiles/cache2_journal_sc00_016.jnl.gz
index 2de5c38..6f89ad1 100755
--- a/test/testfiles/cache2_journal_sc00_016.jnl.gz
+++ b/test/testfiles/cache2_journal_sc00_016.jnl.gz
Binary files differ
diff --git a/test/testfiles/cache2_journal_sc00_017.jnl.gz b/test/testfiles/cache2_journal_sc00_017.jnl.gz
index f60aed8..79a96ae 100755
--- a/test/testfiles/cache2_journal_sc00_017.jnl.gz
+++ b/test/testfiles/cache2_journal_sc00_017.jnl.gz
Binary files differ
diff --git a/test/testfiles/cache2_journal_sc00_018.jnl.gz b/test/testfiles/cache2_journal_sc00_018.jnl.gz
index c6f10ee..50c8dc3 100755
--- a/test/testfiles/cache2_journal_sc00_018.jnl.gz
+++ b/test/testfiles/cache2_journal_sc00_018.jnl.gz
Binary files differ
diff --git a/test/testfiles/cache2_journal_sc01_000.jnl.gz b/test/testfiles/cache2_journal_sc01_000.jnl.gz
index 5d37f04..3244641 100755
--- a/test/testfiles/cache2_journal_sc01_000.jnl.gz
+++ b/test/testfiles/cache2_journal_sc01_000.jnl.gz
Binary files differ
diff --git a/test/testfiles/cache2_journal_sc01_001.jnl.gz b/test/testfiles/cache2_journal_sc01_001.jnl.gz
index 669a307..9563e51 100755
--- a/test/testfiles/cache2_journal_sc01_001.jnl.gz
+++ b/test/testfiles/cache2_journal_sc01_001.jnl.gz
Binary files differ
diff --git a/test/testfiles/cache2_journal_sc01_002.jnl.gz b/test/testfiles/cache2_journal_sc01_002.jnl.gz
index a684d6d..cac45ff 100755
--- a/test/testfiles/cache2_journal_sc01_002.jnl.gz
+++ b/test/testfiles/cache2_journal_sc01_002.jnl.gz
Binary files differ
diff --git a/test/testfiles/cache2_journal_sc01_003.jnl.gz b/test/testfiles/cache2_journal_sc01_003.jnl.gz
index c9265ff..a3cfa45 100755
--- a/test/testfiles/cache2_journal_sc01_003.jnl.gz
+++ b/test/testfiles/cache2_journal_sc01_003.jnl.gz
Binary files differ
diff --git a/test/testfiles/cache2_journal_sc01_004.jnl.gz b/test/testfiles/cache2_journal_sc01_004.jnl.gz
index aacc153..9ce7738 100755
--- a/test/testfiles/cache2_journal_sc01_004.jnl.gz
+++ b/test/testfiles/cache2_journal_sc01_004.jnl.gz
Binary files differ
diff --git a/test/testfiles/cache2_journal_sc02_000.jnl.gz b/test/testfiles/cache2_journal_sc02_000.jnl.gz
index d5675ed..e3906ad 100755
--- a/test/testfiles/cache2_journal_sc02_000.jnl.gz
+++ b/test/testfiles/cache2_journal_sc02_000.jnl.gz
Binary files differ
diff --git a/test/testfiles/cache2_journal_sc02_001.jnl.gz b/test/testfiles/cache2_journal_sc02_001.jnl.gz
index 6a8fbf7..3990c93 100755
--- a/test/testfiles/cache2_journal_sc02_001.jnl.gz
+++ b/test/testfiles/cache2_journal_sc02_001.jnl.gz
Binary files differ
diff --git a/test/testfiles/cache2_journal_sc02_002.jnl.gz b/test/testfiles/cache2_journal_sc02_002.jnl.gz
index 121017e..5e0cd42 100755
--- a/test/testfiles/cache2_journal_sc02_002.jnl.gz
+++ b/test/testfiles/cache2_journal_sc02_002.jnl.gz
Binary files differ
diff --git a/test/testfiles/cache2_journal_sc02_003.jnl.gz b/test/testfiles/cache2_journal_sc02_003.jnl.gz
index b5dbf0a..ef6df83 100755
--- a/test/testfiles/cache2_journal_sc02_003.jnl.gz
+++ b/test/testfiles/cache2_journal_sc02_003.jnl.gz
Binary files differ
diff --git a/test/testfiles/cache2_journal_sc02_004.jnl.gz b/test/testfiles/cache2_journal_sc02_004.jnl.gz
index 6b16e37..833438e 100755
--- a/test/testfiles/cache2_journal_sc02_004.jnl.gz
+++ b/test/testfiles/cache2_journal_sc02_004.jnl.gz
Binary files differ
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);