summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/H5FDprivate.h33
-rw-r--r--src/H5FDvfd_swmr.c135
-rw-r--r--src/H5Fint.c196
-rw-r--r--src/H5Fpkg.h10
-rw-r--r--src/H5Ftest.c361
-rw-r--r--src/H5private.h14
-rw-r--r--test/vfd_swmr.c626
7 files changed, 1116 insertions, 259 deletions
diff --git a/src/H5FDprivate.h b/src/H5FDprivate.h
index 16bb2b7..45ad4c2 100644
--- a/src/H5FDprivate.h
+++ b/src/H5FDprivate.h
@@ -85,21 +85,6 @@
#define H5FD_VFD_SWMR_MD_INDEX_RETRY_MAX 5 /* Maximum retries when deserializing the MD file index */
-/*
- * fs_page_size: Size of pages in both the HDF5 file and the metadata file IN BYTES
- * tick_num: Sequence number of the current tick.
- * Initialized to zero on file creation/open, and incremented by the
- * VFD SWMR writer at the end of each tick.
- * index_offset: The offset of the current metadata file index in the metadata file
- * IN BYTES.
- * index_length: The length of the current metadata file index IN BYTES.
- */
-typedef struct H5FD_vfd_swmr_md_header {
- uint32_t fs_page_size;
- uint64_t tick_num;
- uint64_t index_offset;
- uint64_t index_length;
-} H5FD_vfd_swmr_md_header;
/* Internal representation of metadata file index entry */
/*
@@ -179,6 +164,21 @@ typedef struct H5FD_vfd_swmr_md_index {
} H5FD_vfd_swmr_md_index;
+/*
+ * fs_page_size: Size of pages in both the HDF5 file and the metadata file IN BYTES
+ * tick_num: Sequence number of the current tick.
+ * Initialized to zero on file creation/open, and incremented by the
+ * VFD SWMR writer at the end of each tick.
+ * index_offset: The offset of the current metadata file index in the metadata file
+ * IN BYTES.
+ * index_length: The length of the current metadata file index IN BYTES.
+ */
+typedef struct H5FD_vfd_swmr_md_header {
+ uint32_t fs_page_size;
+ uint64_t tick_num;
+ uint64_t index_offset;
+ uint64_t index_length;
+} H5FD_vfd_swmr_md_header;
#ifdef H5_HAVE_PARALLEL
/* ======== Temporary data transfer properties ======== */
@@ -296,10 +296,13 @@ H5_DLL herr_t H5FD_get_vfd_handle(H5FD_t *file, hid_t fapl, void** file_handle);
H5_DLL herr_t H5FD_set_base_addr(H5FD_t *file, haddr_t base_addr);
H5_DLL haddr_t H5FD_get_base_addr(const H5FD_t *file);
H5_DLL herr_t H5FD_set_paged_aggr(H5FD_t *file, hbool_t paged);
+H5_DLL herr_t H5FD_get_driver_name(const H5FD_t *file, char **driver_name);
/* Function prototypes for VFD SWMR */
H5_DLL herr_t H5FD_vfd_swmr_get_tick_and_idx(H5FD_t *_file, hbool_t read_index,
uint64_t *tick_ptr, uint32_t *num_entries_ptr, H5FD_vfd_swmr_idx_entry_t index[]);
+H5_DLL hbool_t H5FD_is_vfd_swmr_driver(H5FD_t *_file);
+H5_DLL H5FD_t *H5FD_vfd_swmr_get_underlying_vfd(H5FD_t *_file);
/* Function prototypes for MPI based VFDs*/
#ifdef H5_HAVE_PARALLEL
diff --git a/src/H5FDvfd_swmr.c b/src/H5FDvfd_swmr.c
index 9dcf8ef..7400383 100644
--- a/src/H5FDvfd_swmr.c
+++ b/src/H5FDvfd_swmr.c
@@ -12,7 +12,7 @@
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
- * Purpose: VFD SWMR driver
+ * Purpose: VFD SWMR driver for the reader
*/
#include "H5FDdrvr_module.h" /* This source code file is part of the H5FD driver module */
@@ -38,7 +38,7 @@ typedef struct H5FD_vfd_swmr_t {
H5FD_t *hdf5_file_lf; /* Driver info for the HDF5 file */
/* Metadata file */
- int md_fd; /* File descriptor the metadata file */
+ int md_fd; /* File descriptor for the metadata file */
int32_t md_pages_reserved; /* # of pages reserved at the head of the metadata file */
char md_file_path[H5FD_MAX_FILENAME_LEN]; /* Name of the metadate file */
H5FD_vfd_swmr_md_header md_header; /* Metadata file header */
@@ -67,12 +67,12 @@ static herr_t H5FD_vfd_swmr_lock(H5FD_t *_file, hbool_t rw);
static herr_t H5FD_vfd_swmr_unlock(H5FD_t *_file);
/* VFD SWMR */
-static herr_t H5FD_vfd_swmr_header_deserialize(H5FD_t *_file, H5FD_vfd_swmr_md_header *md_header);
-static herr_t H5FD_vfd_swmr_index_deserialize(H5FD_t *_file, H5FD_vfd_swmr_md_index *md_index, H5FD_vfd_swmr_md_header *md_header);
-static herr_t H5FD_vfd_swmr_load_hdr_and_idx(H5FD_t *_file, hbool_t open);
+static herr_t H5FD__vfd_swmr_header_deserialize(H5FD_t *_file, H5FD_vfd_swmr_md_header *md_header);
+static herr_t H5FD__vfd_swmr_index_deserialize(H5FD_t *_file, H5FD_vfd_swmr_md_index *md_index, H5FD_vfd_swmr_md_header *md_header);
+static herr_t H5FD__vfd_swmr_load_hdr_and_idx(H5FD_t *_file, hbool_t open);
static const H5FD_class_t H5FD_vfd_swmr_g = {
- "swmr", /* name */
+ "vfd_swmr", /* name */
MAXADDR, /* maxaddr */
H5F_CLOSE_WEAK, /* fc_degree */
H5FD_vfd_swmr_term, /* terminate */
@@ -118,6 +118,7 @@ H5FL_SEQ_DEFINE(H5FD_vfd_swmr_idx_entry_t);
*
* Purpose: Initializes any interface-specific data or routines.
*
+b
* Return: Non-negative on success/Negative on failure
*
*-------------------------------------------------------------------------
@@ -290,7 +291,7 @@ H5FD_vfd_swmr_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxa
HGOTO_ERROR(H5E_VFL, H5E_OPENERROR, NULL, "unable to open the metadata file after all retry attempts")
/* Retry on loading and decoding the header and index in the metadata file */
- if(H5FD_vfd_swmr_load_hdr_and_idx((H5FD_t *)file, TRUE) < 0)
+ if(H5FD__vfd_swmr_load_hdr_and_idx((H5FD_t *)file, TRUE) < 0)
HGOTO_ERROR(H5E_VFL, H5E_CANTGET, NULL, "unable to load/decode the md file header/index")
/* Hard-wired to open the underlying HDF5 file with SEC2 */
@@ -565,17 +566,10 @@ H5FD_vfd_swmr_read(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED dxpl_id,
HDassert(buf);
/* Try loading and decoding the header and index in the metadata file */
- if(H5FD_vfd_swmr_load_hdr_and_idx(_file, FALSE) < 0)
+ if(H5FD__vfd_swmr_load_hdr_and_idx(_file, FALSE) < 0)
HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "unable to load/decode the md file header/index")
- fs_page_size = file->md_header.fs_page_size;
- num_entries = file->md_index.num_entries;
- if(num_entries) {
- /* Allocate memory for index entries */
- if(NULL == (index = H5FL_SEQ_MALLOC(H5FD_vfd_swmr_idx_entry_t, num_entries)))
- HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "memory allocation failed for index entries")
- HDmemcpy(index, file->md_index.entries, num_entries * sizeof(H5FD_vfd_swmr_idx_entry_t));
- }
+ index = file->md_index.entries;
/* Try finding the addr from the index */
cmp = -1;
@@ -583,7 +577,7 @@ H5FD_vfd_swmr_read(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED dxpl_id,
hi = num_entries;
while(lo < hi && cmp) {
my_idx = (lo + hi) / 2;
- cmp = H5F_addr_cmp(index[my_idx].hdf5_page_offset * fs_page_size, addr);
+ cmp = H5F_addr_cmp(index[my_idx].hdf5_page_offset * file->md_header.fs_page_size, addr);
if(cmp < 0)
hi = my_idx;
else
@@ -648,13 +642,6 @@ H5FD_vfd_swmr_read(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED dxpl_id,
}
done:
- if(ret_value < 0) {
- if(index) {
- HDassert(num_entries);
- index = H5FL_SEQ_FREE(H5FD_vfd_swmr_idx_entry_t, num_entries);
- }
- } /* end if */
-
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5FD_vfd_swmr_read() */
@@ -778,7 +765,7 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5FD_vfd_swmr_load_hdr_and_idx()
+ * Function: H5FD__vfd_swmr_load_hdr_and_idx()
*
* Purpose: Load and decode the header and index in the metadata file
* Try to load and decode the header:
@@ -803,7 +790,7 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5FD_vfd_swmr_load_hdr_and_idx(H5FD_t *_file, hbool_t open)
+H5FD__vfd_swmr_load_hdr_and_idx(H5FD_t *_file, hbool_t open)
{
H5FD_vfd_swmr_t *file = (H5FD_vfd_swmr_t *)_file; /* VFD SWMR file struct */
unsigned load_retries = H5FD_VFD_SWMR_MD_LOAD_RETRY_MAX; /* Retries for loading header and index */
@@ -812,16 +799,16 @@ H5FD_vfd_swmr_load_hdr_and_idx(H5FD_t *_file, hbool_t open)
H5FD_vfd_swmr_md_index md_index; /* Metadata file index */
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT
+ FUNC_ENTER_STATIC
do {
HDmemset(&md_header, 0, sizeof(H5FD_vfd_swmr_md_header));
HDmemset(&md_index, 0, sizeof(H5FD_vfd_swmr_md_index));
/* Load and decode the header */
- if(H5FD_vfd_swmr_header_deserialize(_file, &md_header) >= 0) {
+ if(H5FD__vfd_swmr_header_deserialize(_file, &md_header) >= 0) {
- /* Error if header + index fit does not within md_pages_reserved */
+ /* Error if header + index does not fit within md_pages_reserved */
if((H5FD_MD_HEADER_SIZE + md_header.index_length) >
(uint64_t)((hsize_t)file->md_pages_reserved * md_header.fs_page_size))
HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "header + index does not fit within md_pages_reserved")
@@ -836,7 +823,7 @@ H5FD_vfd_swmr_load_hdr_and_idx(H5FD_t *_file, hbool_t open)
HDassert(md_header.tick_num > file->md_header.tick_num || open);
/* Load and decode the index */
- if(H5FD_vfd_swmr_index_deserialize(_file, &md_index, &md_header) >= 0) {
+ if(H5FD__vfd_swmr_index_deserialize(_file, &md_index, &md_header) >= 0) {
/* tick_num is the same in both header and index */
if(md_header.tick_num == md_index.tick_num) {
@@ -848,6 +835,11 @@ H5FD_vfd_swmr_load_hdr_and_idx(H5FD_t *_file, hbool_t open)
else if(md_header.tick_num > (md_index.tick_num + 1))
HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "tick number mis-match in header and index")
+ if(md_index.entries) {
+ HDassert(md_index.num_entries);
+ md_index.entries = (H5FD_vfd_swmr_idx_entry_t *)H5FL_SEQ_FREE(H5FD_vfd_swmr_idx_entry_t, md_index.entries);
+ }
+
} /* end if index ok */
} /* end if header ok */
@@ -862,12 +854,19 @@ H5FD_vfd_swmr_load_hdr_and_idx(H5FD_t *_file, hbool_t open)
HGOTO_ERROR(H5E_VFL, H5E_CANTLOAD, FAIL, "error in loading/decoding the metadata file header and index")
done:
+ if(ret_value < 0) {
+ if(md_index.entries) {
+ HDassert(md_index.num_entries);
+ md_index.entries = (H5FD_vfd_swmr_idx_entry_t *)H5FL_SEQ_FREE(H5FD_vfd_swmr_idx_entry_t, md_index.entries);
+ }
+ }
+
FUNC_LEAVE_NOAPI(ret_value)
-} /* H5FD_vfd_swmr_load_hdr_and_idx() */
+} /* H5FD__vfd_swmr_load_hdr_and_idx() */
/*-------------------------------------------------------------------------
- * Function: H5FD_vfd_swmr_header_deserialize()
+ * Function: H5FD__vfd_swmr_header_deserialize()
*
* Purpose: To load and decode the header in the metadata file
* --Retry to get a file with size at least the size of the header
@@ -880,7 +879,7 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5FD_vfd_swmr_header_deserialize(H5FD_t *_file, H5FD_vfd_swmr_md_header *md_header)
+H5FD__vfd_swmr_header_deserialize(H5FD_t *_file, H5FD_vfd_swmr_md_header *md_header)
{
H5FD_vfd_swmr_t *file = (H5FD_vfd_swmr_t *)_file; /* VFD SWMR file struct */
struct stat stat_buf; /* Buffer for stat info */
@@ -893,7 +892,7 @@ H5FD_vfd_swmr_header_deserialize(H5FD_t *_file, H5FD_vfd_swmr_md_header *md_head
uint8_t *p = NULL; /* Pointer to buffer */
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT
+ FUNC_ENTER_STATIC
/* Try to stat the metadata file till md header size */
do {
@@ -958,12 +957,12 @@ H5FD_vfd_swmr_header_deserialize(H5FD_t *_file, H5FD_vfd_swmr_md_header *md_head
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* H5FD_vfd_swmr_header_deserialize() */
+} /* H5FD__vfd_swmr_header_deserialize() */
/*-------------------------------------------------------------------------
- * Function: H5FD_vfd_swmr_index_deserialize()
+ * Function: H5FD__vfd_swmr_index_deserialize()
*
* Purpose: Load and decode the index in the metadata file
* --Retry to get a file with size at least the size of the
@@ -979,7 +978,7 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5FD_vfd_swmr_index_deserialize(H5FD_t *_file, H5FD_vfd_swmr_md_index *md_index, H5FD_vfd_swmr_md_header *md_header)
+H5FD__vfd_swmr_index_deserialize(H5FD_t *_file, H5FD_vfd_swmr_md_index *md_index, H5FD_vfd_swmr_md_header *md_header)
{
H5FD_vfd_swmr_t *file = (H5FD_vfd_swmr_t *)_file; /* VFD SWMR file struct */
uint8_t *image; /* Buffer */
@@ -993,7 +992,7 @@ H5FD_vfd_swmr_index_deserialize(H5FD_t *_file, H5FD_vfd_swmr_md_index *md_index,
unsigned index_retries = H5FD_VFD_SWMR_MD_INDEX_RETRY_MAX; /* Retries for loading the index */
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT
+ FUNC_ENTER_STATIC
/* Try to stat the metadata file till at least md (header+index) size */
do {
@@ -1071,9 +1070,15 @@ H5FD_vfd_swmr_index_deserialize(H5FD_t *_file, H5FD_vfd_swmr_md_index *md_index,
done:
if(image)
image = (uint8_t *)H5MM_xfree(image);
+ if(ret_value < 0) {
+ if(md_index->entries) {
+ HDassert(md_index->num_entries);
+ md_index->entries = (H5FD_vfd_swmr_idx_entry_t *)H5FL_SEQ_FREE(H5FD_vfd_swmr_idx_entry_t, md_index->entries);
+ }
+ }
FUNC_LEAVE_NOAPI(ret_value)
-} /* H5FD_vfd_swmr_index_deserialize() */
+} /* H5FD__vfd_swmr_index_deserialize() */
/*-------------------------------------------------------------------------
@@ -1081,7 +1086,7 @@ done:
*
* Purpose: Retrieve tick_num, num_entries and index from the metadata file
* --If the parameter "reload_hdr_and_index" is true, load and decode
- * the header and index via H5FD_vfd_swmr_load_hdr_and_idx(), which
+ * the header and index via H5FD__vfd_swmr_load_hdr_and_idx(), which
* may replace the VFD's local copies of header and index with the
* latest info read.
* --Return tick_num, num_entries and index from the VFD's local copies.
@@ -1102,7 +1107,7 @@ H5FD_vfd_swmr_get_tick_and_idx(H5FD_t *_file, hbool_t reload_hdr_and_index,
/* Load and decode the header and index as indicated */
if(reload_hdr_and_index) {
- if(H5FD_vfd_swmr_load_hdr_and_idx(_file, FALSE) < 0)
+ if(H5FD__vfd_swmr_load_hdr_and_idx(_file, FALSE) < 0)
HGOTO_ERROR(H5E_VFL, H5E_CANTLOAD, FAIL, "unable to load/decode md header and index")
}
@@ -1111,8 +1116,10 @@ H5FD_vfd_swmr_get_tick_and_idx(H5FD_t *_file, hbool_t reload_hdr_and_index,
*tick_ptr = file->md_header.tick_num;
if(num_entries_ptr != NULL) {
- if(*num_entries_ptr >= file->md_index.num_entries && index != NULL)
+ if(*num_entries_ptr >= file->md_index.num_entries && index != NULL) {
+ HDassert(*num_entries_ptr);
HDmemcpy(index, file->md_index.entries, (file->md_index.num_entries * sizeof(H5FD_vfd_swmr_idx_entry_t)));
+ }
*num_entries_ptr = file->md_index.num_entries;
}
@@ -1120,3 +1127,47 @@ H5FD_vfd_swmr_get_tick_and_idx(H5FD_t *_file, hbool_t reload_hdr_and_index,
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* H5FD_vfd_swmr_get_tick_and_idx() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FD_is_vfd_swmr_driver()
+ *
+ * Purpose: Determine if the driver is a VFD SWMR driver
+ *
+ * Return: Success: TRUE/FALSE
+ * Failure: FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+hbool_t
+H5FD_is_vfd_swmr_driver(H5FD_t *_file)
+{
+ H5FD_vfd_swmr_t *file = (H5FD_vfd_swmr_t *)_file; /* VFD SWMR file struct */
+
+ FUNC_ENTER_NOAPI_NOINIT_NOERR
+
+done:
+ FUNC_LEAVE_NOAPI(file->pub.driver_id == H5FD_VFD_SWMR)
+} /* H5FD_is_vfd_swmr_driver() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FD_vfd_swmr_get_underlying_vfd()
+ *
+ * Purpose: Retrieve the underlying driver for the HDF5 file
+ *
+ * Return: Success: SUCCEED
+ * Failure: FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+H5FD_t *
+H5FD_vfd_swmr_get_underlying_vfd(H5FD_t *_file)
+{
+ H5FD_vfd_swmr_t *file = (H5FD_vfd_swmr_t *)_file; /* VFD SWMR file struct */
+
+ FUNC_ENTER_NOAPI_NOINIT_NOERR
+
+done:
+ FUNC_LEAVE_NOAPI(file->hdf5_file_lf)
+} /* H5FD_vfd_swmr_get_underlying_vfd() */
diff --git a/src/H5Fint.c b/src/H5Fint.c
index 248d7a4..9a654d5 100644
--- a/src/H5Fint.c
+++ b/src/H5Fint.c
@@ -45,38 +45,39 @@
/****************/
/* VFD SWMR */
-/* Append entry to the delayed free spaced release linked list */
-#define H5F_DC_APPEND(entry_ptr, head_ptr, tail_ptr, len) \
-{ \
- if((head_ptr) == NULL) { \
- (head_ptr) = (entry_ptr); \
- (tail_ptr) = (entry_ptr); \
- } else { \
- (tail_ptr)->next = (entry_ptr); \
- (entry_ptr)->prev = (tail_ptr); \
- (tail_ptr) = (entry_ptr); \
- } \
- (len)++; \
-} /* H5F_DC_APPEND() */
+
+/* Prepend entry to the delayed free spaced release linked list */
+#define H5F_DC_PREPEND(entry_ptr, head_ptr, tail_ptr, len) \
+{ \
+ if((head_ptr) == NULL) { \
+ (head_ptr) = (entry_ptr); \
+ (tail_ptr) = (entry_ptr); \
+ } else { \
+ (head_ptr)->prev = (entry_ptr); \
+ (entry_ptr)->next = (head_ptr); \
+ (head_ptr) = (entry_ptr); \
+ } \
+ (len)++; \
+} /* H5F_DC_PREPEND() */
/* Remove entry from delayed free spaced release linked list */
-#define H5F_DC_REMOVE(entry_ptr, head_ptr, tail_ptr, len) \
-{ \
- if((head_ptr) == (entry_ptr)) { \
- (head_ptr) = (entry_ptr)->next; \
- if((head_ptr) != NULL ) \
- (head_ptr)->prev = NULL; \
- } else \
- (entry_ptr)->prev->next = (entry_ptr)->next; \
- if((tail_ptr) == (entry_ptr)) { \
- (tail_ptr) = (entry_ptr)->prev; \
- if((tail_ptr) != NULL) \
- (tail_ptr)->next = NULL; \
- } else \
- (entry_ptr)->next->prev = (entry_ptr)->prev; \
- entry_ptr->next = NULL; \
- entry_ptr->prev = NULL; \
- (len)--; \
+#define H5F_DC_REMOVE(entry_ptr, head_ptr, tail_ptr, len) \
+{ \
+ if((head_ptr) == (entry_ptr)) { \
+ (head_ptr) = (entry_ptr)->next; \
+ if((head_ptr) != NULL ) \
+ (head_ptr)->prev = NULL; \
+ } else \
+ (entry_ptr)->prev->next = (entry_ptr)->next; \
+ if((tail_ptr) == (entry_ptr)) { \
+ (tail_ptr) = (entry_ptr)->prev; \
+ if((tail_ptr) != NULL) \
+ (tail_ptr)->next = NULL; \
+ } else \
+ (entry_ptr)->next->prev = (entry_ptr)->prev; \
+ entry_ptr->next = NULL; \
+ entry_ptr->prev = NULL; \
+ (len)--; \
} /* H5F_DC_REMOVE() */
/******************/
@@ -120,7 +121,7 @@ static herr_t H5F__flush_phase2(H5F_t *f, hbool_t closing);
/* VFD SWMR */
static herr_t H5F__vfd_swmr_init(H5F_t *f, hbool_t file_create);
static herr_t H5F__vfd_swmr_close_or_flush(H5F_t *f, hbool_t closing);
-static herr_t H5F__vfd_swmr_update_end_of_tick(H5F_t *f);
+static herr_t H5F__vfd_swmr_update_end_of_tick_and_tick_num(H5F_t *f, hbool_t incr_tick_num);
static herr_t H5F__vfd_swmr_construct_write_md_hdr(H5F_t *f, uint32_t index_len);
static herr_t H5F__vfd_swmr_construct_write_md_idx(H5F_t *f, uint32_t index_len, struct H5FD_vfd_swmr_idx_entry_t index[]);
static herr_t H5F__idx_entry_cmp(const void *_entry1, const void *_entry2);
@@ -1503,6 +1504,7 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id)
hbool_t ci_load = FALSE; /* whether MDC ci load requested */
hbool_t ci_write = FALSE; /* whether MDC CI write requested */
hbool_t file_create = FALSE; /* creating a new file or not */
+ H5FD_t *underlying_lf = NULL; /* underlying file driver for VFD SWMR */
H5F_t *ret_value = NULL; /*actual return value */
FUNC_ENTER_NOAPI(NULL)
@@ -1567,8 +1569,14 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id)
} /* end if */
} /* end if */
+ /* For VFD SWMR driver, retrieve the underlying vfd for the search in H5F__sfile_search() */
+ if(H5FD_is_vfd_swmr_driver(lf))
+ underlying_lf = H5FD_vfd_swmr_get_underlying_vfd(lf);
+ else
+ underlying_lf = lf;
+
/* Is the file already open? */
- if((shared = H5F__sfile_search(lf)) != NULL) {
+ if((shared = H5F__sfile_search(underlying_lf)) != NULL) {
/*
* The file is already open, so use that one instead of the one we
* just opened. We only one one H5FD_t* per file so one doesn't
@@ -3652,7 +3660,7 @@ H5F__vfd_swmr_init(H5F_t *f, hbool_t file_create)
}
/* Update end_of_tick */
- if(H5F__vfd_swmr_update_end_of_tick(f) < 0)
+ if(H5F__vfd_swmr_update_end_of_tick_and_tick_num(f, FALSE) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "unable to update end of tick")
done:
@@ -3806,11 +3814,10 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5F__vfd_swmr_update_end_of_tick
+ * Function: H5F__vfd_swmr_update_end_of_tick_and_tick_num
*
- * Purpose: Set end_of_tick to the current time + tick length:
- * --end_of_tick_g
- * --f->shared->end_of_tick
+ * Purpose: Update end_of_tick (end_of_tick_g, f->shared->end_of_tick)
+ * Update tick_num (tick_num_g, f->shared->tick_num)
*
* Return: Success: SUCCEED
* Failure: FAIL
@@ -3818,27 +3825,55 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5F__vfd_swmr_update_end_of_tick(H5F_t *f)
+H5F__vfd_swmr_update_end_of_tick_and_tick_num(H5F_t *f, hbool_t incr_tick_num)
{
- struct timespec tmp_end_of_tick; /* end_of_tick */
+ struct timespec curr; /* Current time in struct timespec */
+ struct timespec new_end_of_tick; /* new end_of_tick in struct timespec */
+ long curr_nsecs; /* current time in nanoseconds */
+ long tlen_nsecs; /* tick_len in nanoseconds */
+ long end_nsecs; /* end_of_tick in nanoseconds */
+ long new_end_nsecs; /* new end_of_tick in nanoseconds */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_STATIC
- /* Get current time */
- if(HDclock_gettime(CLOCK_MONOTONIC, &tmp_end_of_tick) < 0)
+ /* Get current time in struct timespec */
+ if(HDclock_gettime(CLOCK_MONOTONIC, &curr) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get time via clock_gettime")
- /* Increment by tick length */
- tmp_end_of_tick.tv_nsec += f->shared->vfd_swmr_config.tick_len * 100000000;
- tmp_end_of_tick.tv_sec += tmp_end_of_tick.tv_nsec / 1000000000;
- tmp_end_of_tick.tv_nsec = tmp_end_of_tick.tv_nsec % 1000000000;
- HDmemcpy(&end_of_tick_g, &tmp_end_of_tick, sizeof(struct timespec));
- HDmemcpy(&f->shared->end_of_tick, &tmp_end_of_tick, sizeof(struct timespec));
+ /* Convert curr to nsecs */
+ curr_nsecs = curr.tv_sec * SECOND_TO_NANOSECS + curr.tv_nsec;
+
+ /* Convert tick_len to nanosecs */
+ tlen_nsecs = f->shared->vfd_swmr_config.tick_len * TENTH_SEC_TO_NANOSECS;
+
+ /*
+ * Update tick_num_g, f->shared->tick_num
+ */
+ if(incr_tick_num) {
+ /* Convert end_of_tick_g to nanoseconds */
+ end_nsecs = end_of_tick_g.tv_sec * SECOND_TO_NANOSECS + end_of_tick_g.tv_nsec;
+
+ /* Increment tick_num by # of elapsed ticks */
+ tick_num_g += (1+ (uint64_t)((curr_nsecs - end_nsecs) / tlen_nsecs));
+ f->shared->tick_num = tick_num_g;
+ }
+
+ /*
+ * Update end_of_tick_g, f->shared->end_of_tick
+ */
+ /* Calculate new end_of_tick */
+ new_end_nsecs = curr_nsecs + tlen_nsecs;
+ new_end_of_tick.tv_nsec = new_end_nsecs % SECOND_TO_NANOSECS;
+ new_end_of_tick.tv_sec = new_end_nsecs / SECOND_TO_NANOSECS;
+
+ /* Update end_of_tick */
+ HDmemcpy(&end_of_tick_g, &new_end_of_tick, sizeof(struct timespec));
+ HDmemcpy(&f->shared->end_of_tick, &new_end_of_tick, sizeof(struct timespec));
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* H5F__vfd_swmr_update_end_of_tick() */
+} /* H5F__vfd_swmr_update_end_of_tick_and_tick_num() */
/*-------------------------------------------------------------------------
@@ -3865,6 +3900,7 @@ done:
static herr_t
H5F__vfd_swmr_close_or_flush(H5F_t *f, hbool_t closing)
{
+ H5F_vfd_swmr_dl_entry_t *curr, *next;
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_STATIC
@@ -3896,11 +3932,20 @@ H5F__vfd_swmr_close_or_flush(H5F_t *f, hbool_t closing)
if(H5MV_close(f) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "unable to close the free-space manager for the metadata file")
+ /* Free the delayed list */
+ curr = f->shared->dl_head_ptr;
+ while(curr != NULL) {
+ next = curr->next;
+ curr = H5FL_FREE(H5F_vfd_swmr_dl_entry_t, curr);
+ curr = next;
+ } /* end while */
+ f->shared->dl_head_ptr = f->shared->dl_tail_ptr = NULL;
+
vfd_swmr_file_g = NULL;
} else { /* For file flush */
/* Update end_of_tick */
- if(H5F__vfd_swmr_update_end_of_tick(f) < 0)
+ if(H5F__vfd_swmr_update_end_of_tick_and_tick_num(f, TRUE) < 0)
HDONE_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "unable to update end of tick")
}
@@ -3946,18 +3991,18 @@ H5F__idx_entry_cmp(const void *_entry1, const void *_entry2)
/*-------------------------------------------------------------------------
* Function: H5F_update_vfd_swmr_metadata_file()
*
- * Purpose: Updating the metadata file
- * --Sort index
- * --For each non-null entry_ptr in the index:
+ * Purpose: Update the metadata file with the input index
+ * --Sort index
+ * --For each non-null entry_ptr in the index entries:
* --Insert previous image of the entry onto the delayed list
* --Allocate space for the entry in the metadata file
* --Compute checksum
- * --Update index
+ * --Update index entry
* --Write the entry to the metadata file
* --Set entry_ptr to NULL
* --Construct on disk image of the index and write index to the metadata file
* --Construct on disk image of the header and write header to the metadata file
- * --Release time out space from the delayed list to the free-space manager
+ * --Release time out entries from the delayed list to the free-space manager
*
* Return: SUCCEED/FAIL
*
@@ -3966,26 +4011,26 @@ H5F__idx_entry_cmp(const void *_entry1, const void *_entry2)
herr_t
H5F_update_vfd_swmr_metadata_file(H5F_t *f, uint32_t index_len, struct H5FD_vfd_swmr_idx_entry_t index[])
{
- H5F_vfd_swmr_dl_entry_t *prev; /* Points to the delayed list */
- H5F_vfd_swmr_dl_entry_t *dl_entry;
- haddr_t md_addr;
+ H5F_vfd_swmr_dl_entry_t *prev; /* Points to the previous entry in the delayed list */
+ H5F_vfd_swmr_dl_entry_t *dl_entry; /* Points to an entry in the delayed list */
+ haddr_t md_addr; /* Address in the metadata file */
unsigned i; /* Local index variable */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(FAIL)
- /* Sort index by increasing offset in the HDF5 file */
+ /* Sort index entries by increasing offset in the HDF5 file */
HDqsort(index, index_len, sizeof(H5FD_vfd_swmr_idx_entry_t), H5F__idx_entry_cmp);
/* For each non-null entry_ptr in the index:
- * --If exists, insert previous image of the entry to the delayed list
+ * --Insert previous image of the entry (if exists) to the beginning of the delayed list
* --Allocate space for the entry in the metadata file
- * --Compute checksum, update index, write entry to the metadata file
+ * --Compute checksum, update the index entry, write entry to the metadata file
* --Set entry_ptr to NULL
*/
for(i = 0; i < index_len; i++) {
if(index[i].entry_ptr != NULL) {
- /* Append previous image of the entry to the delayed list */
+ /* Prepend previous image of the entry to the delayed list */
if(index[i].md_file_page_offset) {
if(NULL == (dl_entry = H5FL_CALLOC(H5F_vfd_swmr_dl_entry_t)))
HGOTO_ERROR(H5E_FILE, H5E_CANTALLOC, FAIL, "unable to allocate the delayed entry")
@@ -3993,13 +4038,13 @@ H5F_update_vfd_swmr_metadata_file(H5F_t *f, uint32_t index_len, struct H5FD_vfd_
dl_entry->md_file_page_offset = index[i].md_file_page_offset;
dl_entry->length = index[i].length;
dl_entry->tick_num = f->shared->tick_num;
- H5F_DC_APPEND(dl_entry, f->shared->dl_head_ptr, f->shared->dl_tail_ptr, f->shared->dl_len);
+ H5F_DC_PREPEND(dl_entry, f->shared->dl_head_ptr, f->shared->dl_tail_ptr, f->shared->dl_len);
}
/* Allocate space for the entry in the metadata file */
if((md_addr = H5MV_alloc(f, index[i].length)) == HADDR_UNDEF)
HGOTO_ERROR(H5E_FILE, H5E_WRITEERROR, FAIL, "error in allocating space from the metadata file")
- /* Compute checksum and update the index */
+ /* Compute checksum and update the index entry */
index[i].md_file_page_offset = md_addr/f->shared->fs_page_size;
index[i].chksum = H5_checksum_metadata(index[i].entry_ptr, (size_t)(index[i].length), 0);
@@ -4015,18 +4060,17 @@ H5F_update_vfd_swmr_metadata_file(H5F_t *f, uint32_t index_len, struct H5FD_vfd_
} /* end for */
- /* Construct and write index to the md file */
+ /* Construct and write index to the metadata file */
if(H5F__vfd_swmr_construct_write_md_idx(f, index_len, index) < 0)
- HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "fail to construct & write index in md")
+ HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "fail to construct & write index to md")
/* Construct and write header to the md file */
if(H5F__vfd_swmr_construct_write_md_hdr(f, index_len) < 0)
- HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "fail to construct & write header in md")
+ HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "fail to construct & write header to md")
/*
- * Release time out entry from the delayed list:
- * Scan the delayed list from the bottom up:
- * --release to the metadata file free space manager all entries that have
+ * Release time out entries from the delayed list by scanning the list from the bottom up:
+ * --release to the metadata file free space manager all index entries that have
* resided on the list for more than max_lag ticks
* --remove the associated entries from the list
*/
@@ -4044,8 +4088,8 @@ H5F_update_vfd_swmr_metadata_file(H5F_t *f, uint32_t index_len, struct H5FD_vfd_
/* Free the delayed entry struct */
H5FL_FREE(H5F_vfd_swmr_dl_entry_t, dl_entry);
- }
- /* DO I break from it once it is false ?? */
+ } else
+ break;
dl_entry = prev;
} /* end while */
@@ -4065,14 +4109,14 @@ done:
herr_t
H5F_vfd_swmr_writer_end_of_tick(void)
{
- H5FD_vfd_swmr_idx_entry_t *index;
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(FAIL)
- /* construct */
if(vfd_swmr_file_g) {
- ;
+ /* Update end_of_tick */
+ if(H5F__vfd_swmr_update_end_of_tick_and_tick_num(vfd_swmr_file_g, TRUE) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "unable to update end of tick")
}
done:
@@ -4097,7 +4141,9 @@ H5F_vfd_swmr_reader_end_of_tick(void)
/* construct */
if(vfd_swmr_file_g) {
- ;
+ /* Update end_of_tick */
+ if(H5F__vfd_swmr_update_end_of_tick_and_tick_num(vfd_swmr_file_g, FALSE) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "unable to update end of tick")
}
done:
diff --git a/src/H5Fpkg.h b/src/H5Fpkg.h
index 2a5847e..a373285 100644
--- a/src/H5Fpkg.h
+++ b/src/H5Fpkg.h
@@ -386,8 +386,8 @@ struct H5F_file_t {
uint64_t tick_num; /* Number of the current tick */
struct timespec end_of_tick; /* End time of the current tick */
- /* Metadata file */
- int vfd_swmr_md_fd; /* POSIX: file descriptor of the metadata file */
+ /* Metadata file for VFD SWMR writer */
+ int vfd_swmr_md_fd; /* POSIX: file descriptor for the metadata file */
haddr_t vfd_swmr_md_eoa; /* POSIX: eoa for the metadata file */
/* Free space manager for the metadata file */
@@ -530,6 +530,12 @@ H5_DLL herr_t H5F__get_sohm_mesg_count_test(hid_t fid, unsigned type_id, size_t
H5_DLL herr_t H5F__check_cached_stab_test(hid_t file_id);
H5_DLL herr_t H5F__get_maxaddr_test(hid_t file_id, haddr_t *maxaddr);
H5_DLL herr_t H5F__get_sbe_addr_test(hid_t file_id, haddr_t *sbe_addr);
+
+/* VFD SWMR testing routines */
+
+H5_DLL herr_t H5F__vfd_swmr_writer_md_test(hid_t file_id, hbool_t create);
+H5_DLL herr_t H5F__vfd_swmr_writer_update_md_test(hid_t file_id, unsigned in_num_entries,
+ struct H5FD_vfd_swmr_idx_entry_t *in_index, unsigned num_insert_dl, unsigned num_remove_dl);
#endif /* H5F_TESTING */
#endif /* _H5Fpkg_H */
diff --git a/src/H5Ftest.c b/src/H5Ftest.c
index df9c933..d9ea9b6 100644
--- a/src/H5Ftest.c
+++ b/src/H5Ftest.c
@@ -38,12 +38,14 @@
/* Headers */
/***********/
#include "H5private.h" /* Generic Functions */
+#include "H5FDprivate.h" /* File Drivers */
#include "H5CXprivate.h" /* API Contexts */
#include "H5Eprivate.h" /* Error handling */
#include "H5Fpkg.h" /* File access */
#include "H5Gpkg.h" /* Groups */
#include "H5Iprivate.h" /* IDs */
#include "H5SMpkg.h" /* Shared object header messages */
+#include "H5MMprivate.h" /* Memory management */
/****************/
@@ -64,6 +66,11 @@
/********************/
/* Local Prototypes */
/********************/
+static herr_t H5F__vfd_swmr_decode_md_hdr(int md_fd, H5FD_vfd_swmr_md_header *md_hdr);
+static herr_t H5F__vfd_swmr_decode_md_idx(int md_fd, H5FD_vfd_swmr_md_header *md_hdr, H5FD_vfd_swmr_md_index *md_idx);
+static herr_t H5F__vfd_swmr_verify_md_hdr_and_idx(H5F_t *f,
+ H5FD_vfd_swmr_md_header *md_hdr, H5FD_vfd_swmr_md_index *md_idx,
+ unsigned num_entries, H5FD_vfd_swmr_idx_entry_t *index);
/*********************/
@@ -74,6 +81,8 @@
/*****************************/
/* Library Private Variables */
/*****************************/
+/* Declare external the free list for H5FD_vfd_swmr_idx_entry_t */
+H5FL_SEQ_EXTERN(H5FD_vfd_swmr_idx_entry_t);
/*******************/
@@ -232,3 +241,355 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5F__get_sbe_addr_test() */
+
+/*
+ * VFD SWMR tests
+ */
+
+/*-------------------------------------------------------------------------
+ * Function: H5F__vfd_swmr_writer_md_test
+ *
+ * Purpose: Verify info in the header and index when:
+ * (1) creating an HDF5 file
+ * (2) opening an existing HDF5 file
+ * (3) flushing an HDF5 file
+ *
+ * Open the metadata file
+ * Verify the file size is as expected (md_pages_reserved)
+ * For file create:
+ * --No header magic is found
+ * For file open or file flush:
+ * --Read and decode the header and index in the metadata file
+ * --Verify info in the header and index read from
+ * the metadata file is as expected (empty index)
+ *
+ * Return: SUCCEED/FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5F__vfd_swmr_writer_md_test(hid_t file_id, hbool_t file_create)
+{
+ H5F_t *f; /* File pointer */
+ h5_stat_t stat_buf; /* Buffer for stat info */
+ H5FD_vfd_swmr_md_header md_hdr; /* Header for the metadata file */
+ H5FD_vfd_swmr_md_index md_idx; /* Indedx for the metadata file */
+ int md_fd = -1; /* The metadata file descriptor */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_PACKAGE
+
+ /* Check arguments */
+ if(NULL == (f = (H5F_t *)H5I_object_verify(file_id, H5I_FILE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file")
+
+ /* Open the metadata file */
+ if((md_fd = HDopen(f->shared->vfd_swmr_config.md_file_path, O_RDONLY)) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "error opening metadata file")
+
+ /* Verify the minimum size for the metadata file */
+ if(HDstat(f->shared->vfd_swmr_config.md_file_path, &stat_buf) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_BADFILE, FAIL, "unable to stat the metadata file")
+ if(stat_buf.st_size < (HDoff_t)((hsize_t)f->shared->vfd_swmr_config.md_pages_reserved * f->shared->fs_page_size))
+ HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "incorrect metadata file size")
+
+ if(file_create) { /* Creating file */
+ uint32_t hdr_magic;
+
+ /* Seek to the beginning of the file */
+ if(HDlseek(md_fd, (HDoff_t)0, SEEK_SET) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_SEEKERROR, FAIL, "error seeking metadata file")
+
+ /* Try to read the magic for header */
+ if(HDread(md_fd, &hdr_magic, H5_SIZEOF_MAGIC) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_READERROR, FAIL, "error reading metadata file")
+
+ /* Verify that there is no header magic in the metadata file */
+ if(HDmemcmp(&hdr_magic, H5FD_MD_HEADER_MAGIC, (size_t)H5_SIZEOF_MAGIC) == 0)
+ HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "error finding header magic in the metadata file")
+
+ } else { /* Opening or flushing the file */
+
+ HDmemset(&md_hdr, 0, sizeof(H5FD_vfd_swmr_md_header));
+ HDmemset(&md_idx, 0, sizeof(H5FD_vfd_swmr_md_index));
+
+ /* Decode the header */
+ if(H5F__vfd_swmr_decode_md_hdr(md_fd, &md_hdr) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTDECODE, FAIL, "error decoding header in the metadata file")
+
+ /* Decode the index */
+ if(H5F__vfd_swmr_decode_md_idx(md_fd, &md_hdr, &md_idx) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTDECODE, FAIL, "error decoding index in the metadata file")
+
+ /* Verify info in header and index read from the metadata file */
+ if(H5F__vfd_swmr_verify_md_hdr_and_idx(f, &md_hdr, &md_idx, 0, NULL) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "incorrect info found in header and index of the metadata file")
+ }
+
+done:
+ /* Free the index entries */
+ if(!file_create && md_idx.entries) {
+ HDassert(md_idx.num_entries);
+ H5MM_free(md_idx.entries);
+ }
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5F__vfd_swmr_writer_md_test() */
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F__vfd_swmr_decode_md_hdr
+ *
+ * Purpose: Decode header and verify header magic
+ *
+ * Return: SUCCEED/FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5F__vfd_swmr_decode_md_hdr(int md_fd, H5FD_vfd_swmr_md_header *md_hdr)
+{
+ uint8_t image[H5FD_MD_HEADER_SIZE]; /* Buffer for the header image */
+ uint8_t *p = NULL; /* Points to the image */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_PACKAGE
+
+ p = image;
+
+ /* Seek to the beginning of the file */
+ if(HDlseek(md_fd, (HDoff_t)0, SEEK_SET) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_SEEKERROR, FAIL, "error seeking metadata file")
+
+ /* Read the header */
+ if(HDread(md_fd, image, H5FD_MD_HEADER_SIZE) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_READERROR, FAIL, "error reading metadata file")
+
+ /* Verify magic for header */
+ if(HDmemcmp(p, H5FD_MD_HEADER_MAGIC, (size_t)H5_SIZEOF_MAGIC) != 0)
+ HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "does not find header magic in the metadata file")
+
+ p += H5_SIZEOF_MAGIC;
+
+ /* Deserialize fs_page_size, tick_num, index_offset, index_length */
+ UINT32DECODE(p, md_hdr->fs_page_size);
+ UINT64DECODE(p, md_hdr->tick_num);
+ UINT64DECODE(p, md_hdr->index_offset);
+ UINT64DECODE(p, md_hdr->index_length);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5F__vfd_swmr_decode_md_hdr() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F__vfd_swmr_decode_md_idx
+ *
+ * Purpose: Decode index and verify index magic
+ *
+ * Return: SUCCEED/FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5F__vfd_swmr_decode_md_idx(int md_fd, H5FD_vfd_swmr_md_header *md_hdr, H5FD_vfd_swmr_md_index *md_idx)
+{
+ uint8_t *image = NULL; /* Points to the buffer for the index image */
+ uint8_t *p = NULL; /* Points to the image */
+ unsigned i; /* Local index variable */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_PACKAGE
+
+ /* Allocate buffer for the index image */
+ if(NULL == (image = (uint8_t *)H5MM_malloc(md_hdr->index_length)))
+ HGOTO_ERROR(H5E_FILE, H5E_CANTALLOC, FAIL, "memory allocation failed for index on disk buffer")
+
+ p = image;
+
+ /* Seek to the position of the index */
+ if(HDlseek(md_fd, (HDoff_t)md_hdr->index_offset, SEEK_SET) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_SEEKERROR, FAIL, "unable to seek in metadata file")
+
+ /* Read the index */
+ if(HDread(md_fd, image, md_hdr->index_length) < (int64_t)md_hdr->index_length)
+ HGOTO_ERROR(H5E_FILE, H5E_READERROR, FAIL, "error in reading the header in metadata file")
+
+ /* Verify magic for index */
+ if(HDmemcmp(p, H5FD_MD_INDEX_MAGIC, (size_t)H5_SIZEOF_MAGIC) != 0)
+ HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "no header magic in the metadata file")
+
+ p += H5_SIZEOF_MAGIC;
+
+ /* Deserialize tick_num and num_entries */
+ UINT64DECODE(p, md_idx->tick_num);
+ UINT32DECODE(p, md_idx->num_entries);
+
+ /* Deserialize index entries */
+ if(md_idx->num_entries) {
+
+ /* Allocate memory for the index entries */
+ if(NULL == (md_idx->entries = (H5FD_vfd_swmr_idx_entry_t *)H5MM_calloc(md_idx->num_entries * sizeof(H5FD_vfd_swmr_idx_entry_t))))
+ HGOTO_ERROR(H5E_FILE, H5E_CANTALLOC, FAIL, "memory allocation failed for index entries")
+
+ /* Decode index entries */
+ for(i = 0; i < md_idx->num_entries; i++) {
+ UINT32DECODE(p, md_idx->entries[i].hdf5_page_offset);
+ UINT32DECODE(p, md_idx->entries[i].md_file_page_offset);
+ UINT32DECODE(p, md_idx->entries[i].length);
+ UINT32DECODE(p, md_idx->entries[i].chksum);
+ } /* end for */
+
+ } /* end if */
+
+done:
+ /* Free the buffer */
+ if(image)
+ H5MM_free(image);
+ if(ret_value < 0) {
+ /* Free the index entries */
+ if(md_idx->entries) {
+ HDassert(md_idx->num_entries);
+ H5MM_free(md_idx->entries);
+ }
+ }
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5F__vfd_swmr_decode_md_idx() */
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F__vfd_swmr_verify_md_hdr_idx_test
+ *
+ * Purpose: Verify the header and index in the metadata file:
+ * --fs_page_size in md header is the same as that stored in "f"
+ * --index_length in md header is as indicated by num_entries
+ * --index_offset in md header is right after the header
+ * --number of entries in md index is num_entries
+ * --entries in md index is as indicated by num_entries and index
+ *
+ * Return: SUCCEED/FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5F__vfd_swmr_verify_md_hdr_and_idx(H5F_t *f,
+ H5FD_vfd_swmr_md_header *md_hdr, H5FD_vfd_swmr_md_index *md_idx,
+ unsigned num_entries, H5FD_vfd_swmr_idx_entry_t *index)
+{
+ unsigned i; /* Local index variable */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_PACKAGE
+
+ /* Verify fs_page_size read from header in the metadata file is fs_page_size in f */
+ if(md_hdr->fs_page_size != f->shared->fs_page_size)
+ HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "incorrect fs_page_size read from metadata file")
+
+ /* Verify index_length read from header in the metadata file is the size of num_entries index */
+ if(md_hdr->index_length != H5FD_MD_INDEX_SIZE(num_entries))
+ HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "incorrect index_length read from metadata file")
+
+ /* Verify index_offset read from header in the metadata file is the size of md header */
+ if(md_hdr->index_offset != H5FD_MD_HEADER_SIZE)
+ HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "incorrect index_offset read from metadata file")
+
+ /* Verify num_entries read from index in the metadata file is num_entries */
+ if(md_idx->num_entries != num_entries)
+ HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "incorrect num_entries read from metadata file")
+
+ /* Verify empty/non-empty index entries */
+ if(num_entries == 0) {
+ /* Verify the index is empty */
+ if(md_idx->entries != NULL)
+ HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "incorrect entries in index")
+ } else {
+ /* Verify entries */
+ for(i = 0; i < num_entries; i++) {
+ if(md_idx->entries[i].length != index[i].length)
+ HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "incorrect length read from metadata file")
+
+ if(md_idx->entries[i].hdf5_page_offset != index[i].hdf5_page_offset)
+ HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "incorrect md_file_page_offset read from metadata file")
+
+ if(md_idx->entries[i].md_file_page_offset != index[i].md_file_page_offset)
+ HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "incorrect md_file_page_offset read from metadata file")
+
+ if(md_idx->entries[i].chksum != index[i].chksum)
+ HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "incorrect chksum read from metadata file")
+ }
+ }
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5F__vfd_swmr_verify_md_hdr_and_idx() */
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F__vfd_swmr_update_md_test
+ *
+ * Purpose: Update the metadata file with the input index
+ * Verify the info read from the metadata file is as indicated by
+ * the input: num_entries and index
+ *
+ * Return: SUCCEED/FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5F__vfd_swmr_writer_update_md_test(hid_t file_id, unsigned num_entries, H5FD_vfd_swmr_idx_entry_t *index,
+ unsigned num_insert_dl, unsigned num_remove_dl)
+{
+ H5F_t *f; /* File pointer */
+ int md_fd = -1; /* The metadata file descriptor */
+ H5FD_vfd_swmr_md_header md_hdr; /* Header for the metadata file */
+ H5FD_vfd_swmr_md_index md_idx; /* Indedx for the metadata file */
+ unsigned save_dl_len = 0; /* # of entries in the delayed list */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_PACKAGE
+
+ HDmemset(&md_hdr, 0, sizeof(H5FD_vfd_swmr_md_header));
+ HDmemset(&md_idx, 0, sizeof(H5FD_vfd_swmr_md_index));
+
+ /* Check arguments */
+ if(NULL == (f = (H5F_t *)H5I_object_verify(file_id, H5I_FILE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file")
+
+ /* Save the number of entries in the delayed list */
+ save_dl_len = f->shared->dl_len;
+
+ /* Update the metadata file with the input index */
+ if(H5F_update_vfd_swmr_metadata_file(f, num_entries, index) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTALLOC, FAIL, "error updating the md file with the index")
+
+ /* Verify the number of entries in the delayed list is as expected */
+ if(f->shared->dl_len != (save_dl_len + num_insert_dl - num_remove_dl))
+ HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "incorrect # of entries in the delayed list")
+
+ /* Open the metadata file */
+ if((md_fd = HDopen(f->shared->vfd_swmr_config.md_file_path, O_RDONLY)) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "error opening metadata file")
+
+ /* Decode the header in the metadata file */
+ if(H5F__vfd_swmr_decode_md_hdr(md_fd, &md_hdr) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTDECODE, FAIL, "error decoding header in the metadata file")
+
+ /* Decode the index in the metadata file */
+ if(H5F__vfd_swmr_decode_md_idx(md_fd, &md_hdr, &md_idx) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "error decoding index in the metadata file")
+
+ /* Verify info read from the metadata file is the same as the input index */
+ if(H5F__vfd_swmr_verify_md_hdr_and_idx(f, &md_hdr, &md_idx, num_entries, index) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "incorrect info found in header and index of the metadata file")
+
+done:
+ /* Free index entries */
+ if(md_idx.entries) {
+ HDassert(md_idx.num_entries);
+ H5MM_free(md_idx.entries);
+ }
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5F__vfd_swmr_writer_update_md_test() */
diff --git a/src/H5private.h b/src/H5private.h
index 842ba87..fb01d06 100644
--- a/src/H5private.h
+++ b/src/H5private.h
@@ -374,6 +374,10 @@
/* Raise an integer to a power of 2 */
# define H5_EXP2(n) (1 << (n))
+/* VFD SWMR */
+#define SECOND_TO_NANOSECS 1000000000 /* Second to nanoseconds */
+#define TENTH_SEC_TO_NANOSECS 100000000 /* Tenth of a second to nanoseconds */
+
/*
* HDF Boolean type.
*/
@@ -2070,16 +2074,18 @@ H5_DLL herr_t H5CX_pop(void);
/* Initialize the library */ \
if(vfd_swmr_g) { \
struct timespec curr_time; \
+ long curr_nsecs, end_nsecs; \
if(HDclock_gettime(CLOCK_MONOTONIC, &curr_time) < 0) \
HGOTO_ERROR(H5E_FUNC, H5E_CANTGET, err, "can't get time via clock_gettime") \
- if( (curr_time.tv_sec >= end_of_tick_g.tv_sec) && \
- (curr_time.tv_nsec >= end_of_tick_g.tv_nsec) ) { \
+ curr_nsecs = curr_time.tv_sec * 1000000000 + curr_time.tv_nsec; \
+ end_nsecs = end_of_tick_g.tv_sec * 1000000000 + end_of_tick_g.tv_nsec; \
+ if(curr_nsecs > end_nsecs) { \
if(vfd_swmr_writer_g) { \
- if(H5F_vfd_swmr_writer_end_of_tick() < 0) \
+ if(H5F_vfd_swmr_writer_end_of_tick() < 0) \
HGOTO_ERROR(H5E_FUNC, H5E_CANTSET, err, "end of tick error for VFD SWMR writer") \
} \
else if(!swmr_reader_exit) { \
- if(H5F_vfd_swmr_reader_end_of_tick() < 0) \
+ if(H5F_vfd_swmr_reader_end_of_tick() < 0) \
HGOTO_ERROR(H5E_FUNC, H5E_CANTSET, err, "end of tick error for VFD SWMR reader") \
} \
} \
diff --git a/test/vfd_swmr.c b/test/vfd_swmr.c
index 4d1695a..0cf865a 100644
--- a/test/vfd_swmr.c
+++ b/test/vfd_swmr.c
@@ -24,38 +24,24 @@
/*
* This file needs to access private information from the H5F package.
*/
-#define H5MF_FRIEND /*suppress error about including H5MFpkg */
-#include "H5MFpkg.h"
-#define H5F_FRIEND /*suppress error about including H5Fpkg */
+#define H5F_FRIEND /*suppress error about including H5Fpkg */
#define H5F_TESTING
+#include "H5FDprivate.h"
#include "H5Fpkg.h"
-#include "H5CXprivate.h" /* API Contexts */
-#include "H5Iprivate.h"
-#include "H5PBprivate.h"
+#include "H5CXprivate.h" /* API Contexts */
-
-#define FILENAME_LEN 1024
-#define NUM_DSETS 5
-#define NX 100
-#define NY 50
-
-static unsigned open_file(char *filename, hid_t fapl, hsize_t page_size, size_t page_buffer_size);
+#define FS_PAGE_SIZE 512
+#define FILENAME "vfd_swmr_file.h5"
+#define MD_FILENAME "vfd_swmr_metadata_file"
/* test routines for VFD SWMR */
-static unsigned test_fapl();
-static unsigned test_file_end_tick();
-static unsigned test_file_fapl();
-
-const char *FILENAME[] = {
- "filepaged",
- NULL
-};
-
-
-/*********************/
-/*********************/
+static unsigned test_fapl(void);
+static unsigned test_file_end_tick(void);
+static unsigned test_file_fapl(void);
+static unsigned test_writer_md(void);
+static unsigned test_writer_update_md(void);
/*-------------------------------------------------------------------------
@@ -78,7 +64,7 @@ const char *FILENAME[] = {
*-------------------------------------------------------------------------
*/
static unsigned
-test_fapl()
+test_fapl(void)
{
hid_t fapl = -1; /* File access property list */
H5F_vfd_swmr_config_t *my_config = NULL; /* Configuration for VFD SWMR */
@@ -149,7 +135,7 @@ test_fapl()
TEST_ERROR;
/* Set md_file_path */
- HDstrcpy(my_config->md_file_path, "my_md_file");
+ HDstrcpy(my_config->md_file_path, MD_FILENAME);
my_config->vfd_swmr_writer = TRUE;
/* Should succeed in setting the configuration info */
@@ -168,7 +154,7 @@ test_fapl()
TEST_ERROR;
if(my_config->md_pages_reserved != 2)
TEST_ERROR;
- if(HDstrcmp(my_config->md_file_path, "my_md_file") != 0)
+ if(HDstrcmp(my_config->md_file_path, MD_FILENAME) != 0)
TEST_ERROR;
/* Close the file access property list */
@@ -200,6 +186,13 @@ error:
* B) Verify the VFD SWMR configuration set in fapl
* used to create/open the file is the same as the
* configuration retrieved from the file's fapl.
+ * C) Verify the following when configured as VFD SWMR reader:
+ * (1) there is an existing file opened as writer:
+ * --same process open as reader: will just increment the
+ * file reference count and use the same shared struct
+ * (2) there is no existing file opened as writer:
+ * --opening the file as reader will fail
+ * because there is no metadata file
*
* Return: 0 if test is sucessful
* 1 if test fails
@@ -209,25 +202,22 @@ error:
*-------------------------------------------------------------------------
*/
static unsigned
-test_file_fapl()
+test_file_fapl(void)
{
hid_t fid = -1; /* File ID */
+ hid_t fid_read = -1; /* File ID */
hid_t fcpl = -1; /* File creation property list ID */
hid_t fapl1 = -1; /* File access property list ID */
hid_t fapl2 = -1; /* File access property list ID */
hid_t file_fapl = -1; /* File access property list ID associated with the file */
- H5F_vfd_swmr_config_t *config1 = NULL; /* Configuration for VFD SWMR */
- H5F_vfd_swmr_config_t *config2 = NULL; /* Configuration for VFD SWMR */
- H5F_vfd_swmr_config_t *config3 = NULL; /* Configuration for VFD SWMR */
- herr_t ret; /* Return value */
-hid_t fid_read = -1; /* File ID for VFD SWMR reader */
-hid_t sid = -1;
-hid_t did = -1;
+ H5F_vfd_swmr_config_t *config1 = NULL; /* Configuration for VFD SWMR */
+ H5F_vfd_swmr_config_t *config2 = NULL; /* Configuration for VFD SWMR */
+ H5F_vfd_swmr_config_t *file_config = NULL; /* Configuration for VFD SWMR */
TESTING("VFD SWMR configuration for the file and fapl");
/* Should succeed without VFD SWMR configured */
- if((fid = H5Fcreate("myfile", H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0)
+ if((fid = H5Fcreate(FILENAME, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0)
TEST_ERROR;
/* Close the file */
@@ -239,35 +229,36 @@ hid_t did = -1;
FAIL_STACK_ERROR;
if((config2 = (H5F_vfd_swmr_config_t *)HDmalloc(sizeof(H5F_vfd_swmr_config_t))) == NULL)
FAIL_STACK_ERROR;
- if((config3 = (H5F_vfd_swmr_config_t *)HDmalloc(sizeof(H5F_vfd_swmr_config_t))) == NULL)
+ if((file_config = (H5F_vfd_swmr_config_t *)HDmalloc(sizeof(H5F_vfd_swmr_config_t))) == NULL)
FAIL_STACK_ERROR;
HDmemset(config1, 0, sizeof(H5F_vfd_swmr_config_t));
HDmemset(config2, 0, sizeof(H5F_vfd_swmr_config_t));
- HDmemset(config3, 0, sizeof(H5F_vfd_swmr_config_t));
+ HDmemset(file_config, 0, sizeof(H5F_vfd_swmr_config_t));
/* Create a copy of the file access property list */
if((fapl1 = H5Pcreate(H5P_FILE_ACCESS)) < 0)
TEST_ERROR;
+ /* Configured as VFD SWMR writer */
config1->version = H5F__CURR_VFD_SWMR_CONFIG_VERSION;
config1->tick_len = 4;
config1->max_lag = 6;
config1->vfd_swmr_writer = TRUE;
config1->md_pages_reserved = 2;
- HDstrcpy(config1->md_file_path, "my_md_file");
+ HDstrcpy(config1->md_file_path, MD_FILENAME);
/* Should succeed in setting the VFD SWMR configuration */
if(H5Pset_vfd_swmr_config(fapl1, config1) < 0)
TEST_ERROR;
- /* Should fail to configure VFD SWMR: page buffering and paged aggregation not enabled */
+ /* Should fail to create: page buffering and paged aggregation not enabled */
H5E_BEGIN_TRY {
- fid = H5Fcreate("myfile", H5F_ACC_TRUNC, H5P_DEFAULT, fapl1);
+ fid = H5Fcreate(FILENAME, H5F_ACC_TRUNC, H5P_DEFAULT, fapl1);
} H5E_END_TRY;
if(fid >= 0)
TEST_ERROR;
- /* Create a copy of file creation property list */
+ /* Create a copy of the file creation property list */
if((fcpl = H5Pcreate(H5P_FILE_CREATE)) < 0)
FAIL_STACK_ERROR
@@ -275,9 +266,9 @@ hid_t did = -1;
if(H5Pset_file_space_strategy(fcpl, H5F_FSPACE_STRATEGY_PAGE, FALSE, (hsize_t)1) < 0)
FAIL_STACK_ERROR;
- /* Should fail to configure VFD SWMR: no page buffering */
+ /* Should fail to create: no page buffering */
H5E_BEGIN_TRY {
- fid = H5Fcreate("myfile", H5F_ACC_TRUNC, fcpl, fapl1);
+ fid = H5Fcreate(FILENAME, H5F_ACC_TRUNC, fcpl, fapl1);
} H5E_END_TRY;
if(fid >= 0)
TEST_ERROR;
@@ -286,8 +277,8 @@ hid_t did = -1;
if(H5Pset_page_buffer_size(fapl1, 4096, 0, 0) < 0)
FAIL_STACK_ERROR;
- /* Should succeed to configure VFD SWMR: paged aggregation and page buffering enabled */
- if((fid = H5Fcreate("myfile", H5F_ACC_TRUNC, fcpl, fapl1)) < 0)
+ /* Should succeed to create the file: paged aggregation and page buffering enabled */
+ if((fid = H5Fcreate(FILENAME, H5F_ACC_TRUNC, fcpl, fapl1)) < 0)
TEST_ERROR;
/* Get the file's file access property list */
@@ -295,11 +286,11 @@ hid_t did = -1;
FAIL_STACK_ERROR;
/* Retrieve the VFD SWMR configuration from file_fapl */
- if(H5Pget_vfd_swmr_config(file_fapl, config2) < 0)
+ if(H5Pget_vfd_swmr_config(file_fapl, file_config) < 0)
TEST_ERROR;
/* Verify the retrieved info is the same as config1 */
- if(HDmemcmp(config1, config2, sizeof(H5F_vfd_swmr_config_t)) != 0)
+ if(HDmemcmp(config1, file_config, sizeof(H5F_vfd_swmr_config_t)) != 0)
TEST_ERROR;
/* Closing */
@@ -309,23 +300,23 @@ hid_t did = -1;
FAIL_STACK_ERROR;
- /* Should succeed: VFD SWMR writer */
- if((fid = H5Fopen("myfile", H5F_ACC_RDWR, fapl1)) < 0)
+ /* Should succeed to open the file as VFD SWMR writer */
+ if((fid = H5Fopen(FILENAME, H5F_ACC_RDWR, fapl1)) < 0)
TEST_ERROR;
/* Get the file's file access property list */
if((file_fapl = H5Fget_access_plist(fid)) < 0)
FAIL_STACK_ERROR;
- /* Clear info in config2 */
- HDmemset(config2, 0, sizeof(H5F_vfd_swmr_config_t));
+ /* Clear info in file_config */
+ HDmemset(file_config, 0, sizeof(H5F_vfd_swmr_config_t));
/* Retrieve the VFD SWMR configuration from file_fapl */
- if(H5Pget_vfd_swmr_config(file_fapl, config2) < 0)
+ if(H5Pget_vfd_swmr_config(file_fapl, file_config) < 0)
TEST_ERROR;
/* Verify the retrieved info is the same as config1 */
- if(HDmemcmp(config1, config2, sizeof(H5F_vfd_swmr_config_t)) != 0)
+ if(HDmemcmp(config1, file_config, sizeof(H5F_vfd_swmr_config_t)) != 0)
TEST_ERROR;
/* Closing */
@@ -334,97 +325,130 @@ hid_t did = -1;
if(H5Pclose(file_fapl) < 0)
FAIL_STACK_ERROR;
- /* Set a different VFD SWMR configuration */
/* Create a copy of the file access property list */
if((fapl2 = H5Pcreate(H5P_FILE_ACCESS)) < 0)
TEST_ERROR;
- config3->version = H5F__CURR_VFD_SWMR_CONFIG_VERSION;
- config3->tick_len = 4;
- config3->max_lag = 10;
- config3->vfd_swmr_writer = TRUE;
- config3->md_pages_reserved = 2;
- HDstrcpy(config3->md_file_path, "my_md_file");
+ /* Set up different VFD SWMR configuration */
+ config2->version = H5F__CURR_VFD_SWMR_CONFIG_VERSION;
+ config2->tick_len = 4;
+ config2->max_lag = 10;
+ config2->vfd_swmr_writer = TRUE;
+ config2->md_pages_reserved = 2;
+ HDstrcpy(config2->md_file_path, MD_FILENAME);
/* Should succeed in setting the VFD SWMR configuration */
- if(H5Pset_vfd_swmr_config(fapl2, config3) < 0)
+ if(H5Pset_vfd_swmr_config(fapl2, config2) < 0)
TEST_ERROR;
/* Enable page buffering */
if(H5Pset_page_buffer_size(fapl2, 4096, 0, 0) < 0)
FAIL_STACK_ERROR;
- /* Should succeed: VFD SWMR writer */
- if((fid = H5Fopen("myfile", H5F_ACC_RDWR, fapl2)) < 0)
+ /* Should succeed to open the file as VFD SWMR writer */
+ if((fid = H5Fopen(FILENAME, H5F_ACC_RDWR, fapl2)) < 0)
TEST_ERROR;
/* Get the file's file access property list */
if((file_fapl = H5Fget_access_plist(fid)) < 0)
FAIL_STACK_ERROR;
- /* Clear info in config2 */
- HDmemset(config2, 0, sizeof(H5F_vfd_swmr_config_t));
+ /* Clear info in file_config */
+ HDmemset(file_config, 0, sizeof(H5F_vfd_swmr_config_t));
/* Retrieve the VFD SWMR configuration from file_fapl */
- if(H5Pget_vfd_swmr_config(file_fapl, config2) < 0)
+ if(H5Pget_vfd_swmr_config(file_fapl, file_config) < 0)
TEST_ERROR;
/* Verify the retrieved info is NOT the same as config1 */
- if(HDmemcmp(config1, config2, sizeof(H5F_vfd_swmr_config_t)) == 0)
+ if(HDmemcmp(config1, file_config, sizeof(H5F_vfd_swmr_config_t)) == 0)
TEST_ERROR;
- /* Verify the retrieved info is the same as config3 */
- if(HDmemcmp(config2, config3, sizeof(H5F_vfd_swmr_config_t)) != 0)
+ /* Verify the retrieved info is the same as config2 */
+ if(HDmemcmp(config2, file_config, sizeof(H5F_vfd_swmr_config_t)) != 0)
TEST_ERROR;
- /* Closing */
- if(H5Fclose(fid) < 0)
- FAIL_STACK_ERROR;
- if(H5Pclose(file_fapl) < 0)
- FAIL_STACK_ERROR;
-
- /*
- * VDF SWMR READER
+ /*
+ * The file previously opened as writer is not closed.
*/
/* Create a copy of the file access property list */
if((fapl2 = H5Pcreate(H5P_FILE_ACCESS)) < 0)
TEST_ERROR;
- config3->version = H5F__CURR_VFD_SWMR_CONFIG_VERSION;
- config3->tick_len = 4;
- config3->max_lag = 10;
- config3->vfd_swmr_writer = FALSE;
- config3->md_pages_reserved = 2;
- HDstrcpy(config3->md_file_path, "my_md_file");
+ /* Set up as VFD SWMR reader */
+ config2->version = H5F__CURR_VFD_SWMR_CONFIG_VERSION;
+ config2->tick_len = 4;
+ config2->max_lag = 10;
+ config2->vfd_swmr_writer = FALSE;
+ config2->md_pages_reserved = 2;
+ HDstrcpy(config2->md_file_path, MD_FILENAME);
- /* Should succeed in setting the VFD SWMR configuration */
- if(H5Pset_vfd_swmr_config(fapl2, config3) < 0)
+ /* Should succeed in setting the VFD SWMR configuration in fapl2 */
+ if(H5Pset_vfd_swmr_config(fapl2, config2) < 0)
TEST_ERROR;
/* Enable page buffering */
if(H5Pset_page_buffer_size(fapl2, 4096, 0, 0) < 0)
FAIL_STACK_ERROR;
+ /* Should succeed in opening the file */
+ /* Same process open: even though opened with reader configuration,
+ * it just increments the file reference count and uses the writer's
+ * shared file struct */
+ if((fid_read = H5Fopen(FILENAME, H5F_ACC_RDONLY, fapl2)) < 0)
+ TEST_ERROR;
+
+ /* Clear info in file_config */
+ HDmemset(file_config, 0, sizeof(H5F_vfd_swmr_config_t));
+
+ /* Get the file's file access property list */
+ if((file_fapl = H5Fget_access_plist(fid)) < 0)
+ FAIL_STACK_ERROR;
+
+ /* Retrieve the VFD SWMR configuration from file_fapl */
+ if(H5Pget_vfd_swmr_config(file_fapl, file_config) < 0)
+ TEST_ERROR;
+
+ /* Verify that the retrieved config is a writer */
+ if(file_config->vfd_swmr_writer == FALSE)
+ TEST_ERROR;
+ /* Verify that the retrieved config is not the same as the initial configuration */
+ if(file_config->vfd_swmr_writer == config2->vfd_swmr_writer)
+ TEST_ERROR;
+
+ /* Closing */
+ if(H5Fclose(fid_read) < 0)
+ FAIL_STACK_ERROR;
+ if(H5Fclose(fid) < 0)
+ FAIL_STACK_ERROR;
+ if(H5Pclose(file_fapl) < 0)
+ FAIL_STACK_ERROR;
- /* Open the file for reading only */
+ /*
+ * The file opened as writer is closed.
+ */
+ /* Should fail to open the file as VFD SWMR reader: no metadata file */
H5E_BEGIN_TRY {
- fid_read = H5Fopen("myfile", H5F_ACC_RDONLY, fapl2);
+ fid_read = H5Fopen(FILENAME, H5F_ACC_RDONLY, fapl2);
} H5E_END_TRY;
if(fid_read >= 0)
TEST_ERROR;
+ /* Closing */
if(H5Pclose(fapl1) < 0)
FAIL_STACK_ERROR;
if(H5Pclose(fapl2) < 0)
FAIL_STACK_ERROR;
if(H5Pclose(fcpl) < 0)
FAIL_STACK_ERROR;
+
+ /* Free buffers */
if(config1)
HDfree(config1);
if(config2)
HDfree(config2);
- if(config3)
- HDfree(config3);
+ if(file_config)
+ HDfree(file_config);
PASSED()
return 0;
@@ -440,8 +464,8 @@ error:
HDfree(config1);
if(config2)
HDfree(config2);
- if(config3)
- HDfree(config3);
+ if(file_config)
+ HDfree(file_config);
return 1;
} /* test_file_fapl() */
@@ -463,7 +487,7 @@ error:
*-------------------------------------------------------------------------
*/
static unsigned
-test_file_end_tick()
+test_file_end_tick(void)
{
hid_t fid = -1; /* File ID */
hid_t fapl = -1; /* File access property list */
@@ -474,7 +498,7 @@ test_file_end_tick()
TESTING("H5Fvfd_swmr_end_tick() for VFD SWMR");
/* Should succeed without VFD SWMR configured */
- if((fid = H5Fcreate("myfile", H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0)
+ if((fid = H5Fcreate(FILENAME, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0)
TEST_ERROR;
/* Should fail */
@@ -503,7 +527,7 @@ test_file_end_tick()
my_config->max_lag = 3;
my_config->vfd_swmr_writer = TRUE;
my_config->md_pages_reserved = 2;
- HDstrcpy(my_config->md_file_path, "my_md_file");
+ HDstrcpy(my_config->md_file_path, MD_FILENAME);
/* Should succeed in setting the VFD SWMR configuration */
if(H5Pset_vfd_swmr_config(fapl, my_config) < 0)
@@ -522,7 +546,7 @@ test_file_end_tick()
FAIL_STACK_ERROR;
/* Create the file with VFD SWMR configured */
- if((fid = H5Fcreate("myfile", H5F_ACC_TRUNC, fcpl, fapl)) < 0)
+ if((fid = H5Fcreate(FILENAME, H5F_ACC_TRUNC, fcpl, fapl)) < 0)
FAIL_STACK_ERROR;
/* Should succeed */
@@ -534,7 +558,7 @@ test_file_end_tick()
FAIL_STACK_ERROR;
/* Open the file as VFD SWMR writer */
- if((fid = H5Fopen("myfile", H5F_ACC_RDWR, fapl)) < 0)
+ if((fid = H5Fopen(FILENAME, H5F_ACC_RDWR, fapl)) < 0)
TEST_ERROR;
/* Should succeed */
@@ -545,72 +569,431 @@ test_file_end_tick()
if(H5Fclose(fid) < 0)
FAIL_STACK_ERROR;
-#ifdef NOTYET
- /* Open the file as VFD SWMR reader */
- if((fid = H5Fopen("myfile", H5F_ACC_RDONLY, fapl)) < 0)
+ /* Open the file as reader without VFD SWMR configured */
+ if((fid = H5Fopen(FILENAME, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0)
FAIL_STACK_ERROR;
- /* Should succeed */
- if(H5Fvfd_swmr_end_tick(fid) < 0)
+ /* Should fail */
+ H5E_BEGIN_TRY {
+ ret = H5Fvfd_swmr_end_tick(fid);
+ } H5E_END_TRY;
+ if(ret >= 0)
TEST_ERROR;
/* Close the file */
if(H5Fclose(fid) < 0)
FAIL_STACK_ERROR;
-#endif
- /* Open the file as writer without VFD SWMR configured */
- if((fid = H5Fopen("myfile", H5F_ACC_RDWR, H5P_DEFAULT)) < 0)
+ if(H5Pclose(fapl) < 0)
FAIL_STACK_ERROR;
+ if(H5Pclose(fcpl) < 0)
+ FAIL_STACK_ERROR;
+ if(my_config)
+ HDfree(my_config);
- /* Should fail */
+ PASSED()
+ return 0;
+
+error:
H5E_BEGIN_TRY {
- ret = H5Fvfd_swmr_end_tick(fid);
+ H5Pclose(fapl);
+ H5Pclose(fcpl);
+ H5Fclose(fid);
} H5E_END_TRY;
- if(ret >= 0)
- TEST_ERROR;
+
+ if(my_config)
+ HDfree(my_config);
+
+ return 1;
+} /* test_file_end_tick() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_writer_md()
+ *
+ * Purpose: Verify info in the metadata file when:
+ * --creating the HDF5 file
+ * --flushing the HDF5 file
+ * --opening an existing HDF5 file
+ * It will call the internal testing routine
+ * H5F__vfd_swmr_writer_md_test() to do the following:
+ * --Open the metadata file
+ * --Verify the file size is as expected (md_pages_reserved)
+ * --For file create:
+ * --No header magic is found
+ * --For file open or file flush:
+ * --Read and decode the header and index in the metadata file
+ * --Verify info in the header and index read from
+ * the metadata file is as expected (empty index)
+ *
+ * Return: 0 if test is sucessful
+ * 1 if test fails
+ *
+ * Programmer: Vailin Choi; October 2018
+ *
+ *-------------------------------------------------------------------------
+ */
+static unsigned
+test_writer_md(void)
+{
+ hid_t fid = -1; /* File ID */
+ hid_t fapl = -1; /* File access property list */
+ hid_t fcpl = -1; /* File creation property list */
+ H5F_vfd_swmr_config_t *my_config = NULL; /* Configuration for VFD SWMR */
+
+ TESTING("Create/Open/Flush an HDF5 file for VFD SWMR");
+
+ /* Allocate memory for the configuration structure */
+ if((my_config = (H5F_vfd_swmr_config_t *)HDmalloc(sizeof(H5F_vfd_swmr_config_t))) == NULL)
+ FAIL_STACK_ERROR;
+ HDmemset(my_config, 0, sizeof(H5F_vfd_swmr_config_t));
+
+ /* Create a copy of the file access property list */
+ if((fapl = H5Pcreate(H5P_FILE_ACCESS)) < 0)
+ FAIL_STACK_ERROR;
+
+ /* Set up the VFD SWMR configuration */
+ my_config->version = H5F__CURR_VFD_SWMR_CONFIG_VERSION;
+ my_config->tick_len = 1;
+ my_config->max_lag = 3;
+ my_config->vfd_swmr_writer = TRUE;
+ my_config->md_pages_reserved = 1;
+ HDstrcpy(my_config->md_file_path, MD_FILENAME);
+
+ /* Set the VFD SWMR configuration in fapl */
+ if(H5Pset_vfd_swmr_config(fapl, my_config) < 0)
+ FAIL_STACK_ERROR;
+
+ /* Enable page buffering */
+ if(H5Pset_page_buffer_size(fapl, 4096, 0, 0) < 0)
+ FAIL_STACK_ERROR;
+
+ /* Create a copy of the file creation property list */
+ if((fcpl = H5Pcreate(H5P_FILE_CREATE)) < 0)
+ FAIL_STACK_ERROR
+
+ /* Set file space strategy */
+ if(H5Pset_file_space_strategy(fcpl, H5F_FSPACE_STRATEGY_PAGE, FALSE, (hsize_t)1) < 0)
+ FAIL_STACK_ERROR;
+
+ /* Create an HDF5 file with VFD SWMR configured */
+ if((fid = H5Fcreate(FILENAME, H5F_ACC_TRUNC, fcpl, fapl)) < 0)
+ FAIL_STACK_ERROR;
+
+ /* Verify info in metadata file when creating the HDF5 file */
+ if(H5F__vfd_swmr_writer_md_test(fid, TRUE) < 0)
+ TEST_ERROR
+
+ /* Flush the HDF5 file */
+ if(H5Fflush(fid, H5F_SCOPE_GLOBAL) < 0)
+ FAIL_STACK_ERROR
+
+ /* Verify info in metadata file when flushing the HDF5 file */
+ if(H5F__vfd_swmr_writer_md_test(fid, FALSE) < 0)
+ TEST_ERROR
/* Close the file */
if(H5Fclose(fid) < 0)
FAIL_STACK_ERROR;
- /* Open the file as reader without VFD SWMR configured */
- if((fid = H5Fopen("myfile", H5F_ACC_RDONLY, H5P_DEFAULT)) < 0)
+ /* Re-open the file as VFD SWMR writer */
+ if((fid = H5Fopen(FILENAME, H5F_ACC_RDWR, fapl)) < 0)
+ TEST_ERROR;
+
+ /* Verify info in metadata file when reopening the HDF5 file */
+ if(H5F__vfd_swmr_writer_md_test(fid, FALSE) < 0)
+ TEST_ERROR
+
+ /* Closing */
+ if(H5Fclose(fid) < 0)
+ FAIL_STACK_ERROR;
+ if(H5Pclose(fapl) < 0)
+ FAIL_STACK_ERROR;
+ if(H5Pclose(fcpl) < 0)
FAIL_STACK_ERROR;
- /* Should fail */
+ if(my_config)
+ HDfree(my_config);
+
+ PASSED()
+ return 0;
+
+error:
+ if(my_config)
+ HDfree(my_config);
+
H5E_BEGIN_TRY {
- ret = H5Fvfd_swmr_end_tick(fid);
+ H5Pclose(fapl);
+ H5Pclose(fcpl);
+ H5Fclose(fid);
} H5E_END_TRY;
- if(ret >= 0)
- TEST_ERROR;
+
+ return 1;
+} /* test_writer_md() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_writer_update_md()
+ *
+ * Purpose: Verify info in the metadata file after update with the
+ * constructed index: (A), (B), (C), (D)
+ * It will call the internal testing routine
+ * H5F__vfd_swmr_writer_update_md_test() to do the following:
+ * --Update the metadata file with the input index via the
+ * internal library routine H5F_update_vfd_swmr_metadata_file()
+ * --Verify the entries in the delayed list is as expected
+ * (input: num_insert_dl, num_remove_dl)
+ * --Open the metadata file, read and decode the header and index
+ * --Verify info in the header and index just read from the
+ * metadatea file is as expected (input: num_entries and index)
+ *
+ * Return: 0 if test is sucessful
+ * 1 if test fails
+ *
+ * Programmer: Vailin Choi; October 2018
+ *
+ *-------------------------------------------------------------------------
+ */
+static unsigned
+test_writer_update_md(void)
+{
+ hid_t fid = -1; /* File ID */
+ hid_t fid_read = -1; /* File ID for the reader */
+ hid_t fapl = -1; /* File access property list */
+ hid_t fapl2 = -1; /* File access property list */
+ hid_t fcpl = -1; /* File creation property list */
+ unsigned num_entries = 10; /* Number of entries in the index */
+ unsigned i = 0; /* Local index variables */
+ uint8_t *buf = NULL; /* Data page from the page buffer */
+ hid_t dcpl = -1; /* Dataset creation property list */
+ hid_t sid = -1; /* Dataspace ID */
+ hid_t did = -1; /* Dataset ID */
+ int *rwbuf = NULL; /* Data buffer for writing */
+ H5O_info_t oinfo; /* Object metadata information */
+ char dname[50]; /* Name of dataset */
+ hsize_t dims[2] = {50, 20}; /* Dataset dimension sizes */
+ hsize_t max_dims[2] = {H5S_UNLIMITED, H5S_UNLIMITED}; /* Dataset maximum dimension sizes */
+ hsize_t chunk_dims[2] = {2, 5}; /* Dataset chunked dimension sizes */
+ H5FD_vfd_swmr_idx_entry_t *index = NULL; /* Pointer to the index entries */
+ H5F_vfd_swmr_config_t *my_config = NULL; /* Configuration for VFD SWMR */
+
+ TESTING("Updating the metadata file for VFD SWMR writer");
+
+ /* Allocate memory for the configuration structure */
+ if((my_config = (H5F_vfd_swmr_config_t *)HDmalloc(sizeof(H5F_vfd_swmr_config_t))) == NULL)
+ FAIL_STACK_ERROR;
+ HDmemset(my_config, 0, sizeof(H5F_vfd_swmr_config_t));
+
+ /* Create a copy of the file access property list */
+ if((fapl = H5Pcreate(H5P_FILE_ACCESS)) < 0)
+ FAIL_STACK_ERROR;
+
+ /* Set up the VFD SWMR configuration */
+ my_config->version = H5F__CURR_VFD_SWMR_CONFIG_VERSION;
+ my_config->tick_len = 1;
+ my_config->max_lag = 3;
+ my_config->vfd_swmr_writer = TRUE;
+ my_config->md_pages_reserved = 2;
+ HDstrcpy(my_config->md_file_path, MD_FILENAME);
+
+ /* Set the VFD SWMR configuration in fapl */
+ if(H5Pset_vfd_swmr_config(fapl, my_config) < 0)
+ FAIL_STACK_ERROR;
+
+ /* Enable page buffering */
+ if(H5Pset_page_buffer_size(fapl, FS_PAGE_SIZE, 0, 0) < 0)
+ FAIL_STACK_ERROR;
+
+ /* Create a copy of the file creation property list */
+ if((fcpl = H5Pcreate(H5P_FILE_CREATE)) < 0)
+ FAIL_STACK_ERROR
+
+ /* Set file space strategy */
+ if(H5Pset_file_space_strategy(fcpl, H5F_FSPACE_STRATEGY_PAGE, FALSE, (hsize_t)1) < 0)
+ FAIL_STACK_ERROR;
+ if(H5Pset_file_space_page_size(fcpl, FS_PAGE_SIZE) < 0)
+ FAIL_STACK_ERROR;
+
+ /* Create an HDF5 file with VFD SWMR configured */
+ if((fid = H5Fcreate(FILENAME, H5F_ACC_TRUNC, fcpl, fapl)) < 0)
+ FAIL_STACK_ERROR;
+
+ /* Verify info in the metadata file when creating an HDF5 file */
+ if(H5F__vfd_swmr_writer_md_test(fid, TRUE) < 0)
+ TEST_ERROR
+
+ /* Allocate num_entries for the data buffer */
+ if((buf = (uint8_t *)HDmalloc((num_entries * FS_PAGE_SIZE * sizeof(uint8_t)))) == NULL)
+ FAIL_STACK_ERROR;
+
+ /* Allocate memory for num_entries index */
+ if(NULL == (index = (H5FD_vfd_swmr_idx_entry_t *)HDcalloc(num_entries, sizeof(H5FD_vfd_swmr_idx_entry_t))))
+ FAIL_STACK_ERROR;
+
+ /* (A) Construct index for updating the metadata file */
+ for(i = 0; i < num_entries; i++) {
+ index[i].hdf5_page_offset = (uint64_t)my_config->md_pages_reserved;
+ index[i].md_file_page_offset = 0;
+ index[i].length = (uint32_t)FS_PAGE_SIZE;
+ index[i].entry_ptr = (void *)&buf[i];
+ }
+
+ /* Update with index and verify info in the metadata file */
+ /* Also verify that 0/0 entries are inserted/removed to/from the delayed list */
+ if(H5F__vfd_swmr_writer_update_md_test(fid, num_entries, index, 0, 0) < 0)
+ TEST_ERROR
+
+ /* Create dataset creation property list */
+ if((dcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0)
+ FAIL_STACK_ERROR
+
+ /* Set to use chunked dataset */
+ if(H5Pset_chunk(dcpl, 2, chunk_dims) < 0)
+ FAIL_STACK_ERROR
+
+ /* Create dataspace */
+ if((sid = H5Screate_simple(2, dims, max_dims)) < 0)
+ FAIL_STACK_ERROR
+
+ /* Perform activities to ensure that max_lag ticks elapse */
+ for(i = 0; i < 500; i++) {
+
+ /* Create a chunked dataset */
+ sprintf(dname, "dset %d", i);
+ if((did = H5Dcreate2(fid, dname, H5T_NATIVE_INT, sid, H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0)
+ FAIL_STACK_ERROR
+
+ /* Get dataset object header address */
+ if(H5Oget_info2(did, &oinfo, H5O_INFO_BASIC) < 0)
+ FAIL_STACK_ERROR
+
+ /* Close the dataset */
+ if(H5Dclose(did) < 0)
+ FAIL_STACK_ERROR
+ }
+
+ /* (B) Update every other entry in the index */
+ for(i = 0; i < num_entries; i+= 2)
+ index[i].entry_ptr = (void *)&buf[i];
+
+ /* Update with index and verify info in the metadata file */
+ /* Also verify that 5/0 entries are inserted/removed to/from the delayed list */
+ if(H5F__vfd_swmr_writer_update_md_test(fid, num_entries, index, 5, 0) < 0)
+ TEST_ERROR
+
+ /* Allocate memory for the read/write buffer */
+ if((rwbuf = (int *)HDmalloc(sizeof(int) * (50 * 20))) == NULL)
+ FAIL_STACK_ERROR;
+ for(i = 0; i < (50 * 20); i++)
+ rwbuf[i] = (int)i;
+
+ /* Perform activities to ensure that max_lag ticks elapse */
+ for(i = 0; i < 500; i++) {
+ /* Open the dataset */
+ sprintf(dname, "dset %d", i);
+ if((did = H5Dopen2(fid, dname, H5P_DEFAULT)) < 0)
+ FAIL_STACK_ERROR
+
+ /* Write to the dataset */
+ if(H5Dwrite(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, rwbuf) < 0)
+ FAIL_STACK_ERROR
+
+ /* Get dataset object info */
+ if(H5Oget_info2(did, &oinfo, H5O_INFO_BASIC) < 0)
+ FAIL_STACK_ERROR
+
+ /* Close the dataset */
+ if(H5Dclose(did) < 0)
+ FAIL_STACK_ERROR
+ }
+
+ /* (C) Update every 3 entry in the index */
+ for(i = 0; i < num_entries; i+= 3)
+ index[i].entry_ptr = (void *)&buf[i];
+
+ /* Update with index and verify info in the metadata file */
+ /* Also verify that 4/5 entries are inserted/removed to/from the delayed list */
+ if(H5F__vfd_swmr_writer_update_md_test(fid, num_entries, index, 4, 5) < 0)
+ TEST_ERROR
+
+ /* Clear the read/write buffer */
+ HDmemset(rwbuf, 0, sizeof(sizeof(int) * (50 * 20)));
+
+ /* Perform activities to ensure that max_lag ticks elapse */
+ for(i = 0; i < 500; i++) {
+ /* Open the dataset */
+ sprintf(dname, "dset %d", i);
+ if((did = H5Dopen2(fid, dname, H5P_DEFAULT)) < 0)
+ FAIL_STACK_ERROR
+
+ /* Read from the dataset */
+ if(H5Dread(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, rwbuf) < 0)
+ FAIL_STACK_ERROR
+
+ /* Get dataset object info */
+ if(H5Oget_info2(did, &oinfo, H5O_INFO_BASIC) < 0)
+ FAIL_STACK_ERROR
+
+ /* Close the dataset */
+ if(H5Dclose(did) < 0)
+ FAIL_STACK_ERROR
+ }
+
+ /* (D) Update two entries in the index */
+ index[1].entry_ptr = (void *)&buf[1];
+ index[5].entry_ptr = (void *)&buf[5];
+
+ /* Update with index and verify info in the metadata file */
+ /* Also verify that 2/4 entries are inserted/removed to/from the delayed list */
+ if(H5F__vfd_swmr_writer_update_md_test(fid, num_entries, index, 2, 4) < 0)
+ TEST_ERROR
/* Close the file */
if(H5Fclose(fid) < 0)
FAIL_STACK_ERROR;
+ if(H5Sclose(sid) < 0)
+ FAIL_STACK_ERROR;
+ if(H5Pclose(dcpl) < 0)
+ FAIL_STACK_ERROR;
+
if(H5Pclose(fapl) < 0)
FAIL_STACK_ERROR;
if(H5Pclose(fcpl) < 0)
FAIL_STACK_ERROR;
+
if(my_config)
HDfree(my_config);
+ if(buf)
+ HDfree(buf);
+ if(rwbuf)
+ HDfree(rwbuf);
+
PASSED()
return 0;
error:
+ if(my_config)
+ HDfree(my_config);
+ if(buf)
+ HDfree(buf);
+ if(rwbuf)
+ HDfree(rwbuf);
+ if(index)
+ HDfree(index);
+
H5E_BEGIN_TRY {
+ H5Dclose(did);
+ H5Sclose(sid);
+ H5Pclose(dcpl);
H5Pclose(fapl);
H5Pclose(fcpl);
H5Fclose(fid);
} H5E_END_TRY;
- if(my_config)
- HDfree(my_config);
-
return 1;
-} /* test_file_end_tick() */
+} /* test_writer_update_md() */
/*-------------------------------------------------------------------------
@@ -663,7 +1046,8 @@ main(void)
nerrors += test_file_fapl();
nerrors += test_file_end_tick();
- h5_clean_files(FILENAME, fapl);
+ nerrors += test_writer_md();
+ nerrors += test_writer_update_md();
if(nerrors)
goto error;