diff --git a/MANIFEST b/MANIFEST index 93b5eebcf8..5427596c2a 100644 --- a/MANIFEST +++ b/MANIFEST @@ -835,6 +835,8 @@ ./test/fillval.c ./test/flush1.c ./test/flush2.c +./test/fsync_tests.c +./test/fsync_tests.sh ./test/gen_bad_ohdr.c _DO_NOT_DISTRIBUTE_ ./test/gen_bogus.c _DO_NOT_DISTRIBUTE_ ./test/gen_cross.c _DO_NOT_DISTRIBUTE_ diff --git a/src/H5FD.c b/src/H5FD.c index 5d25f2043c..e0ae05c054 100644 --- a/src/H5FD.c +++ b/src/H5FD.c @@ -2186,6 +2186,11 @@ H5FDaio_read(H5FD_t *file, HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file pointer") } + if ( ( type < H5FD_MEM_DEFAULT ) || ( type >= H5FD_MEM_NTYPES ) ) { + + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "mem type out of range"); + } + /* Get the default dataset transfer property list if the user * didn't provide one */ @@ -2288,6 +2293,11 @@ H5FDaio_write(H5FD_t *file, HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file pointer") } + if ( ( type < H5FD_MEM_DEFAULT ) || ( type >= H5FD_MEM_NTYPES ) ) { + + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "mem type out of range"); + } + /* Get the default dataset transfer property list if the user * didn't provide one */ @@ -2310,8 +2320,17 @@ H5FDaio_write(H5FD_t *file, } if ( ( ctlblk_ptr_ptr == NULL ) || - ( *ctlblk_ptr_ptr != NULL ) ) { + ( (void *)(*ctlblk_ptr_ptr) != NULL ) ) { +#if 0 /* JRM */ + if ( ctlblk_ptr_ptr == NULL ) { + HDfprintf(stdout, "%s: ctlblk_ptr_ptr == NULL.\n", FUNC); + } + if ( ( ctlblk_ptr_ptr != NULL ) && + ( *ctlblk_ptr_ptr != NULL ) ) { + HDfprintf(stdout, "%s: *ctlblk_ptr_ptr != NULL.\n", FUNC); + } +#endif /* JRM */ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "bad ctlblk_ptr_ptr") } @@ -2639,7 +2658,7 @@ H5FDaio_cancel(H5FD_t *file, "ctlblk_ptr NULL on entry") } - result = H5FDaio_cancel(file, ctlblk_ptr); + result = H5FD_aio_cancel(file, ctlblk_ptr); if ( result < 0 ) { diff --git a/src/H5FDcore.c b/src/H5FDcore.c index 0fcc10afe5..f45ca63795 100644 --- a/src/H5FDcore.c +++ b/src/H5FDcore.c @@ -1137,7 +1137,12 @@ done: /*------------------------------------------------------------------------- * Function: H5FD_core_fsync * - * Purpose: Fsync the backing store file if there is one. + * Purpose: Flush and fsync the backing store file if there is one. + * + * This is a somewhat novel interpretation of fsync -- but + * one that gives the results that one would expect. If it + * has been written to the core file driver, it winds up on + * disk after the fsync (assuming there is a backing file). * * Return: Success: 0 * @@ -1160,7 +1165,7 @@ H5FD_core_fsync(H5FD_t *file, herr_t ret_value=SUCCEED; /* Return value */ int result; - FUNC_ENTER_NOAPI(H5FD_core_flush, FAIL) + FUNC_ENTER_NOAPI(H5FD_core_fsync, FAIL) HDassert( file != NULL ); @@ -1170,6 +1175,11 @@ H5FD_core_fsync(H5FD_t *file, if ( ( core_file->fd >= 0 ) && ( core_file->backing_store ) ) { + /* Flush any changed buffers */ + if(H5FD_core_flush(core_file, (hid_t)-1, TRUE) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to flush file") + + result = HDfsync(core_file->fd); if ( result != 0 ) { diff --git a/src/H5FDdirect.c b/src/H5FDdirect.c index 5f713e8b51..71f3936142 100644 --- a/src/H5FDdirect.c +++ b/src/H5FDdirect.c @@ -29,6 +29,13 @@ * this file. */ /* #define _XOPEN_SOURCE 600 */ +/* JRM */ +#if 0 +#define __BSD_VISIBLE 1 +#include +#endif +/* JRM */ + #include "H5private.h" /* Generic Functions */ #include "H5Eprivate.h" /* Error handling */ #include "H5Fprivate.h" /* File access */ diff --git a/src/H5FDfamily.c b/src/H5FDfamily.c index ead68da78f..bced6e630a 100644 --- a/src/H5FDfamily.c +++ b/src/H5FDfamily.c @@ -1716,7 +1716,7 @@ H5FD_family_aio_discard_ctlblk(H5FD_family_aio_ctlblk_t *ctlblk_ptr) } if ( ( ctlblk_ptr->subctlblks == NULL ) || - ( ctlblk_ptr->array_len <= 1 ) ) { + ( ctlblk_ptr->array_len < 1 ) ) { HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, \ "subctlblks fields corrupt?") @@ -1830,7 +1830,7 @@ H5FD_family_aio_extend_ctlblk(H5FD_family_aio_ctlblk_t *ctlblk_ptr) } if ( ( ctlblk_ptr->subctlblks == NULL ) || - ( ctlblk_ptr->array_len <= 1 ) ) { + ( ctlblk_ptr->array_len < 1 ) ) { HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, \ "subctlblks fields corrupt?") @@ -2057,7 +2057,7 @@ H5FD_family_aio_read(H5FD_t *file, HGOTO_ERROR(H5E_INTERNAL, H5E_SYSTEM, FAIL, \ "NULL ctlblk_ptr or bad ctlblk magic") - } else if ( ( ctlblk_ptr->array_len <= 1 ) || + } else if ( ( ctlblk_ptr->array_len < 1 ) || ( ctlblk_ptr->num_subctlblks != 0 ) || ( ctlblk_ptr->subctlblks == NULL ) || ( (ctlblk_ptr->subctlblks)[0].magic != @@ -2116,6 +2116,8 @@ H5FD_family_aio_read(H5FD_t *file, } } + subctlblk_ptr = NULL; + result = H5FDaio_read(family_file->memb[sub_file_num], type, memb_dxpl_id, subfile_addr, subfile_size, buffer_remaining, &subctlblk_ptr); @@ -2236,7 +2238,7 @@ H5FD_family_aio_write(H5FD_t *file, H5P_genplist_t * plist; /* Property list pointer */ H5FD_family_t * family_file; void * buffer_remaining; - void * subctlblk_ptr = NULL; + void * subctlblk_ptr; H5FD_family_aio_ctlblk_t * ctlblk_ptr = NULL; FUNC_ENTER_NOAPI(H5FD_family_aio_write, FAIL) @@ -2296,7 +2298,7 @@ H5FD_family_aio_write(H5FD_t *file, HGOTO_ERROR(H5E_INTERNAL, H5E_SYSTEM, FAIL, \ "NULL ctlblk_ptr or bad ctlblk magic") - } else if ( ( ctlblk_ptr->array_len <= 1 ) || + } else if ( ( ctlblk_ptr->array_len < 1 ) || ( ctlblk_ptr->num_subctlblks != 0 ) || ( ctlblk_ptr->subctlblks == NULL ) || ( (ctlblk_ptr->subctlblks)[0].magic != @@ -2355,6 +2357,8 @@ H5FD_family_aio_write(H5FD_t *file, } } + subctlblk_ptr = NULL; + result = H5FDaio_write(family_file->memb[sub_file_num], type, memb_dxpl_id, subfile_addr, subfile_size, buffer_remaining, &subctlblk_ptr); @@ -2902,14 +2906,14 @@ H5FD_family_aio_fsync(H5FD_t *file, herr_t ret_value = SUCCEED; /* Return value */ herr_t result; hbool_t success = FALSE; - int i; - int num_sub_files; + unsigned int i; + unsigned int num_sub_files; H5FD_family_t * family_file; H5FD_t * tgt_file; H5FD_family_aio_ctlblk_t * ctlblk_ptr = NULL; void * subctlblk_ptr; - FUNC_ENTER_NOAPI(H5FD_family_aio_finish, FAIL) + FUNC_ENTER_NOAPI(H5FD_family_aio_fsync, FAIL) if ( ( file == NULL ) || ( file->cls == NULL ) || @@ -2950,7 +2954,7 @@ H5FD_family_aio_fsync(H5FD_t *file, "bad sub control block array") } - for ( i = i; i < num_sub_files; i++ ) { + for ( i = 0; i < num_sub_files; i++ ) { if ( (ctlblk_ptr->subctlblks[i]).magic != H5FD_FAMILY_AIO_SUBCTLBLK_T__MAGIC ) { @@ -3158,8 +3162,8 @@ H5FD_family_fsync(H5FD_t *file, { herr_t ret_value = SUCCEED; /* Return value */ herr_t result; - int i; - int num_sub_files; + unsigned int i; + unsigned int num_sub_files; H5FD_family_t * family_file; H5FD_t * tgt_file; @@ -3179,6 +3183,11 @@ H5FD_family_fsync(H5FD_t *file, tgt_file = family_file->memb[i]; + if ( tgt_file == NULL ) { + + HGOTO_ERROR(H5E_ARGS, H5E_SYSTEM, FAIL, "NULL tgt file.") + } + result = H5FDfsync(tgt_file, dxpl_id); if ( result < 0 ) { diff --git a/src/H5FDmulti.c b/src/H5FDmulti.c index 1eb557c3f2..fef9e6e07a 100644 --- a/src/H5FDmulti.c +++ b/src/H5FDmulti.c @@ -2233,6 +2233,8 @@ H5FD_multi_aio_alloc_ctlblk(H5FD_multi_aio_ctlblk_t **ctlblk_ptr_ptr) (ctlblk_ptr->sub_ctlblks[i]).finished = FALSE; } + *ctlblk_ptr_ptr = ctlblk_ptr; + return(0); } /* H5FD_multi_aio_alloc_ctlblk() */ @@ -2368,7 +2370,7 @@ H5FD_multi_aio_read(H5FD_t *file, H5FD_multi_t * multi_file; H5FD_t * tgt_file; void * subctlblk_ptr = NULL; - H5FD_multi_aio_ctlblk_t * ctlblk_ptr; + H5FD_multi_aio_ctlblk_t * ctlblk_ptr = NULL; /* Clear the error stack */ H5Eclear2(H5E_DEFAULT); @@ -2535,7 +2537,7 @@ H5FD_multi_aio_write(H5FD_t *file, H5FD_multi_t * multi_file; H5FD_t * tgt_file; void * subctlblk_ptr = NULL; - H5FD_multi_aio_ctlblk_t * ctlblk_ptr; + H5FD_multi_aio_ctlblk_t * ctlblk_ptr = NULL; /* Clear the error stack */ H5Eclear2(H5E_DEFAULT); @@ -3114,7 +3116,7 @@ H5FD_multi_aio_fsync(H5FD_t *file, H5FD_multi_t * multi_file; H5FD_t * drivers[H5FD_MEM_NTYPES]; void * ctlblks[H5FD_MEM_NTYPES]; - H5FD_multi_aio_ctlblk_t * ctlblk_ptr; + H5FD_multi_aio_ctlblk_t * ctlblk_ptr = NULL; /* Clear the error stack */ H5Eclear2(H5E_DEFAULT); @@ -3157,6 +3159,8 @@ H5FD_multi_aio_fsync(H5FD_t *file, H5Epush_ret(func, H5E_ERR_CLS, H5E_VFL, H5E_AIOSYNCFAIL, \ "sub aio fsync request failed.", -1) } + + i++; } /* if all goes well, allocate the control block and initialize it */ diff --git a/src/H5FDsec2.c b/src/H5FDsec2.c index 04120409c5..adb0e73d45 100644 --- a/src/H5FDsec2.c +++ b/src/H5FDsec2.c @@ -28,6 +28,7 @@ /* Interface initialization */ #define H5_INTERFACE_INIT_FUNC H5FD_sec2_init_interface +#include #include #include "H5private.h" /* Generic Functions */ @@ -51,7 +52,7 @@ typedef enum { } H5FD_sec2_file_op_t; /* - * structure used to store the instance of struct aiocb associated with + * structure used to store the instance of struct HDaiocb associated with * each asynchronous operation, along with such data about the operation * needed for its management. * @@ -99,7 +100,7 @@ typedef struct H5FD_sec2_aio_ctlblk_t { void *buf; struct H5FD_sec2_aio_ctlblk_t * next_ptr; struct H5FD_sec2_aio_ctlblk_t * prev_ptr; - struct aiocb ctlblk; + struct HDaiocb ctlblk; } H5FD_sec2_aio_ctlblk_t; @@ -1211,7 +1212,7 @@ H5FD_sec2_aio_alloc_ctlblk(H5FD_sec2_aio_ctlblk_t **ctlblk_ptr_ptr) ctlblk_ptr->prev_ptr = NULL; /* zero the posix control block as recommended */ - bzero((void *)(&(ctlblk_ptr->ctlblk)), sizeof(struct aiocb)); + HDmemset((void *)(&(ctlblk_ptr->ctlblk)), 0, sizeof(struct HDaiocb)); *ctlblk_ptr_ptr = ctlblk_ptr; @@ -1267,7 +1268,7 @@ H5FD_sec2_aio_discard_ctlblk(H5FD_sec2_aio_ctlblk_t *ctlblk_ptr) ctlblk_ptr->prev_ptr = NULL; /* zero the posix control block */ - bzero((void *)(&(ctlblk_ptr->ctlblk)), sizeof(struct aiocb)); + HDmemset((void *)(&(ctlblk_ptr->ctlblk)), 0, sizeof(struct HDaiocb)); ctlblk_ptr = H5FL_FREE(H5FD_sec2_aio_ctlblk_t, ctlblk_ptr); @@ -1350,6 +1351,20 @@ H5FD_sec2_aio_read(H5FD_t *file, HDassert( ctlblk_ptr_ptr != NULL ); HDassert( *ctlblk_ptr_ptr == NULL ); + /* setup the file pointer */ + file_ptr = (H5FD_sec2_t *)file; + + /* Check for overflow conditions */ + if ( ! H5F_addr_defined(addr) ) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, \ + "addr undefined, addr = %llu", (unsigned long long)addr) + if ( REGION_OVERFLOW(addr, size) ) + HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, \ + "addr overflow, addr = %llu", (unsigned long long)addr) + if ( (addr + size) > file_ptr->eoa ) + HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, \ + "addr overflow, addr = %llu", (unsigned long long)addr) + /* allocate the control block */ result = H5FD_sec2_aio_alloc_ctlblk(&ctlblk_ptr); @@ -1366,9 +1381,6 @@ H5FD_sec2_aio_read(H5FD_t *file, "NULL ctlblk_ptr or bad ctlblk magic") } - /* setup the file pointer */ - file_ptr = (H5FD_sec2_t *)file; - /* setup the control block */ ctlblk_ptr->file_ptr = (H5FD_sec2_t *)file; ctlblk_ptr->op = H5FD_SEC2_AIO_OP__READ; @@ -1397,7 +1409,7 @@ H5FD_sec2_aio_read(H5FD_t *file, * haven't succeeded in queueing the read by the time we do a * wait on it. */ - posix_result = aio_read(&(ctlblk_ptr->ctlblk)); + posix_result = HDaio_read(&(ctlblk_ptr->ctlblk)); if ( posix_result != 0 ) { @@ -1414,14 +1426,14 @@ H5FD_sec2_aio_read(H5FD_t *file, #if H5FD_SEC2_AIO_READ__DEBUG HDfprintf(stdout, - "%s: aio_read(ctlblk) failed. errno = %d (%s)\n", + "%s: HDaio_read(ctlblk) failed. errno = %d (%s)\n", FUNC, errno, strerror(errno)); HDfprintf(stdout, "%s: offset/size = %lld/%d\n", FUNC, (long long)addr, (int)size); #endif /* H5FD_SEC2_AIO_READ__DEBUG */ HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, \ - "call to aio_read() failed.") + "call to HDaio_read() failed.") } } else { @@ -1537,6 +1549,20 @@ H5FD_sec2_aio_write(H5FD_t *file, HDassert( ctlblk_ptr_ptr != NULL ); HDassert( *ctlblk_ptr_ptr == NULL ); + /* setup the file pointer */ + file_ptr = (H5FD_sec2_t *)file; + + /* Check for overflow conditions */ + if ( ! H5F_addr_defined(addr) ) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, \ + "addr undefined, addr = %llu", (unsigned long long)addr) + if ( REGION_OVERFLOW(addr, size) ) + HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, \ + "addr overflow, addr = %llu", (unsigned long long)addr) + if ( (addr + size) > file_ptr->eoa ) + HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, \ + "addr overflow, addr = %llu", (unsigned long long)addr) + /* allocate the control block */ result = H5FD_sec2_aio_alloc_ctlblk(&ctlblk_ptr); @@ -1553,9 +1579,6 @@ H5FD_sec2_aio_write(H5FD_t *file, "NULL ctlblk_ptr or bad ctlblk magic") } - /* setu the file pointer */ - file_ptr = (H5FD_sec2_t *)file; - /* setup the control block */ ctlblk_ptr->file_ptr = (H5FD_sec2_t *)file; ctlblk_ptr->op = H5FD_SEC2_AIO_OP__WRITE; @@ -1583,7 +1606,7 @@ H5FD_sec2_aio_write(H5FD_t *file, * haven't succeeded in queueing the write by the time we do a * wait on it. */ - posix_result = aio_write(&(ctlblk_ptr->ctlblk)); + posix_result = HDaio_write(&(ctlblk_ptr->ctlblk)); if ( posix_result != 0 ) { @@ -1600,14 +1623,14 @@ H5FD_sec2_aio_write(H5FD_t *file, #if H5FD_SEC2_AIO_WRITE__DEBUG HDfprintf(stdout, - "%s: aio_write(ctlblk) failed. errno = %d (%s)\n", + "%s: HDaio_write(ctlblk) failed. errno = %d (%s)\n", FUNC, errno, strerror(errno)); HDfprintf(stdout, "%s: offset/size = %lld/%d\n", FUNC, (long long)addr, (int)size); #endif /* H5FD_SEC2_AIO_WRITE__DEBUG */ HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, \ - "call to aio_write() failed.") + "call to HDaio_write() failed.") } } else { @@ -1686,15 +1709,15 @@ done: * If the asynchronous operation indicated by the supplied * control block has been queued and is not known to be * complete (i.e. status is H5FD_SEC2_AIO_STATUS__QUEUED), - * test completion status with aio_error(). + * test completion status with HDaio_error(). * - * If aio_error() returns either 0 or any error code other + * If HDaio_error() returns either 0 or any error code other * than EINPROGRESS, load the error code into the control * block's err_num field, set the control block's status * field to H5FD_SEC2_AIO_STATUS__COMPLETE, set *done_ptr * to TRUE, and return success. * - * If aio_error() returns EAGAIN, simply set *done_ptr to + * If HDaio_error() returns EAGAIN, simply set *done_ptr to * FALSE and return success. * * If the supplied control block is invalid, or if status @@ -1758,18 +1781,18 @@ H5FD_sec2_aio_test(hbool_t *done_ptr, switch ( cb_ptr->op ) { case H5FD_SEC2_AIO_OP__READ: - posix_result = aio_read(&(cb_ptr->ctlblk)); + posix_result = HDaio_read(&(cb_ptr->ctlblk)); break; case H5FD_SEC2_AIO_OP__WRITE: - posix_result = aio_write(&(cb_ptr->ctlblk)); + posix_result = HDaio_write(&(cb_ptr->ctlblk)); break; case H5FD_SEC2_AIO_OP__FSYNC: - /* not sure we want to do this with aio_fsync() -- + /* not sure we want to do this with HDaio_fsync() -- * revisit this issue at some point. */ - posix_result = aio_fsync(O_SYNC, &(cb_ptr->ctlblk)); + posix_result = HDaio_fsync(O_SYNC, &(cb_ptr->ctlblk)); break; default: @@ -1810,7 +1833,7 @@ H5FD_sec2_aio_test(hbool_t *done_ptr, break; case H5FD_SEC2_AIO_STATUS__QUEUED: - posix_result = aio_error(&(cb_ptr->ctlblk)); + posix_result = HDaio_error(&(cb_ptr->ctlblk)); if ( posix_result == EINPROGRESS ) { @@ -1912,7 +1935,7 @@ H5FD_sec2_aio_wait(void *ctlblk_ptr) herr_t ret_value = SUCCEED; /* Return value */ herr_t result; int posix_result; - const struct aiocb * aiocb_list[1] = { NULL }; + const struct HDaiocb * aiocb_list[1] = { NULL }; H5FD_sec2_aio_ctlblk_t * cb_ptr = NULL; H5FD_sec2_t * file_ptr = NULL; @@ -1955,33 +1978,33 @@ H5FD_sec2_aio_wait(void *ctlblk_ptr) case H5FD_SEC2_AIO_OP__READ: case H5FD_SEC2_AIO_OP__WRITE: /* for an asynchronous read or write, we can use - * aio_suspend() to wait for completion of the operation. + * HDaio_suspend() to wait for completion of the operation. */ aiocb_list[0] = &(cb_ptr->ctlblk); - posix_result = aio_suspend(aiocb_list, 1, NULL); + posix_result = HDaio_suspend(aiocb_list, 1, NULL); if ( posix_result != 0 ) { #if H5FD_SEC2_AIO_WAIT__DEBUG HDfprintf(stdout, - "%s: aio_suspend() failed with errno = %d (%s).\n", + "%s: HDaio_suspend() failed with errno = %d (%s).\n", FUNC, errno, strerror(errno)); #endif /* H5FD_SEC2_AIO_WAIT__DEBUG */ HGOTO_ERROR(H5E_IO, H5E_FILE, FAIL, \ - "aio_suspend() failed."); + "HDaio_suspend() failed."); } /* at this point, we know that the operation has * completed, but we don't have its error return. - * Need to call aio_error() for this. Rather than + * Need to call HDaio_error() for this. Rather than * duplicate code, fall through to the next item * in the case statement. */ /***** INTENTIONAL FALL THROUGH *****/ case H5FD_SEC2_AIO_OP__FSYNC: - /* can't use aio_suspend() to wait for the completion - * of an aio_fsync(), so busy wait instead using - * repeated calls to aio_error(). + /* can't use HDaio_suspend() to wait for the completion + * of an HDaio_fsync(), so busy wait instead using + * repeated calls to HDaio_error(). * * In the case of a fall through from the above, * case, we should only make one pass through the @@ -1989,7 +2012,7 @@ H5FD_sec2_aio_wait(void *ctlblk_ptr) */ do { - posix_result = aio_error(&(cb_ptr->ctlblk)); + posix_result = HDaio_error(&(cb_ptr->ctlblk)); if ( posix_result == 0 ) { /* successful completion */ @@ -2088,7 +2111,7 @@ done: *------------------------------------------------------------------------- */ -#define H5FD_SEC2_AIO_FINISH__DEBUG 1 +#define H5FD_SEC2_AIO_FINISH__DEBUG 0 static herr_t H5FD_sec2_aio_finish(int *errno_ptr, @@ -2133,7 +2156,7 @@ H5FD_sec2_aio_finish(int *errno_ptr, switch ( cb_ptr->status ) { case H5FD_SEC2_AIO_STATUS__COMPLETE: - posix_result = aio_return(&(cb_ptr->ctlblk)); + posix_result = HDaio_return(&(cb_ptr->ctlblk)); if ( cb_ptr->err_num == 0 ) { /* operation succeeded */ @@ -2143,14 +2166,14 @@ H5FD_sec2_aio_finish(int *errno_ptr, #if H5FD_SEC2_AIO_FINISH__DEBUG HDfprintf(stdout, - "%s: op successful but aio_return returned -1.\n", + "%s: op successful but HDaio_return returned -1.\n", FUNC); HDfprintf(stdout, "%s: errno = %d (%s).\n", FUNC, errno, strerror(errno)); #endif /* H5FD_SEC2_AIO_FINISH__DEBUG */ HGOTO_ERROR(H5E_ARGS, H5E_SYSTEM, FAIL, \ - "op successful, but aio_return returned -1!?!.") + "op successful, but HDaio_return returned -1!?!.") } if ( (haddr_t)posix_result > cb_ptr->size ) { @@ -2161,28 +2184,62 @@ H5FD_sec2_aio_finish(int *errno_ptr, *errno_ptr = EIO; HGOTO_ERROR(H5E_ARGS, H5E_SYSTEM, FAIL, \ - "aio_return() val > cb_ptr->size!?!") + "HDaio_return() val > cb_ptr->size!?!") } if ( (haddr_t)posix_result != cb_ptr->size ) { +#if H5FD_SEC2_AIO_FINISH__DEBUG + HDfprintf(stdout, "%s: read successful, but short %lld of %lld bytes.\n", + FUNC, (long long)remaining_buffer_size, + (long long)(cb_ptr->size)); +#endif /* H5FD_SEC2_AIO_FINISH__DEBUG */ + if ( cb_ptr->op == H5FD_SEC2_AIO_OP__READ ) { /* if a read is short, but otherwise no error, - * assume that we have reached end of file, and - * fill in the rest of the buffer with nulls. + * check to see if we have reached the end of file. + * If so, fill in the rest of the buffer with nulls. */ - size_t remaining_buffer_size; - void * remaining_buffer; - remaining_buffer_size = - (size_t)(cb_ptr->size) - (size_t)posix_result; + if ( ( (size_t)posix_result < cb_ptr->size ) && + ( (cb_ptr->addr + (haddr_t)posix_result) >= file_ptr->eof ) ) { - remaining_buffer = (void *) - ((uint8_t *)(cb_ptr->buf) + remaining_buffer_size); + size_t remaining_buffer_size; + void * remaining_buffer; +#if H5FD_SEC2_AIO_FINISH__DEBUG + HDfprintf(stdout, "%s: Filling in read past eof with nulls.\n", + FUNC); +#endif /* H5FD_SEC2_AIO_FINISH__DEBUG */ - HDmemset(remaining_buffer, 0, remaining_buffer_size); + remaining_buffer_size = + (size_t)(cb_ptr->size) - (size_t)posix_result; + remaining_buffer = (void *) + ((uint8_t *)(cb_ptr->buf) + remaining_buffer_size); + + HDmemset(remaining_buffer, 0, remaining_buffer_size); + + } else { + + /* flag an error -- although if we get serious about error + * recovery, it would make sense to attempt an SIO read here + * instead. + * + * must set *errno_ptr to something other than 0 on failure. + * The following seems reasonable, but feel free to change it. + */ +#if H5FD_SEC2_AIO_FINISH__DEBUG + HDfprintf(stdout, "%s: Incomplete read -- flagging error.\n", + FUNC); +#endif /* H5FD_SEC2_AIO_FINISH__DEBUG */ + + *errno_ptr = EIO; + + HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, \ + "couldn't complete the read.") + + } } else if ( cb_ptr->op == H5FD_SEC2_AIO_OP__WRITE ) { /* must set *errno_ptr to something other than 0 @@ -2191,13 +2248,21 @@ H5FD_sec2_aio_finish(int *errno_ptr, */ *errno_ptr = EIO; +#if H5FD_SEC2_AIO_FINISH__DEBUG + HDfprintf(stdout, + "%s: write successful, but bytes written = %lld, %lld expected.\n", + FUNC, + (long long)posix_result, + (long long)(cb_ptr->size)); +#endif /* H5FD_SEC2_AIO_FINISH__DEBUG */ + HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, \ - "couldn't complete the write.") + "couldn't complete the write.") } else { /* note that we set cb_ptr->size to 0 in the - * case of aio_fsync(). + * case of HDaio_fsync(). */ HGOTO_ERROR(H5E_INTERNAL, H5E_SYSTEM, FAIL, "this should be unreachable"); @@ -2218,7 +2283,7 @@ H5FD_sec2_aio_finish(int *errno_ptr, "%s: unexpected errno = %d (%s). %d (%s) expected.\n", FUNC, errno, strerror(errno), cb_ptr->err_num, strerror(cb_ptr->err_num)); - HDfprintf(stdout, "%s: aio_return() returned %lld.\n", + HDfprintf(stdout, "%s: HDaio_return() returned %lld.\n", FUNC, (long long)posix_result); } #endif /* H5FD_SEC2_AIO_FINISH__DEBUG */ @@ -2227,7 +2292,7 @@ H5FD_sec2_aio_finish(int *errno_ptr, if ( posix_result != -1 ) { HGOTO_ERROR(H5E_ARGS, H5E_SYSTEM, FAIL, \ - "op failed, but aio_return reports good status!?!.") + "op failed, but HDaio_return reports good status!?!.") } switch ( cb_ptr->op ) { @@ -2314,7 +2379,7 @@ H5FD_sec2_aio_finish(int *errno_ptr, break; case H5FD_SEC2_AIO_OP__FSYNC: - posix_result = fsync(cb_ptr->file_ptr->fd); + posix_result = HDfsync(cb_ptr->file_ptr->fd); if ( posix_result == 0 ) { /* success */ @@ -2324,7 +2389,7 @@ H5FD_sec2_aio_finish(int *errno_ptr, *errno_ptr = errno; HGOTO_ERROR(H5E_IO, H5E_SYNCFAIL, FAIL, \ - "fallback call to fsync() failed.") + "fallback call to HDfsync() failed.") } break; @@ -2493,7 +2558,7 @@ H5FD_sec2_aio_fsync(H5FD_t *file, ctlblk_ptr->retries = -1; /* set ctlblk_ptr->size to zero so as to simplify processing in - * H5FD_sec2_aio_finish(). Needless to say, aio_fsync() doesn't + * H5FD_sec2_aio_finish(). Needless to say, HDaio_fsync() doesn't * get passed a size, and thus doesn't care. */ ctlblk_ptr->size = 0; @@ -2509,7 +2574,7 @@ H5FD_sec2_aio_fsync(H5FD_t *file, * haven't succeeded in queueing the fsync by the time we do a * wait on it. */ - posix_result = aio_fsync(O_SYNC, &(ctlblk_ptr->ctlblk)); + posix_result = HDaio_fsync(O_SYNC, &(ctlblk_ptr->ctlblk)); if ( posix_result != 0 ) { @@ -2526,12 +2591,12 @@ H5FD_sec2_aio_fsync(H5FD_t *file, #if H5FD_SEC2_AIO_READ__DEBUG HDfprintf(stdout, - "%s: aio_fsync(O_SYNC, ctlblk) failed. errno = %d (%s)\n", + "%s: HDaio_fsync(O_SYNC, ctlblk) failed. errno = %d (%s)\n", FUNC, errno, strerror(errno)); #endif /* H5FD_SEC2_AIO_READ__DEBUG */ HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, \ - "call to aio_fsync() failed.") + "call to HDaio_fsync() failed.") } } else { @@ -2587,11 +2652,32 @@ done: * Purpose: Attempt to cancel the asynchronous operation associated * with the control block pointed to by ctlblk_ptr. * - * Note that this - * operation may have completed, but it is an error if - * H5FD_sec2_aio_finish() has been called on it. + * Note that this target operation may not have started, may + * be in progress, or may have completed. Note however, that + * it is an error to call H5FD_sec2_aio_cancel() on an operation + * if it has already been completed by a call to + * H5FD_sec2_aio_finish(). * - * As part of the cancel, free the associated control blocks. + * As part of the cancel, tidy up the operation and free the + * associated control block. + * + * Note however, that "cancel and forget" feature of our + * implementation comes at a cost. While we can cheaply + * cancel operation that have not yet started, or that + * have already completed, our management of operations that + * are in progress are necessarily more time consuming -- at + * least in the case of AIO reads and writes. Here we must + * await conclusion of AIO read/write operations that we + * are not able to cancel -- as if we don't, we risk the + * possiblity that the buffers used in these operations will + * be freed before the operations complese. This in turns + * opens the possibility of reads/writes to unallocated memory + * and thus heap corruption. + * + * In general, this is what we should do anyway, and further, + * at least at this writing I would expect aio cancels to be + * rare. However, if either of these assertions proves untrue, + * we will have to revisit the API for the aio cancel operation. * * Return SUCCEED if successful, and the appropriate error * code otherwise. @@ -2614,10 +2700,10 @@ H5FD_sec2_aio_cancel(void *ctlblk_ptr) herr_t ret_value = SUCCEED; /* Return value */ herr_t result; hbool_t cancel_succeeded = FALSE; - int posix_result; + ssize_t posix_result; H5FD_sec2_aio_ctlblk_t * cb_ptr = NULL; H5FD_sec2_t * file_ptr = NULL; - + const struct HDaiocb * aiocb_list[1] = { NULL }; FUNC_ENTER_NOAPI(H5FD_sec2_aio_cancel, FAIL) if ( ( ctlblk_ptr == NULL ) || @@ -2631,7 +2717,7 @@ H5FD_sec2_aio_cancel(void *ctlblk_ptr) if ( ( cb_ptr->op != H5FD_SEC2_AIO_OP__READ ) && ( cb_ptr->op != H5FD_SEC2_AIO_OP__WRITE ) && - ( cb_ptr->op != H5FD_SEC2_AIO_OP__WRITE ) ) { + ( cb_ptr->op != H5FD_SEC2_AIO_OP__FSYNC ) ) { HGOTO_ERROR(H5E_ARGS, H5E_SYSTEM, FAIL, \ "Undefined or unknown ctlblk op on entry.") @@ -2653,65 +2739,69 @@ H5FD_sec2_aio_cancel(void *ctlblk_ptr) /* the asynchronous operation has been queued -- must attempt * to cancel it. */ - posix_result = aio_cancel(cb_ptr->file_ptr->fd, &(cb_ptr->ctlblk)); + posix_result = HDaio_cancel(cb_ptr->file_ptr->fd, &(cb_ptr->ctlblk)); switch ( posix_result ) { case AIO_CANCELED: /* success */ +#if H5FD_SEC2_AIO_CANCEL__DEBUG + HDfprintf(stdout, "%s: HDaio_cancel() reports AIO_CANCELED.\n", FUNC); +#endif /* H5FD_SEC2_AIO_CANCEL__DEBUG */ /* verify that the cancel succeeded */ - posix_result = aio_error(&(cb_ptr->ctlblk)); + posix_result = HDaio_error(&(cb_ptr->ctlblk)); if ( posix_result != ECANCELED ) { #if H5FD_SEC2_AIO_CANCEL__DEBUG HDfprintf(stdout, - "%s: aio_error() returned %d after successful cancel.\n", + "%s: HDaio_error() returned %d after successful cancel.\n", FUNC, posix_result); HDfprintf(stdout, "%s: errno = %d (%s).\n", FUNC, errno, strerror(errno)); #endif /* H5FD_SEC2_AIO_CANCEL__DEBUG */ HGOTO_ERROR(H5E_IO, H5E_AIOCANCELFAIL, FAIL, \ - "aio_error() didn't return ECANCELED after cancel.") + "HDaio_error() didn't return ECANCELED after cancel.") } - /* call aio_return() to let the OS tidy up after the + /* call HDaio_return() to let the OS tidy up after the * operation */ - posix_result = aio_return(&(cb_ptr->ctlblk)); + posix_result = HDaio_return(&(cb_ptr->ctlblk)); if ( ( posix_result != -1 ) && ( errno != ECANCELED ) ) { #if H5FD_SEC2_AIO_CANCEL__DEBUG HDfprintf(stdout, - "%s: aio_return() returned %d after successful cancel.\n", + "%s: HDaio_return() returned %d after successful cancel.\n", FUNC, posix_result); HDfprintf(stdout, "%s: errno = %d (%s).\n", FUNC, errno, strerror(errno)); #endif /* H5FD_SEC2_AIO_CANCEL__DEBUG */ HGOTO_ERROR(H5E_IO, H5E_AIOCANCELFAIL, FAIL, \ - "unexpected aio_return() after successful cancel.") + "unexpected HDaio_return() after successful cancel.") } cancel_succeeded = TRUE; break; case AIO_NOTCANCELED: - /* operation in progress when aio_cancel() was called. + /* operation in progress when HDaio_cancel() was called. * * this is a bit sticky, as we can't just drop the - * operation on the floor. Instead, we must hold on - * to the associated control block until the operation - * completes, and then discard it. + * operation on the floor. * - * The easy way to do this would be to just wait until - * the operation completes, and call aio_return() on - * it, and then discard the control block. + * To make things more difficult, if the operation + * is a read or write, it is possible that the operation + * has a dynamically allocated buffer associated with it. + * Thus in the case of a read or a write, we must wait + * until the operation completes, call HDaio_return(), and + * then discard the control block. * - * However, this would be a bit slow. So instead, - * we mark the operation as canceled, place it on - * a canceled op queue, and check to see if any - * canceled ops have completed whenever we do - * anything else. + * In the case of an fsync, no buffer can be associated + * with the operation. In this case, we can mark the + * operation as canceled, place it on a canceled op + * queue, and check to see if any canceled ops have + * completed whenever we do anything else. * * Rather than duplicate code, just set the control * block status to @@ -2721,29 +2811,94 @@ H5FD_sec2_aio_cancel(void *ctlblk_ptr) * and deal with switching queues at the end of this * function. */ - cb_ptr->status = H5FD_SEC2_AIO_STATUS__CANCELED_IN_PROGRESS; +#if H5FD_SEC2_AIO_CANCEL__DEBUG + HDfprintf(stdout, "%s: HDaio_cancel() reports AIO_NOTCANCELED.\n", FUNC); +#endif /* H5FD_SEC2_AIO_CANCEL__DEBUG */ + + if ( ( cb_ptr->op == H5FD_SEC2_AIO_OP__READ ) || + ( cb_ptr->op == H5FD_SEC2_AIO_OP__WRITE ) ) { +#if H5FD_SEC2_AIO_CANCEL__DEBUG + HDfprintf(stdout, "%s: completing read or write\n", FUNC); +#endif /* H5FD_SEC2_AIO_CANCEL__DEBUG */ + + /* await the end of the read or write */ + aiocb_list[0] = &(cb_ptr->ctlblk); + posix_result = HDaio_suspend(aiocb_list, 1, NULL); + + if ( posix_result != 0 ) { +#if H5FD_SEC2_AIO_CANCEL__DEBUG + HDfprintf(stdout, + "%s: HDaio_suspend() failed with errno = %d (%s).\n", + FUNC, errno, strerror(errno)); +#endif /* H5FD_SEC2_AIO_CANCEL__DEBUG */ + HGOTO_ERROR(H5E_IO, H5E_AIOCANCELFAIL, FAIL, \ + "HDaio_suspend() failed after in progress."); + } + + /* call HDaio_return() to let the OS tidy up after the + * operation + */ + posix_result = HDaio_return(&(cb_ptr->ctlblk)); + + /* as we are trying to cancel the operation, the + * return value is typically of no interest. However, if + * desired for debugging purposes, display result if they + * indicate failure. + */ + if ( posix_result == -1 ) { + +#if H5FD_SEC2_AIO_CANCEL__DEBUG + HDfprintf(stdout, + "%s: HDaio_return() returned %d after successful HDaio_suspend().\n", + FUNC, posix_result); + HDfprintf(stdout, "%s: errno = %d (%s).\n", + FUNC, errno, strerror(errno)); +#endif /* H5FD_SEC2_AIO_CANCEL__DEBUG */ + } + + cancel_succeeded = TRUE; + + } else { +#if H5FD_SEC2_AIO_CANCEL__DEBUG + HDfprintf(stdout, "%s: marked fsync canceled in progress\n", FUNC); +#endif /* H5FD_SEC2_AIO_CANCEL__DEBUG */ + + cb_ptr->status = H5FD_SEC2_AIO_STATUS__CANCELED_IN_PROGRESS; + + } break; case AIO_ALLDONE: /* operation was alread completed */ - /* call aio_error() to verify that the op has completed */ - posix_result = aio_error(&(cb_ptr->ctlblk)); +#if H5FD_SEC2_AIO_CANCEL__DEBUG + HDfprintf(stdout, "%s: HDaio_cancel() reports AIO_ALLDONE.\n", FUNC); +#endif /* H5FD_SEC2_AIO_CANCEL__DEBUG */ - if ( posix_result == EINPROGRESS ) { + /* On both Solaris and BSD, we run into problem if we + * use a call to HDaio_error() to verify that the aio operation + * is, in fact, complete. + * + * On the one hand, given that the result of calling HDaio_return + * on an operation that is not complete is specifically undefined, + * it seems prudent to make this verification. + * + * On the other hand, the ommition doesn't seem to + * cause any problems on any system tested so far. + * + * Thus I've decided to ommit the call -- even though the + * standard does seem to indicate that it should succeed + * in this case. + */ - HGOTO_ERROR(H5E_IO, H5E_AIOCANCELFAIL, FAIL, \ - "aio_error() reports op still in progress.") - } - - /* call aio_return() to let the OS tidy up after the + /* call HDaio_return() to let the OS tidy up after the * operation */ - posix_result = aio_return(&(cb_ptr->ctlblk)); + posix_result = HDaio_return(&(cb_ptr->ctlblk)); if ( posix_result == EINVAL ) { HGOTO_ERROR(H5E_IO, H5E_AIOCANCELFAIL, FAIL, \ - "aio_return() failed after cancel after completion.") + "HDaio_return() failed after cancel after completion.") } cancel_succeeded = TRUE; break; @@ -2751,21 +2906,21 @@ H5FD_sec2_aio_cancel(void *ctlblk_ptr) case -1: /* error */ #if H5FD_SEC2_AIO_CANCEL__DEBUG HDfprintf(stdout, - "%s: aio_cancel() failed with errno = %d(%s).\n", + "%s: HDaio_cancel() failed with errno = %d(%s).\n", FUNC, errno, strerror(errno)); #endif /* H5FD_SEC2_AIO_CANCEL__DEBUG */ HGOTO_ERROR(H5E_IO, H5E_AIOCANCELFAIL, FAIL, \ - "call to aio_cancel() failed.") + "call to HDaio_cancel() failed.") break; default: #if H5FD_SEC2_AIO_CANCEL__DEBUG HDfprintf(stdout, - "%s: aio_cancel() returned unexpected value %d.\n", + "%s: HDaio_cancel() returned unexpected value %d.\n", FUNC, posix_result); #endif /* H5FD_SEC2_AIO_CANCEL__DEBUG */ HGOTO_ERROR(H5E_IO, H5E_AIOCANCELFAIL, FAIL, \ - "call to aio_cancel() returned unexpected value.") + "call to HDaio_cancel() returned unexpected value.") break; } break; @@ -2816,7 +2971,8 @@ H5FD_sec2_aio_cancel(void *ctlblk_ptr) done: if ( ( cancel_succeeded ) || - ( cb_ptr->status == H5FD_SEC2_AIO_STATUS__CANCELED_IN_PROGRESS ) ) { + ( ( cb_ptr != NULL ) && + ( cb_ptr->status == H5FD_SEC2_AIO_STATUS__CANCELED_IN_PROGRESS ) ) ) { /* must remove the control block from the appropriate op list * and then release it. @@ -2880,7 +3036,7 @@ done: * * Purpose: Check the head of the canceled list for operations that * were canceled while in progress that have since completed. - * If any are found, call aio_return() on them, and discard + * If any are found, call HDaio_return() on them, and discard * the control blocks. * * Return SUCCEED if no errors are detected, and FAIL @@ -2904,7 +3060,7 @@ H5FD_sec2_aio_cancel__retire_canceled_in_progress(H5FD_sec2_t * file_ptr) herr_t ret_value = SUCCEED; /* Return value */ herr_t result; hbool_t done = FALSE; - int posix_result; + ssize_t posix_result; H5FD_sec2_aio_ctlblk_t * cb_ptr = NULL; FUNC_ENTER_NOAPI(H5FD_sec2_aio_cancel__retire_canceled_in_progress, FAIL) @@ -2924,8 +3080,8 @@ H5FD_sec2_aio_cancel__retire_canceled_in_progress(H5FD_sec2_t * file_ptr) "non-canceled op on canceled list") } - /* call aio_error() to see if the op has completed */ - posix_result = aio_error(&(cb_ptr->ctlblk)); + /* call HDaio_error() to see if the op has completed */ + posix_result = HDaio_error(&(cb_ptr->ctlblk)); if ( posix_result == EINPROGRESS ) { @@ -2933,15 +3089,18 @@ H5FD_sec2_aio_cancel__retire_canceled_in_progress(H5FD_sec2_t * file_ptr) } else { - /* call aio_return() to let the OS tidy up after the + /* call HDaio_return() to let the OS tidy up after the * operation */ - posix_result = aio_return(&(cb_ptr->ctlblk)); +#if H5FD_SEC2_AIO_CANCEL__RETIRE_CANCELED_IN_PROGRESS__DEBUG + HDfprintf(stdout, "%s: retiring head of canceled list.\n", FUNC); +#endif /* H5FD_SEC2_AIO_CANCEL__RETIRE_CANCELED_IN_PROGRESS__DEBUG */ + posix_result = HDaio_return(&(cb_ptr->ctlblk)); if ( posix_result == EINVAL ) { HGOTO_ERROR(H5E_IO, H5E_AIOCANCELFAIL, FAIL, \ - "aio_return() failed after cancel after completion.") + "HDaio_return() failed after cancel after completion.") } H5FD_SEC2__DLL_REMOVE(cb_ptr, \ diff --git a/src/H5private.h b/src/H5private.h index d3fc1e8bca..a0325c0dd0 100644 --- a/src/H5private.h +++ b/src/H5private.h @@ -491,6 +491,39 @@ typedef struct { #ifndef HDacos #define HDacos(X) acos(X) #endif /* HDacos */ + +#ifndef HDaiocb + #define HDaiocb aiocb +#endif /* HDaiocb */ + +#ifndef HDaio_cancel + #define HDaio_cancel(F,A) aio_cancel(F, A) +#endif /* HDaio_cancel */ + +#ifndef HDaio_error + #define HDaio_error(A) aio_error(A) +#endif /* HDaio_error */ + +#ifndef HDaio_fsync + #define HDaio_fsync(O,A) aio_fsync(O, A) +#endif /* HDaio_fsync */ + +#ifndef HDaio_read + #define HDaio_read(A) aio_read(A) +#endif /* HDaio_read */ + +#ifndef HDaio_return + #define HDaio_return(A) aio_return(A) +#endif /* HDaio_return */ + +#ifndef HDaio_suspend + #define HDaio_suspend(L,N,T) aio_suspend(L, N, T) +#endif /* HDaio_suspend */ + +#ifndef HDaio_write + #define HDaio_write(A) aio_write(A) +#endif /* HDaio_write */ + #ifndef HDalarm #ifdef H5_HAVE_ALARM #define HDalarm(N) alarm(N) diff --git a/test/Makefile.am b/test/Makefile.am index d342c17472..d642fcabc9 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -23,10 +23,10 @@ include $(top_srcdir)/config/commence.am INCLUDES=-I$(top_srcdir)/src -I$(top_builddir)/src -# Test script for error_test and err_compat -TEST_SCRIPT = testerror.sh testlibinfo.sh testcheck_version.sh +# Test script for error_test, err_compat, and fsync +TEST_SCRIPT = testerror.sh testlibinfo.sh testcheck_version.sh fsync_tests.sh check_SCRIPTS = $(TEST_SCRIPT) -SCRIPT_DEPEND = error_test$(EXEEXT) err_compat$(EXEEXT) +SCRIPT_DEPEND = error_test$(EXEEXT) err_compat$(EXEEXT) fsync_tests.c$(EXEEXT) # These are our main targets. They should be listed in the order to be @@ -50,7 +50,8 @@ TEST_PROG=testhdf5 lheap ohdr stab gheap cache cache_api \ # 'make check' doesn't run them directly, so they are not included in TEST_PROG. # Also build testmeta, which is used for timings test. It builds quickly, # and this lets automake keep all its test programs in one place. -check_PROGRAMS=$(TEST_PROG) error_test err_compat tcheck_version testmeta +check_PROGRAMS=$(TEST_PROG) error_test err_compat tcheck_version testmeta \ + fsync_tests # These programs generate test files for the tests. They don't need to be diff --git a/test/Makefile.in b/test/Makefile.in index b31652b6c4..57958b947b 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -58,7 +58,8 @@ DIST_COMMON = $(srcdir)/H5srcdir_str.h.in $(srcdir)/Makefile.am \ $(top_srcdir)/config/commence.am \ $(top_srcdir)/config/conclude.am COPYING check_PROGRAMS = $(am__EXEEXT_1) error_test$(EXEEXT) \ - err_compat$(EXEEXT) tcheck_version$(EXEEXT) testmeta$(EXEEXT) + err_compat$(EXEEXT) tcheck_version$(EXEEXT) testmeta$(EXEEXT) \ + fsync_tests$(EXEEXT) @BUILD_ALL_CONDITIONAL_TRUE@noinst_PROGRAMS = $(am__EXEEXT_2) TESTS = $(check_PROGRAMS) $(check_SCRIPTS) subdir = test @@ -197,6 +198,10 @@ freespace_SOURCES = freespace.c freespace_OBJECTS = freespace.$(OBJEXT) freespace_LDADD = $(LDADD) freespace_DEPENDENCIES = libh5test.la $(LIBHDF5) +fsync_tests_SOURCES = fsync_tests.c +fsync_tests_OBJECTS = fsync_tests.$(OBJEXT) +fsync_tests_LDADD = $(LDADD) +fsync_tests_DEPENDENCIES = libh5test.la $(LIBHDF5) gen_bad_ohdr_SOURCES = gen_bad_ohdr.c gen_bad_ohdr_OBJECTS = gen_bad_ohdr.$(OBJEXT) gen_bad_ohdr_LDADD = $(LDADD) @@ -376,20 +381,7 @@ SOURCES = $(libh5test_la_SOURCES) app_ref.c big.c bittests.c btree2.c \ cache.c cache_api.c cmpd_dset.c cross_read.c dangle.c dsets.c \ dt_arith.c dtransform.c dtypes.c earray.c enum.c err_compat.c \ error_test.c extend.c external.c farray.c fheap.c fillval.c \ - flush1.c flush2.c freespace.c gen_bad_ohdr.c gen_bogus.c \ - gen_cross.c gen_deflate.c gen_filespace.c gen_filters.c \ - gen_new_array.c gen_new_fill.c gen_new_group.c gen_new_mtime.c \ - gen_new_super.c gen_noencoder.c gen_nullspace.c \ - gen_specmetaread.c gen_udlinks.c getname.c gheap.c hyperslab.c \ - istore.c lheap.c links.c mf.c mount.c mtime.c ntypes.c \ - objcopy.c ohdr.c pool.c reserved.c set_extent.c \ - space_overflow.c stab.c tcheck_version.c $(testhdf5_SOURCES) \ - testmeta.c $(ttsafe_SOURCES) unlink.c vfd.c -DIST_SOURCES = $(libh5test_la_SOURCES) app_ref.c big.c bittests.c \ - btree2.c cache.c cache_api.c cmpd_dset.c cross_read.c dangle.c \ - dsets.c dt_arith.c dtransform.c dtypes.c earray.c enum.c \ - err_compat.c error_test.c extend.c external.c farray.c fheap.c \ - fillval.c flush1.c flush2.c freespace.c gen_bad_ohdr.c \ + flush1.c flush2.c freespace.c fsync_tests.c gen_bad_ohdr.c \ gen_bogus.c gen_cross.c gen_deflate.c gen_filespace.c \ gen_filters.c gen_new_array.c gen_new_fill.c gen_new_group.c \ gen_new_mtime.c gen_new_super.c gen_noencoder.c \ @@ -399,6 +391,20 @@ DIST_SOURCES = $(libh5test_la_SOURCES) app_ref.c big.c bittests.c \ set_extent.c space_overflow.c stab.c tcheck_version.c \ $(testhdf5_SOURCES) testmeta.c $(ttsafe_SOURCES) unlink.c \ vfd.c +DIST_SOURCES = $(libh5test_la_SOURCES) app_ref.c big.c bittests.c \ + btree2.c cache.c cache_api.c cmpd_dset.c cross_read.c dangle.c \ + dsets.c dt_arith.c dtransform.c dtypes.c earray.c enum.c \ + err_compat.c error_test.c extend.c external.c farray.c fheap.c \ + fillval.c flush1.c flush2.c freespace.c fsync_tests.c \ + gen_bad_ohdr.c gen_bogus.c gen_cross.c gen_deflate.c \ + gen_filespace.c gen_filters.c gen_new_array.c gen_new_fill.c \ + gen_new_group.c gen_new_mtime.c gen_new_super.c \ + gen_noencoder.c gen_nullspace.c gen_specmetaread.c \ + gen_udlinks.c getname.c gheap.c hyperslab.c istore.c lheap.c \ + links.c mf.c mount.c mtime.c ntypes.c objcopy.c ohdr.c pool.c \ + reserved.c set_extent.c space_overflow.c stab.c \ + tcheck_version.c $(testhdf5_SOURCES) testmeta.c \ + $(ttsafe_SOURCES) unlink.c vfd.c ETAGS = etags CTAGS = ctags am__tty_colors = \ @@ -691,10 +697,10 @@ CHECK_CLEANFILES = *.chkexe *.chklog *.clog cmpd_dset.h5 \ app_ref.h5 farray.h5 earray.h5 INCLUDES = -I$(top_srcdir)/src -I$(top_builddir)/src -# Test script for error_test and err_compat -TEST_SCRIPT = testerror.sh testlibinfo.sh testcheck_version.sh +# Test script for error_test, err_compat, and fsync +TEST_SCRIPT = testerror.sh testlibinfo.sh testcheck_version.sh fsync_tests.sh check_SCRIPTS = $(TEST_SCRIPT) -SCRIPT_DEPEND = error_test$(EXEEXT) err_compat$(EXEEXT) +SCRIPT_DEPEND = error_test$(EXEEXT) err_compat$(EXEEXT) fsync_tests.c$(EXEEXT) # These are our main targets. They should be listed in the order to be # executed, generally most specific tests to least specific tests. @@ -909,6 +915,9 @@ flush2$(EXEEXT): $(flush2_OBJECTS) $(flush2_DEPENDENCIES) freespace$(EXEEXT): $(freespace_OBJECTS) $(freespace_DEPENDENCIES) @rm -f freespace$(EXEEXT) $(LINK) $(freespace_OBJECTS) $(freespace_LDADD) $(LIBS) +fsync_tests$(EXEEXT): $(fsync_tests_OBJECTS) $(fsync_tests_DEPENDENCIES) + @rm -f fsync_tests$(EXEEXT) + $(LINK) $(fsync_tests_OBJECTS) $(fsync_tests_LDADD) $(LIBS) gen_bad_ohdr$(EXEEXT): $(gen_bad_ohdr_OBJECTS) $(gen_bad_ohdr_DEPENDENCIES) @rm -f gen_bad_ohdr$(EXEEXT) $(LINK) $(gen_bad_ohdr_OBJECTS) $(gen_bad_ohdr_LDADD) $(LIBS) @@ -1056,6 +1065,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/flush1.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/flush2.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/freespace.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fsync_tests.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gen_bad_ohdr.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gen_bogus.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gen_cross.Po@am__quote@ diff --git a/test/fsync_tests.c b/test/fsync_tests.c new file mode 100644 index 0000000000..06cd11c5c8 --- /dev/null +++ b/test/fsync_tests.c @@ -0,0 +1,3618 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * Copyright by the Board of Trustees of the University of Illinois. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the files COPYING and Copyright.html. COPYING can be found at the root * + * of the source code distribution tree; Copyright.html can be found at the * + * root level of an installed copy of the electronic HDF5 document set and * + * is linked from the top-level documents page. It can also be found at * + * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* Programmer: John Mainzer + * 11/10 + * + * This file contains tests for the fsync and aio fsync + * vfd calls. + */ + +#include + +#define H5F_PACKAGE /*suppress error about including H5Fpkg */ + +#include "h5test.h" +#include "H5Eprivate.h" +#include "H5Iprivate.h" +#include "H5MMprivate.h" /* Memory management */ +#include "H5MFprivate.h" +#include "H5ACprivate.h" +#include "cache_common.h" +#include "H5Fpkg.h" + + +/* global variable declarations: */ + +#define KB 1024 +#define FAMILY_SIZE_AIO (32 * KB * KB) + +#define TYPE_SLICE ((haddr_t)0x20000000LL) + +#define TEST_IN_PROGRESS_FILE_NAME_INDEX 0 +const char *FILENAMES[] = { + "test_in_progress", + "sec2_fsync_test", + "core_fsync_test", + "stdio_fsync_test", + "family_fsync_test", + "multi_fsync_test", + "sec2_aio_fsync_poll_test", + "core_aio_fsync_poll_test", + "stdio_aio_fsync_poll_test", + "family_aio_fsync_poll_test", + "multi_aio_fsync_poll_test", + "sec2_aio_fsync_wait_test", + "core_aio_fsync_wait_test", + "stdio_aio_fsync_wait_test", + "family_aio_fsync_wait_test", + "multi_aio_fsync_wait_test", + "targeted_multi_fsync_test", + "targeted_multi_aio_fsync_poll_test", + "targeted_multi_aio_fsync_wait_test", + NULL +}; + + +/* private function declarations: */ + +/* utility functions */ + +static void check_test_in_progress(const char * str, hbool_t verbose); + +static hbool_t file_exists(const char * file_path_ptr, hbool_t verbose); + +static void load_test_buffer(hsize_t buf_size, const char * tag, char * buf); + +static void mark_test_in_progress(const char * str); + +static void usage(void); + +/* test functions */ + +static void setup_generic_aio_fsync_test(const int file_name_num, + hid_t fapl_id, + const char * tag, + hsize_t write_size, + haddr_t maxaddr, + hbool_t wait_on_fsync, + hbool_t verbose); + +static void setup_generic_fsync_test(const int file_name_num, + hid_t fapl_id, + const char * tag, + hsize_t write_size, + haddr_t maxaddr, + hbool_t verbose); + +static void check_generic_fsync_test(const int file_name_num, + hid_t fapl_id, + const char * tag, + hsize_t file_size, + haddr_t maxaddr, + hbool_t verbose); + +static void setup_multi_file_driver_fsync_test(const int file_name_num, + const char * tag, + hsize_t write_size, + hbool_t verbose); + +static void setup_multi_file_driver_aio_fsync_test(const int file_name_num, + const char * tag, + hsize_t write_size, + hbool_t wait_on_fsync, + hbool_t verbose); + +static void check_multi_file_driver_fsync_test(const int file_name_num, + const char * tag, + hsize_t file_size, + hbool_t verbose); + + +/**************************************************************************/ +/**************************************************************************/ +/********************************* tests: *********************************/ +/**************************************************************************/ +/**************************************************************************/ + +/*** fsync and aio fsync test utility functions ***/ + +/*------------------------------------------------------------------------- + * Function: check_test_in_progress() + * + * Purpose: If pass is true on entry, test to see if the test in + * progress file exists. If it does not, set pass to FALSE + * and set a failure message. + * + * If the test in progress file does exist, check to see if + * its contents matches the supplied string. It it does not, + * set pass to FALSE and set the appropriate failure message. + * + * Do nothing if pass is FALSE on entry. + * + * Return: void + * + * Programmer: John Mainzer + * 11/9/10 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + +static void +check_test_in_progress(const char * str, + hbool_t verbose) + +{ + const char * fcn_name = "check_test_in_progress()"; + char buffer[512]; + char filename[512]; + hbool_t show_progress = FALSE; + size_t input_len; + ssize_t bytes_read; + int cp = 0; + int fd = -1; + h5_stat_t buf; + + if ( show_progress ) { + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, pass, cp++); + HDfflush(stdout); + } + + if ( pass ) { + + if ( ( str == NULL ) || + ( strlen(str) <= 0 ) || + ( strlen(str) >= 512 ) ) { + + pass = FALSE; + failure_mssg = "bad str on entry to check_test_in_progress()."; + } + } + + if ( show_progress ) { + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, pass, cp++); + HDfflush(stdout); + } + + /* setup the test in progress file name */ + if ( pass ) { + + if ( h5_fixname(FILENAMES[TEST_IN_PROGRESS_FILE_NAME_INDEX], + H5P_DEFAULT, filename, sizeof(filename)) == NULL ) { + + pass = FALSE; + failure_mssg = "h5_fixname() failed.\n"; + } + else if ( strlen(filename) >= 512 ) { + + pass = FALSE; + failure_mssg = "test in progress file name too long.\n"; + } + } + + if ( show_progress ) { + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, pass, cp++); + HDfflush(stdout); + } + + if ( verbose ) { + HDfprintf(stdout, "%s filename = \"%s\".\n", fcn_name, filename); + HDfflush(stdout); + } + + if ( ( pass ) && ( ! file_exists(filename, verbose) ) ) { + + pass = FALSE; + failure_mssg = "test not in progress?!?"; + } + + + /* get the length of the test in progress file */ + if ( pass ) { + + if ( HDstat(filename, &buf) != 0 ) { + + if ( verbose ) { + + HDfprintf(stdout, "%s: HDstat() failed with errno = %d.\n", + fcn_name, errno); + } + failure_mssg = "stat() failed on test in progress file."; + pass = FALSE; + + } else { + + if ( (buf.st_size) == 0 ) { + + failure_mssg = "test in progress file empty?!?"; + pass = FALSE; + + } else if ( (buf.st_size) >= 512 ) { + + failure_mssg = "test in progress file too big?!?"; + pass = FALSE; + + } else { + + input_len = (size_t)(buf.st_size); + + if ( verbose ) { + + HDfprintf(stdout, "%s: input_len = %d.\n", + fcn_name, (int)input_len); + } + } + } + } + + /* open the test in progress file */ + if ( pass ) { + + if ( (fd = HDopen(filename, O_RDONLY, 0777)) == -1 ) { + + if ( verbose ) { + + HDfprintf(stdout, "%s: HDopen(i) failed with errno = %d.\n", + fcn_name, errno); + } + failure_mssg = "Can't open test in progress file."; + pass = FALSE; + } + } + + /* read the contents of the test in progress file */ + if ( pass ) + { + bytes_read = HDread(fd, buffer, input_len); + + if ( bytes_read != (int)input_len ) { + + if ( verbose ) { + + HDfprintf(stdout, + "%s: HDread() failed. bytes_read = %d, errno = %d.\n", + fcn_name, (int)bytes_read, errno); + } + failure_mssg = "error reading test in progress file."; + pass = FALSE; + } + + buffer[input_len] = '\0'; + } + + if ( fd != -1 ) { + + if ( HDclose(fd) != 0 ) { + + if ( verbose ) { + + HDfprintf(stdout, "%s: HDclose() failed with errno = %d.\n", + fcn_name, errno); + } + + if ( pass ) { + + failure_mssg = "Can't close test in progress file."; + pass = FALSE; + } + } + } + + HDremove(filename); + + if ( pass ) { + + if ( strcmp(str, buffer) != 0 ) { + + if ( verbose ) { + + HDfprintf(stdout, + "%s: expected/actual test in progress = %s/%s\n", + fcn_name, str, buffer); + } + + pass = FALSE; + failure_mssg = "Unexpected test in progress?!?"; + } + } + + return; + +} /* check_test_in_progress() */ + + +/*------------------------------------------------------------------------- + * Function: file_exists() + * + * Purpose: If pass is true on entry, stat the target file, and + * return TRUE if it exists, and FALSE if it does not. + * + * If any errors are detected in this process, set pass + * to FALSE and set failure_mssg to point to an appropriate + * error message. + * + * Do nothing and return FALSE if pass is FALSE on entry. + * + * Return: void + * + * Programmer: John Mainzer + * 11/9/10 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + +static hbool_t +file_exists(const char * file_path_ptr, + hbool_t verbose) +{ + const char * fcn_name = "file_exists()"; + hbool_t ret_val = FALSE; /* will set to TRUE if necessary */ + h5_stat_t buf; + + if ( pass ) { + + if ( file_path_ptr == NULL ) { + + failure_mssg = "file_path_ptr NULL on entry?!?", + pass = FALSE; + } + } + + if ( pass ) { + + if ( HDstat(file_path_ptr, &buf) == 0 ) { + + if ( verbose ) { + + HDfprintf(stdout, "%s: HDstat(%s) succeeded.\n", fcn_name, + file_path_ptr); + } + + ret_val = TRUE; + + } else if ( errno == ENOENT ) { + + if ( verbose ) { + + HDfprintf(stdout, "%s: HDstat(%s) failed with ENOENT\n", + fcn_name, file_path_ptr); + } + + } else { + + if ( verbose ) { + + HDfprintf(stdout, + "%s: HDstat() failed with unexpected errno = %d.\n", + fcn_name, errno); + } + + failure_mssg = "HDstat() returned unexpected value."; + pass = FALSE; + + } + } + + return(ret_val); + +} /* file_exists() */ + + +/*------------------------------------------------------------------------- + * Function: mark_test_in_progress() + * + * Purpose: If pass is true on entry, test to see if the test in + * progress file exists. If it does, set pass to FALSE + * and set a failure message. + * + * If the test in progress file doesn't exist, create it, + * open it, write the supplied string to it, and then close + * it. If any errors are detected, set pass to FALSE, and + * set the appropriate failure message. + * + * Do nothing if pass is FALSE on entry. + * + * Return: void + * + * Programmer: John Mainzer + * 11/9/10 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + +static void +mark_test_in_progress(const char * str) + +{ + const char * fcn_name = "mark_test_in_progress()"; + char filename[512]; + hbool_t show_progress = FALSE; + hbool_t verbose = FALSE; + int cp = 0; + ssize_t bytes_written; + int fd = -1; + + if ( show_progress ) { + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, pass, cp++); + HDfflush(stdout); + } + + if ( pass ) { + + if ( ( str == NULL ) || + ( strlen(str) >= 512 ) ) { + + pass = FALSE; + failure_mssg = "bad str on entry to mark_test_in_progress()."; + } + } + + if ( show_progress ) { + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, pass, cp++); + HDfflush(stdout); + } + + /* setup the test in progress file name */ + if ( pass ) { + + if ( h5_fixname(FILENAMES[TEST_IN_PROGRESS_FILE_NAME_INDEX], + H5P_DEFAULT, filename, sizeof(filename)) == NULL ) { + + pass = FALSE; + failure_mssg = "h5_fixname() failed.\n"; + } + else if ( strlen(filename) >= 512 ) { + + pass = FALSE; + failure_mssg = "test in progress file name too long.\n"; + } + } + + if ( show_progress ) { + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, pass, cp++); + HDfflush(stdout); + } + + if ( verbose ) { + HDfprintf(stdout, "%s filename = \"%s\".\n", fcn_name, filename); + HDfflush(stdout); + } + + if ( ( pass ) && ( file_exists(filename, verbose) ) ) { + + pass = FALSE; + failure_mssg = "test already in progress?!?"; + } + + /* open the test in progress file */ + if ( pass ) { + + if ( (fd = HDopen(filename, O_WRONLY|O_CREAT|O_TRUNC, 0777)) + == -1 ) { + + if ( verbose ) { + + HDfprintf(stdout, "%s: HDopen(i) failed with errno = %d.\n", + fcn_name, errno); + } + failure_mssg = "Can't open test in progress file."; + pass = FALSE; + } + } + + if ( pass ) { + + bytes_written = HDwrite(fd, str, strlen(str)); + + if ( bytes_written != (int)strlen(str) ) { + + if ( verbose ) { + + HDfprintf(stdout, + "%s: HDwrite() failed. bytes_written = %d, errno = %d.\n", + fcn_name, (int)bytes_written, errno); + } + failure_mssg = "error writing test in progress file."; + pass = FALSE; + } + } + + if ( fd != -1 ) { + + if ( HDclose(fd) != 0 ) { + + if ( verbose ) { + + HDfprintf(stdout, "%s: HDclose() failed with errno = %d.\n", + fcn_name, errno); + } + + if ( pass ) { + + failure_mssg = "Can't close test in progress file."; + pass = FALSE; + } + } + } + + return; + +} /* mark_test_in_progress() */ + + +/*************************************************************************** + * Function: load_test_buffer + * + * Purpose: If pass is TRUE, load the supplied buffer with test data. + * Otherwise do nothing. + * + * Return: void + * + * Programmer: John Mainzer + * 11/9/11 + * + **************************************************************************/ + +#define LINE_LEN 64 +#define LINE_NUM_BUF_LEN 16 + +static void +load_test_buffer(hsize_t buf_size, + const char * tag, + char * buf) +{ + /* const char * fcn_name = "load_test_buffer():"; */ + char line_num_buf[LINE_NUM_BUF_LEN + 1]; + int line_num_buf_len; + int tag_len; + hsize_t i; + int j; + int line_num = 0; + + HDassert( buf_size > 0 ); + HDassert( tag != NULL ); + HDassert( buf != NULL ); + + if ( pass ) { + + tag_len = (int)HDstrlen(tag); + + HDassert( tag_len > 0 ); + HDassert( LINE_NUM_BUF_LEN + tag_len < LINE_LEN - 1 ); + + j = 0; + + for ( i = 0; i < buf_size; i++ ) { + + if ( j == 0 ) { /* we are starting a new line */ + + if ( line_num <= 999999999 ) { + + HDsnprintf(line_num_buf, (size_t)LINE_NUM_BUF_LEN, + "%09d ", line_num); + + } else { + + HDsnprintf(line_num_buf, (size_t)LINE_NUM_BUF_LEN, "xxxxxxxxx "); + } + + line_num_buf_len = (int)HDstrlen(line_num_buf); + + HDassert( line_num_buf_len <= LINE_NUM_BUF_LEN ); + } + + if ( j < line_num_buf_len ) { + + buf[i] = line_num_buf[j]; + j++; + + } else if ( j < line_num_buf_len + tag_len ) { + + buf[i] = tag[j - line_num_buf_len]; + j++; + + } else if ( j < LINE_LEN - 1 ) { + + buf[i] = ' '; + j++; + + } else { + + buf[i] = '\n'; + j = 0; + line_num++; + } + } + } + + return; + +} /* load_test_buffer() */ + +#undef LINE_LEN +#undef LINE_NUM_BUF_LEN + + +/*************************************************************************** + * Function: setup_generic_aio_fsync_test + * + * Purpose: Setup test to verify that the aio fsync vfd call works as + * expected for the target file driver. + * + * To do this, open the specified file with the driver + * indicated by the fapl_id, write data to the file with + * the supplied tag, call an aio_fsync, wait or poll (as + * directed) until done, and then exit without closing the + * file. + * + * Return: void + * + * Programmer: John Mainzer + * 1/28/11 + * + **************************************************************************/ + +static void +setup_generic_aio_fsync_test(const int file_name_num, + hid_t fapl_id, + const char * tag, + hsize_t write_size, + haddr_t maxaddr, + hbool_t wait_on_fsync, + hbool_t verbose) +{ + const char * fcn_name = "setup_generic_aio_fsync_test():"; + char * write_buf = NULL; + char filename[1024]; + hbool_t done = FALSE; + hbool_t show_progress = FALSE; + int cp = 0; + int error_num; + herr_t result; + void * wrt_ctlblk_ptr = NULL; + void * fsync_ctlblk_ptr = NULL; + H5FD_t * h5fd_ptr = NULL; + + /* setup the file name */ + if ( pass ) { + + if ( h5_fixname(FILENAMES[file_name_num], fapl_id, + filename, sizeof(filename)) == NULL ) { + + pass = FALSE; + failure_mssg = "h5_fixname() failed (1).\n"; + } + } + + if ( show_progress ) { /* 0 */ + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, pass, cp++); + HDfflush(stdout); + } + + if ( verbose ) { + + HDfprintf(stdout, "%s filename = \"%s\".\n", fcn_name, filename); + HDfprintf(stdout, "%s tag = \"%s\".\n", fcn_name, tag); + HDfprintf(stdout, "%s write_size = 0x%llx.\n", fcn_name, (long long)write_size); + HDfprintf(stdout, "%s max_addr = 0x%llx.\n", fcn_name, (long long)write_size); + HDfprintf(stdout, "%d wait_on_fsync = %d.\n", fcn_name, (int)wait_on_fsync); + HDfprintf(stdout, "%s: FILENAMES[%d] = \"%s\".\n", fcn_name, file_name_num, + FILENAMES[file_name_num]); + HDfflush(stdout); + } + + if ( pass ) { /* allocate write buffer */ + + write_buf = (char *)HDmalloc((size_t)(write_size + 1)); + + if ( write_buf == NULL ) { + + pass = FALSE; + failure_mssg = "write buffer allocation failed."; + } + } + + if ( show_progress ) { /* 1 */ + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, pass, cp++); + HDfflush(stdout); + } + + if ( pass ) { /* setup write buffer */ + + load_test_buffer(write_size, tag, write_buf); + } + + if ( verbose ) { + + HDfprintf(stdout, "%s strlen(write_buf) = %lld.\n", + fcn_name, (long long)strlen(write_buf)); + } + + if ( show_progress ) { /* 2 */ + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, pass, cp++); + HDfflush(stdout); + } + + /* create the file */ + if ( pass ) { + + h5fd_ptr = H5FDopen(filename, (H5F_ACC_RDWR | H5F_ACC_CREAT), + fapl_id, maxaddr); + + if ( h5fd_ptr == NULL ) { + + pass = FALSE; + failure_mssg = "H5FDopen() failed."; + + } else { + + mark_test_in_progress("fsync_test"); + } + } + + if ( show_progress ) { /* 3 */ + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, pass, cp++); + HDfflush(stdout); + } + + /* set the EOA */ + if ( pass ) { + + result = H5FDset_eoa(h5fd_ptr, H5FD_MEM_DEFAULT, maxaddr); + + if ( result < 0 ) { + + pass = FALSE; + failure_mssg = "H5FDset_eoa() failed."; + } + } + + if ( show_progress ) { /* 4 */ + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, pass, cp++); + HDfflush(stdout); + } + + /* do the write */ + if ( pass ) { + + result = H5FDaio_write(h5fd_ptr, H5FD_MEM_DRAW, H5P_DEFAULT, (haddr_t)0, + (size_t)write_size, (void *)write_buf, &wrt_ctlblk_ptr); + + if ( ( result < 0 ) || ( wrt_ctlblk_ptr == NULL ) ) { + + pass = FALSE; + failure_mssg = "H5FDaio_write() failed.\n"; + } + } + + if ( show_progress ) { /* 5 */ + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, pass, cp++); + HDfflush(stdout); + } + + /* do the aio_fsync() */ + if ( pass ) { + + result = H5FDaio_fsync(h5fd_ptr, &fsync_ctlblk_ptr); + + if ( ( result < 0 ) || ( fsync_ctlblk_ptr == NULL ) ) { + + pass = FALSE; + failure_mssg = "H5FDaio_fsync(0) failed."; + } + } + + if ( show_progress ) { /* 6 */ + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, pass, cp++); + HDfflush(stdout); + } + + /* await the completion of the fsync */ + if ( pass ) { + + if ( wait_on_fsync ) { + + result = H5FDaio_wait(h5fd_ptr, fsync_ctlblk_ptr); + + if ( result < 0 ) { + + pass = FALSE; + failure_mssg = "H5FDaio_wait(0) failed."; + } + } else { + + done = FALSE; + + while ( ( pass ) && ( ! done ) ) { + + result = H5FDaio_test(h5fd_ptr, &done, fsync_ctlblk_ptr); + + if ( result < 0 ) { + + pass = FALSE; + failure_mssg = "H5FDaio_test(0) failed."; + } + } + } + } + + if ( show_progress ) { /* 7 */ + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, pass, cp++); + HDfflush(stdout); + } + + /* complete the aio fsync */ + if ( pass ) { + + result = H5FDaio_finish(h5fd_ptr, &error_num, fsync_ctlblk_ptr); + + if ( ( result < 0 ) || ( error_num != 0 ) ) { + + pass = FALSE; + failure_mssg = "H5FDaio_finish(0) failed."; + } + } + + if ( show_progress ) { /* 8 */ + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, pass, cp++); + HDfflush(stdout); + } + + /* at this point, the aio write should be complete as well -- verify this + * and then discard the write buffer. + */ + if ( pass ) { + + done = FALSE; + + result = H5FDaio_test(h5fd_ptr, &done, wrt_ctlblk_ptr); + + if ( result < 0 ) { + + pass = FALSE; + failure_mssg = "H5FDaio_test(1) failed."; + + } else if ( done != TRUE ) { + + pass = FALSE; + failure_mssg = "aio_write() not complete after completion of aio_fsync()."; + + } + } + + if ( show_progress ) { /* 9 */ + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, pass, cp++); + HDfflush(stdout); + } + + /* finish the aio_write() */ + if ( pass ) { + + result = H5FDaio_finish(h5fd_ptr, &error_num, wrt_ctlblk_ptr); + + if ( ( result < 0 ) || ( error_num != 0 ) ) { + + pass = FALSE; + failure_mssg = "H5FDaio_finish(1) failed."; + } + } + + if ( show_progress ) { /* 10 */ + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, pass, cp++); + HDfflush(stdout); + } + + /* discard the write buffer */ + + if ( write_buf != NULL ) { + + HDfree(write_buf); + write_buf = NULL; + } + + if ( show_progress ) { /* 11 */ + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, pass, cp++); + HDfflush(stdout); + } + + /* do the abort */ + if ( pass ) { + + abort(); + } + + if ( show_progress ) { /* 12 */ + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, pass, cp++); + HDfflush(stdout); + } + + return; + +} /* setup_generic_aio_fsync_test() */ + + +/*************************************************************************** + * Function: setup_generic_fsync_test + * + * Purpose: Setup test to verify that the fsync vfd call works as + * expected for the target file driver. + * + * To do this, open the specified file with the driver + * indicated by the fapl_id, write data to the file with + * the supplied tag, call an fsync, and then exit without + * closing the file. + * + * Return: void + * + * Programmer: John Mainzer + * 11/9/11 + * + **************************************************************************/ + +static void +setup_generic_fsync_test(const int file_name_num, + hid_t fapl_id, + const char * tag, + hsize_t write_size, + haddr_t maxaddr, + hbool_t verbose) +{ + const char * fcn_name = "setup_generic_fsync_test():"; + char * write_buf = NULL; + char filename[1024]; + hbool_t show_progress = FALSE; + int cp = 0; + herr_t result; + H5FD_t * h5fd_ptr = NULL; + + /* setup the file name */ + if ( pass ) { + + if ( h5_fixname(FILENAMES[file_name_num], fapl_id, + filename, sizeof(filename)) == NULL ) { + + pass = FALSE; + failure_mssg = "h5_fixname() failed (1).\n"; + } + } + + if ( show_progress ) { /* 0 */ + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, pass, cp++); + HDfflush(stdout); + } + + if ( verbose ) { + + HDfprintf(stdout, "%s filename = \"%s\".\n", fcn_name, filename); + HDfprintf(stdout, "%s tag = \"%s\".\n", fcn_name, tag); + HDfprintf(stdout, "%s write_size = 0x%llx.\n", fcn_name, (long long)write_size); + HDfprintf(stdout, "%s max_addr = 0x%llx.\n", fcn_name, (long long)write_size); + HDfprintf(stdout, "%s: FILENAMES[%d] = \"%s\".\n", fcn_name, file_name_num, + FILENAMES[file_name_num]); + HDfflush(stdout); + } + + if ( pass ) { /* allocate write buffer */ + + write_buf = (char *)HDmalloc((size_t)(write_size + 1)); + + if ( write_buf == NULL ) { + + pass = FALSE; + failure_mssg = "write buffer allocation failed."; + } + } + + if ( show_progress ) { /* 1 */ + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, pass, cp++); + HDfflush(stdout); + } + + if ( pass ) { /* setup write buffer */ + + load_test_buffer(write_size, tag, write_buf); + } + + if ( verbose ) { + + HDfprintf(stdout, "%s strlen(write_buf) = %lld.\n", + fcn_name, (long long)strlen(write_buf)); + } + + if ( show_progress ) { /* 2 */ + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, pass, cp++); + HDfflush(stdout); + } + + /* create the file */ + if ( pass ) { + + h5fd_ptr = H5FDopen(filename, (H5F_ACC_RDWR | H5F_ACC_CREAT), + fapl_id, maxaddr); + + if ( h5fd_ptr == NULL ) { + + pass = FALSE; + failure_mssg = "H5FDopen() failed."; + + } else { + + mark_test_in_progress("fsync_test"); + } + } + + if ( show_progress ) { /* 3 */ + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, pass, cp++); + HDfflush(stdout); + } + + /* set the EOA */ + if ( pass ) { + + result = H5FDset_eoa(h5fd_ptr, H5FD_MEM_DEFAULT, maxaddr); + + if ( result < 0 ) { + + pass = FALSE; + failure_mssg = "H5FDset_eoa() failed."; + } + } + + if ( show_progress ) { /* 4 */ + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, pass, cp++); + HDfflush(stdout); + } + + /* do the write */ + if ( pass ) { + + result = H5FDwrite(h5fd_ptr, H5FD_MEM_DRAW, H5P_DEFAULT, (haddr_t)0, + (size_t)write_size, (void *)write_buf); + + if ( result < 0 ) { + + pass = FALSE; + failure_mssg = "H5FDwrite() failed.\n"; + } + } + + if ( show_progress ) { /* 5 */ + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, pass, cp++); + HDfflush(stdout); + } + + /* discard the write buffer */ + + if ( write_buf != NULL ) { + + HDfree(write_buf); + write_buf = NULL; + } + + if ( show_progress ) { /* 6 */ + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, pass, cp++); + HDfflush(stdout); + } + + + /* do the fsync */ + if ( pass ) { + + result = H5FDfsync(h5fd_ptr, H5P_DEFAULT); + + if ( result < 0 ) { + + pass = FALSE; + failure_mssg = "H5FDfsync() failed.\n"; + } + } + + if ( show_progress ) { /* 7 */ + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, pass, cp++); + HDfflush(stdout); + } + + /* do the abort */ + if ( pass ) { + + abort(); + } + + if ( show_progress ) { /* 8 */ + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, pass, cp++); + HDfflush(stdout); + } + + return; + +} /* setup_generic_fsync_test() */ + + +/*************************************************************************** + * Function: setup_multi_file_driver_fsync_test + * + * Purpose: Setup test to verify that the fsync vfd call works as + * expected for the target file driver. + * + * To do this, open the specified file with the driver + * indicated by the fapl_id, write data to the file with + * the supplied tag, call an fsync, and then exit without + * closing the file. + * + * Return: void + * + * Programmer: John Mainzer + * 2/4/11 + * + **************************************************************************/ + +static void +setup_multi_file_driver_fsync_test(const int file_name_num, + const char * tag, + hsize_t write_size, + hbool_t verbose) +{ + const char * fcn_name = "setup_multi_file_driver_fsync_test():"; + const char * memb_name[H5FD_MEM_NTYPES]; + const char * (type_names[H5FD_MEM_NTYPES]) = + { + "H5FD_MEM_DEFAULT", + "H5FD_MEM_SUPER", + "H5FD_MEM_BTREE", + "H5FD_MEM_DRAW", + "H5FD_MEM_GHEAP", + "H5FD_MEM_LHEAP", + "H5FD_MEM_OHDR" + }; + char * (write_bufs[H5FD_MEM_NTYPES]) = { NULL, NULL, NULL, NULL, NULL, NULL, NULL }; + char filename[1024]; + hbool_t show_progress = FALSE; + int cp = 0; + unsigned int i; + hid_t fapl_id; + hid_t memb_fapl[H5FD_MEM_NTYPES]; + herr_t result; + haddr_t eoa; + haddr_t max_addr; + haddr_t memb_addr[H5FD_MEM_NTYPES]; + H5FD_mem_t mt; + H5FD_mem_t memb_map[H5FD_MEM_NTYPES]; + H5FD_t * h5fd_ptr = NULL; + + if ( show_progress ) { /* 0 */ + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, pass, cp++); + HDfflush(stdout); + } + + if ( pass ) { /* setup fapl for multi file driver */ + + for ( mt = 0; mt < H5FD_MEM_NTYPES; mt++ ) { + + memb_addr[mt] = HADDR_UNDEF; + memb_fapl[mt] = H5P_DEFAULT; + memb_map[mt] = H5FD_MEM_DRAW; + memb_name[mt] = NULL; + } + + memb_map[H5FD_MEM_SUPER] = H5FD_MEM_SUPER; + memb_fapl[H5FD_MEM_SUPER] = H5P_DEFAULT; + memb_name[H5FD_MEM_SUPER] = "%s-s.h5"; + memb_addr[H5FD_MEM_SUPER] = 0; + + memb_map[H5FD_MEM_BTREE] = H5FD_MEM_BTREE; + memb_fapl[H5FD_MEM_BTREE] = H5P_DEFAULT; + memb_name[H5FD_MEM_BTREE] = "%s-b.h5"; + memb_addr[H5FD_MEM_BTREE] = memb_addr[H5FD_MEM_SUPER] + TYPE_SLICE; + + memb_map[H5FD_MEM_DRAW] = H5FD_MEM_DRAW; + memb_fapl[H5FD_MEM_DRAW] = H5P_DEFAULT; + memb_name[H5FD_MEM_DRAW] = "%s-r.h5"; + memb_addr[H5FD_MEM_DRAW] = memb_addr[H5FD_MEM_BTREE] + TYPE_SLICE; + + memb_map[H5FD_MEM_GHEAP] = H5FD_MEM_GHEAP; + memb_fapl[H5FD_MEM_GHEAP] = H5P_DEFAULT; + memb_name[H5FD_MEM_GHEAP] = "%s-g.h5"; + memb_addr[H5FD_MEM_GHEAP] = memb_addr[H5FD_MEM_DRAW] + TYPE_SLICE; + + memb_map[H5FD_MEM_LHEAP] = H5FD_MEM_LHEAP; + memb_fapl[H5FD_MEM_LHEAP] = H5P_DEFAULT; + memb_name[H5FD_MEM_LHEAP] = "%s-l.h5"; + memb_addr[H5FD_MEM_LHEAP] = memb_addr[H5FD_MEM_GHEAP] + TYPE_SLICE; + + memb_map[H5FD_MEM_OHDR] = H5FD_MEM_OHDR; + memb_fapl[H5FD_MEM_OHDR] = H5P_DEFAULT; + memb_name[H5FD_MEM_OHDR] = "%s-o.h5"; + memb_addr[H5FD_MEM_OHDR] = memb_addr[H5FD_MEM_LHEAP] + TYPE_SLICE; + + max_addr = memb_addr[H5FD_MEM_OHDR] + TYPE_SLICE; + + fapl_id = h5_fileaccess(); + + if ( H5Pset_fapl_multi(fapl_id, memb_map, memb_fapl, memb_name, + memb_addr, FALSE) < 0 ) { + + pass = FALSE; + failure_mssg = "H5Pset_fapl_multi() failed."; + + } + } + + if ( show_progress ) { /* 1 */ + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, pass, cp++); + HDfflush(stdout); + } + + + /* setup the file name */ + if ( pass ) { + + if ( h5_fixname(FILENAMES[file_name_num], fapl_id, + filename, sizeof(filename)) == NULL ) { + + pass = FALSE; + failure_mssg = "h5_fixname() failed (1).\n"; + } + } + + if ( verbose ) { + + HDfprintf(stdout, "%s filename = \"%s\".\n", fcn_name, filename); + HDfprintf(stdout, "%s tag = \"%s\".\n", fcn_name, tag); + HDfprintf(stdout, "%s write_size = 0x%llx.\n", fcn_name, (long long)write_size); + HDfprintf(stdout, "%s max_addr = 0x%llx.\n", fcn_name, (long long)max_addr); + HDfprintf(stdout, "%s: FILENAMES[%d] = \"%s\".\n", fcn_name, file_name_num, + FILENAMES[file_name_num]); + HDfflush(stdout); + } + + if ( show_progress ) { /* 2 */ + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, pass, cp++); + HDfflush(stdout); + } + + if ( pass ) { /* allocate write buffer */ + + for ( i = H5FD_MEM_SUPER; i <= H5FD_MEM_OHDR; i++ ) { + + write_bufs[i] = (char *)HDmalloc((size_t)(write_size + 1)); + + if ( write_bufs[i] == NULL ) { + + pass = FALSE; + failure_mssg = "write buffer allocation failed."; + } + } + } + + if ( show_progress ) { /* 3 */ + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, pass, cp++); + HDfflush(stdout); + } + + if ( pass ) { /* setup write buffers */ + + char file_tag[80]; + + HDassert( tag != NULL ); + HDassert( strlen(tag) <= 30 ); + + for ( i = H5FD_MEM_SUPER; i <= H5FD_MEM_OHDR; i++ ) { + + HDsnprintf(file_tag, (size_t)80, "%s:%s", tag, type_names[i]); + HDassert( strlen(file_tag) <= 48 ); + load_test_buffer(write_size, file_tag, write_bufs[i]); + + if ( verbose ) { + + HDfprintf(stdout, "%s strlen(write_bufs[%d]) = %lld.\n", + fcn_name, i, (long long)strlen(write_bufs[i])); + } + } + } + + if ( show_progress ) { /* 4 */ + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, pass, cp++); + HDfflush(stdout); + } + + /* create the file */ + if ( pass ) { + + h5fd_ptr = H5FDopen(filename, (H5F_ACC_RDWR | H5F_ACC_CREAT), + fapl_id, max_addr); + + if ( h5fd_ptr == NULL ) { + + pass = FALSE; + failure_mssg = "H5FDopen() failed."; + + } else { + + mark_test_in_progress("fsync_test"); + } + } + + if ( show_progress ) { /* 5 */ + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, pass, cp++); + HDfflush(stdout); + } + + /* set the EOA */ + + if ( verbose ) { + + for ( mt = H5FD_MEM_SUPER; mt <= H5FD_MEM_OHDR; mt++ ) { + + eoa = H5FDget_eoa(h5fd_ptr, mt); + + if ( eoa == HADDR_UNDEF ) { + + HDfprintf(stdout, "%s: H5FDget_eoa(h5fd_ptr, %s) failed.\n", + fcn_name, type_names[(int)mt]); + + } else { + + HDfprintf(stdout, "%s: H5FDget_eoa(h5fd_ptr, %s) returned 0x%llx.\n", + fcn_name, type_names[(int)mt], (unsigned long long)eoa); + + } + } + } + + mt = H5FD_MEM_SUPER; + while ( ( pass ) && ( mt <= H5FD_MEM_OHDR ) ) { + + if ( verbose ) { + + HDfprintf(stdout, + "calling H5FDset_eoa(h5fd_ptr, %s, (%d * TYPE_SLICE) - 1).\n", + type_names[(int)mt], (int)(mt)); + } + + result = H5FDset_eoa(h5fd_ptr, mt, (((haddr_t)(mt)) * TYPE_SLICE) - 1); + + if ( result < 0 ) { + + pass = FALSE; + failure_mssg = "H5FDset_eoa() failed."; + } + + mt++; + } + + if ( verbose ) { + + for ( mt = H5FD_MEM_SUPER; mt <= H5FD_MEM_OHDR; mt++ ) { + + eoa = H5FDget_eoa(h5fd_ptr, mt); + + if ( eoa == HADDR_UNDEF ) { + + HDfprintf(stdout, "%s: H5FDget_eoa(h5fd_ptr, %s) failed.\n", + fcn_name, type_names[(int)mt]); + + } else { + + HDfprintf(stdout, "%s: H5FDget_eoa(h5fd_ptr, %s) returned 0x%llx.\n", + fcn_name, type_names[(int)mt], (unsigned long long)eoa); + + } + } + } + + if ( show_progress ) { /* 6 */ + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, pass, cp++); + HDfflush(stdout); + } + + /* do the write */ + if ( pass ) { + + i = H5FD_MEM_SUPER; + + while ( ( pass ) && ( i <= H5FD_MEM_OHDR ) ) { + + if ( verbose ) { + + HDfprintf(stdout, + "calling H5FDwrite(h5fd_ptr, %s, H5P_DEFAULT, 0x%llx, 0x%llx, write_bufs[%d])\n", + type_names[i], + (unsigned long long)(((haddr_t)(i - 1)) * TYPE_SLICE), + (unsigned long long)write_size, + i); + } + + result = H5FDwrite(h5fd_ptr, (H5F_mem_t)i, H5P_DEFAULT, + ((haddr_t)(i - 1)) * TYPE_SLICE, + (size_t)write_size, (void *)write_bufs[i]); + + if ( result < 0 ) { + + pass = FALSE; + failure_mssg = "H5FDwrite() failed.\n"; + } + + i++; + } + } + + if ( show_progress ) { /* 7 */ + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, pass, cp++); + HDfflush(stdout); + } + + /* discard the write buffers */ + + for ( i = H5FD_MEM_SUPER; i <= H5FD_MEM_OHDR; i++ ) { + + if ( write_bufs[i] != NULL ) { + + HDfree(write_bufs[i]); + write_bufs[i] = NULL; + } + } + + if ( show_progress ) { /* 8 */ + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, pass, cp++); + HDfflush(stdout); + } + + + /* do the fsync */ + if ( pass ) { + + result = H5FDfsync(h5fd_ptr, H5P_DEFAULT); + + if ( result < 0 ) { + + pass = FALSE; + failure_mssg = "H5FDfsync() failed.\n"; + } + } + + if ( show_progress ) { /* 9 */ + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, pass, cp++); + HDfflush(stdout); + } + + /* do the abort */ + if ( pass ) { + + abort(); + } + + if ( show_progress ) { /* 10 */ + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, pass, cp++); + HDfflush(stdout); + } + + return; + +} /* setup_multi_file_driver_fsync_test() */ + + +/*************************************************************************** + * Function: setup_multi_file_driver_aio_fsync_test + * + * Purpose: Setup test to verify that the aio fsync vfd call works as + * expected for the multi file driver. + * + * To do this, open the specified file with the multi file + * driver, write data to the file with the supplied tag, call + * an aio fsync, and then exit without closing the file. + * + * Return: void + * + * Programmer: John Mainzer + * 2/4/11 + * + **************************************************************************/ + +static void +setup_multi_file_driver_aio_fsync_test(const int file_name_num, + const char * tag, + hsize_t write_size, + hbool_t wait_on_fsync, + hbool_t verbose) +{ + const char * fcn_name = "setup_multi_file_driver_aio_fsync_test():"; + const char * memb_name[H5FD_MEM_NTYPES]; + const char * (type_names[H5FD_MEM_NTYPES]) = + { + "H5FD_MEM_DEFAULT", + "H5FD_MEM_SUPER", + "H5FD_MEM_BTREE", + "H5FD_MEM_DRAW", + "H5FD_MEM_GHEAP", + "H5FD_MEM_LHEAP", + "H5FD_MEM_OHDR" + }; + char * (write_bufs[H5FD_MEM_NTYPES]) = { NULL, NULL, NULL, NULL, NULL, NULL, NULL }; + char filename[1024]; + hbool_t done; + hbool_t show_progress = FALSE; + int cp = 0; + int error_num; + unsigned int i; + hid_t fapl_id; + hid_t memb_fapl[H5FD_MEM_NTYPES]; + herr_t result; + haddr_t eoa; + haddr_t max_addr; + haddr_t memb_addr[H5FD_MEM_NTYPES]; + void * (wrt_ctlblk_ptrs[H5FD_MEM_NTYPES]) = { NULL, NULL, NULL, NULL, NULL, NULL, NULL }; + void * fsync_ctlblk_ptr = NULL; + H5FD_mem_t mt; + H5FD_mem_t memb_map[H5FD_MEM_NTYPES]; + H5FD_t * h5fd_ptr = NULL; + + if ( show_progress ) { /* 0 */ + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, pass, cp++); + HDfflush(stdout); + } + + if ( pass ) { /* setup fapl for multi file driver */ + + for ( mt = 0; mt < H5FD_MEM_NTYPES; mt++ ) { + + memb_addr[mt] = HADDR_UNDEF; + memb_fapl[mt] = H5P_DEFAULT; + memb_map[mt] = H5FD_MEM_DRAW; + memb_name[mt] = NULL; + } + + memb_map[H5FD_MEM_SUPER] = H5FD_MEM_SUPER; + memb_fapl[H5FD_MEM_SUPER] = H5P_DEFAULT; + memb_name[H5FD_MEM_SUPER] = "%s-s.h5"; + memb_addr[H5FD_MEM_SUPER] = 0; + + memb_map[H5FD_MEM_BTREE] = H5FD_MEM_BTREE; + memb_fapl[H5FD_MEM_BTREE] = H5P_DEFAULT; + memb_name[H5FD_MEM_BTREE] = "%s-b.h5"; + memb_addr[H5FD_MEM_BTREE] = memb_addr[H5FD_MEM_SUPER] + TYPE_SLICE; + + memb_map[H5FD_MEM_DRAW] = H5FD_MEM_DRAW; + memb_fapl[H5FD_MEM_DRAW] = H5P_DEFAULT; + memb_name[H5FD_MEM_DRAW] = "%s-r.h5"; + memb_addr[H5FD_MEM_DRAW] = memb_addr[H5FD_MEM_BTREE] + TYPE_SLICE; + + memb_map[H5FD_MEM_GHEAP] = H5FD_MEM_GHEAP; + memb_fapl[H5FD_MEM_GHEAP] = H5P_DEFAULT; + memb_name[H5FD_MEM_GHEAP] = "%s-g.h5"; + memb_addr[H5FD_MEM_GHEAP] = memb_addr[H5FD_MEM_DRAW] + TYPE_SLICE; + + memb_map[H5FD_MEM_LHEAP] = H5FD_MEM_LHEAP; + memb_fapl[H5FD_MEM_LHEAP] = H5P_DEFAULT; + memb_name[H5FD_MEM_LHEAP] = "%s-l.h5"; + memb_addr[H5FD_MEM_LHEAP] = memb_addr[H5FD_MEM_GHEAP] + TYPE_SLICE; + + memb_map[H5FD_MEM_OHDR] = H5FD_MEM_OHDR; + memb_fapl[H5FD_MEM_OHDR] = H5P_DEFAULT; + memb_name[H5FD_MEM_OHDR] = "%s-o.h5"; + memb_addr[H5FD_MEM_OHDR] = memb_addr[H5FD_MEM_LHEAP] + TYPE_SLICE; + + max_addr = memb_addr[H5FD_MEM_OHDR] + TYPE_SLICE; + + fapl_id = h5_fileaccess(); + + if ( H5Pset_fapl_multi(fapl_id, memb_map, memb_fapl, memb_name, + memb_addr, FALSE) < 0 ) { + + pass = FALSE; + failure_mssg = "H5Pset_fapl_multi() failed."; + + } + } + + if ( show_progress ) { /* 1 */ + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, pass, cp++); + HDfflush(stdout); + } + + + /* setup the file name */ + if ( pass ) { + + if ( h5_fixname(FILENAMES[file_name_num], fapl_id, + filename, sizeof(filename)) == NULL ) { + + pass = FALSE; + failure_mssg = "h5_fixname() failed (1).\n"; + } + } + + if ( verbose ) { + + HDfprintf(stdout, "%s filename = \"%s\".\n", fcn_name, filename); + HDfprintf(stdout, "%s tag = \"%s\".\n", fcn_name, tag); + HDfprintf(stdout, "%s write_size = 0x%llx.\n", fcn_name, (long long)write_size); + HDfprintf(stdout, "%s max_addr = 0x%llx.\n", fcn_name, (long long)max_addr); + HDfprintf(stdout, "%s: FILENAMES[%d] = \"%s\".\n", fcn_name, file_name_num, + FILENAMES[file_name_num]); + HDfflush(stdout); + } + + if ( show_progress ) { /* 2 */ + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, pass, cp++); + HDfflush(stdout); + } + + if ( pass ) { /* allocate write buffer */ + + for ( i = H5FD_MEM_SUPER; i <= H5FD_MEM_OHDR; i++ ) { + + write_bufs[i] = (char *)HDmalloc((size_t)(write_size + 1)); + + if ( write_bufs[i] == NULL ) { + + pass = FALSE; + failure_mssg = "write buffer allocation failed."; + } + } + } + + if ( show_progress ) { /* 3 */ + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, pass, cp++); + HDfflush(stdout); + } + + if ( pass ) { /* setup write buffers */ + + char file_tag[80]; + + HDassert( tag != NULL ); + HDassert( strlen(tag) <= 30 ); + + for ( i = H5FD_MEM_SUPER; i <= H5FD_MEM_OHDR; i++ ) { + + HDsnprintf(file_tag, (size_t)80, "%s:%s", tag, type_names[i]); + HDassert( strlen(file_tag) <= 48 ); + load_test_buffer(write_size, file_tag, write_bufs[i]); + + if ( verbose ) { + + HDfprintf(stdout, "%s strlen(write_bufs[%d]) = %lld.\n", + fcn_name, i, (long long)strlen(write_bufs[i])); + } + } + } + + if ( show_progress ) { /* 4 */ + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, pass, cp++); + HDfflush(stdout); + } + + /* create the file */ + if ( pass ) { + + h5fd_ptr = H5FDopen(filename, (H5F_ACC_RDWR | H5F_ACC_CREAT), + fapl_id, max_addr); + + if ( h5fd_ptr == NULL ) { + + pass = FALSE; + failure_mssg = "H5FDopen() failed."; + + } else { + + mark_test_in_progress("fsync_test"); + } + } + + if ( show_progress ) { /* 5 */ + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, pass, cp++); + HDfflush(stdout); + } + + /* set the EOA */ + + if ( verbose ) { + + for ( mt = H5FD_MEM_SUPER; mt <= H5FD_MEM_OHDR; mt++ ) { + + eoa = H5FDget_eoa(h5fd_ptr, mt); + + if ( eoa == HADDR_UNDEF ) { + + HDfprintf(stdout, "%s: H5FDget_eoa(h5fd_ptr, %s) failed.\n", + fcn_name, type_names[(int)mt]); + + } else { + + HDfprintf(stdout, "%s: H5FDget_eoa(h5fd_ptr, %s) returned 0x%llx.\n", + fcn_name, type_names[(int)mt], (unsigned long long)eoa); + + } + } + } + + mt = H5FD_MEM_SUPER; + while ( ( pass ) && ( mt <= H5FD_MEM_OHDR ) ) { + + if ( verbose ) { + + HDfprintf(stdout, + "calling H5FDset_eoa(h5fd_ptr, %s, (%d * TYPE_SLICE) - 1).\n", + type_names[(int)mt], (int)(mt)); + } + + result = H5FDset_eoa(h5fd_ptr, mt, (((haddr_t)(mt)) * TYPE_SLICE) - 1); + + if ( result < 0 ) { + + pass = FALSE; + failure_mssg = "H5FDset_eoa() failed."; + } + + mt++; + } + + if ( verbose ) { + + for ( mt = H5FD_MEM_SUPER; mt <= H5FD_MEM_OHDR; mt++ ) { + + eoa = H5FDget_eoa(h5fd_ptr, mt); + + if ( eoa == HADDR_UNDEF ) { + + HDfprintf(stdout, "%s: H5FDget_eoa(h5fd_ptr, %s) failed.\n", + fcn_name, type_names[(int)mt]); + + } else { + + HDfprintf(stdout, "%s: H5FDget_eoa(h5fd_ptr, %s) returned 0x%llx.\n", + fcn_name, type_names[(int)mt], (unsigned long long)eoa); + + } + } + } + + if ( show_progress ) { /* 6 */ + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, pass, cp++); + HDfflush(stdout); + } + + /* queue the writes */ + if ( pass ) { + + i = H5FD_MEM_SUPER; + + while ( ( pass ) && ( i <= H5FD_MEM_OHDR ) ) { + + if ( verbose ) { + + HDfprintf(stdout, + "calling H5FDaio_write(%s, %s, %s, 0x%llx, 0x%llx, write_bufs[%d], &(wrt_ctlblk_ptrs[%d])\n", + "h5fd_ptr", + type_names[i], + "H5P_DEFAULT", + (unsigned long long)(((haddr_t)(i - 1)) * TYPE_SLICE), + (unsigned long long)write_size, + i, + i); + } + + result = H5FDaio_write(h5fd_ptr, (H5F_mem_t)i, H5P_DEFAULT, + ((haddr_t)(i - 1)) * TYPE_SLICE, + (size_t)write_size, (void *)write_bufs[i], + &(wrt_ctlblk_ptrs[i])); + + if ( ( result < 0 ) || ( wrt_ctlblk_ptrs[i] == NULL ) ) { + + pass = FALSE; + failure_mssg = "H5FDaio_write() failed.\n"; + } + + i++; + } + } + + if ( show_progress ) { /* 7 */ + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, pass, cp++); + HDfflush(stdout); + } + + /* do the aio_fsync() */ + if ( pass ) { + + result = H5FDaio_fsync(h5fd_ptr, &fsync_ctlblk_ptr); + + if ( ( result < 0 ) || ( fsync_ctlblk_ptr == NULL ) ) { + + pass = FALSE; + failure_mssg = "H5FDaio_fsync(0) failed."; + } + } + + if ( show_progress ) { /* 8 */ + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, pass, cp++); + HDfflush(stdout); + } + + /* await the completion of the fsync */ + if ( pass ) { + + if ( wait_on_fsync ) { + + result = H5FDaio_wait(h5fd_ptr, fsync_ctlblk_ptr); + + if ( result < 0 ) { + + pass = FALSE; + failure_mssg = "H5FDaio_wait(0) failed."; + } + } else { + + done = FALSE; + + while ( ( pass ) && ( ! done ) ) { + + result = H5FDaio_test(h5fd_ptr, &done, fsync_ctlblk_ptr); + + if ( result < 0 ) { + + pass = FALSE; + failure_mssg = "H5FDaio_test(0) failed."; + } + } + } + } + + if ( show_progress ) { /* 9 */ + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, pass, cp++); + HDfflush(stdout); + } + + /* complete the aio fsync */ + if ( pass ) { + + result = H5FDaio_finish(h5fd_ptr, &error_num, fsync_ctlblk_ptr); + + if ( ( result < 0 ) || ( error_num != 0 ) ) { + + pass = FALSE; + failure_mssg = "H5FDaio_finish(0) failed."; + } + } + + if ( show_progress ) { /* 10 */ + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, pass, cp++); + HDfflush(stdout); + } + + /* at this point, the aio writes should be complete as well -- verify this. */ + if ( pass ) { + + i = H5FD_MEM_SUPER; + + while ( ( pass ) && ( i <= H5FD_MEM_OHDR ) ) { + + done = FALSE; + + result = H5FDaio_test(h5fd_ptr, &done, wrt_ctlblk_ptrs[i]); + + if ( result < 0 ) { + + pass = FALSE; + failure_mssg = "H5FDaio_test(1) failed."; + + } else if ( done != TRUE ) { + + pass = FALSE; + failure_mssg = "aio_write() not complete after completion of aio_fsync()."; + + } + + i++; + } + } + + if ( show_progress ) { /* 11 */ + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, pass, cp++); + HDfflush(stdout); + } + + /* discard the write buffers */ + + for ( i = H5FD_MEM_SUPER; i <= H5FD_MEM_OHDR; i++ ) { + + if ( write_bufs[i] != NULL ) { + + HDfree(write_bufs[i]); + write_bufs[i] = NULL; + } + } + + if ( show_progress ) { /* 12 */ + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, pass, cp++); + HDfflush(stdout); + } + + /* do the abort */ + if ( pass ) { + + abort(); + } + + if ( show_progress ) { /* 13 */ + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, pass, cp++); + HDfflush(stdout); + } + + return; + +} /* setup_multi_file_driver_aio_fsync_test() */ + + +/*************************************************************************** + * Function: check_generic_fsync_test + * + * Purpose: Check to verify that the specified file contains the + * expected data. + * + * To do this, first check to verify that a test is in + * progress. + * + * Then open the test file created by + * setup_generic_fsync_test(), and verify that it + * contains the expected data. + * + * On either success or failure, clean up the test file. + * + * Return: void + * + * Programmer: John Mainzer + * 11/9/10 + * + **************************************************************************/ + +static void +check_generic_fsync_test(const int file_name_num, + hid_t fapl_id, + const char * tag, + hsize_t file_size, + haddr_t maxaddr, + hbool_t verbose) +{ + const char * fcn_name = "check_generic_fsync_test():"; + char * read_buf = NULL; + char * test_buf = NULL; + char file_name[1024]; + hbool_t show_progress = FALSE; + hbool_t skip_file_existance_and_size_checks = FALSE; + int cp = 0; + herr_t result; + hsize_t i; + hid_t driver_id; + H5FD_t * h5fd_ptr = NULL; + h5_stat_t buf; + + check_test_in_progress("fsync_test", verbose); + + if ( pass ) { + + driver_id = H5Pget_driver(fapl_id); + + if ( driver_id < 0 ) { + + pass = FALSE; + failure_mssg = "H5Pget_driver() failed.\n"; + + } else if ( ( driver_id == H5FD_FAMILY ) || ( driver_id == H5FD_MULTI ) ) { + + /* file appears to be a family or multi file -- thus the usual + * existance and size checks will fail. + */ + skip_file_existance_and_size_checks = TRUE; + } + } + + /* setup the file name */ + if ( pass ) { + + if ( h5_fixname(FILENAMES[file_name_num], fapl_id, file_name, + sizeof(file_name)) == NULL ) { + + pass = FALSE; + failure_mssg = "h5_fixname() failed.\n"; + } + } + + if ( show_progress ) { /* 0 */ + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, pass, cp++); + HDfflush(stdout); + } + + if ( verbose ) { + HDfprintf(stdout, "%s file_name = \"%s\".\n", fcn_name, file_name); + HDfprintf(stdout, "%s skip_file_existance_and_size_checks = %d.\n", + fcn_name, (int)skip_file_existance_and_size_checks); + HDfflush(stdout); + } + + /* allocate the read and expected data buffers */ + if ( pass ) { + + read_buf = (char *)HDmalloc((size_t)(file_size + 1)); + test_buf = (char *)HDmalloc((size_t)(file_size + 1)); + + if ( ( read_buf == NULL ) || + ( test_buf == NULL ) ) { + + pass = FALSE; + failure_mssg = "buffer allocation(s) failed."; + } + } + + if ( show_progress ) { /* 1 */ + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, (int)pass, cp++); + HDfflush(stdout); + } + + /* initialize the expected data buffer */ + if ( pass ) { + + load_test_buffer(file_size, tag, test_buf); + } + + if ( show_progress ) { /* 2 */ + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, (int)pass, cp++); + HDfflush(stdout); + } + + /* verify that the target file exists. Note that we skip this test if + * skip_file_existance_and_size_checks is true -- in this case we are + * dealing with either a family or multi file name, and thus that no + * file of the exact name provided can be expected to exist. + */ + if ( ( pass ) && + ( ! skip_file_existance_and_size_checks ) && + ( ! file_exists(file_name, verbose) ) ) { + + pass = FALSE; + failure_mssg = "target file doesn't exist?"; + } + + if ( show_progress ) { /* 3 */ + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, (int)pass, cp++); + HDfflush(stdout); + } + + /* verify that the target file is of the expected length */ + if ( ( pass ) && ( ! skip_file_existance_and_size_checks ) ) { + + if ( HDstat(file_name, &buf) != 0 ) { + + if ( verbose ) { + + HDfprintf(stdout, "%s: HDstat() failed with errno = %d.\n", + fcn_name, errno); + } + + failure_mssg = "stat() failed on test in progress file."; + pass = FALSE; + + } else { + + if ( (buf.st_size) == 0 ) { + + failure_mssg = "target file is empty?!?"; + pass = FALSE; + + } else if ( (hsize_t)(buf.st_size) < file_size ) { + + failure_mssg = "target file is too small?!?"; + pass = FALSE; + + } else if ( (hsize_t)(buf.st_size) > file_size ) { + + failure_mssg = "target file is too big?!?"; + pass = FALSE; + } + } + } + + if ( show_progress ) { /* 4 */ + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, (int)pass, cp++); + HDfflush(stdout); + } + + /* open the indicated file with the specifiec file driver */ + if ( pass ) { + + h5fd_ptr = H5FDopen(file_name, H5F_ACC_RDWR, fapl_id, maxaddr); + + if ( h5fd_ptr == NULL ) { + + pass = FALSE; + failure_mssg = "H5FDopen() failed."; + } + } + + if ( show_progress ) { /* 5 */ + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, (int)pass, cp++); + HDfflush(stdout); + } + + /* set the eoa */ + if ( pass ) { + + result = H5FDset_eoa(h5fd_ptr, H5FD_MEM_DEFAULT, maxaddr); + + if ( result < 0 ) { + + pass = FALSE; + failure_mssg = "H5FDset_eoa() failed."; + } + } + + if ( show_progress ) { /* 6 */ + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, (int)pass, cp++); + HDfflush(stdout); + } + + /* read the contents of the target file */ + if ( pass ) { + + result = H5FDread(h5fd_ptr, H5FD_MEM_DEFAULT, H5P_DEFAULT, (haddr_t)0, + (size_t)file_size, (void *)read_buf); + + if ( result < 0 ) { + + pass = FALSE; + failure_mssg = "H5FDread() failed."; + } + } + + if ( show_progress ) { /* 7 */ + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, (int)pass, cp++); + HDfflush(stdout); + } + + /* compare the actual file target file data with the expected contents */ + if ( pass ) { + + /* observe that this test is weak if skip_file_existance_and_size_checks + * TRUE -- it only tells us if the file contains the expected data -- + * not if it contains extranious data. Unfortunately, to the best of + * my knowlege we don't have any easy way to determine file size in the + * family and multi file case. Thus this is as best we can do right now + * without building extensive knowlege of these formats into the test. + */ + + i = 0; + while ( ( pass ) && ( i < file_size ) ) { + + if ( read_buf[i] != test_buf[i] ) { + + if ( verbose ) { + + HDfprintf(stdout, "data mismatch at %d.\n", i); + HDfflush(stdout); + } + + pass = FALSE; + failure_mssg = "data mismatch"; + } + + i++; + } + } + + if ( show_progress ) { /* 8 */ + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, (int)pass, cp++); + HDfflush(stdout); + } + + /* close target file */ + if ( pass ) { + + result = H5FDclose(h5fd_ptr); + + if ( result < 0 ) { + + pass = FALSE; + failure_mssg = "H5FDclose() failed."; + } + } + + if ( show_progress ) { /* 9 */ + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, (int)pass, cp++); + HDfflush(stdout); + } + + /* discard the read and expected buffers */ + + if ( read_buf != NULL ) { + + HDfree(read_buf); + read_buf = NULL; + } + + if ( test_buf != NULL ) { + + HDfree(test_buf); + test_buf = NULL; + } + + if ( show_progress ) { /* 10 */ + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, (int)pass, cp++); + HDfflush(stdout); + } + + + /* delete the target file */ + if ( pass ) { +#if 1 + h5_cleanup(FILENAMES, fapl_id); +#endif + } + + return; + +} /* check_generic_fsync_test() */ + + +/*************************************************************************** + * Function: check_multi_file_driver_fsync_test + * + * Purpose: Check to verify that the specified file contains the + * expected data. + * + * To do this, first check to verify that a test is in + * progress. + * + * Then open the test file created by + * setup_generic_fsync_test(), and verify that it + * contains the expected data. + * + * On either success or failure, clean up the test file. + * + * Return: void + * + * Programmer: John Mainzer + * 11/9/10 + * + **************************************************************************/ + +static void +check_multi_file_driver_fsync_test(const int file_name_num, + const char * tag, + hsize_t write_size, + hbool_t verbose) +{ + const char * fcn_name = "check_multi_file_driver_fsync_test():"; + const char * memb_name[H5FD_MEM_NTYPES]; + const char * (type_names[H5FD_MEM_NTYPES]) = + { + "H5FD_MEM_DEFAULT", + "H5FD_MEM_SUPER", + "H5FD_MEM_BTREE", + "H5FD_MEM_DRAW", + "H5FD_MEM_GHEAP", + "H5FD_MEM_LHEAP", + "H5FD_MEM_OHDR" + }; + char * (read_bufs[H5FD_MEM_NTYPES]) = { NULL, NULL, NULL, NULL, NULL, NULL, NULL }; + char * (test_bufs[H5FD_MEM_NTYPES]) = { NULL, NULL, NULL, NULL, NULL, NULL, NULL }; + char file_name[1024]; + hbool_t show_progress = FALSE; + int cp = 0; + herr_t result; + hsize_t i; + hsize_t j; + hid_t fapl_id; + hid_t memb_fapl[H5FD_MEM_NTYPES]; + haddr_t eoa; + haddr_t max_addr; + haddr_t memb_addr[H5FD_MEM_NTYPES]; + H5FD_mem_t mt; + H5FD_mem_t memb_map[H5FD_MEM_NTYPES]; + H5FD_t * h5fd_ptr = NULL; + + check_test_in_progress("fsync_test", verbose); + + if ( show_progress ) { /* 0 */ + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, pass, cp++); + HDfflush(stdout); + } + + if ( pass ) { /* setup fapl for multi file driver */ + + for ( mt = 0; mt < H5FD_MEM_NTYPES; mt++ ) { + + memb_addr[mt] = HADDR_UNDEF; + memb_fapl[mt] = H5P_DEFAULT; + memb_map[mt] = H5FD_MEM_DRAW; + memb_name[mt] = NULL; + } + + memb_map[H5FD_MEM_SUPER] = H5FD_MEM_SUPER; + memb_fapl[H5FD_MEM_SUPER] = H5P_DEFAULT; + memb_name[H5FD_MEM_SUPER] = "%s-s.h5"; + memb_addr[H5FD_MEM_SUPER] = 0; + + memb_map[H5FD_MEM_BTREE] = H5FD_MEM_BTREE; + memb_fapl[H5FD_MEM_BTREE] = H5P_DEFAULT; + memb_name[H5FD_MEM_BTREE] = "%s-b.h5"; + memb_addr[H5FD_MEM_BTREE] = memb_addr[H5FD_MEM_SUPER] + TYPE_SLICE; + + memb_map[H5FD_MEM_DRAW] = H5FD_MEM_DRAW; + memb_fapl[H5FD_MEM_DRAW] = H5P_DEFAULT; + memb_name[H5FD_MEM_DRAW] = "%s-r.h5"; + memb_addr[H5FD_MEM_DRAW] = memb_addr[H5FD_MEM_BTREE] + TYPE_SLICE; + + memb_map[H5FD_MEM_GHEAP] = H5FD_MEM_GHEAP; + memb_fapl[H5FD_MEM_GHEAP] = H5P_DEFAULT; + memb_name[H5FD_MEM_GHEAP] = "%s-g.h5"; + memb_addr[H5FD_MEM_GHEAP] = memb_addr[H5FD_MEM_DRAW] + TYPE_SLICE; + + memb_map[H5FD_MEM_LHEAP] = H5FD_MEM_LHEAP; + memb_fapl[H5FD_MEM_LHEAP] = H5P_DEFAULT; + memb_name[H5FD_MEM_LHEAP] = "%s-l.h5"; + memb_addr[H5FD_MEM_LHEAP] = memb_addr[H5FD_MEM_GHEAP] + TYPE_SLICE; + + memb_map[H5FD_MEM_OHDR] = H5FD_MEM_OHDR; + memb_fapl[H5FD_MEM_OHDR] = H5P_DEFAULT; + memb_name[H5FD_MEM_OHDR] = "%s-o.h5"; + memb_addr[H5FD_MEM_OHDR] = memb_addr[H5FD_MEM_LHEAP] + TYPE_SLICE; + + max_addr = memb_addr[H5FD_MEM_OHDR] + TYPE_SLICE; + + fapl_id = h5_fileaccess(); + + if ( H5Pset_fapl_multi(fapl_id, memb_map, memb_fapl, memb_name, + memb_addr, FALSE) < 0 ) { + + pass = FALSE; + failure_mssg = "H5Pset_fapl_multi() failed."; + + } + } + + if ( show_progress ) { /* 1 */ + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, pass, cp++); + HDfflush(stdout); + } + + /* setup the file name */ + if ( pass ) { + + if ( h5_fixname(FILENAMES[file_name_num], fapl_id, file_name, + sizeof(file_name)) == NULL ) { + + pass = FALSE; + failure_mssg = "h5_fixname() failed.\n"; + } + } + + if ( verbose ) { + HDfprintf(stdout, "%s file_name = \"%s\".\n", fcn_name, file_name); + HDfflush(stdout); + } + + if ( show_progress ) { /* 2 */ + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, pass, cp++); + HDfflush(stdout); + } + + + /* allocate the read and test buffers */ + if ( pass ) { + + for ( i = H5FD_MEM_SUPER; i <= H5FD_MEM_OHDR; i++ ) { + + read_bufs[i] = (char *)HDmalloc((size_t)(write_size + 1)); + test_bufs[i] = (char *)HDmalloc((size_t)(write_size + 1)); + + if ( read_bufs[i] == NULL ) { + + pass = FALSE; + failure_mssg = "read buffer allocation failed."; + + } else if ( test_bufs[i] == NULL ) { + + pass = FALSE; + failure_mssg = "test buffer allocation failed."; + } + } + } + + if ( show_progress ) { /* 3 */ + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, (int)pass, cp++); + HDfflush(stdout); + } + + if ( pass ) { /* setup test buffers */ + + char file_tag[80]; + + HDassert( tag != NULL ); + HDassert( strlen(tag) <= 30 ); + + for ( i = H5FD_MEM_SUPER; i <= H5FD_MEM_OHDR; i++ ) { + + HDsnprintf(file_tag, (size_t)80, "%s:%s", tag, type_names[i]); + HDassert( strlen(file_tag) <= 48 ); + load_test_buffer(write_size, file_tag, test_bufs[i]); + + if ( verbose ) { + + HDfprintf(stdout, "%s strlen(test_bufs[%d]) = %lld.\n", + fcn_name, i, (long long)strlen(test_bufs[i])); + } + } + } + + if ( show_progress ) { /* 4 */ + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, (int)pass, cp++); + HDfflush(stdout); + } + + /* open the indicated file with the specifiec file driver */ + if ( pass ) { + + h5fd_ptr = H5FDopen(file_name, H5F_ACC_RDWR, fapl_id, max_addr); + + if ( h5fd_ptr == NULL ) { + + pass = FALSE; + failure_mssg = "H5FDopen() failed."; + } + } + + if ( show_progress ) { /* 5 */ + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, (int)pass, cp++); + HDfflush(stdout); + } + + /* set the EOA */ + + if ( verbose ) { + + for ( mt = H5FD_MEM_SUPER; mt <= H5FD_MEM_OHDR; mt++ ) { + + eoa = H5FDget_eoa(h5fd_ptr, mt); + + if ( eoa == HADDR_UNDEF ) { + + HDfprintf(stdout, "%s: H5FDget_eoa(h5fd_ptr, %s) failed.\n", + fcn_name, type_names[(int)mt]); + + } else { + + HDfprintf(stdout, "%s: H5FDget_eoa(h5fd_ptr, %s) returned 0x%llx.\n", + fcn_name, type_names[(int)mt], (unsigned long long)eoa); + + } + } + } + + mt = H5FD_MEM_SUPER; + while ( ( pass ) && ( mt <= H5FD_MEM_OHDR ) ) { + + if ( verbose ) { + + HDfprintf(stdout, + "calling H5FDset_eoa(h5fd_ptr, %s, (%d * TYPE_SLICE) - 1).\n", + type_names[(int)mt], (int)(mt)); + } + + result = H5FDset_eoa(h5fd_ptr, mt, (((haddr_t)(mt)) * TYPE_SLICE) - 1); + + if ( result < 0 ) { + + pass = FALSE; + failure_mssg = "H5FDset_eoa() failed."; + } + + mt++; + } + + if ( verbose ) { + + for ( mt = H5FD_MEM_SUPER; mt <= H5FD_MEM_OHDR; mt++ ) { + + eoa = H5FDget_eoa(h5fd_ptr, mt); + + if ( eoa == HADDR_UNDEF ) { + + HDfprintf(stdout, "%s: H5FDget_eoa(h5fd_ptr, %s) failed.\n", + fcn_name, type_names[(int)mt]); + + } else { + + HDfprintf(stdout, "%s: H5FDget_eoa(h5fd_ptr, %s) returned 0x%llx.\n", + fcn_name, type_names[(int)mt], (unsigned long long)eoa); + + } + } + } + + if ( show_progress ) { /* 6 */ + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, (int)pass, cp++); + HDfflush(stdout); + } + + /* read the contents of the target file */ + if ( pass ) { + + i = H5FD_MEM_SUPER; + + while ( ( pass ) && ( i <= H5FD_MEM_OHDR ) ) { + + result = H5FDread(h5fd_ptr, (H5F_mem_t)i, H5P_DEFAULT, + ((haddr_t)(i - 1)) * TYPE_SLICE, + (size_t)write_size, (void *)read_bufs[i]); + + if ( result < 0 ) { + + pass = FALSE; + failure_mssg = "H5FDread() failed.\n"; + } + + i++; + } + } + + if ( show_progress ) { /* 7 */ + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, (int)pass, cp++); + HDfflush(stdout); + } + + /* compare the actual file target file data with the expected contents */ + if ( pass ) { + + i = H5FD_MEM_SUPER; + while ( ( pass ) && ( i <= H5FD_MEM_OHDR ) ) { + + j = 0; + while ( ( pass ) && ( j < write_size ) ) { + + if ( (read_bufs[i])[j] != (test_bufs[i])[j] ) { + + if ( verbose ) { + + HDfprintf(stdout, "data mismatch at %d/%d.\n", (int)i, (int)j); + HDfflush(stdout); + } + + pass = FALSE; + failure_mssg = "data mismatch"; + } + + j++; + } + + i++; + } + } + + if ( show_progress ) { /* 8 */ + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, (int)pass, cp++); + HDfflush(stdout); + } + + /* close target file */ + if ( pass ) { + + result = H5FDclose(h5fd_ptr); + + if ( result < 0 ) { + + pass = FALSE; + failure_mssg = "H5FDclose() failed."; + } + } + + if ( show_progress ) { /* 9 */ + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, (int)pass, cp++); + HDfflush(stdout); + } + + /* discard the read and test buffers */ + for ( i = H5FD_MEM_SUPER; i <= H5FD_MEM_OHDR; i++ ) { + + if ( test_bufs[i] != NULL ) { + + HDfree(test_bufs[i]); + test_bufs[i] = NULL; + } + + if ( read_bufs[i] != NULL ) { + + HDfree(read_bufs[i]); + read_bufs[i] = NULL; + } + } + + if ( show_progress ) { /* 10 */ + + HDfprintf(stdout, "%s%d cp = %d.\n", fcn_name, (int)pass, cp++); + HDfflush(stdout); + } + + + /* delete the target file */ + if ( pass ) { +#if 1 + h5_cleanup(FILENAMES, fapl_id); +#endif + } + + return; + +} /* check_multi_file_driver_fsync_test() */ + + +/*------------------------------------------------------------------------- + * Function: usage + * + * Purpose: Display a brief message describing the purpose and use + * of the program. + * + * Return: void + * + * Programmer: John Mainzer + * 11/10/10 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + +void +usage(void) + +{ + const char * s[] = + { + "\n", + "fsync_tests:\n", + "\n", + "Setup or check the results of the specified fsync test.\n", + "\n", + "usage: fsync_tests [] [verbose]\n", + "\n", + "where:\n", + "\n", + " ::= ( generic_fsync_test |\n", + " generic_aio_fsync_wait_test |\n", + " generic_aio_fsync_poll_test |\n", + " multi_fd_fsync_test |\n", + " multi_fd_aio_fsync_wait_test |\n", + " multi_fd_aio_fsync_poll_test)\n", + "\n", + " ::= ( sec2 | core | stdio | family | multi)\n", + "\n", + " ::= ( setup | check )\n", + "\n", + " ::= positive decimal integer (default 1048576).\n" + "\n", + "Returns 0 on success, 1 on failure.\n", + "\n", + "multi_fd_fsync_test, multi_fd_aio_fsync_wait_test, and multi_fd_aio_fsync_poll_test\n", + "all require use of the multi file driver.\n" + "\n", + NULL, + }; + int i = 0; + + while ( s[i] != NULL ) { + + HDfprintf(stdout, "%s", s[i]); + i++; + } + + return; + +} /* usage() */ + + +/*------------------------------------------------------------------------- + * Function: main + * + * Purpose: Run the specified setup or check of fsync. + * + * Return: Success: 0 + * + * Failure: A positive integer. + * + * Programmer: John Mainzer + * 10/10/10 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + +int +main(int argc, + char * argv[]) +{ + const char * tag; + const char * memb_name[H5FD_MEM_NTYPES]; + char * test_ptr; + int express_test; + int file_name_num; + int result = 0; + hbool_t all_digits = TRUE; + hbool_t have_verbose = FALSE; + hbool_t verbose = FALSE; + enum operation { setup, check } op; + enum file_driver { sec2_fd, core_fd, stdio_fd, family_fd, multi_fd } tgt_driver; + enum test_to_run { generic_fsync_test, + generic_aio_fsync_poll_test, + generic_aio_fsync_wait_test, + multi_fd_fsync_test, + multi_fd_aio_fsync_poll_test, + multi_fd_aio_fsync_wait_test } tgt_test; + hid_t fapl; + hid_t memb_fapl[H5FD_MEM_NTYPES]; + hsize_t write_size = (1024 * 1024); + haddr_t max_addr; + haddr_t memb_addr[H5FD_MEM_NTYPES]; + H5FD_mem_t mt; + H5FD_mem_t memb_map[H5FD_MEM_NTYPES]; + + express_test = GetTestExpress(); + + pass = TRUE; + + if ( H5open() < 0 ) { + + pass = FALSE; + failure_mssg = "H5open() failed."; + } + + if ( ( argc == 6 ) || ( argc == 5 ) ) { + + if ( argc == 6 ) { + + if ( strcmp("verbose", argv[5]) == 0 ) { + + have_verbose = TRUE; + verbose = TRUE; + + } else { + + pass = FALSE; + usage(); + + } + } + + if ( ( ! have_verbose ) && ( strcmp("verbose", argv[4]) == 0 ) ) { + + have_verbose = TRUE; + verbose = TRUE; + + } else { + + test_ptr = argv[4]; + + while ( ( *test_ptr != '\0' ) && ( all_digits ) ) { + + all_digits = ( ( all_digits ) && ( isdigit(*test_ptr) != 0 ) ); + test_ptr++; + } + + if ( ! all_digits ) { + + pass = FALSE; + usage(); + + } else { + + write_size = (hsize_t)atoll(argv[4]); + + if ( write_size <= 0 ) { + + pass = FALSE; + usage(); + } + } + } + } else if ( argc != 4 ) { + + pass = FALSE; + usage(); + } + + if ( verbose ) { + + if ( argc == 6 ) { + + HDfprintf(stdout, "%s %s %s %s %s %s\n", + argv[0], argv[1], argv[2], argv[3], argv[4], argv[5]); + } else if ( argc == 5 ) { + + HDfprintf(stdout, "%s %s %s %s %s\n", + argv[0], argv[1], argv[2], argv[3], argv[4]); + } else { + + HDfprintf(stdout, "%s %s %s %s\n", + argv[0], argv[1], argv[2], argv[3]); + } + } + + if ( pass ) { + + if ( strcmp("setup", argv[3]) == 0 ) { + + op = setup; + + } else if ( strcmp("check", argv[3]) == 0 ) { + + op = check; + + } else { + + pass = FALSE; + usage(); + } + } + + if ( pass ) { + + if ( strcmp("sec2", argv[2]) == 0 ) { + + tgt_driver = sec2_fd; + + } else if( strcmp("core", argv[2]) == 0 ) { + + tgt_driver = core_fd; + + } else if( strcmp("stdio", argv[2]) == 0 ) { + + tgt_driver = stdio_fd; + + } else if( strcmp("family", argv[2]) == 0 ) { + + tgt_driver = family_fd; + + } else if( strcmp("multi", argv[2]) == 0 ) { + + tgt_driver = multi_fd; + + } else { + + pass = FALSE; + usage(); + } + } + + if ( pass ) { + + if ( strcmp("generic_fsync_test", argv[1]) == 0 ) { + + tgt_test = generic_fsync_test; + + } else if ( strcmp("generic_aio_fsync_wait_test", argv[1]) == 0 ) { + + tgt_test = generic_aio_fsync_wait_test; + + } else if ( strcmp("generic_aio_fsync_poll_test", argv[1]) == 0 ) { + + tgt_test = generic_aio_fsync_poll_test; + + } else if ( strcmp("multi_fd_fsync_test", argv[1]) == 0 ) { + + tgt_test = multi_fd_fsync_test; + + } else if ( strcmp("multi_fd_aio_fsync_wait_test", argv[1]) == 0 ) { + + tgt_test = multi_fd_aio_fsync_wait_test; + + } else if ( strcmp("multi_fd_aio_fsync_poll_test", argv[1]) == 0 ) { + + tgt_test = multi_fd_aio_fsync_poll_test; + + } else { + + pass = FALSE; + usage(); + } + } + + if ( ( pass ) && + ( ( tgt_test == multi_fd_fsync_test ) || + ( tgt_test == multi_fd_aio_fsync_wait_test ) || + ( tgt_test == multi_fd_aio_fsync_poll_test ) ) && + ( tgt_driver != multi_fd ) ) { + + pass = FALSE; + usage(); + } + + if ( verbose ) { + + const char * test_string; + const char * driver_string; + const char * op_string; + + switch ( tgt_test ) { + + case generic_fsync_test: + test_string = "generic_fsync_test"; + break; + + case generic_aio_fsync_poll_test: + test_string = "generic_aio_fsync_poll_test"; + break; + + case generic_aio_fsync_wait_test: + test_string = "generic_aio_fsync_wait_test"; + break; + + case multi_fd_fsync_test: + test_string = "multi_fd_fsync_test"; + break; + + case multi_fd_aio_fsync_poll_test: + test_string = "multi_fd_aio_fsync_poll_test"; + break; + + case multi_fd_aio_fsync_wait_test: + test_string = "multi_fd_aio_fsync_wait_test"; + break; + + default: + test_string = "???"; + break; + } + + switch ( tgt_driver ) { + + case sec2_fd: driver_string = "sec2"; break; + case core_fd: driver_string = "core"; break; + case stdio_fd: driver_string = "stdio"; break; + case family_fd: driver_string = "family"; break; + case multi_fd: driver_string = "multi"; break; + default: driver_string = "???"; break; + } + + switch ( op ) { + + case setup: op_string = "setup"; break; + case check: op_string = "check"; break; + default: op_string = "???"; break; + } + + HDfprintf(stdout, "fsync_tests %s %s %s %lld verbose\n", test_string, + driver_string, op_string, (long long)write_size); + } + + if ( pass ) { + + H5open(); + + switch ( tgt_test ) { + + case generic_fsync_test: + + switch ( tgt_driver ) { + + case sec2_fd: + max_addr = 0x40000000; + file_name_num = 1; + tag = "SEC2 SIO fsync"; + fapl = h5_fileaccess(); + if ( H5Pset_fapl_sec2(fapl) < 0 ) { + + pass = FALSE; + failure_mssg = "H5Pset_fapl_sec2() failed."; + + } + break; + + case core_fd: + if ( op == setup ) { + + max_addr = (haddr_t)write_size; + file_name_num = 2; + tag = "CORE SIO fsync"; + fapl = h5_fileaccess(); + if ( H5Pset_fapl_core(fapl, (size_t)max_addr, TRUE ) < 0 ) { + + pass = FALSE; + failure_mssg = "H5Pset_fapl_core() failed."; + + } + } else /* op == check */ { + + max_addr = 0x40000000; + file_name_num = 2; + tag = "CORE SIO fsync"; + fapl = h5_fileaccess(); + + /* At present, the core file driver doesn't allow us to load + * and existing file and use that -- hence we use the stdio + * file driver to check the core file + */ + if ( H5Pset_fapl_stdio(fapl) < 0 ) { + + pass = FALSE; + failure_mssg = "H5Pset_fapl_stdio() failed."; + + } + } + break; + + case stdio_fd: + max_addr = 0x40000000; + file_name_num = 3; + tag = "STDIO SIO fsync"; + fapl = h5_fileaccess(); + if ( H5Pset_fapl_stdio(fapl) < 0 ) { + + pass = FALSE; + failure_mssg = "H5Pset_fapl_stdio() failed."; + + } + break; + + case family_fd: + max_addr = 0x40000000; + file_name_num = 4; + tag = "Family File SIO fsync"; + fapl = h5_fileaccess(); + if ( H5Pset_fapl_family(fapl, (hsize_t)FAMILY_SIZE_AIO, + H5P_DEFAULT) < 0 ) { + + pass = FALSE; + failure_mssg = "H5Pset_fapl_family() failed."; + + } + break; + + case multi_fd: + max_addr = 0x40000000; + file_name_num = 5; + tag = "Multi File SIO fsync"; + + for ( mt = 0; mt < H5FD_MEM_NTYPES; mt++ ) { + + memb_addr[mt] = HADDR_UNDEF; + memb_fapl[mt] = H5P_DEFAULT; + memb_map[mt] = H5FD_MEM_SUPER; + memb_name[mt] = NULL; + } + memb_map[H5FD_MEM_DRAW] = H5FD_MEM_DRAW; + + memb_fapl[H5FD_MEM_SUPER] = H5P_DEFAULT; + memb_name[H5FD_MEM_SUPER] = "%s-m.h5"; + memb_addr[H5FD_MEM_SUPER] = 0; + + memb_fapl[H5FD_MEM_DRAW] = H5P_DEFAULT; + memb_name[H5FD_MEM_DRAW] = "%s-r.h5"; + memb_addr[H5FD_MEM_DRAW] = HADDR_MAX/2; + + fapl = h5_fileaccess(); + + if ( H5Pset_fapl_multi(fapl, memb_map, memb_fapl, memb_name, + memb_addr, FALSE) < 0 ) { + + pass = FALSE; + failure_mssg = "H5Pset_fapl_multi() failed."; + } + break; + + default: + pass = FALSE; + failure_mssg = "unknown driver."; + break; + } + + if ( pass ) { + + switch ( op ) { + + case setup: + setup_generic_fsync_test(file_name_num, fapl, tag, write_size, + max_addr, verbose); + break; + + case check: + check_generic_fsync_test(file_name_num, fapl, tag, write_size, + max_addr, verbose); + break; + + default: + pass = FALSE; + failure_mssg = "unknown op."; + break; + } + } + break; + + case generic_aio_fsync_poll_test: + + switch ( tgt_driver ) { + + case sec2_fd: + max_addr = 0x40000000; + file_name_num = 6; + tag = "SEC2 AIO fsync poll"; + fapl = h5_fileaccess(); + if ( H5Pset_fapl_sec2(fapl) < 0 ) { + + pass = FALSE; + failure_mssg = "H5Pset_fapl_sec2() failed."; + + } + break; + + case core_fd: + if ( op == setup ) { + + max_addr = (haddr_t)write_size; + file_name_num = 7; + tag = "CORE AIO fsync poll"; + fapl = h5_fileaccess(); + if ( H5Pset_fapl_core(fapl, (size_t)max_addr, TRUE ) < 0 ) { + + pass = FALSE; + failure_mssg = "H5Pset_fapl_core() failed."; + + } + } else /* op == check */ { + + max_addr = 0x40000000; + file_name_num = 7; + tag = "CORE AIO fsync poll"; + fapl = h5_fileaccess(); + + /* At present, the core file driver doesn't allow us to load + * and existing file and use that -- hence we use the stdio + * file driver to check the core file + */ + if ( H5Pset_fapl_stdio(fapl) < 0 ) { + + pass = FALSE; + failure_mssg = "H5Pset_fapl_stdio() failed."; + + } + } + break; + + case stdio_fd: + max_addr = 0x40000000; + file_name_num = 8; + tag = "STDIO AIO fsync poll"; + fapl = h5_fileaccess(); + if ( H5Pset_fapl_stdio(fapl) < 0 ) { + + pass = FALSE; + failure_mssg = "H5Pset_fapl_stdio() failed."; + + } + break; + + case family_fd: + max_addr = 0x40000000; + file_name_num = 9; + tag = "Family File AIO fsync poll"; + fapl = h5_fileaccess(); + if ( H5Pset_fapl_family(fapl, (hsize_t)FAMILY_SIZE_AIO, + H5P_DEFAULT) < 0 ) { + + pass = FALSE; + failure_mssg = "H5Pset_fapl_family() failed."; + + } + break; + + case multi_fd: + max_addr = 0x40000000; + file_name_num = 10; + tag = "Multi File AIO fsync poll"; + + for ( mt = 0; mt < H5FD_MEM_NTYPES; mt++ ) { + + memb_addr[mt] = HADDR_UNDEF; + memb_fapl[mt] = H5P_DEFAULT; + memb_map[mt] = H5FD_MEM_SUPER; + memb_name[mt] = NULL; + } + memb_map[H5FD_MEM_DRAW] = H5FD_MEM_DRAW; + + memb_fapl[H5FD_MEM_SUPER] = H5P_DEFAULT; + memb_name[H5FD_MEM_SUPER] = "%s-m.h5"; + memb_addr[H5FD_MEM_SUPER] = 0; + + memb_fapl[H5FD_MEM_DRAW] = H5P_DEFAULT; + memb_name[H5FD_MEM_DRAW] = "%s-r.h5"; + memb_addr[H5FD_MEM_DRAW] = HADDR_MAX/2; + + fapl = h5_fileaccess(); + + if ( H5Pset_fapl_multi(fapl, memb_map, memb_fapl, memb_name, + memb_addr, FALSE) < 0 ) { + + pass = FALSE; + failure_mssg = "H5Pset_fapl_multi() failed."; + } + break; + + default: + pass = FALSE; + failure_mssg = "unknown driver."; + break; + } + + if ( pass ) { + + switch ( op ) { + + case setup: + setup_generic_aio_fsync_test(file_name_num, fapl, tag, + write_size, max_addr, FALSE, + verbose); + break; + + case check: + check_generic_fsync_test(file_name_num, fapl, tag, write_size, + max_addr, verbose); + break; + + default: + pass = FALSE; + failure_mssg = "unknown op."; + break; + } + } + break; + + case generic_aio_fsync_wait_test: + + switch ( tgt_driver ) { + + case sec2_fd: + max_addr = 0x40000000; + file_name_num = 11; + tag = "SEC2 AIO fsync wait"; + fapl = h5_fileaccess(); + if ( H5Pset_fapl_sec2(fapl) < 0 ) { + + pass = FALSE; + failure_mssg = "H5Pset_fapl_sec2() failed."; + + } + break; + + case core_fd: + if ( op == setup ) { + + max_addr = (haddr_t)write_size; + file_name_num = 12; + tag = "CORE AIO fsync wait"; + fapl = h5_fileaccess(); + if ( H5Pset_fapl_core(fapl, (size_t)max_addr, TRUE ) < 0 ) { + + pass = FALSE; + failure_mssg = "H5Pset_fapl_core() failed."; + + } + } else /* op == check */ { + + max_addr = 0x40000000; + file_name_num = 12; + tag = "CORE AIO fsync wait"; + fapl = h5_fileaccess(); + + /* At present, the core file driver doesn't allow us to load + * and existing file and use that -- hence we use the stdio + * file driver to check the core file + */ + if ( H5Pset_fapl_stdio(fapl) < 0 ) { + + pass = FALSE; + failure_mssg = "H5Pset_fapl_stdio() failed."; + + } + } + break; + + case stdio_fd: + max_addr = 0x40000000; + file_name_num = 13; + tag = "STDIO AIO fsync wait"; + fapl = h5_fileaccess(); + if ( H5Pset_fapl_stdio(fapl) < 0 ) { + + pass = FALSE; + failure_mssg = "H5Pset_fapl_stdio() failed."; + + } + break; + + case family_fd: + max_addr = 0x40000000; + file_name_num = 14; + tag = "Family File AIO fsync wait"; + fapl = h5_fileaccess(); + if ( H5Pset_fapl_family(fapl, (hsize_t)FAMILY_SIZE_AIO, + H5P_DEFAULT) < 0 ) { + + pass = FALSE; + failure_mssg = "H5Pset_fapl_family() failed."; + + } + break; + + case multi_fd: + max_addr = 0x40000000; + file_name_num = 15; + tag = "Multi File AIO fsync wait"; + + for ( mt = 0; mt < H5FD_MEM_NTYPES; mt++ ) { + + memb_addr[mt] = HADDR_UNDEF; + memb_fapl[mt] = H5P_DEFAULT; + memb_map[mt] = H5FD_MEM_SUPER; + memb_name[mt] = NULL; + } + memb_map[H5FD_MEM_DRAW] = H5FD_MEM_DRAW; + + memb_fapl[H5FD_MEM_SUPER] = H5P_DEFAULT; + memb_name[H5FD_MEM_SUPER] = "%s-m.h5"; + memb_addr[H5FD_MEM_SUPER] = 0; + + memb_fapl[H5FD_MEM_DRAW] = H5P_DEFAULT; + memb_name[H5FD_MEM_DRAW] = "%s-r.h5"; + memb_addr[H5FD_MEM_DRAW] = HADDR_MAX/2; + + fapl = h5_fileaccess(); + + if ( H5Pset_fapl_multi(fapl, memb_map, memb_fapl, memb_name, + memb_addr, FALSE) < 0 ) { + + pass = FALSE; + failure_mssg = "H5Pset_fapl_multi() failed."; + } + break; + + default: + pass = FALSE; + failure_mssg = "unknown driver."; + break; + } + + if ( pass ) { + + switch ( op ) { + + case setup: + setup_generic_aio_fsync_test(file_name_num, fapl, tag, + write_size, max_addr, TRUE, + verbose); + break; + + case check: + check_generic_fsync_test(file_name_num, fapl, tag, write_size, + max_addr, verbose); + break; + + default: + pass = FALSE; + failure_mssg = "unknown op."; + break; + } + } + break; + + case multi_fd_fsync_test: + HDassert( tgt_driver == multi_fd ); + file_name_num = 16; + tag = "targeted multi fd fsync test"; + if ( pass ) { + + switch ( op ) { + + case setup: + setup_multi_file_driver_fsync_test(file_name_num, tag, + write_size, verbose); + break; + + case check: + check_multi_file_driver_fsync_test(file_name_num, tag, + write_size, verbose); + break; + + default: + pass = FALSE; + failure_mssg = "unknown op."; + break; + } + } + break; + + case multi_fd_aio_fsync_wait_test: + HDassert( tgt_driver == multi_fd ); + file_name_num = 17; + tag = "multi fd aio fsync wait test"; + if ( pass ) { + + switch ( op ) { + + case setup: + setup_multi_file_driver_aio_fsync_test(file_name_num, tag, + write_size, TRUE, verbose); + break; + + case check: + check_multi_file_driver_fsync_test(file_name_num, tag, + write_size, verbose); + break; + + default: + pass = FALSE; + failure_mssg = "unknown op."; + break; + } + } + break; + + case multi_fd_aio_fsync_poll_test: + HDassert( tgt_driver == multi_fd ); + file_name_num = 18; + tag = "multi fd aio fsync poll test"; + if ( pass ) { + + switch ( op ) { + + case setup: + setup_multi_file_driver_aio_fsync_test(file_name_num, tag, + write_size, FALSE, verbose); + break; + + case check: + check_multi_file_driver_fsync_test(file_name_num, tag, + write_size, verbose); + break; + + default: + pass = FALSE; + failure_mssg = "unknown op."; + break; + } + } + break; + + default: + pass = FALSE; + failure_mssg = "unknown tgt_test."; + break; + } + } + + if ( verbose ) { + + if ( pass ) { + + if ( setup ) { + + /* this should be unreachable as, in the event of success, we + * should have aborted by now. + */ + HDfprintf(stdout, "test setup succeeded.\n"); + + } else if ( check ) { + + HDfprintf(stdout, "test passed.\n"); + + } + } else { + + HDfprintf(stdout, "FAILED. Failure mssg = \"%s\"\n", + failure_mssg); + } + } + + if ( ! pass ) { + + result = 1; + } + + if ( result != 0 ) { + + HDfprintf(stderr, "fail\n"); + } + + return(result); + +} /* main() */ + diff --git a/test/fsync_tests.sh b/test/fsync_tests.sh new file mode 100755 index 0000000000..5347f4caa3 --- /dev/null +++ b/test/fsync_tests.sh @@ -0,0 +1,299 @@ +#! /bin/sh +# +# Copyright by The HDF Group. +# Copyright by the Board of Trustees of the University of Illinois. +# All rights reserved. +# +# This file is part of HDF5. The full HDF5 copyright notice, including +# terms governing use, modification, and redistribution, is contained in +# the files COPYING and Copyright.html. COPYING can be found at the root +# of the source code distribution tree; Copyright.html can be found at the +# root level of an installed copy of the electronic HDF5 document set and +# is linked from the top-level documents page. It can also be found at +# http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have +# access to either file, you may request a copy from help@hdfgroup.org. +# +# Tests for journaling related marking and unmarking of HDF5 files. +# +# These tests used to be in cache_journal.c, but had to be moved +# out as the tests require simulated crashes, and it is difficult to +# do this in a C program without using fork(). + +nerrors=0 + +# The build (current) directory might be different than the source directory. +if test -z "$srcdir"; then + srcdir=. +fi + +test -d ./testfiles || mkdir ./testfiles + +# Print a line-line message left justified in a field of 70 characters +# beginning with the word "Testing". +# +TESTING() { + SPACES=" " + echo "Testing $* $SPACES" | cut -c1-70 | tr -d '\012' +} + +# Run a test and print PASS or *FAIL*. If a test fails then increment +# the `nerrors' global variable. +# +TEST() { + TEST_ERR=$1 # The test name + TEST_ERR_BIN=`pwd`/$TEST_ERR # The path of the test binary + TEST_DESC=$2 + TEST_SIZE=$3 + TEST_STDERR=fsync_test.stderr + + #Run the test: + trap "" 6 + $RUNSERIAL $TEST_ERR_BIN $TEST_DESC setup $TEST_SIZE + trap 6 + TESTING $TEST_DESC $TEST_SIZE bytes + $RUNSERIAL $TEST_ERR_BIN $TEST_DESC check $TEST_SIZE > $TEST_STDERR + if [ $? -eq 0 ] + then + + # it is possible that we are running on a machine that discards + # our return code -- such as red storm. + # + # Thus check the contents of the stderr file before declaring a + # pass. + + if [ `wc -c < $TEST_STDERR` = '0' ] + then + + echo " PASSED" + + else + + echo "*FAILED*" + nerrors="`expr $nerrors + 1`" + + fi + else + echo "*FAILED*" + nerrors="`expr $nerrors + 1`" + fi + + # delete the stderr file before we quit + rm $TEST_STDERR +} + +# Print a "SKIP" message +SKIP() { + TESTING $@ + echo " -SKIP-" +} + +############################################################################## +############################################################################## +### T H E T E S T S ### +############################################################################## +############################################################################## + +echo "Tests to verify correct operation of the fsync and aio fsync calls" +echo "under various HDF5 file drivers. Most tests involve abnormal exits." +echo "Thus the \"Aborted\" messages between tests are expected." + + +# sec2 SIO fsync tests: + +TEST fsync_tests "generic_fsync_test sec2" "56" +TEST fsync_tests "generic_fsync_test sec2" "1048576" +TEST fsync_tests "generic_fsync_test sec2" "20000000" + + +# core SIO fsync tests: + +TEST fsync_tests "generic_fsync_test core" "62" +TEST fsync_tests "generic_fsync_test core" "1048576" +TEST fsync_tests "generic_fsync_test core" "3000000" + + +# stdio SIO fsync tests: + +TEST fsync_tests "generic_fsync_test stdio" "88" +TEST fsync_tests "generic_fsync_test stdio" "1048576" +TEST fsync_tests "generic_fsync_test stdio" "4000000" + + +# family SIO fsync tests: +# +# Note that the family file driver SIO fsync tests don't use file +# sizes below 32 MB. We do this as the fsync test code sets the +# family member size to 32 MB, and the family file driver open +# call sets the member size to the size of the first file in +# the family. +# +# Under normal circumstances, this value is overwritten when the +# super block is decoded (HDF 1.8 and up), but since these tests +# are working at the file driver level, this adjustment is not +# made. Rather than fiddle with the family file driver internal +# data structures, we go with the flow and do our tests file +# total file sizes greater than 32 MB. +# JRM -- 1/27/11 + +TEST fsync_tests "generic_fsync_test family" "33554432" +TEST fsync_tests "generic_fsync_test family" "33554433" +TEST fsync_tests "generic_fsync_test family" "40000000" +TEST fsync_tests "generic_fsync_test family" "67108863" +TEST fsync_tests "generic_fsync_test family" "67108864" +TEST fsync_tests "generic_fsync_test family" "100000000" + + +# multi SIO fsync tests +# +# The generic SIO fsync test doesn't exercise the fsync multi +# file driver call fully -- but it is a good first smoke check. + +TEST fsync_tests "generic_fsync_test multi" "99" +TEST fsync_tests "generic_fsync_test multi" "1048576" +TEST fsync_tests "generic_fsync_test multi" "5000000" + +# Now do multi file driver specific fsync tests. This should +# exercise the multi file driver a bit more fully. + +TEST fsync_tests "multi_fd_fsync_test multi" "99" +TEST fsync_tests "multi_fd_fsync_test multi" "1048576" +TEST fsync_tests "multi_fd_fsync_test multi" "5000000" + + + + + + + + +# sec2 AIO fsync poll tests: + +TEST fsync_tests "generic_aio_fsync_poll_test sec2" "56" +TEST fsync_tests "generic_aio_fsync_poll_test sec2" "1048576" +TEST fsync_tests "generic_aio_fsync_poll_test sec2" "20000000" + + +# core AIO fsync poll tests: + +TEST fsync_tests "generic_aio_fsync_poll_test core" "62" +TEST fsync_tests "generic_aio_fsync_poll_test core" "1048576" +TEST fsync_tests "generic_aio_fsync_poll_test core" "3000000" + + +# stdio AIO fsync poll tests: + +TEST fsync_tests "generic_aio_fsync_poll_test stdio" "88" +TEST fsync_tests "generic_aio_fsync_poll_test stdio" "1048576" +TEST fsync_tests "generic_aio_fsync_poll_test stdio" "4000000" + + +# family AIO fsync poll tests: +# +# Note that the family file driver AIO fsync tests don't use file +# sizes below 32 MB. We do this as the fsync test code sets the +# family member size to 32 MB, and the family file driver open +# call sets the member size to the size of the first file in +# the family. +# +# Under normal circumstances, this value is overwritten when the +# super block is decoded (HDF 1.8 and up), but since these tests +# are working at the file driver level, this adjustment is not +# made. Rather than fiddle with the family file driver internal +# data structures, we go with the flow and do our tests file +# total file sizes greater than 32 MB. +# JRM -- 1/27/11 + +TEST fsync_tests "generic_aio_fsync_poll_test family" "33554432" +TEST fsync_tests "generic_aio_fsync_poll_test family" "33554433" +TEST fsync_tests "generic_aio_fsync_poll_test family" "40000000" +TEST fsync_tests "generic_aio_fsync_poll_test family" "67108863" +TEST fsync_tests "generic_aio_fsync_poll_test family" "67108864" +TEST fsync_tests "generic_aio_fsync_poll_test family" "100000000" + + +# multi AIO fsync poll tests +# +# The generic AIO fsync test doesn't exercise the fsync multi +# file driver call fully -- but it is a good first smoke check. + +TEST fsync_tests "generic_aio_fsync_poll_test multi" "99" +TEST fsync_tests "generic_aio_fsync_poll_test multi" "1048576" +TEST fsync_tests "generic_aio_fsync_poll_test multi" "5000000" + + +# Now do multi file driver specific fsync tests. This should +# exercise the multi file driver a bit more fully. + +TEST fsync_tests "multi_fd_aio_fsync_poll_test multi" "111" +TEST fsync_tests "multi_fd_aio_fsync_poll_test multi" "1048576" +TEST fsync_tests "multi_fd_aio_fsync_poll_test multi" "5800000" + + +# sec2 AIO fsync wait tests: + +TEST fsync_tests "generic_aio_fsync_wait_test sec2" "56" +TEST fsync_tests "generic_aio_fsync_wait_test sec2" "1048576" +TEST fsync_tests "generic_aio_fsync_wait_test sec2" "20000000" + + +# core AIO fsync poll tests: + +TEST fsync_tests "generic_aio_fsync_wait_test core" "62" +TEST fsync_tests "generic_aio_fsync_wait_test core" "1048576" +TEST fsync_tests "generic_aio_fsync_wait_test core" "3000000" + + +# stdio AIO fsync poll tests: + +TEST fsync_tests "generic_aio_fsync_wait_test stdio" "88" +TEST fsync_tests "generic_aio_fsync_wait_test stdio" "1048576" +TEST fsync_tests "generic_aio_fsync_wait_test stdio" "4000000" + + +# family AIO fsync poll tests: +# +# Note that the family file driver AIO fsync tests don't use file +# sizes below 32 MB. We do this as the fsync test code sets the +# family member size to 32 MB, and the family file driver open +# call sets the member size to the size of the first file in +# the family. +# +# Under normal circumstances, this value is overwritten when the +# super block is decoded (HDF 1.8 and up), but since these tests +# are working at the file driver level, this adjustment is not +# made. Rather than fiddle with the family file driver internal +# data structures, we go with the flow and do our tests file +# total file sizes greater than 32 MB. +# JRM -- 1/27/11 + +TEST fsync_tests "generic_aio_fsync_wait_test family" "33554432" +TEST fsync_tests "generic_aio_fsync_wait_test family" "33554433" +TEST fsync_tests "generic_aio_fsync_wait_test family" "40000000" +TEST fsync_tests "generic_aio_fsync_wait_test family" "67108863" +TEST fsync_tests "generic_aio_fsync_wait_test family" "67108864" +TEST fsync_tests "generic_aio_fsync_wait_test family" "100000000" + + +# multi AIO fsync poll tests +# +# The generic AIO fsync test doesn't exercise the fsync multi +# file driver call fully -- but it is a good first smoke check. + +TEST fsync_tests "generic_aio_fsync_wait_test multi" "66" +TEST fsync_tests "generic_aio_fsync_wait_test multi" "1048576" +TEST fsync_tests "generic_aio_fsync_wait_test multi" "5200000" + + +# Now do multi file driver specific fsync tests. This should +# exercise the multi file driver a bit more fully. + +TEST fsync_tests "multi_fd_aio_fsync_wait_test multi" "88" +TEST fsync_tests "multi_fd_aio_fsync_wait_test multi" "1048576" +TEST fsync_tests "multi_fd_aio_fsync_wait_test multi" "5400000" + + +if test $nerrors -eq 0 ; then + echo "All fsync tests passed." +fi + +exit $nerrors diff --git a/test/vfd.c b/test/vfd.c index fee72a8094..35ec070fcb 100644 --- a/test/vfd.c +++ b/test/vfd.c @@ -26,6 +26,7 @@ #define FAMILY_NUMBER 4 #define FAMILY_SIZE (1*KB) #define FAMILY_SIZE2 (5*KB) +#define FAMILY_SIZE_AIO (32 * KB * KB) #define MULTI_SIZE 128 #define CORE_INCREMENT (4*KB) @@ -47,30 +48,66 @@ const char *FILENAME[] = { "new_family_v16_", "multi_file", "direct_file", + "sec2_aio_test", + "core_aio_test", + "stdio_aio_test", + "family_aio_test", + "multi_aio_test", + "multi_aio_test2", + "sec2_aio_error_test", + "core_aio_error_test", + "stdio_aio_error_test", + "family_aio_error_test", + "multi_aio_error_test", NULL }; #define COMPAT_BASENAME "family_v16_" +#define READ_OP 0 +#define WRITE_OP 1 + +static void aio_multi_read_write_fsync_cancel_check(H5FD_t * file, + int op_count, + int ops[], + H5FD_mem_t types[], + haddr_t offsets[], + size_t lengths[], + const char * tags[], + hbool_t * pass_ptr, + const char ** failure_mssg_ptr); + +static void aio_multi_write_sync_read_check(H5FD_t * file, + int write_count, + H5FD_mem_t types[], + haddr_t offsets[], + size_t lengths[], + const char * tags[], + hbool_t * pass_ptr, + const char ** failure_mssg_ptr); + +static void aio_single_write_read_check(H5FD_t * file, + H5FD_mem_t type, + const char * tag_string, + haddr_t offset, + const size_t write_size, + hbool_t do_wait, + hbool_t * pass_ptr, + const char ** failure_mssg_ptr); + static int generic_aio_test(const char * test_banner, - const char * file_name, + const int file_name_num, hid_t fapl_id, haddr_t maxaddr); -static void generic_aio_test__single_write_read_test(H5FD_t * file, - char * tag_string, - haddr_t offset, - const size_t write_size, - hbool_t do_wait, - hbool_t * pass_ptr, - char ** failure_mssg_ptr); +static int generic_aio_input_error_tests(const char * test_banner, + const char * tag_string, + const int file_name_num, + hid_t fapl_id, + hbool_t verbose); -static void generic_aio_test__multiple_write_sync_read_test(H5FD_t * file, - int write_count, - haddr_t offsets[], - size_t lengths[], - hbool_t * pass_ptr, - char ** failure_mssg_ptr); +static int multi_file_driver_aio_test(const char * test_banner, + const int file_name_num); /*------------------------------------------------------------------------- @@ -1143,528 +1180,297 @@ error: return -1; } - + /*------------------------------------------------------------------------- - * Function: generic_aio_test() + * Function: aio_multi_read_write_fsync_cancel_check * - * Purpose: Run a basic functionality test with the specified file - * and driver. + * Purpose: Kick off the specified set of AIO reads and writes, call + * H5FDaio_fsync, and then use H5FDaio_cancel to cancel all + * operations. * - * Return: Success: 0 - * Failure: -1 - * - * Programmer: JRM -- 7/15/10 - * - *------------------------------------------------------------------------- - */ - -static int -generic_aio_test(const char * test_banner, - const char * file_name, - hid_t fapl_id, - haddr_t maxaddr) -{ - const char * fcn_name = "generic_aio_test()"; - char * failure_mssg = NULL; - char read_buf[128]; - hbool_t done; - hbool_t pass = TRUE; - int error_num; - int i; - int ret_val = 0; - int write_count = 10; - size_t write_size; - size_t lengths[] = { 1024, - 512, - 16, - 4096, - 31, - (1024 * 1024), - (4 * 1024 * 1024), - (1024 * 1024 + 1), - (64 * 1024 *1024), - 24}; - herr_t result; - haddr_t offset; - haddr_t offsets[] = {(haddr_t)0, - (haddr_t)1024, - (haddr_t)1536, - (haddr_t)1552, - (haddr_t)5648, - (haddr_t)5679, - (haddr_t)1054255, - (haddr_t)5248559, - (haddr_t)6297136, - (haddr_t)73406000}; - H5FD_t * file; - - TESTING(test_banner); - - /* create the file */ - if ( pass ) { - - file = H5FDopen(file_name, (H5F_ACC_RDWR | H5F_ACC_CREAT), - fapl_id, maxaddr); - - if ( file == NULL ) { - - pass = FALSE; - failure_mssg = "H5FDopen() failed."; - } - } - - /* first do some simple write, read back, and compare results tests with - * buffers of various sizes - */ - - offset = (haddr_t)0; - write_size = (size_t)64; - - generic_aio_test__single_write_read_test(file, - "64 bytes -- test for completion", - offset, - write_size, - /* do_wait = */ FALSE, - &pass, - &failure_mssg); - - offset += (haddr_t)write_size; - - generic_aio_test__single_write_read_test(file, - "64 bytes -- wait for completion", - offset, - write_size, - /* do_wait = */ FALSE, - &pass, - &failure_mssg); - - offset += (haddr_t)write_size; - - write_size *= (size_t)4; - - generic_aio_test__single_write_read_test(file, - "256 bytes -- test for completion", - offset, - write_size, - /* do_wait = */ FALSE, - &pass, - &failure_mssg); - - offset += (haddr_t)write_size; - - generic_aio_test__single_write_read_test(file, - "256 bytes -- wait for completion", - offset, - write_size, - /* do_wait = */ FALSE, - &pass, - &failure_mssg); - - offset += (haddr_t)write_size; - - write_size *= (size_t)4; - - generic_aio_test__single_write_read_test(file, - "1 KB -- test for completion", - offset, - write_size, - /* do_wait = */ FALSE, - &pass, - &failure_mssg); - - offset += (haddr_t)write_size; - - generic_aio_test__single_write_read_test(file, - "1 KB -- wait for completion", - offset, - write_size, - /* do_wait = */ FALSE, - &pass, - &failure_mssg); - - offset += (haddr_t)write_size; - - write_size *= (size_t)4; - - generic_aio_test__single_write_read_test(file, - "4 KB -- test for completion", - offset, - write_size, - /* do_wait = */ FALSE, - &pass, - &failure_mssg); - - offset += (haddr_t)write_size; - - generic_aio_test__single_write_read_test(file, - "4 KB -- wait for completion", - offset, - write_size, - /* do_wait = */ FALSE, - &pass, - &failure_mssg); - - offset += (haddr_t)write_size; - - write_size *= (size_t)16; - - generic_aio_test__single_write_read_test(file, - "64 KB -- test for completion", - offset, - write_size, - /* do_wait = */ FALSE, - &pass, - &failure_mssg); - - offset += (haddr_t)write_size; - - generic_aio_test__single_write_read_test(file, - "64 KB -- wait for completion", - offset, - write_size, - /* do_wait = */ FALSE, - &pass, - &failure_mssg); - - offset += (haddr_t)write_size; - - write_size *= (size_t)16; - - generic_aio_test__single_write_read_test(file, - "1 MB -- test for completion", - offset, - write_size, - /* do_wait = */ FALSE, - &pass, - &failure_mssg); - - offset += (haddr_t)write_size; - - generic_aio_test__single_write_read_test(file, - "1 MB -- wait for completion", - offset, - write_size, - /* do_wait = */ FALSE, - &pass, - &failure_mssg); - - offset += (haddr_t)write_size; - - write_size *= (size_t)16; - - generic_aio_test__single_write_read_test(file, - "16 MB -- test for completion", - offset, - write_size, - /* do_wait = */ FALSE, - &pass, - &failure_mssg); - - offset += (haddr_t)write_size; - - generic_aio_test__single_write_read_test(file, - "16 MB -- wait for completion", - offset, - write_size, - /* do_wait = */ FALSE, - &pass, - &failure_mssg); - - offset += (haddr_t)write_size; - - write_size *= (size_t)16; - - generic_aio_test__single_write_read_test(file, - "256 MB -- test for completion", - offset, - write_size, - /* do_wait = */ FALSE, - &pass, - &failure_mssg); - - offset += (haddr_t)write_size; - - generic_aio_test__single_write_read_test(file, - "256 MB -- wait for completion", - offset, - write_size, - /* do_wait = */ FALSE, - &pass, - &failure_mssg); - - - - generic_aio_test__multiple_write_sync_read_test(file, - write_count, - offsets, - lengths, - &pass, - &failure_mssg); - - - if ( file != NULL ) { - - result = H5FDclose(file); - - if ( result < 0 ) { - - pass = FALSE; - failure_mssg = "H5FDclose() failed."; - - } else if ( HDremove(file_name) < 0 ) { - - pass = FALSE; - failure_mssg = "HDremove() failed.\n"; - } - - } - - if ( pass ) { - - PASSED(); - - } else { - - HDfprintf(stdout, "%s: failure_mssg = \"%s\".\n", - fcn_name, failure_mssg); - H5_FAILED(); - ret_val = -1; - } - - return(ret_val); - -} /* generic_aio_test() */ - - -/*------------------------------------------------------------------------- - * Function: generic_aio_test__single_write_read_test() - * - * Purpose: Kick of a single asynchronous write, wait until it is done - * (via either H5FDtest or H5FDwait, as directed), and then - * conplete the write. - * - * Kick off a single asynchronous read of the data just - * written, wait until it is done, (via either H5FDtest - * or H5FDwait, as directed), and then complete the read. - * - * Verify that the write buffer contains the expected data. - * - * In the event of failure, set *pass_ptr to FALSE, and set - * *failure_mssg_ptr to an appropriate error message. - * - * If *pass_ptr is FALSE on entry, do nothing and return. + * As H5FDaio_cancel() discards the control blocks, there is + * no real test to perform, other than to verify that + * H5FDaio_cancel() returns successfully. * * Return: void. * - * Programmer: JRM -- 7/15/10 - * + * Programmer: JRM -- 2/2/11 + * *------------------------------------------------------------------------- */ static void -generic_aio_test__single_write_read_test(H5FD_t * file, - char * tag_string, - haddr_t offset, - const size_t write_size, - hbool_t do_wait, - hbool_t * pass_ptr, - char ** failure_mssg_ptr) +aio_multi_read_write_fsync_cancel_check(H5FD_t * file, + int op_count, + int ops[], + H5FD_mem_t types[], + haddr_t offsets[], + size_t lengths[], + const char * tags[], + hbool_t * pass_ptr, + const char ** failure_mssg_ptr) { - const char * fcn_name = "generic_aio_test__single_write_read_test()"; - char * write_buf = NULL; - char * read_buf = NULL; - hbool_t done; - int error_num; + const char * fcn_name = "aio_multi_read_write_fsync_cancel_check()"; + const char * H5FD_mem_t_strings[H5FD_MEM_NTYPES] = + { + "H5FD_MEM_DEFAULT ", + "H5FD_MEM_SUPER ", + "H5FD_MEM_BTREE ", + "H5FD_MEM_DRAW ", + "H5FD_MEM_GHEAP ", + "H5FD_MEM_LHEAP ", + "H5FD_MEM_OHDR " + }; + const char * type_string = NULL; + const char * tag_string = NULL; + char write_num[16]; + char ** bufs = NULL; + void * fsync_aioctlblk = NULL; + void ** ctlblks = NULL; + hbool_t show_progress = FALSE; int i; + int j; int tag_len; - int ret_val = 0; + int type_string_len; + int op_num_len; herr_t result; - void * aioctlblk_ptr = NULL; if ( *pass_ptr ) { if ( ( file == NULL ) || - ( tag_string == NULL ) || - ( write_size <= 0 ) || - ( HDstrlen(tag_string) > write_size ) ) { + ( op_count <= 0 ) || + ( ops == NULL ) || + ( types == NULL ) || + ( offsets == NULL ) || + ( lengths == NULL ) || + ( tags == NULL ) || + ( failure_mssg_ptr == NULL ) ) { *pass_ptr = FALSE; *failure_mssg_ptr = - "bad param(s) passed to generic_aio_test__single_write_read_test()"; + "bad param(s) passed to aio_multi_read_write_fsync_cancel_check()"; } } - if ( *pass_ptr ) { /* allocate and initialize buffers */ + if ( show_progress ) + HDfprintf(stdout, "%s:%d: allocating buffers.\n", fcn_name, *pass_ptr); - write_buf = (char *)HDmalloc(write_size + 1); - read_buf = (char *)HDmalloc(write_size + 1); + if ( *pass_ptr ) { /* allocate arrays of pointers to */ - if ( ( write_buf == NULL ) || - ( read_buf == NULL ) ) { + bufs = (char **)HDmalloc((size_t)op_count * sizeof(char *)); + ctlblks = (void **)HDmalloc((size_t)op_count * sizeof(void *)); - *pass_ptr = NULL; - *failure_mssg_ptr = "buffer allocation(s) failed."; + if ( ( bufs == NULL ) || + ( ctlblks == NULL ) ) { + + *pass_ptr = FALSE; + *failure_mssg_ptr = "buffer allocation(s) failed(1)."; } else { - tag_len = strlen(tag_string); + for ( i = 0; i < op_count; i++ ) { - for ( i = 0; i < write_size; i++ ) { + bufs[i] = NULL; + ctlblks[i] = NULL; + } + } + } - if ( i < tag_len ) { + if ( *pass_ptr ) { /* allocate and intialize buffers */ - write_buf[i] = tag_string[i]; + i = 0; - } else { + while ( ( *pass_ptr ) && + ( i < op_count ) ) { - write_buf[i] = ' '; + if ( lengths[i] <= 0 ) { + + *pass_ptr = FALSE; + *failure_mssg_ptr = "length[i] <= 16."; + + } else { + + bufs[i] = (char *)HDmalloc(lengths[i] * sizeof(char)); + + if ( bufs[i] == NULL ) { + + *pass_ptr = FALSE; + *failure_mssg_ptr = "buffer allocation(s) failed(2)."; + } + else + { + sprintf(write_num, "%d: ", i); + op_num_len = (int)HDstrlen(write_num); + + HDassert( op_num_len < 16 ); + + type_string = H5FD_mem_t_strings[types[i]]; + type_string_len = (int)HDstrlen(type_string); + + HDassert( type_string_len < 20 ); + + tag_string = tags[i]; + tag_len = (int)HDstrlen(tag_string); + + for ( j = 0; j < (int)lengths[i]; j++ ) { + + if ( j < op_num_len ) { + + *(bufs[i] + j) = write_num[j]; + + } else if ( j < op_num_len + type_string_len ) { + + *(bufs[i] + j) = type_string[j - op_num_len]; + + } else if ( j < op_num_len + type_string_len + tag_len ) { + + *(bufs[i] + j) = tag_string[j - op_num_len - type_string_len]; + + } else { + + *(bufs[i] + j) = '\0'; + } + } } - - read_buf[i] = '\0'; } + + i++; } } - if ( *pass_ptr ) { - - result = H5FDaio_write(file, H5FD_MEM_DRAW, H5P_DEFAULT, - offset, write_size, (void *)(write_buf), - &aioctlblk_ptr); - - if ( ( result < 0 ) || ( aioctlblk_ptr == NULL ) ) { - - *pass_ptr = FALSE; - *failure_mssg_ptr = "H5FDaio_write(0) failed."; - } - } - - if ( do_wait ) { - - if ( *pass_ptr ) { - - result = H5FDaio_wait(file, aioctlblk_ptr); - - if ( result < 0 ) { - - *pass_ptr = FALSE; - *failure_mssg_ptr = "H5FDaio_wait(1) failed."; - } - } - } else { - - done = FALSE; - while ( ( *pass_ptr ) && ( ! done ) ) { - - result = H5FDaio_test(file, &done, aioctlblk_ptr); - - if ( result < 0 ) { - - *pass_ptr = FALSE; - *failure_mssg_ptr = "H5FDaio_test(0) failed."; - } - } - } - - if ( *pass_ptr ) { - - result = H5FDaio_finish(file, &error_num, aioctlblk_ptr); - - if ( ( result < 0 ) || ( error_num != 0 ) ) { - - *pass_ptr = FALSE; - *failure_mssg_ptr = "H5FDaio_finish(0) failed."; - } - } - - if ( *pass_ptr ) { - - aioctlblk_ptr = NULL; - - result = H5FDaio_read(file, H5FD_MEM_DRAW, H5P_DEFAULT, - offset, write_size, (void *)read_buf, - &aioctlblk_ptr); - - if ( ( result < 0 ) || ( aioctlblk_ptr == NULL ) ) { - - *pass_ptr = FALSE; - *failure_mssg_ptr = "H5FDaio_read(0) failed."; - } - } - - if ( do_wait ) { - - if ( *pass_ptr ) { - - result = H5FDaio_wait(file, aioctlblk_ptr); - - if ( result < 0 ) { - - *pass_ptr = FALSE; - *failure_mssg_ptr = "H5FDaio_wait(1) failed."; - } - } - } else { - - done = FALSE; - while ( ( *pass_ptr ) && ( ! done ) ) { - - result = H5FDaio_test(file, &done, aioctlblk_ptr); - - if ( result < 0 ) { - - *pass_ptr = FALSE; - *failure_mssg_ptr = "H5FDaio_test(1) failed."; - } - } - } - - if ( *pass_ptr ) { - - result = H5FDaio_finish(file, &error_num, aioctlblk_ptr); - - if ( ( result < 0 ) || ( error_num != 0 ) ) { - - *pass_ptr = FALSE; - *failure_mssg_ptr = "H5FDaio_finish(1) failed."; - } - } + if ( show_progress ) + HDfprintf(stdout, "%s:%d: kicking off reads and writes.\n", fcn_name, *pass_ptr); + /* kick off the reads and writes */ i = 0; - while ( ( *pass_ptr ) && ( i < (int)write_size ) ) { + while ( ( *pass_ptr ) && + ( i < op_count ) ) { - if ( read_buf[i] != write_buf[i] ) { + switch( ops[i] ) { + + case READ_OP: + result = H5FDaio_read(file, types[i], H5P_DEFAULT, + offsets[i], lengths[i], (void *)(bufs[i]), + &(ctlblks[i])); + + if ( ( result < 0 ) || ( ctlblks[i] == NULL ) ) { + + *pass_ptr = FALSE; + *failure_mssg_ptr = "H5FDaio_read(0) failed."; + } + break; + + case WRITE_OP: + result = H5FDaio_write(file, types[i], H5P_DEFAULT, + offsets[i], lengths[i], (void *)(bufs[i]), + &(ctlblks[i])); + + if ( ( result < 0 ) || ( ctlblks[i] == NULL ) ) { + + *pass_ptr = FALSE; + *failure_mssg_ptr = "H5FDaio_write(0) failed."; + } + break; + + default: + *pass_ptr = FALSE; + *failure_mssg_ptr = "unknown op."; + break; + } - *pass_ptr = FALSE; - *failure_mssg_ptr = "data mismatch(1)."; - } i++; } - if ( write_buf != NULL ) { /* must discard write buffer */ + if ( show_progress ) + HDfprintf(stdout, "%s:%d: calling aio fsync.\n", fcn_name, *pass_ptr); - HDfree(write_buf); - write_buf = NULL; + /* do an aio_fsync */ + if ( *pass_ptr ) { + + result = H5FDaio_fsync(file, &fsync_aioctlblk); + + if ( ( result < 0 ) || ( fsync_aioctlblk == NULL ) ) { + + *pass_ptr = FALSE; + *failure_mssg_ptr = "H5FDaio_fsync(0) failed."; + } } - if ( read_buf != NULL ) { /* must discard read buffer */ + if ( show_progress ) + HDfprintf(stdout, "%s:%d: canceling all aio read/write ops.\n", fcn_name, *pass_ptr); - HDfree(read_buf); - read_buf = NULL; + /* canceling the reads and writes */ + i = 0; + while ( ( *pass_ptr ) && + ( i < op_count ) ) { + + result = H5FDaio_cancel(file, ctlblks[i]); + + if ( result < 0 ) { + + *pass_ptr = FALSE; + *failure_mssg_ptr = "H5FDaio_cancel(0) failed."; + } + + i++; } + if ( show_progress ) + HDfprintf(stdout, "%s:%d: canceling aio fsync op.\n", fcn_name, *pass_ptr); + + /* canceling the aio_fsync */ + if ( *pass_ptr ) { + + result = H5FDaio_cancel(file, fsync_aioctlblk); + + if ( result < 0 ) { + + *pass_ptr = FALSE; + *failure_mssg_ptr = "H5FDaio_cancel(1) failed."; + } + } + + /* discard the buffers */ + + if ( show_progress ) + HDfprintf(stdout, "%s:%d: discarding buffers.\n", fcn_name, *pass_ptr); + + if ( bufs != NULL ) { + + for ( i = 0; i < op_count; i++ ) { + + if ( bufs[i] != NULL ) { + + HDfree(bufs[i]); + bufs[i] = NULL; + } + } + HDfree(bufs); + bufs = NULL; + } + + if ( ctlblks != NULL ) { + + HDfree(ctlblks); + ctlblks = NULL; + } + + if ( show_progress ) + HDfprintf(stdout, "%s:%d: done.\n", fcn_name, *pass_ptr); + return; -} /* generic_aio_test__single_write_read_test() */ +} /* aio_multi_read_write_fsync_cancel_check() */ /*------------------------------------------------------------------------- - * Function: generic_aio_test__multiple_write_sync_read_test + * Function: aio_multi_write_sync_read_check * * Purpose: Kick off the specified number of writes, each of the - * the specified length. + * the specified length, memory type, and address. * * Wait and/or test until the aio writes are complete, and - * all aio_fsync. + * call aio_fsync. * * Then read the data back into memory, and verify that * we read the expected data. @@ -1677,20 +1483,35 @@ generic_aio_test__single_write_read_test(H5FD_t * file, * * Return: void. * - * Programmer: JRM -- 7/15/10 + * Programmer: JRM -- 11/2/10 * *------------------------------------------------------------------------- */ static void -generic_aio_test__multiple_write_sync_read_test(H5FD_t * file, - int write_count, - haddr_t offsets[], - size_t lengths[], - hbool_t * pass_ptr, - char ** failure_mssg_ptr) +aio_multi_write_sync_read_check(H5FD_t * file, + int write_count, + H5FD_mem_t types[], + haddr_t offsets[], + size_t lengths[], + const char * tags[], + hbool_t * pass_ptr, + const char ** failure_mssg_ptr) { - const char * fcn_name = "generic_aio_test__multiple_write_sync_read_test()"; + const char * fcn_name = "aio_multi_write_sync_read_check()"; + const char * H5FD_mem_t_strings[H5FD_MEM_NTYPES] = + { + "H5FD_MEM_DEFAULT ", + "H5FD_MEM_SUPER ", + "H5FD_MEM_BTREE ", + "H5FD_MEM_DRAW ", + "H5FD_MEM_GHEAP ", + "H5FD_MEM_LHEAP ", + "H5FD_MEM_OHDR " + }; + const char * type_string = NULL; + const char * tag_string = NULL; + char write_num[16]; char ** write_bufs = NULL; char ** read_bufs = NULL; void * fsync_aioctlblk = NULL; @@ -1702,20 +1523,23 @@ generic_aio_test__multiple_write_sync_read_test(H5FD_t * file, int i; int j; int tag_len; - int ret_val = 0; + int type_string_len; + int write_num_len; herr_t result; if ( *pass_ptr ) { if ( ( file == NULL ) || ( write_count <= 0 ) || + ( types == NULL ) || ( offsets == NULL ) || ( lengths == NULL ) || + ( tags == NULL ) || ( failure_mssg_ptr == NULL ) ) { *pass_ptr = FALSE; *failure_mssg_ptr = - "bad param(s) passed to generic_aio_test__multiple_write_sync_read_test()"; + "bad param(s) passed to aio_multi_write_sync_read_check()"; } } @@ -1732,7 +1556,7 @@ generic_aio_test__multiple_write_sync_read_test(H5FD_t * file, ( read_bufs == NULL ) || ( ctlblks == NULL ) ) { - *pass_ptr = NULL; + *pass_ptr = FALSE; *failure_mssg_ptr = "buffer allocation(s) failed(1)."; } else { @@ -1755,7 +1579,7 @@ generic_aio_test__multiple_write_sync_read_test(H5FD_t * file, if ( lengths[i] <= 0 ) { - *pass_ptr = NULL; + *pass_ptr = FALSE; *failure_mssg_ptr = "length[i] <= 16."; } else { @@ -1766,22 +1590,45 @@ generic_aio_test__multiple_write_sync_read_test(H5FD_t * file, if ( ( write_bufs[i] == NULL ) || ( read_bufs[i] == NULL ) ) { - *pass_ptr = NULL; + *pass_ptr = FALSE; *failure_mssg_ptr = "buffer allocation(s) failed(2)."; } else { - sprintf(write_bufs[i], "%d", i); + sprintf(write_num, "%d: ", i); + write_num_len = (int)HDstrlen(write_num); - tag_len = HDstrlen(write_bufs[i]); + HDassert( write_num_len < 16 ); - HDassert( tag_len < 16 ); + type_string = H5FD_mem_t_strings[types[i]]; + type_string_len = (int)HDstrlen(type_string); - for ( j = 0; j < lengths[i]; j++ ) { + HDassert( type_string_len < 20 ); - if ( j >= tag_len ) { + tag_string = tags[i]; + tag_len = (int)HDstrlen(tag_string); - *(write_bufs[i] + j) = ' '; + for ( j = 0; j < (int)lengths[i]; j++ ) { + + if ( j < write_num_len ) { + + *(write_bufs[i] + j) = write_num[j]; + + } else if ( j < write_num_len + type_string_len ) { + + *(write_bufs[i] + j) = + type_string[j - write_num_len]; + + } else if ( j < write_num_len + + type_string_len + + tag_len ) { + + *(write_bufs[i] + j) = + tag_string[j - write_num_len - type_string_len]; + + } else { + + *(write_bufs[i] + j) = '\0'; } *(read_bufs[i] + j) = '\0'; @@ -1801,7 +1648,7 @@ generic_aio_test__multiple_write_sync_read_test(H5FD_t * file, while ( ( *pass_ptr ) && ( i < write_count ) ) { - result = H5FDaio_write(file, H5FD_MEM_DRAW, H5P_DEFAULT, + result = H5FDaio_write(file, types[i], H5P_DEFAULT, offsets[i], lengths[i], (void *)(write_bufs[i]), &(ctlblks[i])); @@ -1817,7 +1664,7 @@ generic_aio_test__multiple_write_sync_read_test(H5FD_t * file, if ( show_progress ) HDfprintf(stdout, "%s:%d: waiting for writes.\n", fcn_name, *pass_ptr); - /* wait for the writes to complete -- test have the time, and wait the + /* wait for the writes to complete -- test half the time, and wait the * other half */ i = 0; @@ -1852,7 +1699,7 @@ generic_aio_test__multiple_write_sync_read_test(H5FD_t * file, } } - do_wait = ! do_wait; + do_wait = (hbool_t)(! do_wait); i++; } @@ -1925,7 +1772,7 @@ generic_aio_test__multiple_write_sync_read_test(H5FD_t * file, while ( ( *pass_ptr ) && ( i < write_count ) ) { - result = H5FDaio_read(file, H5FD_MEM_DRAW, H5P_DEFAULT, + result = H5FDaio_read(file, types[0], H5P_DEFAULT, offsets[i], lengths[i], (void *)(read_bufs[i]), &(ctlblks[i])); @@ -1938,7 +1785,7 @@ generic_aio_test__multiple_write_sync_read_test(H5FD_t * file, i++; } - /* wait for the reads to complete -- test have the time, and wait the + /* wait for the reads to complete -- test half the time, and wait the * other half */ @@ -1977,7 +1824,7 @@ generic_aio_test__multiple_write_sync_read_test(H5FD_t * file, } } - do_wait = ! do_wait; + do_wait = (hbool_t)(! do_wait); i++; } @@ -2016,7 +1863,7 @@ generic_aio_test__multiple_write_sync_read_test(H5FD_t * file, j = 0; while ( ( *pass_ptr ) && - ( j < lengths[i] ) ) { + ( j < (int)lengths[i] ) ) { if ( (write_bufs[i])[j] != (read_bufs[i])[j] ) { @@ -2080,7 +1927,3241 @@ generic_aio_test__multiple_write_sync_read_test(H5FD_t * file, return; -} /* generic_aio_test__multiple_write_sync_read_test() */ +} /* aio_multi_write_sync_read_check() */ + + +/*------------------------------------------------------------------------- + * Function: aio_single_write_read_check() + * + * Purpose: Kick of a single asynchronous write, wait until it is done + * (via either H5FDtest or H5FDwait, as directed), and then + * conplete the write. + * + * Kick off a single asynchronous read of the data just + * written, wait until it is done, (via either H5FDtest + * or H5FDwait, as directed), and then complete the read. + * + * Verify that the read buffer contains the expected data. + * + * In the event of failure, set *pass_ptr to FALSE, and set + * *failure_mssg_ptr to an appropriate error message. + * + * If *pass_ptr is FALSE on entry, do nothing and return. + * + * Return: void. + * + * Programmer: JRM -- 7/15/10 + * + *------------------------------------------------------------------------- + */ + +static void +aio_single_write_read_check(H5FD_t * file, + H5FD_mem_t type, + const char * tag_string, + haddr_t offset, + const size_t write_size, + hbool_t do_wait, + hbool_t * pass_ptr, + const char ** failure_mssg_ptr) +{ + const char * fcn_name = "aio_single_write_read_check()"; + const char * H5FD_mem_t_strings[H5FD_MEM_NTYPES] = + { + "H5FD_MEM_DEFAULT", + "H5FD_MEM_SUPER", + "H5FD_MEM_BTREE", + "H5FD_MEM_DRAW", + "H5FD_MEM_GHEAP", + "H5FD_MEM_LHEAP", + "H5FD_MEM_OHDR" + }; + const char * type_string = NULL; + char * write_buf = NULL; + char * read_buf = NULL; + hbool_t done; + hbool_t show_progress = FALSE; + hbool_t verbose = FALSE; + int error_num; + int cp = 0; + int i; + int type_string_len; + int tag_len; + herr_t result; + void * aioctlblk_ptr = NULL; + + HDassert( ( type >= 0 ) && ( type < H5FD_MEM_NTYPES ) ); + + if ( verbose ) { + + HDfprintf(stdout, "entering %s.\n", fcn_name); + HDfprintf(stdout, " file->driver_id = 0x%llx.\n", + (unsigned long long)(file->driver_id)); + if ( file->driver_id == H5FD_CORE ) { + HDfprintf(stdout, " file driver == CORE.\n"); + } + if ( ( type >= 0 ) && ( type < H5FD_MEM_NTYPES ) ) { + + HDfprintf(stdout, " type = %d (\"%s\").\n", + (int)type, H5FD_mem_t_strings[(int)type]); + + } else { + + HDfprintf(stdout, " type = %d (\?\?\?).\n", (int)type); + } + HDfprintf(stdout, " tag_string = \"%s\".\n", tag_string); + HDfprintf(stdout, " offset = 0x%llx.\n", + (unsigned long long)offset); + HDfprintf(stdout, " write_size = 0x%llx.\n", + (unsigned long long)write_size); + HDfprintf(stdout, " do_wait = %d.\n", (int)do_wait); + HDfprintf(stdout, " *pass_ptr = %d.\n", (int)(*pass_ptr)); + } + + if ( *pass_ptr ) { + + if ( ( file == NULL ) || + ( type < 0 ) || + ( type >= H5FD_MEM_NTYPES ) || + ( tag_string == NULL ) || + ( write_size <= 0 ) || + ( HDstrlen(tag_string) > write_size ) ) { + + *pass_ptr = FALSE; + *failure_mssg_ptr = + "bad param(s) passed to aio_single_write_read_check()"; + } + } + + if ( show_progress ) { /* cp == 0 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d -- alloc & init buffers.\n", + fcn_name, cp++, (int)(*pass_ptr)); + } + + if ( *pass_ptr ) { /* allocate and initialize buffers */ + + write_buf = (char *)HDmalloc(write_size + 1); + read_buf = (char *)HDmalloc(write_size + 1); + + if ( ( write_buf == NULL ) || + ( read_buf == NULL ) ) { + + *pass_ptr = FALSE; + *failure_mssg_ptr = "buffer allocation(s) failed."; + + } else { + + type_string = H5FD_mem_t_strings[type]; + + HDassert( type_string != NULL ); + + type_string_len = (int)HDstrlen(type_string); + + HDassert( type_string_len < 20 ); + + tag_len = (int)HDstrlen(tag_string); + + for ( i = 0; i < (int)write_size; i++ ) { + + if ( i < type_string_len ) { + + write_buf[i] = type_string[i]; + + } else if ( i == type_string_len ) { + + write_buf[i] = ' '; + + } else if ( i < type_string_len + tag_len + 1 ) { + + write_buf[i] = tag_string[i - type_string_len - 1]; + + } else if ( i < (int)(write_size - 1) ) { + + write_buf[i] = ' '; + + } else { + + write_buf[i] = '\0'; + } + + read_buf[i] = '\0'; + } + } + } + + if ( show_progress ) { /* cp == 1 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d -- kicking off write.\n", + fcn_name, cp++, (int)(*pass_ptr)); + } + + if ( *pass_ptr ) { + + result = H5FDaio_write(file, type, H5P_DEFAULT, + offset, write_size, (void *)(write_buf), + &aioctlblk_ptr); + + if ( ( result < 0 ) || ( aioctlblk_ptr == NULL ) ) { + + *pass_ptr = FALSE; + *failure_mssg_ptr = "H5FDaio_write(0) failed."; + } + } + + if ( show_progress ) { /* cp == 2 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d, do_wait = %d -- waiting til done.\n", + fcn_name, cp++, (int)(*pass_ptr), (int)do_wait); + } + + if ( do_wait ) { + + if ( *pass_ptr ) { + + result = H5FDaio_wait(file, aioctlblk_ptr); + + if ( result < 0 ) { + + *pass_ptr = FALSE; + *failure_mssg_ptr = "H5FDaio_wait(1) failed."; + } + } + } else { + + done = FALSE; + while ( ( *pass_ptr ) && ( ! done ) ) { + + result = H5FDaio_test(file, &done, aioctlblk_ptr); + + if ( result < 0 ) { + + *pass_ptr = FALSE; + *failure_mssg_ptr = "H5FDaio_test(0) failed."; + } + } + } + + if ( show_progress ) { /* cp == 3 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d -- finishing write.\n", + fcn_name, cp++, (int)(*pass_ptr)); + } + + if ( *pass_ptr ) { + + result = H5FDaio_finish(file, &error_num, aioctlblk_ptr); + + if ( ( result < 0 ) || ( error_num != 0 ) ) { + + *pass_ptr = FALSE; + *failure_mssg_ptr = "H5FDaio_finish(0) failed."; + } + } + + if ( show_progress ) { /* cp == 4 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d -- kicking off read.\n", + fcn_name, cp++, (int)(*pass_ptr)); + } + + if ( *pass_ptr ) { + + aioctlblk_ptr = NULL; + + result = H5FDaio_read(file, type, H5P_DEFAULT, + offset, write_size, (void *)read_buf, + &aioctlblk_ptr); + + if ( ( result < 0 ) || ( aioctlblk_ptr == NULL ) ) { + + *pass_ptr = FALSE; + *failure_mssg_ptr = "H5FDaio_read(0) failed."; + } + } + + if ( show_progress ) { /* cp == 5 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d, do_wait = %d -- waiting til done.\n", + fcn_name, cp++, (int)(*pass_ptr), (int)do_wait); + } + + if ( do_wait ) { + + if ( *pass_ptr ) { + + result = H5FDaio_wait(file, aioctlblk_ptr); + + if ( result < 0 ) { + + *pass_ptr = FALSE; + *failure_mssg_ptr = "H5FDaio_wait(1) failed."; + } + } + } else { + + done = FALSE; + while ( ( *pass_ptr ) && ( ! done ) ) { + + result = H5FDaio_test(file, &done, aioctlblk_ptr); + + if ( result < 0 ) { + + *pass_ptr = FALSE; + *failure_mssg_ptr = "H5FDaio_test(1) failed."; + } + } + } + + if ( show_progress ) { /* cp == 6 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d -- finishing read.\n", + fcn_name, cp++, (int)(*pass_ptr)); + } + + if ( *pass_ptr ) { + + result = H5FDaio_finish(file, &error_num, aioctlblk_ptr); + + if ( ( result < 0 ) || ( error_num != 0 ) ) { + + *pass_ptr = FALSE; + *failure_mssg_ptr = "H5FDaio_finish(1) failed."; + } + } + + if ( show_progress ) { /* cp == 7 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d -- comparing buffers.\n", + fcn_name, cp++, (int)(*pass_ptr)); + } + + i = 0; + while ( ( *pass_ptr ) && ( i < (int)write_size ) ) { + + if ( read_buf[i] != write_buf[i] ) { + + *pass_ptr = FALSE; + *failure_mssg_ptr = "data mismatch(1)."; + } + i++; + } + + if ( show_progress ) { /* cp == 8 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d -- discarding write buf.\n", + fcn_name, cp++, (int)(*pass_ptr)); + } + + if ( write_buf != NULL ) { /* must discard write buffer */ + + HDfree(write_buf); + write_buf = NULL; + } + + if ( show_progress ) { /* cp == 9 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d -- discarding read buf.\n", + fcn_name, cp++, (int)(*pass_ptr)); + } + + if ( read_buf != NULL ) { /* must discard read buffer */ + + HDfree(read_buf); + read_buf = NULL; + } + + if ( show_progress ) { /* cp == 10 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d -- done.\n", + fcn_name, cp++, (int)(*pass_ptr)); + } + + if ( verbose ) { + + HDfprintf(stdout, "exiting %s.\n", fcn_name); + } + + + return; + +} /* aio_single_write_read_check() */ + + +/*------------------------------------------------------------------------- + * Function: generic_aio_test() + * + * Purpose: Run a basic functionality test with the specified file + * and driver. + * + * Return: Success: 0 + * Failure: -1 + * + * Programmer: JRM -- 7/15/10 + * + *------------------------------------------------------------------------- + */ + +static int +generic_aio_test(const char * test_banner, + const int file_name_num, + hid_t fapl_id, + haddr_t maxaddr) +{ + const char * fcn_name = "generic_aio_test()"; + const char * failure_mssg = NULL; + const char * tags[] = { "1 KB write", + "512 B write", + "16 B wrt", + "4 KB write", + "31 B write", + "1 MB write", + "4 MB write", + "1 MB + 1 B write", + "64 MB write", + "24 B write" }; + char file_name[1024]; + hbool_t pass = TRUE; + hbool_t show_progress = FALSE; + hbool_t verbose = FALSE; + int cp = 0; + int ret_val = 0; + int write_count = 10; + int op_count = 10; + int ops[] = { READ_OP, + WRITE_OP, + READ_OP, + WRITE_OP, + READ_OP, + WRITE_OP, + READ_OP, + WRITE_OP, + READ_OP, + WRITE_OP }; + H5FD_mem_t types[] = { H5FD_MEM_DRAW, + H5FD_MEM_DRAW, + H5FD_MEM_DRAW, + H5FD_MEM_DRAW, + H5FD_MEM_DRAW, + H5FD_MEM_DRAW, + H5FD_MEM_DRAW, + H5FD_MEM_DRAW, + H5FD_MEM_DRAW, + H5FD_MEM_DRAW }; + size_t write_size; + size_t lengths[] = { 1024, + 512, + 16, + 4096, + 31, + (1024 * 1024), + (4 * 1024 * 1024), + (1024 * 1024 + 1), + (64 * 1024 *1024), + 24}; + herr_t result; + haddr_t offset; + haddr_t offsets[] = {(haddr_t)0, + (haddr_t)1024, + (haddr_t)1536, + (haddr_t)1552, + (haddr_t)5648, + (haddr_t)5679, + (haddr_t)1054255, + (haddr_t)5248559, + (haddr_t)6297136, + (haddr_t)73406000}; + H5FD_t * file; + + if ( verbose ) { + + HDfprintf(stdout, + "entering generic_aio_test(\"%s\", %d(\"%s\"), %d, 0x%llx)\n", + test_banner, file_name_num, FILENAME[file_name_num], + (int)fapl_id, (unsigned long long)maxaddr); + } + + TESTING(test_banner); + + if ( show_progress ) { /* cp == 0 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d -- fixing file name.\n", + fcn_name, cp++, (int)pass); + } + + /* setup the file name */ + if ( pass ) { + + if ( NULL == h5_fixname(FILENAME[file_name_num], fapl_id, + file_name, sizeof(file_name)) ) { + + pass = FALSE; + failure_mssg = "h5_fixname() failed."; + } + } + + if ( verbose ) { + + HDfprintf(stdout, "%s: file_name = \"%s\".\n", fcn_name, file_name); + } + + if ( show_progress ) { /* cp == 1 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d -- opening file.\n", + fcn_name, cp++, (int)pass); + } + + /* create the file */ + if ( pass ) { + + file = H5FDopen(file_name, (H5F_ACC_RDWR | H5F_ACC_CREAT), + fapl_id, maxaddr); + + if ( file == NULL ) { + + pass = FALSE; + failure_mssg = "H5FDopen() failed."; + } + } + + if ( show_progress ) { /* cp == 2 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d -- setting eoa.\n", + fcn_name, cp++, (int)pass); + } + + /* set the EOA */ + if ( pass ) { + + result = H5FDset_eoa(file, H5FD_MEM_DEFAULT, maxaddr); + + if ( result < 0 ) { + + pass = FALSE; + failure_mssg = "H5FDset_eoa() failed."; + } + } + + if ( show_progress ) { /* cp == 3 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d -- swrchk 64 bytes, poll.\n", + fcn_name, cp++, (int)pass); + } + + /* first do some simple write, read back, and compare results tests with + * buffers of various sizes + */ + + offset = (haddr_t)0; + write_size = (size_t)64; + + aio_single_write_read_check(file, + H5FD_MEM_DRAW, + "64 bytes -- test for completion", + offset, + write_size, + /* do_wait = */ FALSE, + &pass, + &failure_mssg); + + if ( show_progress ) { /* cp == 4 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d -- swrchk 64 bytes, wait.\n", + fcn_name, cp++, (int)pass); + } + + offset += (haddr_t)write_size; + + aio_single_write_read_check(file, + H5FD_MEM_DRAW, + "64 bytes -- wait for completion", + offset, + write_size, + /* do_wait = */ TRUE, + &pass, + &failure_mssg); + + if ( show_progress ) { /* cp == 5 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d -- swrchk 256 bytes, poll.\n", + fcn_name, cp++, (int)pass); + } + + offset += (haddr_t)write_size; + + write_size *= (size_t)4; + + aio_single_write_read_check(file, + H5FD_MEM_DRAW, + "256 bytes -- test for completion", + offset, + write_size, + /* do_wait = */ FALSE, + &pass, + &failure_mssg); + + if ( show_progress ) { /* cp == 6 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d -- swrchk 256 bytes, wait.\n", + fcn_name, cp++, (int)pass); + } + + offset += (haddr_t)write_size; + + aio_single_write_read_check(file, + H5FD_MEM_DRAW, + "256 bytes -- wait for completion", + offset, + write_size, + /* do_wait = */ TRUE, + &pass, + &failure_mssg); + + if ( show_progress ) { /* cp == 7 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d -- swrchk 1 KB, poll.\n", + fcn_name, cp++, (int)pass); + } + + offset += (haddr_t)write_size; + + write_size *= (size_t)4; + + aio_single_write_read_check(file, + H5FD_MEM_DRAW, + "1 KB -- test for completion", + offset, + write_size, + /* do_wait = */ FALSE, + &pass, + &failure_mssg); + + if ( show_progress ) { /* cp == 8 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d -- swrchk 1 KB, wait.\n", + fcn_name, cp++, (int)pass); + } + + offset += (haddr_t)write_size; + + aio_single_write_read_check(file, + H5FD_MEM_DRAW, + "1 KB -- wait for completion", + offset, + write_size, + /* do_wait = */ TRUE, + &pass, + &failure_mssg); + + if ( show_progress ) { /* cp == 9 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d -- swrchk 4 KB, poll.\n", + fcn_name, cp++, (int)pass); + } + + offset += (haddr_t)write_size; + + write_size *= (size_t)4; + + aio_single_write_read_check(file, + H5FD_MEM_DRAW, + "4 KB -- test for completion", + offset, + write_size, + /* do_wait = */ FALSE, + &pass, + &failure_mssg); + + if ( show_progress ) { /* cp == 10 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d -- swrchk 4 KB, wait.\n", + fcn_name, cp++, (int)pass); + } + + offset += (haddr_t)write_size; + + aio_single_write_read_check(file, + H5FD_MEM_DRAW, + "4 KB -- wait for completion", + offset, + write_size, + /* do_wait = */ TRUE, + &pass, + &failure_mssg); + + if ( show_progress ) { /* cp == 11 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d -- swrchk 64 KB, poll.\n", + fcn_name, cp++, (int)pass); + } + + offset += (haddr_t)write_size; + + write_size *= (size_t)16; + + aio_single_write_read_check(file, + H5FD_MEM_DRAW, + "64 KB -- test for completion", + offset, + write_size, + /* do_wait = */ FALSE, + &pass, + &failure_mssg); + + if ( show_progress ) { /* cp == 12 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d -- swrchk 64 KB, wait.\n", + fcn_name, cp++, (int)pass); + } + + offset += (haddr_t)write_size; + + aio_single_write_read_check(file, + H5FD_MEM_DRAW, + "64 KB -- wait for completion", + offset, + write_size, + /* do_wait = */ TRUE, + &pass, + &failure_mssg); + + if ( show_progress ) { /* cp == 13 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d -- swrchk 1 MB, poll.\n", + fcn_name, cp++, (int)pass); + } + + offset += (haddr_t)write_size; + + write_size *= (size_t)16; + + aio_single_write_read_check(file, + H5FD_MEM_DRAW, + "1 MB -- test for completion", + offset, + write_size, + /* do_wait = */ FALSE, + &pass, + &failure_mssg); + + if ( show_progress ) { /* cp == 14 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d -- swrchk 1 MB, wait.\n", + fcn_name, cp++, (int)pass); + } + + offset += (haddr_t)write_size; + + aio_single_write_read_check(file, + H5FD_MEM_DRAW, + "1 MB -- wait for completion", + offset, + write_size, + /* do_wait = */ TRUE, + &pass, + &failure_mssg); + + if ( show_progress ) { /* cp == 15 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d -- swrchk 16 MB, poll.\n", + fcn_name, cp++, (int)pass); + } + + offset += (haddr_t)write_size; + + write_size *= (size_t)16; + + aio_single_write_read_check(file, + H5FD_MEM_DRAW, + "16 MB -- test for completion", + offset, + write_size, + /* do_wait = */ FALSE, + &pass, + &failure_mssg); + + if ( show_progress ) { /* cp == 16 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d -- swrchk 16 MB, wait.\n", + fcn_name, cp++, (int)pass); + } + + offset += (haddr_t)write_size; + + aio_single_write_read_check(file, + H5FD_MEM_DRAW, + "16 MB -- wait for completion", + offset, + write_size, + /* do_wait = */ TRUE, + &pass, + &failure_mssg); + + if ( show_progress ) { /* cp == 17 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d -- swrchk 256 MB, poll.\n", + fcn_name, cp++, (int)pass); + } + + offset += (haddr_t)write_size; + + write_size *= (size_t)16; + + aio_single_write_read_check(file, + H5FD_MEM_DRAW, + "256 MB -- test for completion", + offset, + write_size, + /* do_wait = */ FALSE, + &pass, + &failure_mssg); + + if ( show_progress ) { /* cp == 18 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d -- swrchk 256 MB, wait.\n", + fcn_name, cp++, (int)pass); + } + + offset += (haddr_t)write_size; + + aio_single_write_read_check(file, + H5FD_MEM_DRAW, + "256 MB -- wait for completion", + offset, + write_size, + /* do_wait = */ TRUE, + &pass, + &failure_mssg); + + if ( show_progress ) { /* cp == 19 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d -- mwsrchk.\n", + fcn_name, cp++, (int)pass); + } + + aio_multi_write_sync_read_check(file, + write_count, + types, + offsets, + lengths, + tags, + &pass, + &failure_mssg); + + if ( show_progress ) { /* cp == 20 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d -- wrfcchk.\n", + fcn_name, cp++, (int)pass); + } +#if 1 /* JRM */ + aio_multi_read_write_fsync_cancel_check(file, + op_count, + ops, + types, + offsets, + lengths, + tags, + &pass, + &failure_mssg); +#endif /* JRM */ + if ( show_progress ) { /* cp == 21 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d -- close file.\n", + fcn_name, cp++, (int)pass); + } + + if ( file != NULL ) { + + result = H5FDclose(file); + + if ( result < 0 ) { + + pass = FALSE; + failure_mssg = "H5FDclose() failed."; + + } else if ( h5_cleanup(FILENAME, fapl_id) == 0 ) { + + pass = FALSE; + failure_mssg = "h5_cleanup() failed.\n"; + } + } + + if ( show_progress ) { /* cp == 22 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d -- report results.\n", + fcn_name, cp++, (int)pass); + } + + if ( pass ) { + + PASSED(); + + } else { + + HDfprintf(stdout, "%s: failure_mssg = \"%s\".\n", + fcn_name, failure_mssg); + H5_FAILED(); + ret_val = -1; + } + + if ( verbose ) { + + HDfprintf(stdout, "exiting generic_aio_test() -- ret_val == %d.\n", + ret_val); + } + + return(ret_val); + +} /* generic_aio_test() */ + + +/*------------------------------------------------------------------------- + * Function: generic_aio_input_error_tests() + * + * Purpose: Run a basic set of input error rejection tests on the + * various AIO VFD calls on the driver specified by the + * supplied FAPL. + * + * Return: Success: 0 + * Failure: -1 + * + * Programmer: JRM -- 2/21/11 + * + *------------------------------------------------------------------------- + */ + +static int +generic_aio_input_error_tests(const char * test_banner, + const char * tag_string, + const int file_name_num, + hid_t fapl_id, + hbool_t verbose) +{ + const char * fcn_name = "generic_aio_input_error_tests()"; + const char * failure_mssg = NULL; + const char * type_string = NULL; + char * write_buf = NULL; + char * read_buf = NULL; + char file_name[1024]; + hbool_t done; + hbool_t pass = TRUE; + hbool_t show_progress = FALSE; + int cp = 0; + int error_num; + int i; + int ret_val = 0; + int type_string_len; + int tag_len; + const size_t write_size = 0x100; + herr_t result; + haddr_t maxaddr = 0x1000; + H5F_mem_t mem_type; + H5FD_t * file; + void * fsync_ctlblk_ptr = NULL; + void * write_ctlblk_ptr = NULL; + void * read_ctlblk_ptr = NULL; + + if ( verbose ) { + + HDfprintf(stdout, + "entering generic_aio_input_error_tests(\"%s\", %d(\"%s\"), %d, %d)\n", + test_banner, file_name_num, FILENAME[file_name_num], + (int)fapl_id, (int)verbose); + } + + TESTING(test_banner); + + if ( show_progress ) { /* cp == 0 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, (int)pass); + } + + /* setup the file name */ + if ( pass ) { + + if ( NULL == h5_fixname(FILENAME[file_name_num], fapl_id, + file_name, sizeof(file_name)) ) { + + pass = FALSE; + failure_mssg = "h5_fixname() failed."; + } + } + + if ( verbose ) { + + HDfprintf(stdout, "%s: file_name = \"%s\".\n", fcn_name, file_name); + } + + if ( show_progress ) { /* cp == 1 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, (int)pass); + } + + /* create the file */ + if ( pass ) { + + file = H5FDopen(file_name, (H5F_ACC_RDWR | H5F_ACC_CREAT), + fapl_id, maxaddr); + + if ( file == NULL ) { + + pass = FALSE; + failure_mssg = "H5FDopen() failed."; + } + } + + if ( show_progress ) { /* cp == 2 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, (int)pass); + } + + /* set the EOA */ + if ( pass ) { + + result = H5FDset_eoa(file, H5FD_MEM_DEFAULT, maxaddr); + + if ( result < 0 ) { + + pass = FALSE; + failure_mssg = "H5FDset_eoa() failed."; + } + } + + if ( show_progress ) { /* cp == 3 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, (int)pass); + } + + /* in what follows, we will verify that various AIO calls reject invalid + * input in the expected manner. However, before we do so, we must construct + * some valid inputs. Do this now. + */ + + if ( pass ) { /* allocate and initialize buffers, initialize mem_type */ + + if ( verbose ) { + + HDfprintf(stdout, "%s: allocating write_buf = (char *)HDmalloc(%d).\n", + fcn_name, (int)(write_size + 1)); + } + + write_buf = (char *)HDmalloc(write_size + 1); + + if ( verbose ) { + + HDfprintf(stdout, "%s: allocating read_buf = (char *)HDmalloc(%d).\n", + fcn_name, (int)(write_size + 1)); + } + + read_buf = (char *)HDmalloc(write_size + 1); + + if ( ( write_buf == NULL ) || + ( read_buf == NULL ) ) { + + pass = FALSE; + failure_mssg = "buffer allocation(s) failed."; + + } else { + + mem_type = H5FD_MEM_DEFAULT; + + type_string = "H5FD_MEM_DEFAULT"; + + HDassert( type_string != NULL ); + + type_string_len = (int)HDstrlen(type_string); + + HDassert( type_string_len < 20 ); + + tag_len = (int)HDstrlen(tag_string); + + for ( i = 0; i < (int)write_size; i++ ) { + + if ( i < type_string_len ) { + + write_buf[i] = type_string[i]; + + } else if ( i == type_string_len ) { + + write_buf[i] = ' '; + + } else if ( i < type_string_len + tag_len + 1 ) { + + write_buf[i] = tag_string[i - type_string_len - 1]; + + } else { + + write_buf[i] = '\0'; + } + + read_buf[i] = '\0'; + } + } + } + + if ( show_progress ) { /* cp == 4 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, (int)(pass)); + } + + /* now make several attempts to queue an asynchronous write with invalid input + * of some sort or another. All such calls should be rejected. + */ + + /* try to queue a write with a NULL file */ + if ( pass ) { + + H5E_BEGIN_TRY { + result = H5FDaio_write(NULL, H5FD_MEM_DEFAULT, H5P_DEFAULT, (haddr_t)0x000, + write_size, (void *)(write_buf), &write_ctlblk_ptr); + } H5E_END_TRY; + + if ( result >= 0 ) { + + pass = FALSE; + failure_mssg = "Call to H5FDaio_write() succeeded with NULL file."; + + } else if ( write_ctlblk_ptr != NULL ) { + + pass = FALSE; + failure_mssg = "write_ctlblk_ptr != NULL after failed call to H5FDaio_write(0)"; + } + } + + if ( show_progress ) { /* cp == 5 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, (int)pass); + } + + + /* try to queue a write with an invalid memory type */ + if ( pass ) { + + H5E_BEGIN_TRY { + result = H5FDaio_write(file, H5FD_MEM_NTYPES, H5P_DEFAULT, (haddr_t)0x000, + write_size, (void *)(write_buf), &write_ctlblk_ptr); + } H5E_END_TRY; + + if ( result >= 0 ) { + + pass = FALSE; + failure_mssg = "Call to H5FDaio_write() succeeded with invalid memory type."; + + } else if ( write_ctlblk_ptr != NULL ) { + + pass = FALSE; + failure_mssg = "write_ctlblk_ptr != NULL after failed call to H5FDaio_write(1)"; + } + } + + if ( show_progress ) { /* cp == 6 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, (int)pass); + } + + + /* try to queue a write with an invalid dxpl -- do this by passing in a fapl ID + * instead. + */ + if ( pass ) { + + H5E_BEGIN_TRY { + result = H5FDaio_write(file, H5FD_MEM_DEFAULT, fapl_id, (haddr_t)0x000, + write_size, (void *)(write_buf), &write_ctlblk_ptr); + } H5E_END_TRY; + + if ( result >= 0 ) { + + pass = FALSE; + failure_mssg = "Call to H5FDaio_write() succeeded with invalid dxpl."; + + } else if ( write_ctlblk_ptr != NULL ) { + + pass = FALSE; + failure_mssg = "write_ctlblk_ptr != NULL after failed call to H5FDaio_write(2)"; + } + } + + if ( show_progress ) { /* cp == 7 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, (int)pass); + } + + + /* try to queue a write with an invalid address */ + if ( pass ) { + + H5E_BEGIN_TRY { + result = H5FDaio_write(file, H5FD_MEM_DEFAULT, H5P_DEFAULT, HADDR_UNDEF, + write_size, (void *)(write_buf), &write_ctlblk_ptr); + } H5E_END_TRY; + + if ( result >= 0 ) { + + pass = FALSE; + failure_mssg = "Call to H5FDaio_write() succeeded with invalid address."; + + } else if ( write_ctlblk_ptr != NULL ) { + + pass = FALSE; + failure_mssg = "write_ctlblk_ptr != NULL after failed call to H5FDaio_write(3)"; + } + } + + if ( show_progress ) { /* cp == 8 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, (int)pass); + } + + + /* try to queue a write with an address beyond the eoa */ + if ( pass ) { + + H5E_BEGIN_TRY { + result = H5FDaio_write(file, H5FD_MEM_DEFAULT, H5P_DEFAULT, maxaddr + 1, + write_size, (void *)(write_buf), &write_ctlblk_ptr); + } H5E_END_TRY; + + if ( result >= 0 ) { + + pass = FALSE; + failure_mssg = "Call to H5FDaio_write() succeeded with address beyond eoa."; + + } else if ( write_ctlblk_ptr != NULL ) { + + pass = FALSE; + failure_mssg = "write_ctlblk_ptr != NULL after failed call to H5FDaio_write(4)"; + } + } + + if ( show_progress ) { /* cp == 9 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, (int)pass); + } + + + /* try to queue a write with zero size */ + if ( pass ) { + + H5E_BEGIN_TRY { + result = H5FDaio_write(file, H5FD_MEM_DEFAULT, H5P_DEFAULT, (haddr_t)0x0000, + 0, (void *)(write_buf), &write_ctlblk_ptr); + } H5E_END_TRY; + + if ( result >= 0 ) { + + pass = FALSE; + failure_mssg = "Call to H5FDaio_write() succeeded with zero size."; + + } else if ( write_ctlblk_ptr != NULL ) { + + pass = FALSE; + failure_mssg = "write_ctlblk_ptr != NULL after failed call to H5FDaio_write(5)"; + } + } + + if ( show_progress ) { /* cp == 10 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, (int)pass); + } + + + /* try to queue a write with address + size greater than eoa */ + if ( pass ) { + + H5E_BEGIN_TRY { + result = H5FDaio_write(file, H5FD_MEM_DEFAULT, H5P_DEFAULT, + maxaddr - (write_size / 2), write_size, + (void *)(write_buf), &write_ctlblk_ptr); + } H5E_END_TRY; + + if ( result >= 0 ) { + + pass = FALSE; + failure_mssg = "Call to H5FDaio_write() succeeded with addr + size > eoa."; + + } else if ( write_ctlblk_ptr != NULL ) { + + pass = FALSE; + failure_mssg = "write_ctlblk_ptr != NULL after failed call to H5FDaio_write(6)"; + } + } + + if ( show_progress ) { /* cp == 11 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, (int)pass); + } + + + /* try to queue a write with a NULL buffer pointer */ + if ( pass ) { + + H5E_BEGIN_TRY { + result = H5FDaio_write(file, H5FD_MEM_DEFAULT, H5P_DEFAULT, (haddr_t)0x0000, + write_size, (void *)(NULL), &write_ctlblk_ptr); + } H5E_END_TRY; + + if ( result >= 0 ) { + + pass = FALSE; + failure_mssg = "Call to H5FDaio_write() succeeded with NULL buffer pointer."; + + } else if ( write_ctlblk_ptr != NULL ) { + + pass = FALSE; + failure_mssg = "write_ctlblk_ptr != NULL after failed call to H5FDaio_write(7)"; + } + } + + if ( show_progress ) { /* cp == 12 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, (int)pass); + } + + + /* try to queue a write with a NULL control block pointer pointer */ + if ( pass ) { + + H5E_BEGIN_TRY { + result = H5FDaio_write(file, H5FD_MEM_DEFAULT, H5P_DEFAULT, (haddr_t)0x0000, + write_size, (void *)(write_buf), NULL); + } H5E_END_TRY; + + if ( result >= 0 ) { + + pass = FALSE; + failure_mssg = "Call to H5FDaio_write() succeeded with NULL ctlblk_ptr_ptr."; + + } else if ( write_ctlblk_ptr != NULL ) { + + pass = FALSE; + failure_mssg = "write_ctlblk_ptr != NULL after failed call to H5FDaio_write(8)"; + } + } + + if ( show_progress ) { /* cp == 13 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, (int)pass); + } + + + /* try to queue a write with *ctlblk_ptr_ptr != NULL */ + if ( pass ) { + + write_ctlblk_ptr = (void *)read_buf; + + H5E_BEGIN_TRY { + result = H5FDaio_write(file, H5FD_MEM_DEFAULT, H5P_DEFAULT, (haddr_t)0x0000, + write_size, (void *)(write_buf), &write_ctlblk_ptr); + } H5E_END_TRY; + + if ( result >= 0 ) { + + pass = FALSE; + failure_mssg = "Call to H5FDaio_write() succeeded with *ctlblk_ptr_ptr != NULL."; + + } + + write_ctlblk_ptr = NULL; + } + + if ( show_progress ) { /* cp == 14 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, (int)pass); + } + + + /* now go ahead and queue the write successfully, as we will need an operation + * in progress to test H5FDaio_test() and H5FDaio_wait(). + */ + if ( pass ) { + + result = H5FDaio_write(file, H5FD_MEM_DEFAULT, H5P_DEFAULT, (haddr_t)0x0000, + write_size, (void *)(write_buf), &write_ctlblk_ptr); + + if ( ( result < 0 ) || ( write_ctlblk_ptr == NULL ) ) { + + pass = FALSE; + failure_mssg = "valid call to H5FDaio_write() failed."; + } + } + + if ( show_progress ) { /* cp == 15 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, (int)pass); + } + + + + /* Make several calls to H5FDaio_test() with invalid input of some sort. + * All such calls should fail. + */ + + /* try to test the status of the write using a NULL file pointer */ + if ( pass ) { + + H5E_BEGIN_TRY { + result = H5FDaio_test(NULL, &done, write_ctlblk_ptr); + } H5E_END_TRY; + + if ( result >= 0 ) { + + pass = FALSE; + failure_mssg = "Call to H5FDaio_test() succeeded with NULL file."; + } + } + + if ( show_progress ) { /* cp == 16 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, (int)pass); + } + + + /* try to test the status of the write using a NULL done_ptr */ + if ( pass ) { + + H5E_BEGIN_TRY { + result = H5FDaio_test(file, NULL, write_ctlblk_ptr); + } H5E_END_TRY; + + if ( result >= 0 ) { + + pass = FALSE; + failure_mssg = "Call to H5FDaio_test() succeeded with NULL done pointer."; + } + } + + if ( show_progress ) { /* cp == 17 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, (int)pass); + } + + + /* try to test the status of the write using a NULL control block pointer */ + if ( pass ) { + + H5E_BEGIN_TRY { + result = H5FDaio_test(file, &done, NULL); + } H5E_END_TRY; + + if ( result >= 0 ) { + + pass = FALSE; + failure_mssg = "Call to H5FDaio_test() succeeded with NULL ctlblk_ptr."; + } + } + + if ( show_progress ) { /* cp == 18 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, (int)pass); + } + + + /* try to test the status of the write using an invalid control block pointer */ + if ( pass ) { + + H5E_BEGIN_TRY { + result = H5FDaio_test(file, &done, (void *)read_buf); + } H5E_END_TRY; + + if ( result >= 0 ) { + + pass = FALSE; + failure_mssg = "Call to H5FDaio_test() succeeded with invalid ctlblk_ptr."; + } + } + + if ( show_progress ) { /* cp == 19 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, (int)pass); + } + + + /* Now make several calls to H5FDaio_wait() with invalid input of some sort. + * All such calls should fail. + */ + + /* try to do a wait with a NULL file pointer */ + if ( pass ) { + + H5E_BEGIN_TRY { + result = H5FDaio_wait(NULL, write_ctlblk_ptr); + } H5E_END_TRY; + + if ( result >= 0 ) { + + pass = FALSE; + failure_mssg = "Call to H5FDaio_wait() succeeded with NULL file."; + } + } + + if ( show_progress ) { /* cp == 20 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, (int)pass); + } + + + /* try to do a wait with a NULL control block pointer */ + if ( pass ) { + + H5E_BEGIN_TRY { + result = H5FDaio_wait(file, NULL); + } H5E_END_TRY; + + if ( result >= 0 ) { + + pass = FALSE; + failure_mssg = "Call to H5FDaio_wait() succeeded with NULL ctlblk_ptr."; + } + } + + if ( show_progress ) { /* cp == 21 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, (int)pass); + } + + + /* try to do a wait with an invalid control block pointer */ + if ( pass ) { + + H5E_BEGIN_TRY { + result = H5FDaio_wait(file, (void *)read_buf); + } H5E_END_TRY; + + if ( result >= 0 ) { + + pass = FALSE; + failure_mssg = "Call to H5FDaio_wait() succeeded with invalid ctlblk_ptr."; + } + } + + if ( show_progress ) { /* cp == 22 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, (int)pass); + } + + + /* finally, do a valid call to H5FDaio_wait() to ensure that the write has + * completed, as we will need a completed write for our tests of H5FDaio_finish(). + */ + if ( pass ) { + + result = H5FDaio_wait(file, write_ctlblk_ptr); + + if ( result < 0 ) { + + pass = FALSE; + failure_mssg = "valid call H5FDaio_wait() failed."; + } + } + + if ( show_progress ) { /* cp == 23 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, (int)pass); + } + + + + + /* Testing H5FDaio_finish() is a bit difficult, as in general, the function + * should fail if the target operation is not complete when H5FDaio_finish() + * is called. Unfortunately, given the vaguries of AIO implementations (or + * lack of same) it will be difficult to reliably provide an operation that + * is in progress to test this error. Thus for now, we will neglect this + * issue. + * + * Hence, in the following tests we will make several calls to H5FDaio_finish() + * with other invalid input. Needless to say, all of these calls should fail. + */ + + /* try to finish the write with a NULL file pointer */ + if ( pass ) { + + H5E_BEGIN_TRY { + result = H5FDaio_finish(NULL, &error_num, write_ctlblk_ptr); + } H5E_END_TRY; + + if ( result >= 0 ) { + + pass = FALSE; + failure_mssg = "Call to H5FDaio_finish() succeeded with NULL file."; + } + } + + if ( show_progress ) { /* cp == 24 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, (int)pass); + } + + + /* try to finish the write with a NULL errno_ptr */ + if ( pass ) { + + H5E_BEGIN_TRY { + result = H5FDaio_finish(file, NULL, write_ctlblk_ptr); + } H5E_END_TRY; + + if ( result >= 0 ) { + + pass = FALSE; + failure_mssg = "Call to H5FDaio_finish() succeeded with NULL errno_ptr."; + } + } + + if ( show_progress ) { /* cp == 25 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, (int)pass); + } + + + /* try to finish the write with a NULL control block pointer */ + if ( pass ) { + + H5E_BEGIN_TRY { + result = H5FDaio_finish(file, &error_num, NULL); + } H5E_END_TRY; + + if ( result >= 0 ) { + + pass = FALSE; + failure_mssg = "Call to H5FDaio_finish() succeeded with NULL ctlblk_ptr."; + } + } + + if ( show_progress ) { /* cp == 26 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, (int)pass); + } + + + /* try to finish the write with an invalid control block pointer */ + if ( pass ) { + + H5E_BEGIN_TRY { + result = H5FDaio_finish(file, &error_num, (void *)read_buf); + } H5E_END_TRY; + + if ( result >= 0 ) { + + pass = FALSE; + failure_mssg = "Call to H5FDaio_finish() succeeded with an invalid ctlblk_ptr."; + } + } + + if ( show_progress ) { /* cp == 27 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, (int)pass); + } + + + /* finally, finish the write properly */ + if ( pass ) { + + result = H5FDaio_finish(file, &error_num, write_ctlblk_ptr); + + if ( result < 0 ) { + + pass = FALSE; + failure_mssg = "Valid call to H5FDaio_finish() failed for write."; + + } else if ( error_num != 0 ) { + + pass = FALSE; + failure_mssg = "AIO write failed."; + + } + } + + if ( show_progress ) { /* cp == 28 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, (int)pass); + } + + + + /* Next, make several attempts to queue an asynchonous fsync with invalid input + * of some sort. All attempts should fail. + */ + + /* try to queue an AIO fsync with a NULL file pointer */ + if ( pass ) { + + H5E_BEGIN_TRY { + result = H5FDaio_fsync(NULL, &fsync_ctlblk_ptr); + } H5E_END_TRY; + + if ( result >= 0 ) { + + pass = FALSE; + failure_mssg = "Call to H5FDaio_fsync() succeeded with NULL file."; + } + } + + if ( show_progress ) { /* cp == 29 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, (int)pass); + } + + + /* try to queue an AIO fsync with a NULL control block pointer pointer */ + if ( pass ) { + + H5E_BEGIN_TRY { + result = H5FDaio_fsync(file, NULL); + } H5E_END_TRY; + + if ( result >= 0 ) { + + pass = FALSE; + failure_mssg = "Call to H5FDaio_fsync() succeeded with NULL ctlblk_ptr_ptr."; + } + } + + if ( show_progress ) { /* cp == 30 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, (int)pass); + } + + + /* try to queue an AIO fsync with *ctlblk_ptr_ptr != NULL */ + if ( pass ) { + + fsync_ctlblk_ptr = (void *)read_buf; + + H5E_BEGIN_TRY { + result = H5FDaio_fsync(NULL, &fsync_ctlblk_ptr); + } H5E_END_TRY; + + if ( result >= 0 ) { + + pass = FALSE; + failure_mssg = "Call to H5FDaio_fsync() succeeded with *ctlblk_ptr_ptr != NULL."; + } + } + + if ( show_progress ) { /* cp == 31 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, (int)pass); + } + + + + /* Next, make several attempts to queue an AIO read with invalid input of some + * sort -- all attempts should fail. + */ + + /* try to queue a read with a NULL file */ + if ( pass ) { + + H5E_BEGIN_TRY { + result = H5FDaio_read(NULL, H5FD_MEM_DEFAULT, H5P_DEFAULT, (haddr_t)0x000, + write_size, (void *)(read_buf), &read_ctlblk_ptr); + } H5E_END_TRY; + + if ( result >= 0 ) { + + pass = FALSE; + failure_mssg = "Call to H5FDaio_read() succeeded with NULL file."; + + } else if ( read_ctlblk_ptr != NULL ) { + + pass = FALSE; + failure_mssg = "read_ctlblk_ptr != NULL after failed call to H5FDaio_read(0)"; + } + } + + if ( show_progress ) { /* cp == 32 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, (int)pass); + } + + + /* try to queue a read with an invalid memory type */ + if ( pass ) { + + H5E_BEGIN_TRY { + result = H5FDaio_read(file, H5FD_MEM_NTYPES, H5P_DEFAULT, (haddr_t)0x000, + write_size, (void *)(read_buf), &read_ctlblk_ptr); + } H5E_END_TRY; + + if ( result >= 0 ) { + + pass = FALSE; + failure_mssg = "Call to H5FDaio_read() succeeded with invalid memory type."; + + } else if ( read_ctlblk_ptr != NULL ) { + + pass = FALSE; + failure_mssg = "read_ctlblk_ptr != NULL after failed call to H5FDaio_read(1)"; + } + } + + if ( show_progress ) { /* cp == 33 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, (int)pass); + } + + + /* try to queue a read with an invalid dxpl -- do this by passing in a fapl ID + * instead. + */ + if ( pass ) { + + H5E_BEGIN_TRY { + result = H5FDaio_read(file, H5FD_MEM_DEFAULT, fapl_id, (haddr_t)0x000, + write_size, (void *)(read_buf), &read_ctlblk_ptr); + } H5E_END_TRY; + + if ( result >= 0 ) { + + pass = FALSE; + failure_mssg = "Call to H5FDaio_read() succeeded with invalid memory type."; + + } else if ( read_ctlblk_ptr != NULL ) { + + pass = FALSE; + failure_mssg = "read_ctlblk_ptr != NULL after failed call to H5FDaio_read(2)"; + } + } + + if ( show_progress ) { /* cp == 34 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, (int)pass); + } + + + /* try to queue a read with an invalid address */ + if ( pass ) { + + H5E_BEGIN_TRY { + result = H5FDaio_read(file, H5FD_MEM_DEFAULT, H5P_DEFAULT, HADDR_UNDEF, + write_size, (void *)(read_buf), &read_ctlblk_ptr); + } H5E_END_TRY; + + if ( result >= 0 ) { + + pass = FALSE; + failure_mssg = "Call to H5FDaio_read() succeeded with invalid address."; + + } else if ( read_ctlblk_ptr != NULL ) { + + pass = FALSE; + failure_mssg = "read_ctlblk_ptr != NULL after failed call to H5FDaio_read(3)"; + } + } + + if ( show_progress ) { /* cp == 35 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, (int)pass); + } + + + /* try to queue a read with an address beyond the eoa */ + if ( pass ) { + + H5E_BEGIN_TRY { + result = H5FDaio_read(file, H5FD_MEM_DEFAULT, H5P_DEFAULT, maxaddr + 1, + write_size, (void *)(read_buf), &read_ctlblk_ptr); + } H5E_END_TRY; + + if ( result >= 0 ) { + + pass = FALSE; + failure_mssg = "Call to H5FDaio_read() succeeded with address beyond eoa."; + + } else if ( read_ctlblk_ptr != NULL ) { + + pass = FALSE; + failure_mssg = "read_ctlblk_ptr != NULL after failed call to H5FDaio_read(4)"; + } + } + + if ( show_progress ) { /* cp == 36 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, (int)pass); + } + + + /* try to queue a read with zero size */ + if ( pass ) { + + H5E_BEGIN_TRY { + result = H5FDaio_read(file, H5FD_MEM_DEFAULT, H5P_DEFAULT, (haddr_t)0x0000, + 0, (void *)(read_buf), &read_ctlblk_ptr); + } H5E_END_TRY; + + if ( result >= 0 ) { + + pass = FALSE; + failure_mssg = "Call to H5FDaio_read() succeeded with zero size."; + + } else if ( read_ctlblk_ptr != NULL ) { + + pass = FALSE; + failure_mssg = "read_ctlblk_ptr != NULL after failed call to H5FDaio_read(5)"; + } + } + + if ( show_progress ) { /* cp == 37 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, (int)pass); + } + + + /* try to queue a read with address + size greater than eoa */ + if ( pass ) { + + H5E_BEGIN_TRY { + result = H5FDaio_read(file, H5FD_MEM_DEFAULT, H5P_DEFAULT, + maxaddr - (write_size / 2), write_size, + (void *)(read_buf), &read_ctlblk_ptr); + } H5E_END_TRY; + + if ( result >= 0 ) { + + pass = FALSE; + failure_mssg = "Call to H5FDaio_read() succeeded with addr + size > eoa."; + + } else if ( read_ctlblk_ptr != NULL ) { + + pass = FALSE; + failure_mssg = "read_ctlblk_ptr != NULL after failed call to H5FDaio_read(6)"; + } + } + + if ( show_progress ) { /* cp == 38 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, (int)pass); + } + + + /* try to queue a read with a NULL buffer pointer */ + if ( pass ) { + + H5E_BEGIN_TRY { + result = H5FDaio_read(file, H5FD_MEM_DEFAULT, H5P_DEFAULT, (haddr_t)0x0000, + write_size, (void *)(NULL), &read_ctlblk_ptr); + } H5E_END_TRY; + + if ( result >= 0 ) { + + pass = FALSE; + failure_mssg = "Call to H5FDaio_read() succeeded with NULL buffer pointer."; + + } else if ( read_ctlblk_ptr != NULL ) { + + pass = FALSE; + failure_mssg = "read_ctlblk_ptr != NULL after failed call to H5FDaio_read(7)"; + } + } + + if ( show_progress ) { /* cp == 39 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, (int)pass); + } + + + /* try to queue a read with a NULL control block pointer pointer */ + if ( pass ) { + + H5E_BEGIN_TRY { + result = H5FDaio_read(file, H5FD_MEM_DEFAULT, H5P_DEFAULT, (haddr_t)0x0000, + write_size, (void *)(read_buf), NULL); + } H5E_END_TRY; + + if ( result >= 0 ) { + + pass = FALSE; + failure_mssg = "Call to H5FDaio_read() succeeded with NULL ctlblk_ptr_ptr."; + + } else if ( read_ctlblk_ptr != NULL ) { + + pass = FALSE; + failure_mssg = "read_ctlblk_ptr != NULL after failed call to H5FDaio_read(8)"; + } + } + + if ( show_progress ) { /* cp == 40 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, (int)pass); + } + + + /* try to queue a read with *ctlblk_ptr_ptr != NULL */ + if ( pass ) { + + read_ctlblk_ptr = (void *)read_buf; + + H5E_BEGIN_TRY { + result = H5FDaio_read(file, H5FD_MEM_DEFAULT, H5P_DEFAULT, (haddr_t)0x0000, + write_size, (void *)(read_buf), &read_ctlblk_ptr); + } H5E_END_TRY; + + if ( result >= 0 ) { + + pass = FALSE; + failure_mssg = "Call to H5FDaio_read() succeeded with *ctlblk_ptr_ptr != NULL."; + } + + read_ctlblk_ptr = NULL; + } + + if ( show_progress ) { /* cp == 41 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, (int)pass); + } + + + /* go ahead and queue the read successfully, as we will need an operation + * (possibly) in progress to test H5FDaio_cancel() + */ + if ( pass ) { + + result = H5FDaio_read(file, H5FD_MEM_DEFAULT, H5P_DEFAULT, (haddr_t)0x0000, + write_size, (void *)(read_buf), &read_ctlblk_ptr); + + if ( ( result < 0 ) || ( read_ctlblk_ptr == NULL ) ) { + + pass = FALSE; + failure_mssg = "valid call to H5FDaio_read() failed."; + } + } + + if ( show_progress ) { /* cp == 42 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, (int)pass); + } + + + /* Now, make several calls to H5FDaio_cancel() with invalid input of some sort. */ + + /* try to cancel the read with a NULL file pointer */ + if ( pass ) { + + H5E_BEGIN_TRY { + result = H5FDaio_cancel(NULL, read_ctlblk_ptr); + } H5E_END_TRY; + + if ( result >= 0 ) { + + pass = FALSE; + failure_mssg = "Call to H5FDaio_cancel() succeeded with NULL file."; + + } + } + + if ( show_progress ) { /* cp == 43 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, (int)pass); + } + + + /* try to cancel the read with a NULL control block ptr */ + if ( pass ) { + + H5E_BEGIN_TRY { + result = H5FDaio_cancel(file, NULL); + } H5E_END_TRY; + + if ( result >= 0 ) { + + pass = FALSE; + failure_mssg = "Call to H5FDaio_cancel() succeeded with NULL ctlblk_ptr."; + + } + } + + if ( show_progress ) { /* cp == 44 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, (int)pass); + } + + + /* try to cancel the read with an invalid control block ptr */ + if ( pass ) { + + H5E_BEGIN_TRY { + result = H5FDaio_cancel(file, (void *)write_buf); + } H5E_END_TRY; + + if ( result >= 0 ) { + + pass = FALSE; + failure_mssg = "Call to H5FDaio_cancel() succeeded with invalid ctlblk_ptr."; + + } + } + + if ( show_progress ) { /* cp == 45 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, (int)pass); + } + + + /* finally, try to cancel the read with valid input -- should succeed */ + if ( pass ) { + + result = H5FDaio_cancel(file, read_ctlblk_ptr); + + if ( result < 0 ) { + + pass = FALSE; + failure_mssg = "Valid call to H5FDaio_cancel() failed."; + + } + } + + if ( show_progress ) { /* cp == 46 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, (int)pass); + } + + + if ( file != NULL ) { + + result = H5FDclose(file); + + if ( result < 0 ) { + + pass = FALSE; + failure_mssg = "H5FDclose() failed."; + + } else if ( h5_cleanup(FILENAME, fapl_id) == 0 ) { + + pass = FALSE; + failure_mssg = "h5_cleanup() failed.\n"; + } + } + + if ( show_progress ) { /* cp == 47 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, (int)pass); + } + + if ( pass ) { + + PASSED(); + + } else { + + HDfprintf(stdout, "%s: failure_mssg = \"%s\".\n", + fcn_name, failure_mssg); + H5_FAILED(); + ret_val = -1; + } + + if ( verbose ) { + + HDfprintf(stdout, "exiting generic_aio_input_error_tests() -- ret_val == %d.\n", + ret_val); + } + + return(ret_val); + +} /* generic_aio_input_error_tests() */ + + +/*------------------------------------------------------------------------- + * Function: multi_file_driver_aio_test() + * + * Purpose: On most file drivers, the type of the data written is + * largely irrelevant. However, for the multi file driver, + * the type of the data indicates the file to which the + * data is written, and also specifies a corrected offset + * in the target file. + * + * Thus the generic aio tests are not sufficient here -- + * we must write all types of data, and verify that they + * are directed properly. + * + * Return: Success: 0 + * Failure: -1 + * + * Programmer: JRM -- 10/21/10 + * + *------------------------------------------------------------------------- + */ + +#define TYPE_SLICE ((haddr_t)0x24000000LL) + +static int +multi_file_driver_aio_test(const char * test_banner, + const int file_name_num) +{ + const char * fcn_name = "multi_file_driver_aio_test()"; + const char * memb_name[H5FD_MEM_NTYPES]; + const char * (type_names[H5FD_MEM_NTYPES]) = + { + "H5FD_MEM_DEFAULT", + "H5FD_MEM_SUPER", + "H5FD_MEM_BTREE", + "H5FD_MEM_DRAW", + "H5FD_MEM_GHEAP", + "H5FD_MEM_LHEAP", + "H5FD_MEM_OHDR" + }; + const char * failure_mssg = NULL; + const char * tags[] = { + "1 KB write", + "1 KB write", + "1 KB write", + "1 KB write", + "1 KB write", + "1 KB write", + + "512 B write", + "512 B write", + "512 B write", + "512 B write", + "512 B write", + "512 B write", + + "16 B wrt", + "16 B wrt", + "16 B wrt", + "16 B wrt", + "16 B wrt", + "16 B wrt", + + "4 KB write", + "4 KB write", + "4 KB write", + "4 KB write", + "4 KB write", + "4 KB write", + + "31 B write", + "31 B write", + "31 B write", + "31 B write", + "31 B write", + "31 B write", + + "1 MB write", + "1 MB write", + "1 MB write", + "1 MB write", + "1 MB write", + "1 MB write", + + "4 MB write", + "4 MB write", + "4 MB write", + "4 MB write", + "4 MB write", + "4 MB write", + + "1 MB + 1 B write", + "1 MB + 1 B write", + "1 MB + 1 B write", + "1 MB + 1 B write", + "1 MB + 1 B write", + "1 MB + 1 B write", + + "64 MB write", + "64 MB write", + "64 MB write", + "64 MB write", + "64 MB write", + "64 MB write", + + "24 B write", + "24 B write", + "24 B write", + "24 B write", + "24 B write", + "24 B write", + }; + char file_name[1024]; + hbool_t pass = TRUE; + hbool_t show_progress = FALSE; + hbool_t verbose = FALSE; + int cp = 0; + int i; + int ret_val = 0; + int write_count = 60; + int op_count = 60; + int ops[] = { READ_OP, READ_OP, READ_OP, READ_OP, READ_OP, READ_OP, + WRITE_OP, WRITE_OP, WRITE_OP, WRITE_OP, WRITE_OP, WRITE_OP, + READ_OP, READ_OP, READ_OP, READ_OP, READ_OP, READ_OP, + WRITE_OP, WRITE_OP, WRITE_OP, WRITE_OP, WRITE_OP, WRITE_OP, + READ_OP, READ_OP, READ_OP, READ_OP, READ_OP, READ_OP, + WRITE_OP, WRITE_OP, WRITE_OP, WRITE_OP, WRITE_OP, WRITE_OP, + READ_OP, READ_OP, READ_OP, READ_OP, READ_OP, READ_OP, + WRITE_OP, WRITE_OP, WRITE_OP, WRITE_OP, WRITE_OP, WRITE_OP, + READ_OP, READ_OP, READ_OP, READ_OP, READ_OP, READ_OP, + WRITE_OP, WRITE_OP, WRITE_OP, WRITE_OP, WRITE_OP, WRITE_OP }; + hid_t fapl_id; + hid_t memb_fapl[H5FD_MEM_NTYPES]; + H5FD_mem_t types[] = { + H5FD_MEM_SUPER, + H5FD_MEM_BTREE, + H5FD_MEM_DRAW, + H5FD_MEM_GHEAP, + H5FD_MEM_LHEAP, + H5FD_MEM_OHDR, + + H5FD_MEM_SUPER, + H5FD_MEM_BTREE, + H5FD_MEM_DRAW, + H5FD_MEM_GHEAP, + H5FD_MEM_LHEAP, + H5FD_MEM_OHDR, + + H5FD_MEM_SUPER, + H5FD_MEM_BTREE, + H5FD_MEM_DRAW, + H5FD_MEM_GHEAP, + H5FD_MEM_LHEAP, + H5FD_MEM_OHDR, + + H5FD_MEM_SUPER, + H5FD_MEM_BTREE, + H5FD_MEM_DRAW, + H5FD_MEM_GHEAP, + H5FD_MEM_LHEAP, + H5FD_MEM_OHDR, + + H5FD_MEM_SUPER, + H5FD_MEM_BTREE, + H5FD_MEM_DRAW, + H5FD_MEM_GHEAP, + H5FD_MEM_LHEAP, + H5FD_MEM_OHDR, + + H5FD_MEM_SUPER, + H5FD_MEM_BTREE, + H5FD_MEM_DRAW, + H5FD_MEM_GHEAP, + H5FD_MEM_LHEAP, + H5FD_MEM_OHDR, + + H5FD_MEM_SUPER, + H5FD_MEM_BTREE, + H5FD_MEM_DRAW, + H5FD_MEM_GHEAP, + H5FD_MEM_LHEAP, + H5FD_MEM_OHDR, + + H5FD_MEM_SUPER, + H5FD_MEM_BTREE, + H5FD_MEM_DRAW, + H5FD_MEM_GHEAP, + H5FD_MEM_LHEAP, + H5FD_MEM_OHDR, + + H5FD_MEM_SUPER, + H5FD_MEM_BTREE, + H5FD_MEM_DRAW, + H5FD_MEM_GHEAP, + H5FD_MEM_LHEAP, + H5FD_MEM_OHDR, + + H5FD_MEM_SUPER, + H5FD_MEM_BTREE, + H5FD_MEM_DRAW, + H5FD_MEM_GHEAP, + H5FD_MEM_LHEAP, + H5FD_MEM_OHDR, + }; + size_t write_size; + size_t lengths[] = + { + 1024, + 1024, + 1024, + 1024, + 1024, + 1024, + + 512, + 512, + 512, + 512, + 512, + 512, + + 16, + 16, + 16, + 16, + 16, + 16, + + 4096, + 4096, + 4096, + 4096, + 4096, + 4096, + + 31, + 31, + 31, + 31, + 31, + 31, + + (1024 * 1024), + (1024 * 1024), + (1024 * 1024), + (1024 * 1024), + (1024 * 1024), + (1024 * 1024), + + (4 * 1024 * 1024), + (4 * 1024 * 1024), + (4 * 1024 * 1024), + (4 * 1024 * 1024), + (4 * 1024 * 1024), + (4 * 1024 * 1024), + + (1024 * 1024 + 1), + (1024 * 1024 + 1), + (1024 * 1024 + 1), + (1024 * 1024 + 1), + (1024 * 1024 + 1), + (1024 * 1024 + 1), + + (64 * 1024 *1024), + (64 * 1024 *1024), + (64 * 1024 *1024), + (64 * 1024 *1024), + (64 * 1024 *1024), + (64 * 1024 *1024), + + 24, + 24, + 24, + 24, + 24, + 24, + }; + herr_t result; + haddr_t eoa; + haddr_t max_addr; + haddr_t memb_addr[H5FD_MEM_NTYPES]; + haddr_t offset; + haddr_t offsets[] = { + (haddr_t)(0), + (haddr_t)(0 + (1 * TYPE_SLICE)), + (haddr_t)(0 + (2 * TYPE_SLICE)), + (haddr_t)(0 + (3 * TYPE_SLICE)), + (haddr_t)(0 + (4 * TYPE_SLICE)), + (haddr_t)(0 + (5 * TYPE_SLICE)), + + (haddr_t)(1024), + (haddr_t)(1024 + (1 * TYPE_SLICE)), + (haddr_t)(1024 + (2 * TYPE_SLICE)), + (haddr_t)(1024 + (3 * TYPE_SLICE)), + (haddr_t)(1024 + (4 * TYPE_SLICE)), + (haddr_t)(1024 + (5 * TYPE_SLICE)), + + (haddr_t)(1536), + (haddr_t)(1536 + (1 * TYPE_SLICE)), + (haddr_t)(1536 + (2 * TYPE_SLICE)), + (haddr_t)(1536 + (3 * TYPE_SLICE)), + (haddr_t)(1536 + (4 * TYPE_SLICE)), + (haddr_t)(1536 + (5 * TYPE_SLICE)), + + (haddr_t)(1552), + (haddr_t)(1552 + (1 * TYPE_SLICE)), + (haddr_t)(1552 + (2 * TYPE_SLICE)), + (haddr_t)(1552 + (3 * TYPE_SLICE)), + (haddr_t)(1552 + (4 * TYPE_SLICE)), + (haddr_t)(1552 + (5 * TYPE_SLICE)), + + (haddr_t)(5648), + (haddr_t)(5648 + (1 * TYPE_SLICE)), + (haddr_t)(5648 + (2 * TYPE_SLICE)), + (haddr_t)(5648 + (3 * TYPE_SLICE)), + (haddr_t)(5648 + (4 * TYPE_SLICE)), + (haddr_t)(5648 + (5 * TYPE_SLICE)), + + (haddr_t)(5679), + (haddr_t)(5679 + (1 * TYPE_SLICE)), + (haddr_t)(5679 + (2 * TYPE_SLICE)), + (haddr_t)(5679 + (3 * TYPE_SLICE)), + (haddr_t)(5679 + (4 * TYPE_SLICE)), + (haddr_t)(5679 + (5 * TYPE_SLICE)), + + (haddr_t)(1054255), + (haddr_t)(1054255 + (1 * TYPE_SLICE)), + (haddr_t)(1054255 + (2 * TYPE_SLICE)), + (haddr_t)(1054255 + (3 * TYPE_SLICE)), + (haddr_t)(1054255 + (4 * TYPE_SLICE)), + (haddr_t)(1054255 + (5 * TYPE_SLICE)), + + (haddr_t)(5248559), + (haddr_t)(5248559 + (1 * TYPE_SLICE)), + (haddr_t)(5248559 + (2 * TYPE_SLICE)), + (haddr_t)(5248559 + (3 * TYPE_SLICE)), + (haddr_t)(5248559 + (4 * TYPE_SLICE)), + (haddr_t)(5248559 + (5 * TYPE_SLICE)), + + (haddr_t)(6297136), + (haddr_t)(6297136 + (1 * TYPE_SLICE)), + (haddr_t)(6297136 + (2 * TYPE_SLICE)), + (haddr_t)(6297136 + (3 * TYPE_SLICE)), + (haddr_t)(6297136 + (4 * TYPE_SLICE)), + (haddr_t)(6297136 + (5 * TYPE_SLICE)), + + (haddr_t)(73406000), + (haddr_t)(73406000 + (1 * TYPE_SLICE)), + (haddr_t)(73406000 + (2 * TYPE_SLICE)), + (haddr_t)(73406000 + (3 * TYPE_SLICE)), + (haddr_t)(73406000 + (4 * TYPE_SLICE)), + (haddr_t)(73406000 + (5 * TYPE_SLICE)), + }; + haddr_t type_offset; + H5FD_mem_t mt; + H5FD_mem_t memb_map[H5FD_MEM_NTYPES]; + H5FD_t * file; + + if ( verbose ) { + + HDfprintf(stdout, + "entering multi_file_driver_aio_test(\"%s\", %d(\"%s\"))\n", + test_banner, file_name_num, FILENAME[file_name_num]); + } + + TESTING(test_banner); + + if ( show_progress ) { /* cp == 0 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d -- setting up fapl.\n", + fcn_name, cp++, (int)pass); + } + + /* setup the fapl -- this is somewhat involved fot the multi file driver */ + if ( pass ) { + + for ( mt = 0; mt < H5FD_MEM_NTYPES; mt++ ) { + + memb_addr[mt] = HADDR_UNDEF; + memb_fapl[mt] = H5P_DEFAULT; + memb_map[mt] = H5FD_MEM_DRAW; + memb_name[mt] = NULL; + } + + memb_map[H5FD_MEM_SUPER] = H5FD_MEM_SUPER; + memb_fapl[H5FD_MEM_SUPER] = H5P_DEFAULT; + memb_name[H5FD_MEM_SUPER] = "%s-s.h5"; + memb_addr[H5FD_MEM_SUPER] = 0; + + memb_map[H5FD_MEM_BTREE] = H5FD_MEM_BTREE; + memb_fapl[H5FD_MEM_BTREE] = H5P_DEFAULT; + memb_name[H5FD_MEM_BTREE] = "%s-b.h5"; + memb_addr[H5FD_MEM_BTREE] = memb_addr[H5FD_MEM_SUPER] + TYPE_SLICE; + + memb_map[H5FD_MEM_DRAW] = H5FD_MEM_DRAW; + memb_fapl[H5FD_MEM_DRAW] = H5P_DEFAULT; + memb_name[H5FD_MEM_DRAW] = "%s-r.h5"; + memb_addr[H5FD_MEM_DRAW] = memb_addr[H5FD_MEM_BTREE] + TYPE_SLICE; + + memb_map[H5FD_MEM_GHEAP] = H5FD_MEM_GHEAP; + memb_fapl[H5FD_MEM_GHEAP] = H5P_DEFAULT; + memb_name[H5FD_MEM_GHEAP] = "%s-g.h5"; + memb_addr[H5FD_MEM_GHEAP] = memb_addr[H5FD_MEM_DRAW] + TYPE_SLICE; + + memb_map[H5FD_MEM_LHEAP] = H5FD_MEM_LHEAP; + memb_fapl[H5FD_MEM_LHEAP] = H5P_DEFAULT; + memb_name[H5FD_MEM_LHEAP] = "%s-l.h5"; + memb_addr[H5FD_MEM_LHEAP] = memb_addr[H5FD_MEM_GHEAP] + TYPE_SLICE; + + memb_map[H5FD_MEM_OHDR] = H5FD_MEM_OHDR; + memb_fapl[H5FD_MEM_OHDR] = H5P_DEFAULT; + memb_name[H5FD_MEM_OHDR] = "%s-o.h5"; + memb_addr[H5FD_MEM_OHDR] = memb_addr[H5FD_MEM_LHEAP] + TYPE_SLICE; + + max_addr = memb_addr[H5FD_MEM_OHDR] + TYPE_SLICE; + + fapl_id = h5_fileaccess(); + + if ( H5Pset_fapl_multi(fapl_id, memb_map, memb_fapl, memb_name, + memb_addr, FALSE) < 0 ) { + + pass = FALSE; + failure_mssg = "H5Pset_fapl_multi() failed."; + + } + } + + + if ( show_progress ) { /* cp == 1 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d -- fixing name.\n", + fcn_name, cp++, (int)pass); + } + + + /* setup the file name */ + if ( pass ) { + + if ( NULL == h5_fixname(FILENAME[file_name_num], fapl_id, + file_name, sizeof(file_name)) ) { + + pass = FALSE; + failure_mssg = "h5_fixname() failed."; + } + } + + if ( show_progress ) { /* cp == 2 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d -- opening file.\n", + fcn_name, cp++, (int)pass); + } + + /* create the file */ + if ( pass ) { + + file = H5FDopen(file_name, (H5F_ACC_RDWR | H5F_ACC_CREAT), + fapl_id, max_addr); + + if ( file == NULL ) { + + pass = FALSE; + failure_mssg = "H5FDopen() failed."; + } + } + + if ( show_progress ) { /* cp == 3 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d -- setting eoa.\n", + fcn_name, cp++, (int)pass); + } + + /* set the EOA */ + if ( verbose ) { + + for ( mt = H5FD_MEM_SUPER; mt <= H5FD_MEM_OHDR; mt++ ) { + + eoa = H5FDget_eoa(file, mt); + + if ( eoa == HADDR_UNDEF ) { + + HDfprintf(stdout, "%s: H5FDget_eoa(file, %s) failed.\n", + fcn_name, type_names[(int)mt]); + + } else { + + HDfprintf(stdout, "%s: H5FDget_eoa(file, %s) returned 0x%llx.\n", + fcn_name, type_names[(int)mt], (unsigned long long)eoa); + + } + } + } + + mt = H5FD_MEM_SUPER; + while ( ( pass ) && ( mt <= H5FD_MEM_OHDR ) ) { + + if ( verbose ) { + + HDfprintf(stdout, + "calling H5FDset_eoa(file, %s, (%d * TYPE_SLICE) - 1).\n", + type_names[(int)mt], (int)(mt)); + } + + result = H5FDset_eoa(file, mt, (((haddr_t)(mt)) * TYPE_SLICE) - 1); + + if ( result < 0 ) { + + pass = FALSE; + failure_mssg = "H5FDset_eoa() failed."; + } + + mt++; + } + + if ( verbose ) { + + for ( mt = H5FD_MEM_SUPER; mt <= H5FD_MEM_OHDR; mt++ ) { + + eoa = H5FDget_eoa(file, mt); + + if ( eoa == HADDR_UNDEF ) { + + HDfprintf(stdout, "%s: H5FDget_eoa(file, %s) failed.\n", + fcn_name, type_names[(int)mt]); + + } else { + + HDfprintf(stdout, "%s: H5FDget_eoa(file, %s) returned 0x%llx.\n", + fcn_name, type_names[(int)mt], (unsigned long long)eoa); + + } + } + } + + if ( show_progress ) { /* cp == 4 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d -- swrchk 64 bytes - poll.\n", + fcn_name, cp++, (int)pass); + } + + /* first do some simple write, read back, and compare results tests with + * buffers of various sizes + */ + + offset = (haddr_t)0; + write_size = (size_t)64; + + if ( verbose ) { + + HDfprintf(stdout, "%s: offset = 0x%llx, write_size = 0x%llx, eow = 0x%llx.\n", + fcn_name, + (unsigned long long)offset, (unsigned long long)write_size, + (unsigned long long)(offset + write_size)); + } + + for ( i = 1; i < H5FD_MEM_NTYPES; i++ ) { + + if ( pass ) { + + type_offset = ((haddr_t)(i - 1) * TYPE_SLICE) + offset; + + HDassert( type_offset < ((haddr_t)i * TYPE_SLICE) ); + + aio_single_write_read_check(file, + (H5FD_mem_t)i, + "64 bytes -- test for completion", + type_offset, + write_size, + /* do_wait = */ FALSE, + &pass, + &failure_mssg); + } + } + + if ( show_progress ) { /* cp == 5 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d -- swrchk 64 bytes - wait.\n", + fcn_name, cp++, (int)pass); + } + + offset += (haddr_t)write_size; + + if ( verbose ) { + + HDfprintf(stdout, "%s: offset = 0x%llx, write_size = 0x%llx, eow = 0x%llx.\n", + fcn_name, + (unsigned long long)offset, (unsigned long long)write_size, + (unsigned long long)(offset + write_size)); + } + + for ( i = 1; i < H5FD_MEM_NTYPES; i++ ) { + + if ( pass ) { + + type_offset = ((haddr_t)(i - 1) * TYPE_SLICE) + offset; + + HDassert( type_offset < ((haddr_t)(i) * TYPE_SLICE) ); + + aio_single_write_read_check(file, + (H5FD_mem_t)i, + "64 bytes -- wait for completion", + type_offset, + write_size, + /* do_wait = */ TRUE, + &pass, + &failure_mssg); + } + } + + + if ( show_progress ) { /* cp == 6 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d -- swrchk 256 bytes - poll.\n", + fcn_name, cp++, (int)pass); + } + + offset += (haddr_t)write_size; + + write_size *= (size_t)4; + + if ( verbose ) { + + HDfprintf(stdout, "%s: offset = 0x%llx, write_size = 0x%llx, eow = 0x%llx.\n", + fcn_name, + (unsigned long long)offset, (unsigned long long)write_size, + (unsigned long long)(offset + write_size)); + } + + for ( i = 1; i < H5FD_MEM_NTYPES; i++ ) { + + if ( pass ) { + + type_offset = ((haddr_t)(i - 1) * TYPE_SLICE) + offset; + + HDassert( type_offset < ((haddr_t)(i) * TYPE_SLICE) ); + + aio_single_write_read_check(file, + (H5FD_mem_t)i, + "256 bytes -- test for completion", + type_offset, + write_size, + /* do_wait = */ FALSE, + &pass, + &failure_mssg); + } + } + + if ( show_progress ) { /* cp == 7 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d -- swrchk 256 bytes - wait.\n", + fcn_name, cp++, (int)pass); + } + + offset += (haddr_t)write_size; + + if ( verbose ) { + + HDfprintf(stdout, "%s: offset = 0x%llx, write_size = 0x%llx, eow = 0x%llx.\n", + fcn_name, + (unsigned long long)offset, (unsigned long long)write_size, + (unsigned long long)(offset + write_size)); + } + + for ( i = 1; i < H5FD_MEM_NTYPES; i++ ) { + + if ( pass ) { + + type_offset = ((haddr_t)(i - 1) * TYPE_SLICE) + offset; + + HDassert( type_offset < ((haddr_t)(i) * TYPE_SLICE) ); + + aio_single_write_read_check(file, + (H5FD_mem_t)i, + "256 bytes -- wait for completion", + type_offset, + write_size, + /* do_wait = */ TRUE, + &pass, + &failure_mssg); + } + } + + + if ( show_progress ) { /* cp == 8 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d -- swrchk 1 KB - poll.\n", + fcn_name, cp++, (int)pass); + } + + offset += (haddr_t)write_size; + + write_size *= (size_t)4; + + if ( verbose ) { + + HDfprintf(stdout, "%s: offset = 0x%llx, write_size = 0x%llx, eow = 0x%llx.\n", + fcn_name, + (unsigned long long)offset, (unsigned long long)write_size, + (unsigned long long)(offset + write_size)); + } + + for ( i = 1; i < H5FD_MEM_NTYPES; i++ ) { + + if ( pass ) { + + type_offset = ((haddr_t)(i - 1) * TYPE_SLICE) + offset; + + HDassert( type_offset < ((haddr_t)(i) * TYPE_SLICE) ); + + aio_single_write_read_check(file, + (H5FD_mem_t)i, + "1 KB -- test for completion", + type_offset, + write_size, + /* do_wait = */ FALSE, + &pass, + &failure_mssg); + } + } + + if ( show_progress ) { /* cp == 9 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d -- swrchk 1 KB - wait.\n", + fcn_name, cp++, (int)pass); + } + + offset += (haddr_t)write_size; + + if ( verbose ) { + + HDfprintf(stdout, "%s: offset = 0x%llx, write_size = 0x%llx, eow = 0x%llx.\n", + fcn_name, + (unsigned long long)offset, (unsigned long long)write_size, + (unsigned long long)(offset + write_size)); + } + + for ( i = 1; i < H5FD_MEM_NTYPES; i++ ) { + + if ( pass ) { + + type_offset = ((haddr_t)(i - 1) * TYPE_SLICE) + offset; + + HDassert( type_offset < ((haddr_t)(i) * TYPE_SLICE) ); + + aio_single_write_read_check(file, + (H5FD_mem_t)i, + "1 KB -- wait for completion", + type_offset, + write_size, + /* do_wait = */ TRUE, + &pass, + &failure_mssg); + } + } + + if ( show_progress ) { /* cp == 10 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d -- swrchk 4 KB - poll.\n", + fcn_name, cp++, (int)pass); + } + + offset += (haddr_t)write_size; + + write_size *= (size_t)4; + + if ( verbose ) { + + HDfprintf(stdout, "%s: offset = 0x%llx, write_size = 0x%llx, eow = 0x%llx.\n", + fcn_name, + (unsigned long long)offset, (unsigned long long)write_size, + (unsigned long long)(offset + write_size)); + } + + for ( i = 1; i < H5FD_MEM_NTYPES; i++ ) { + + if ( pass ) { + + type_offset = ((haddr_t)(i - 1) * TYPE_SLICE) + offset; + + HDassert( type_offset < ((haddr_t)(i) * TYPE_SLICE) ); + + aio_single_write_read_check(file, + (H5FD_mem_t)i, + "4 KB -- test for completion", + type_offset, + write_size, + /* do_wait = */ FALSE, + &pass, + &failure_mssg); + } + } + + if ( show_progress ) { /* cp == 11 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d -- swrchk 4 KB - wait.\n", + fcn_name, cp++, (int)pass); + } + + offset += (haddr_t)write_size; + + if ( verbose ) { + + HDfprintf(stdout, "%s: offset = 0x%llx, write_size = 0x%llx, eow = 0x%llx.\n", + fcn_name, + (unsigned long long)offset, (unsigned long long)write_size, + (unsigned long long)(offset + write_size)); + } + + for ( i = 1; i < H5FD_MEM_NTYPES; i++ ) { + + if ( pass ) { + + type_offset = ((haddr_t)(i - 1) * TYPE_SLICE) + offset; + + HDassert( type_offset < ((haddr_t)(i) * TYPE_SLICE) ); + + aio_single_write_read_check(file, + (H5FD_mem_t)i, + "4 KB -- wait for completion", + type_offset, + write_size, + /* do_wait = */ TRUE, + &pass, + &failure_mssg); + } + } + + + if ( show_progress ) { /* cp == 12 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d -- swrchk 64 KB - poll.\n", + fcn_name, cp++, (int)pass); + } + + offset += (haddr_t)write_size; + + write_size *= (size_t)16; + + if ( verbose ) { + + HDfprintf(stdout, "%s: offset = 0x%llx, write_size = 0x%llx, eow = 0x%llx.\n", + fcn_name, + (unsigned long long)offset, (unsigned long long)write_size, + (unsigned long long)(offset + write_size)); + } + + for ( i = 1; i < H5FD_MEM_NTYPES; i++ ) { + + if ( pass ) { + + type_offset = ((haddr_t)(i - 1) * TYPE_SLICE) + offset; + + HDassert( type_offset < ((haddr_t)(i) * TYPE_SLICE) ); + + aio_single_write_read_check(file, + (H5FD_mem_t)i, + "64 KB -- test for completion", + type_offset, + write_size, + /* do_wait = */ FALSE, + &pass, + &failure_mssg); + } + } + + if ( show_progress ) { /* cp == 13 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d -- swrchk 64 KB - wait.\n", + fcn_name, cp++, (int)pass); + } + + offset += (haddr_t)write_size; + + if ( verbose ) { + + HDfprintf(stdout, "%s: offset = 0x%llx, write_size = 0x%llx, eow = 0x%llx.\n", + fcn_name, + (unsigned long long)offset, (unsigned long long)write_size, + (unsigned long long)(offset + write_size)); + } + + for ( i = 1; i < H5FD_MEM_NTYPES; i++ ) { + + if ( pass ) { + + type_offset = ((haddr_t)(i - 1) * TYPE_SLICE) + offset; + + HDassert( type_offset < ((haddr_t)(i) * TYPE_SLICE) ); + + aio_single_write_read_check(file, + (H5FD_mem_t)i, + "64 KB -- wait for completion", + type_offset, + write_size, + /* do_wait = */ TRUE, + &pass, + &failure_mssg); + } + } + + if ( show_progress ) { /* cp == 14 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d -- swrchk 1 MB - poll.\n", + fcn_name, cp++, (int)pass); + } + + offset += (haddr_t)write_size; + + write_size *= (size_t)16; + + if ( verbose ) { + + HDfprintf(stdout, "%s: offset = 0x%llx, write_size = 0x%llx, eow = 0x%llx.\n", + fcn_name, + (unsigned long long)offset, (unsigned long long)write_size, + (unsigned long long)(offset + write_size)); + } + + for ( i = 1; i < H5FD_MEM_NTYPES; i++ ) { + + if ( pass ) { + + type_offset = ((haddr_t)(i - 1) * TYPE_SLICE) + offset; + + HDassert( type_offset < ((haddr_t)(i) * TYPE_SLICE) ); + + aio_single_write_read_check(file, + (H5FD_mem_t)i, + "1 MB -- test for completion", + type_offset, + write_size, + /* do_wait = */ FALSE, + &pass, + &failure_mssg); + } + } + + if ( show_progress ) { /* cp == 15 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d -- swrchk 1 MB wait.\n", + fcn_name, cp++, (int)pass); + } + + offset += (haddr_t)write_size; + + if ( verbose ) { + + HDfprintf(stdout, "%s: offset = 0x%llx, write_size = 0x%llx, eow = 0x%llx.\n", + fcn_name, + (unsigned long long)offset, (unsigned long long)write_size, + (unsigned long long)(offset + write_size)); + } + + for ( i = 1; i < H5FD_MEM_NTYPES; i++ ) { + + if ( pass ) { + + type_offset = ((haddr_t)(i - 1) * TYPE_SLICE) + offset; + + HDassert( type_offset < ((haddr_t)(i) * TYPE_SLICE) ); + + aio_single_write_read_check(file, + (H5FD_mem_t)i, + "1 MB -- wait for completion", + type_offset, + write_size, + /* do_wait = */ TRUE, + &pass, + &failure_mssg); + } + } + + if ( show_progress ) { /* cp == 16 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d -- swrchk 16 MB - poll.\n", + fcn_name, cp++, (int)pass); + } + + offset += (haddr_t)write_size; + + write_size *= (size_t)16; + + if ( verbose ) { + + HDfprintf(stdout, "%s: offset = 0x%llx, write_size = 0x%llx, eow = 0x%llx.\n", + fcn_name, + (unsigned long long)offset, (unsigned long long)write_size, + (unsigned long long)(offset + write_size)); + } + + for ( i = 1; i < H5FD_MEM_NTYPES; i++ ) { + + if ( pass ) { + + type_offset = ((haddr_t)(i - 1) * TYPE_SLICE) + offset; + + HDassert( type_offset < ((haddr_t)(i) * TYPE_SLICE) ); + + aio_single_write_read_check(file, + (H5FD_mem_t)i, + "16 MB -- test for completion", + type_offset, + write_size, + /* do_wait = */ FALSE, + &pass, + &failure_mssg); + } + } + + if ( show_progress ) { /* cp == 17 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d -- swrchk 16 MB - wait.\n", + fcn_name, cp++, (int)pass); + } + + offset += (haddr_t)write_size; + + if ( verbose ) { + + HDfprintf(stdout, "%s: offset = 0x%llx, write_size = 0x%llx, eow = 0x%llx.\n", + fcn_name, + (unsigned long long)offset, (unsigned long long)write_size, + (unsigned long long)(offset + write_size)); + } + + for ( i = 1; i < H5FD_MEM_NTYPES; i++ ) { + + if ( pass ) { + + type_offset = ((haddr_t)(i - 1) * TYPE_SLICE) + offset; + + HDassert( type_offset < ((haddr_t)(i) * TYPE_SLICE) ); + + aio_single_write_read_check(file, + (H5FD_mem_t)i, + "16 MB -- wait for completion", + type_offset, + write_size, + /* do_wait = */ TRUE, + &pass, + &failure_mssg); + } + } + + if ( show_progress ) { /* cp == 18 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d -- swrchk 256 MB - poll.\n", + fcn_name, cp++, (int)pass); + } + + offset += (haddr_t)write_size; + + write_size *= (size_t)16; + + if ( verbose ) { + + HDfprintf(stdout, "%s: offset = 0x%llx, write_size = 0x%llx, eow = 0x%llx.\n", + fcn_name, + (unsigned long long)offset, (unsigned long long)write_size, + (unsigned long long)(offset + write_size)); + } + + for ( i = 1; i < H5FD_MEM_NTYPES; i++ ) { + + if ( pass ) { + + type_offset = ((haddr_t)(i - 1) * TYPE_SLICE) + offset; + + HDassert( type_offset < ((haddr_t)(i) * TYPE_SLICE) ); + + aio_single_write_read_check(file, + (H5FD_mem_t)i, + "256 MB -- test for completion", + type_offset, + write_size, + /* do_wait = */ FALSE, + &pass, + &failure_mssg); + } + } + + if ( show_progress ) { /* cp == 19 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d -- swrchk 256 MB - wait.\n", + fcn_name, cp++, (int)pass); + } + + offset += (haddr_t)write_size; + + if ( verbose ) { + + HDfprintf(stdout, "%s: offset = 0x%llx, write_size = 0x%llx, eow = 0x%llx.\n", + fcn_name, + (unsigned long long)offset, (unsigned long long)write_size, + (unsigned long long)(offset + write_size)); + } + + for ( i = 1; i < H5FD_MEM_NTYPES; i++ ) { + + if ( pass ) { + + type_offset = ((haddr_t)(i - 1) * TYPE_SLICE) + offset; + + if ( type_offset >= ((haddr_t)(i) * TYPE_SLICE) ) { + + HDfprintf(stdout, "type_offset = 0x%llx.\n", type_offset); + HDfprintf(stdout, + "i = %d, TYPE_SLICE = 0x%llx, offset = 0x%llx.\n", + i, (long long)TYPE_SLICE, (long long)offset); + HDfprintf(stdout, "((i + 1) * TYPE_SLICE) = 0x%llx.\n", + (long long)((haddr_t)(i + 1) * TYPE_SLICE) ); + } + + HDassert( type_offset < ((haddr_t)(i + 1) * TYPE_SLICE) ); + + aio_single_write_read_check(file, + (H5FD_mem_t)i, + "256 MB -- wait for completion", + type_offset, + write_size, + /* do_wait = */ TRUE, + &pass, + &failure_mssg); + } + } + + if ( show_progress ) { /* cp == 20 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d -- mwsrchk.\n", + fcn_name, cp++, (int)pass); + } + + aio_multi_write_sync_read_check(file, + write_count, + types, + offsets, + lengths, + tags, + &pass, + &failure_mssg); + + if ( show_progress ) { /* cp == 21 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d -- wrfcchk.\n", + fcn_name, cp++, (int)pass); + } +#if 1 /* JRM */ + aio_multi_read_write_fsync_cancel_check(file, + op_count, + ops, + types, + offsets, + lengths, + tags, + &pass, + &failure_mssg); +#endif /* JRM */ + if ( show_progress ) { /* cp == 22 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d -- close file.\n", + fcn_name, cp++, (int)pass); + } + + if ( file != NULL ) { + + result = H5FDclose(file); + + if ( result < 0 ) { + + pass = FALSE; + failure_mssg = "H5FDclose() failed."; + + } else if ( h5_cleanup(FILENAME, fapl_id) == 0 ) { + + pass = FALSE; + failure_mssg = "h5_cleanup() failed.\n"; + + } + } + + if ( show_progress ) { /* cp == 22 */ + HDfprintf(stdout, "%s: cp = %d, pass = %d -- done.\n", + fcn_name, cp++, (int)pass); + } + + if ( pass ) { + + PASSED(); + + } else { + + HDfprintf(stdout, "%s: failure_mssg = \"%s\".\n", + fcn_name, failure_mssg); + H5_FAILED(); + ret_val = -1; + } + + if ( verbose ) { + + HDfprintf(stdout, "exiting generic_aio_test() -- ret_val == %d.\n", + ret_val); + } + + return(ret_val); + +} /* multi_file_driver_aio_test() */ + +#undef TYPE_SLICE /*------------------------------------------------------------------------- @@ -2099,48 +5180,225 @@ generic_aio_test__multiple_write_sync_read_test(H5FD_t * file, int main(void) { - int nerrors = 0; - hid_t fapl; + const char *memb_name[H5FD_MEM_NTYPES]; + int nerrors = 0; + int result; + hid_t fapl; + hid_t memb_fapl[H5FD_MEM_NTYPES]; + haddr_t memb_addr[H5FD_MEM_NTYPES]; + H5FD_mem_t mt; + H5FD_mem_t memb_map[H5FD_MEM_NTYPES]; h5_reset(); - +#if 1 nerrors += test_sec2() < 0 ? 1 : 0; nerrors += test_core() < 0 ? 1 : 0; nerrors += test_family() < 0 ? 1 : 0; nerrors += test_family_compat() < 0 ? 1 : 0; nerrors += test_multi() < 0 ? 1 : 0; nerrors += test_direct() < 0 ? 1 : 0; +#endif +/* Note that we don't need to close the fapl in the + * following tests as generic_aio_test() will do this + * for us. + */ +#if 1 /* SEC2 test */ fapl = h5_fileaccess(); + if ( H5Pset_fapl_sec2(fapl) < 0 ) { nerrors++; } else { - nerrors += generic_aio_test("SEC2 AIO VFD", "sec2_aio_test", - fapl, (haddr_t)0x40000000); + result = generic_aio_test("AIO on SEC2 file driver", 6, fapl, + (haddr_t)0x40000000); + nerrors += ( result < 0 ) ? 1 : 0; } - H5Pclose(fapl); -#if 0 -/* TODO: Add tests for other file drivers. - * Add test for new synchronous fsync VFD call. - */ - fapl = h5_fileaccess(); + + if ( H5Pset_fapl_sec2(fapl) < 0 ) { + + nerrors++; + + } else { + + + result = generic_aio_input_error_tests("AIO on SEC2 file driver error rejection", + "AIO SEC2 error rejection", + 12, fapl, FALSE); + nerrors += ( result < 0 ) ? 1 : 0; + } +#endif /* SEC2 test */ + +#if 1 /* CORE test */ + fapl = h5_fileaccess(); + if(H5Pset_fapl_core(fapl, (size_t)0x40000000, TRUE) < 0) { nerrors++; } else { - nerrors += generic_aio_test("CORE VFD", "core_aio_test", - fapl, (haddr_t)0x40000000); + result = generic_aio_test("AIO on CORE file driver", 7, fapl, + (haddr_t)0x40000000); + nerrors += ( result < 0 ) ? 1 : 0; } - H5Pclose(fapl); + fapl = h5_fileaccess(); + + if(H5Pset_fapl_core(fapl, (size_t)0x40000000, TRUE) < 0) { + + nerrors++; + + } else { + + result = generic_aio_input_error_tests("AIO on CORE file driver error rejection", + "AIO CORE error rejection", + 13, fapl, FALSE); + nerrors += ( result < 0 ) ? 1 : 0; + } #endif + +#if 1 /* STDIO test */ + fapl = h5_fileaccess(); + + if(H5Pset_fapl_stdio(fapl) < 0) { + + nerrors++; + + } else { + + result = generic_aio_test("AIO on STDIO file driver", 8, fapl, + (haddr_t)0x40000000); + nerrors += ( result < 0 ) ? 1 : 0; + } + + fapl = h5_fileaccess(); + + if(H5Pset_fapl_stdio(fapl) < 0) { + + nerrors++; + + } else { + + result = generic_aio_input_error_tests("AIO on STDIO file driver error rejection", + "AIO STDIO error rejection", + 14, fapl, FALSE); + nerrors += ( result < 0 ) ? 1 : 0; + } +#endif + +#if 1 /* FAMILY File test */ + fapl = h5_fileaccess(); + + if(H5Pset_fapl_family(fapl, (hsize_t)FAMILY_SIZE_AIO, H5P_DEFAULT) < 0) { + + nerrors++; + + } else { + + result = generic_aio_test("AIO on FAMILY file driver", 9, fapl, + (haddr_t)0x40000000); + nerrors += ( result < 0 ) ? 1 : 0; + } + + fapl = h5_fileaccess(); + + if(H5Pset_fapl_family(fapl, (hsize_t)FAMILY_SIZE_AIO, H5P_DEFAULT) < 0) { + + nerrors++; + + } else { + + result = generic_aio_input_error_tests("AIO on FAMILY file driver error rejection", + "AIO FAMILY error rejection", + 15, fapl, FALSE); + nerrors += ( result < 0 ) ? 1 : 0; + } +#endif + +#if 1 /* MULTI File test */ + /* The generic aio test is ill suited to the multi file driver, as + * it takes no real cognisance of the type of data being written. + * However, it is a good initial smoke check so we will begin with + * it. + */ + + /* set up member map so all metadata goes in one file, everything + * else in a second file. + */ + + for ( mt = 0; mt < H5FD_MEM_NTYPES; mt++ ) { + + memb_addr[mt] = HADDR_UNDEF; + memb_fapl[mt] = H5P_DEFAULT; + memb_map[mt] = H5FD_MEM_SUPER; + memb_name[mt] = NULL; + } + memb_map[H5FD_MEM_DRAW] = H5FD_MEM_DRAW; + + memb_fapl[H5FD_MEM_SUPER] = H5P_DEFAULT; + memb_name[H5FD_MEM_SUPER] = "%s-m.h5"; + memb_addr[H5FD_MEM_SUPER] = 0; + + memb_fapl[H5FD_MEM_DRAW] = H5P_DEFAULT; + memb_name[H5FD_MEM_DRAW] = "%s-r.h5"; + memb_addr[H5FD_MEM_DRAW] = HADDR_MAX/2; + + fapl = h5_fileaccess(); + + if ( H5Pset_fapl_multi(fapl, memb_map, memb_fapl, memb_name, + memb_addr, FALSE) < 0 ) { + + nerrors++; + + } else { + + result = generic_aio_test("AIO on MULTI file driver", 10, fapl, + (haddr_t)0x40000000); + nerrors += ( result < 0 ) ? 1 : 0; + + result = multi_file_driver_aio_test( + "AIO with varied mem types on MULTI file driver", 11); + nerrors += ( result < 0 ) ? 1 : 0; + } + + for ( mt = 0; mt < H5FD_MEM_NTYPES; mt++ ) { + + memb_addr[mt] = HADDR_UNDEF; + memb_fapl[mt] = H5P_DEFAULT; + memb_map[mt] = H5FD_MEM_SUPER; + memb_name[mt] = NULL; + } + memb_map[H5FD_MEM_DRAW] = H5FD_MEM_DRAW; + + memb_fapl[H5FD_MEM_SUPER] = H5P_DEFAULT; + memb_name[H5FD_MEM_SUPER] = "%s-m.h5"; + memb_addr[H5FD_MEM_SUPER] = 0; + + memb_fapl[H5FD_MEM_DRAW] = H5P_DEFAULT; + memb_name[H5FD_MEM_DRAW] = "%s-r.h5"; + memb_addr[H5FD_MEM_DRAW] = HADDR_MAX/2; + + fapl = h5_fileaccess(); + + if ( H5Pset_fapl_multi(fapl, memb_map, memb_fapl, memb_name, + memb_addr, FALSE) < 0 ) { + + nerrors++; + + } else { + + result = generic_aio_input_error_tests("AIO on MULTI file driver error rejection", + "AIO MULTI error rejection", + 15, fapl, FALSE); + nerrors += ( result < 0 ) ? 1 : 0; + } +#endif + if(nerrors) { printf("***** %d Virtual File Driver TEST%s FAILED! *****\n", nerrors, nerrors > 1 ? "S" : ""); @@ -2150,4 +5408,3 @@ main(void) printf("All Virtual File Driver tests passed.\n"); return 0; } -