From 8d4873173fe95ffd8a274c9d9a6c1e8b5e017957 Mon Sep 17 00:00:00 2001 From: Dana Robinson Date: Wed, 5 May 2021 15:07:40 -0700 Subject: Brings native H5Fdelete implementation from develop --- MANIFEST | 1 + src/H5FD.c | 34 ++++ src/H5FDcore.c | 35 ++++ src/H5FDdirect.c | 27 +++ src/H5FDfamily.c | 95 ++++++++++- src/H5FDhdfs.c | 1 + src/H5FDint.c | 44 +++++ src/H5FDlog.c | 27 +++ src/H5FDmirror.c | 3 +- src/H5FDmpio.c | 128 +++++++++++---- src/H5FDmulti.c | 115 +++++++++---- src/H5FDprivate.h | 1 + src/H5FDpublic.h | 2 + src/H5FDros3.c | 1 + src/H5FDsec2.c | 29 +++- src/H5FDsplitter.c | 1 + src/H5FDstdio.c | 30 ++++ src/H5FDvfd_swmr.c | 3 +- src/H5Fint.c | 35 +++- src/H5VLnative_file.c | 9 +- test/h5test.c | 62 +------ test/tfile.c | 21 +-- test/vfd.c | 370 +++++++++++++++++++++++++----------------- testpar/t_file.c | 55 +++++++ testpar/testphdf5.c | 2 + testpar/testphdf5.h | 1 + tools/src/misc/CMakeLists.txt | 22 ++- tools/src/misc/Makefile.am | 3 +- tools/src/misc/h5delete.c | 66 ++++++++ tools/src/misc/h5repart.c | 10 +- 30 files changed, 933 insertions(+), 300 deletions(-) create mode 100644 tools/src/misc/h5delete.c diff --git a/MANIFEST b/MANIFEST index 52be873..cba2237 100644 --- a/MANIFEST +++ b/MANIFEST @@ -1771,6 +1771,7 @@ ./tools/src/misc/Makefile.am ./tools/src/misc/h5clear.c ./tools/src/misc/h5debug.c +./tools/src/misc/h5delete.c ./tools/src/misc/h5mkgrp.c ./tools/src/misc/h5repart.c ./tools/test/misc/Makefile.am diff --git a/src/H5FD.c b/src/H5FD.c index ef443ac..fcf39f5 100644 --- a/src/H5FD.c +++ b/src/H5FD.c @@ -2007,3 +2007,37 @@ H5FDdriver_query(hid_t driver_id, unsigned long *flags /*out*/) done: FUNC_LEAVE_API(ret_value) } /* end H5FDdriver_query() */ + +/*------------------------------------------------------------------------- + * Function: H5FDdelete + * + * Purpose: Deletes a file + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5FDdelete(const char *filename, hid_t fapl_id) +{ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_API(FAIL) + H5TRACE2("e", "*si", filename, fapl_id); + + /* Check arguments */ + if (!filename || !*filename) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no file name specified") + + if (H5P_DEFAULT == fapl_id) + fapl_id = H5P_FILE_ACCESS_DEFAULT; + else if (TRUE != H5P_isa_class(fapl_id, H5P_FILE_ACCESS)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list") + + /* Call private function */ + if (H5FD_delete(filename, fapl_id) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTDELETEFILE, FAIL, "unable to delete file") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5FDdelete() */ diff --git a/src/H5FDcore.c b/src/H5FDcore.c index 8af5065..f405200 100644 --- a/src/H5FDcore.c +++ b/src/H5FDcore.c @@ -148,6 +148,7 @@ static herr_t H5FD__core_flush(H5FD_t *_file, hid_t dxpl_id, hbool_t closing); static herr_t H5FD__core_truncate(H5FD_t *_file, hid_t dxpl_id, hbool_t closing); static herr_t H5FD__core_lock(H5FD_t *_file, hbool_t rw); static herr_t H5FD__core_unlock(H5FD_t *_file); +static herr_t H5FD__core_delete(const char *filename, hid_t fapl_id); static const H5FD_class_t H5FD_core_g = { "core", /* name */ @@ -181,6 +182,7 @@ static const H5FD_class_t H5FD_core_g = { H5FD__core_truncate, /* truncate */ H5FD__core_lock, /* lock */ H5FD__core_unlock, /* unlock */ + H5FD__core_delete, /* del */ NULL, /* dedup */ H5FD_FLMAP_DICHOTOMY /* fl_map */ }; @@ -1709,3 +1711,36 @@ H5FD__core_unlock(H5FD_t *_file) done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__core_unlock() */ + +/*------------------------------------------------------------------------- + * Function: H5FD__core_delete + * + * Purpose: Delete a file + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ +static herr_t +H5FD__core_delete(const char *filename, hid_t fapl_id) +{ + const H5FD_core_fapl_t *fa = NULL; + H5P_genplist_t * plist; /* Property list pointer */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + HDassert(filename); + + if (NULL == (plist = (H5P_genplist_t *)H5I_object(fapl_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list") + if (NULL == (fa = (const H5FD_core_fapl_t *)H5P_peek_driver_info(plist))) + HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "bad VFL driver info") + + if (fa->backing_store) + if (HDremove(filename) < 0) + HSYS_GOTO_ERROR(H5E_VFL, H5E_CANTDELETEFILE, FAIL, "unable to delete file") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5FD__core_delete() */ diff --git a/src/H5FDdirect.c b/src/H5FDdirect.c index 54704cf..2a51883 100644 --- a/src/H5FDdirect.c +++ b/src/H5FDdirect.c @@ -137,6 +137,7 @@ static herr_t H5FD__direct_write(H5FD_t *_file, H5FD_mem_t type, hid_t fapl_id, static herr_t H5FD__direct_truncate(H5FD_t *_file, hid_t dxpl_id, hbool_t closing); static herr_t H5FD__direct_lock(H5FD_t *_file, hbool_t rw); static herr_t H5FD__direct_unlock(H5FD_t *_file); +static herr_t H5FD__direct_delete(const char *filename, hid_t fapl_id); static const H5FD_class_t H5FD_direct_g = { "direct", /* name */ @@ -170,6 +171,7 @@ static const H5FD_class_t H5FD_direct_g = { H5FD__direct_truncate, /* truncate */ H5FD__direct_lock, /* lock */ H5FD__direct_unlock, /* unlock */ + H5FD__direct_delete, /* del */ NULL, /* dedup */ H5FD_FLMAP_DICHOTOMY /* fl_map */ }; @@ -1381,4 +1383,29 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__direct_unlock() */ +/*------------------------------------------------------------------------- + * Function: H5FD__direct_delete + * + * Purpose: Delete a file + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ +static herr_t +H5FD__direct_delete(const char *filename, hid_t H5_ATTR_UNUSED fapl_id) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + HDassert(filename); + + if (HDremove(filename) < 0) + HSYS_GOTO_ERROR(H5E_VFL, H5E_CANTDELETEFILE, FAIL, "unable to delete file") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5FD__direct_delete() */ + #endif /* H5_HAVE_DIRECT */ diff --git a/src/H5FDfamily.c b/src/H5FDfamily.c index 8817c47..2356309 100644 --- a/src/H5FDfamily.c +++ b/src/H5FDfamily.c @@ -101,6 +101,7 @@ static herr_t H5FD__family_flush(H5FD_t *_file, hid_t dxpl_id, hbool_t closing) static herr_t H5FD__family_truncate(H5FD_t *_file, hid_t dxpl_id, hbool_t closing); static herr_t H5FD__family_lock(H5FD_t *_file, hbool_t rw); static herr_t H5FD__family_unlock(H5FD_t *_file); +static herr_t H5FD__family_delete(const char *filename, hid_t fapl_id); /* The class struct */ static const H5FD_class_t H5FD_family_g = { @@ -135,7 +136,8 @@ static const H5FD_class_t H5FD_family_g = { H5FD__family_truncate, /* truncate */ H5FD__family_lock, /* lock */ H5FD__family_unlock, /* unlock */ - NULL, /*dedup */ + H5FD__family_delete, /* del */ + NULL, /* dedup */ H5FD_FLMAP_DICHOTOMY /* fl_map */ }; @@ -1344,3 +1346,94 @@ H5FD__family_unlock(H5FD_t *_file) done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__family_unlock() */ + +/*------------------------------------------------------------------------- + * Function: H5FD__family_delete + * + * Purpose: Delete a file + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ +static herr_t +H5FD__family_delete(const char *filename, hid_t fapl_id) +{ + H5P_genplist_t * plist; + const H5FD_family_fapl_t *fa; + hid_t memb_fapl_id = H5I_INVALID_HID; + unsigned current_member; + char * member_name = NULL; + char * temp = NULL; + herr_t delete_error = FAIL; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_STATIC + + HDassert(filename); + + /* Get the driver info (for the member fapl) + * The family_open call accepts H5P_DEFAULT, so we'll accept that here, too. + */ + if (H5P_FILE_ACCESS_DEFAULT == fapl_id) + memb_fapl_id = H5P_FILE_ACCESS_DEFAULT; + else { + if (NULL == (plist = (H5P_genplist_t *)H5I_object(fapl_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list") + if (NULL == (fa = (const H5FD_family_fapl_t *)H5P_peek_driver_info(plist))) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "bad family VFD driver info") + memb_fapl_id = fa->memb_fapl_id; + } + + /* Allocate space for the string buffers */ + if (NULL == (member_name = (char *)H5MM_malloc(H5FD_FAM_MEMB_NAME_BUF_SIZE))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "unable to allocate member name") + if (NULL == (temp = (char *)H5MM_malloc(H5FD_FAM_MEMB_NAME_BUF_SIZE))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "unable to allocate temporary member name") + + /* Sanity check to make sure that generated names are unique */ + HDsnprintf(member_name, H5FD_FAM_MEMB_NAME_BUF_SIZE, filename, 0); + HDsnprintf(temp, H5FD_FAM_MEMB_NAME_BUF_SIZE, filename, 1); + if (!HDstrcmp(member_name, temp)) + HGOTO_ERROR(H5E_VFL, H5E_CANTDELETEFILE, FAIL, "provided file name cannot generate unique sub-files") + + /* Delete all the family members */ + current_member = 0; + while (1) { + /* Fix up the filename with the current member's number */ + HDsnprintf(member_name, H5FD_FAM_MEMB_NAME_BUF_SIZE, filename, current_member); + + /* Attempt to delete the member files. If the first file throws an error + * we always consider this an error. With subsequent member files, however, + * errors usually mean that we hit the last member file so we ignore them. + * + * Note that this means that any missing files in the family will leave + * undeleted members behind. + */ + H5E_BEGIN_TRY + { + delete_error = H5FD_delete(member_name, memb_fapl_id); + } + H5E_END_TRY; + if (FAIL == delete_error) { + if (0 == current_member) + HGOTO_ERROR(H5E_VFL, H5E_CANTDELETEFILE, FAIL, "unable to delete member file") + else + H5E_clear_stack(NULL); + break; + } + current_member++; + } /* end while */ + +done: + if (member_name) + H5MM_xfree(member_name); + if (temp) + H5MM_xfree(temp); + + /* Don't close memb_fapl_id - We didn't bump its reference count since we're + * only using it in this call. + */ + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5FD__family_delete() */ diff --git a/src/H5FDhdfs.c b/src/H5FDhdfs.c index e44b575..50e02a4 100644 --- a/src/H5FDhdfs.c +++ b/src/H5FDhdfs.c @@ -309,6 +309,7 @@ static const H5FD_class_t H5FD_hdfs_g = { H5FD__hdfs_truncate, /* truncate */ NULL, /* lock */ NULL, /* unlock */ + NULL, /* del */ NULL, /* dedup */ H5FD_FLMAP_DICHOTOMY /* fl_map */ }; diff --git a/src/H5FDint.c b/src/H5FDint.c index 3ab5ab7..23dfa4d 100644 --- a/src/H5FDint.c +++ b/src/H5FDint.c @@ -381,3 +381,47 @@ H5FD_driver_query(const H5FD_class_t *driver, unsigned long *flags /*out*/) FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD_driver_query() */ + +/*------------------------------------------------------------------------- + * Function: H5FD_delete + * + * Purpose: Private version of H5FDdelete() + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ +herr_t +H5FD_delete(const char *filename, hid_t fapl_id) +{ + H5FD_class_t * driver; /* VFD for file */ + H5FD_driver_prop_t driver_prop; /* Property for driver ID & info */ + H5P_genplist_t * plist; /* Property list pointer */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Sanity checks */ + HDassert(filename); + + /* Get file access property list */ + if (NULL == (plist = (H5P_genplist_t *)H5I_object(fapl_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list") + + /* Get the VFD to open the file with */ + if (H5P_peek(plist, H5F_ACS_FILE_DRV_NAME, &driver_prop) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get driver ID & info") + + /* Get driver info */ + if (NULL == (driver = (H5FD_class_t *)H5I_object(driver_prop.driver_id))) + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "invalid driver ID in file access property list") + if (NULL == driver->del) + HGOTO_ERROR(H5E_VFL, H5E_UNSUPPORTED, FAIL, "file driver has no 'del' method") + + /* Dispatch to file driver */ + if ((driver->del)(filename, fapl_id)) + HGOTO_ERROR(H5E_VFL, H5E_CANTDELETEFILE, FAIL, "delete failed") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5FD_delete() */ diff --git a/src/H5FDlog.c b/src/H5FDlog.c index be8bfce..327c9b9 100644 --- a/src/H5FDlog.c +++ b/src/H5FDlog.c @@ -177,6 +177,7 @@ static herr_t H5FD__log_write(H5FD_t *_file, H5FD_mem_t type, hid_t fapl_id, ha static herr_t H5FD__log_truncate(H5FD_t *_file, hid_t dxpl_id, hbool_t closing); static herr_t H5FD__log_lock(H5FD_t *_file, hbool_t rw); static herr_t H5FD__log_unlock(H5FD_t *_file); +static herr_t H5FD__log_delete(const char *filename, hid_t fapl_id); static const H5FD_class_t H5FD_log_g = { "log", /* name */ @@ -210,6 +211,7 @@ static const H5FD_class_t H5FD_log_g = { H5FD__log_truncate, /* truncate */ H5FD__log_lock, /* lock */ H5FD__log_unlock, /* unlock */ + H5FD__log_delete, /* del */ NULL, /* dedup */ H5FD_FLMAP_DICHOTOMY /* fl_map */ }; @@ -1773,3 +1775,28 @@ H5FD__log_unlock(H5FD_t *_file) done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__log_unlock() */ + +/*------------------------------------------------------------------------- + * Function: H5FD__log_delete + * + * Purpose: Delete a file + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ +static herr_t +H5FD__log_delete(const char *filename, hid_t H5_ATTR_UNUSED fapl_id) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + HDassert(filename); + + if (HDremove(filename) < 0) + HSYS_GOTO_ERROR(H5E_VFL, H5E_CANTDELETEFILE, FAIL, "unable to delete file") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5FD__log_delete() */ diff --git a/src/H5FDmirror.c b/src/H5FDmirror.c index 2f145a4..3ea71ce 100644 --- a/src/H5FDmirror.c +++ b/src/H5FDmirror.c @@ -191,7 +191,8 @@ static const H5FD_class_t H5FD_mirror_g = { H5FD__mirror_truncate, /* truncate */ H5FD__mirror_lock, /* lock */ H5FD__mirror_unlock, /* unlock */ - NULL, /* dedup */ + NULL, /* del */ + NULL, /* dedup */ H5FD_FLMAP_DICHOTOMY /* fl_map */ }; diff --git a/src/H5FDmpio.c b/src/H5FDmpio.c index 9dbd443..b229207 100644 --- a/src/H5FDmpio.c +++ b/src/H5FDmpio.c @@ -86,6 +86,7 @@ static herr_t H5FD__mpio_write(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, const void *buf); static herr_t H5FD__mpio_flush(H5FD_t *_file, hid_t dxpl_id, hbool_t closing); static herr_t H5FD__mpio_truncate(H5FD_t *_file, hid_t dxpl_id, hbool_t closing); +static herr_t H5FD__mpio_delete(const char *filename, hid_t fapl_id); static int H5FD__mpio_mpi_rank(const H5FD_t *_file); static int H5FD__mpio_mpi_size(const H5FD_t *_file); static MPI_Comm H5FD__mpio_communicator(const H5FD_t *_file); @@ -94,43 +95,44 @@ static MPI_Comm H5FD__mpio_communicator(const H5FD_t *_file); static const H5FD_class_mpi_t H5FD_mpio_g = { { /* Start of superclass information */ - "mpio", /*name */ - HADDR_MAX, /*maxaddr */ - H5F_CLOSE_SEMI, /*fc_degree */ - H5FD__mpio_term, /*terminate */ - NULL, /*sb_size */ - NULL, /*sb_encode */ - NULL, /*sb_decode */ - 0, /*fapl_size */ - NULL, /*fapl_get */ - NULL, /*fapl_copy */ - NULL, /*fapl_free */ - 0, /*dxpl_size */ - NULL, /*dxpl_copy */ - NULL, /*dxpl_free */ - H5FD__mpio_open, /*open */ - H5FD__mpio_close, /*close */ - NULL, /*cmp */ - H5FD__mpio_query, /*query */ - NULL, /*get_type_map */ - NULL, /*alloc */ - NULL, /*free */ - H5FD__mpio_get_eoa, /*get_eoa */ - H5FD__mpio_set_eoa, /*set_eoa */ - H5FD__mpio_get_eof, /*get_eof */ - H5FD__mpio_get_handle, /*get_handle */ - H5FD__mpio_read, /*read */ - H5FD__mpio_write, /*write */ - H5FD__mpio_flush, /*flush */ - H5FD__mpio_truncate, /*truncate */ - NULL, /*lock */ - NULL, /*unlock */ - NULL, /* dedup */ - H5FD_FLMAP_DICHOTOMY /*fl_map */ + "mpio", /* name */ + HADDR_MAX, /* maxaddr */ + H5F_CLOSE_SEMI, /* fc_degree */ + H5FD__mpio_term, /* terminate */ + NULL, /* sb_size */ + NULL, /* sb_encode */ + NULL, /* sb_decode */ + 0, /* fapl_size */ + NULL, /* fapl_get */ + NULL, /* fapl_copy */ + NULL, /* fapl_free */ + 0, /* dxpl_size */ + NULL, /* dxpl_copy */ + NULL, /* dxpl_free */ + H5FD__mpio_open, /* open */ + H5FD__mpio_close, /* close */ + NULL, /* cmp */ + H5FD__mpio_query, /* query */ + NULL, /* get_type_map */ + NULL, /* alloc */ + NULL, /* free */ + H5FD__mpio_get_eoa, /* get_eoa */ + H5FD__mpio_set_eoa, /* set_eoa */ + H5FD__mpio_get_eof, /* get_eof */ + H5FD__mpio_get_handle, /* get_handle */ + H5FD__mpio_read, /* read */ + H5FD__mpio_write, /* write */ + H5FD__mpio_flush, /* flush */ + H5FD__mpio_truncate, /* truncate */ + NULL, /* lock */ + NULL, /* unlock */ + H5FD__mpio_delete, /* del */ + NULL, /* dedup */ + H5FD_FLMAP_DICHOTOMY /* fl_map */ }, /* End of superclass information */ - H5FD__mpio_mpi_rank, /*get_rank */ - H5FD__mpio_mpi_size, /*get_size */ - H5FD__mpio_communicator /*get_comm */ + H5FD__mpio_mpi_rank, /* get_rank */ + H5FD__mpio_mpi_size, /* get_size */ + H5FD__mpio_communicator /* get_comm */ }; #ifdef H5FDmpio_DEBUG @@ -1747,6 +1749,60 @@ done: } /* end H5FD__mpio_truncate() */ /*------------------------------------------------------------------------- + * Function: H5FD__mpio_delete + * + * Purpose: Delete a file + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ +static herr_t +H5FD__mpio_delete(const char *filename, hid_t fapl_id) +{ + H5P_genplist_t *plist; /* Property list pointer */ + MPI_Comm comm = MPI_COMM_NULL; + MPI_Info info = MPI_INFO_NULL; + int mpi_rank = INT_MAX; + int mpi_code; /* MPI return code */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + HDassert(filename); + + if (NULL == (plist = H5P_object_verify(fapl_id, H5P_FILE_ACCESS))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list") + HDassert(H5FD_MPIO == H5P_peek_driver(plist)); + + /* Get the MPI communicator and info from the fapl */ + if (H5P_get(plist, H5F_ACS_MPI_PARAMS_INFO_NAME, &info) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get MPI info object") + if (H5P_get(plist, H5F_ACS_MPI_PARAMS_COMM_NAME, &comm) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get MPI communicator") + + /* Get the MPI rank of this process */ + if (MPI_SUCCESS != (mpi_code = MPI_Comm_rank(comm, &mpi_rank))) + HMPI_GOTO_ERROR(FAIL, "MPI_Comm_rank failed", mpi_code) + + /* Set up a barrier */ + if (MPI_SUCCESS != (mpi_code = MPI_Barrier(comm))) + HMPI_GOTO_ERROR(FAIL, "MPI_Barrier failed", mpi_code) + + /* Delete the file */ + if (mpi_rank == 0) + if (MPI_SUCCESS != (mpi_code = MPI_File_delete(filename, info))) + HMPI_GOTO_ERROR(FAIL, "MPI_File_delete failed", mpi_code) + + /* Set up a barrier (don't want processes to run ahead of the delete) */ + if (MPI_SUCCESS != (mpi_code = MPI_Barrier(comm))) + HMPI_GOTO_ERROR(FAIL, "MPI_Barrier failed", mpi_code) + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5FD__mpio_delete() */ + +/*------------------------------------------------------------------------- * Function: H5FD__mpio_mpi_rank * * Purpose: Returns the MPI rank for a process diff --git a/src/H5FDmulti.c b/src/H5FDmulti.c index d6d56a6..8b87319 100644 --- a/src/H5FDmulti.c +++ b/src/H5FDmulti.c @@ -142,42 +142,44 @@ static herr_t H5FD_multi_flush(H5FD_t *_file, hid_t dxpl_id, hbool_t closing); static herr_t H5FD_multi_truncate(H5FD_t *_file, hid_t dxpl_id, hbool_t closing); static herr_t H5FD_multi_lock(H5FD_t *_file, hbool_t rw); static herr_t H5FD_multi_unlock(H5FD_t *_file); +static herr_t H5FD_multi_delete(const char *filename, hid_t fapl_id); /* The class struct */ static const H5FD_class_t H5FD_multi_g = { - "multi", /*name */ - HADDR_MAX, /*maxaddr */ - H5F_CLOSE_WEAK, /* fc_degree */ - H5FD_multi_term, /*terminate */ - H5FD_multi_sb_size, /*sb_size */ - H5FD_multi_sb_encode, /*sb_encode */ - H5FD_multi_sb_decode, /*sb_decode */ - sizeof(H5FD_multi_fapl_t), /*fapl_size */ - H5FD_multi_fapl_get, /*fapl_get */ - H5FD_multi_fapl_copy, /*fapl_copy */ - H5FD_multi_fapl_free, /*fapl_free */ - 0, /*dxpl_size */ - NULL, /*dxpl_copy */ - NULL, /*dxpl_free */ - H5FD_multi_open, /*open */ - H5FD_multi_close, /*close */ - H5FD_multi_cmp, /*cmp */ - H5FD_multi_query, /*query */ - H5FD_multi_get_type_map, /*get_type_map */ - H5FD_multi_alloc, /*alloc */ - H5FD_multi_free, /*free */ - H5FD_multi_get_eoa, /*get_eoa */ - H5FD_multi_set_eoa, /*set_eoa */ - H5FD_multi_get_eof, /*get_eof */ - H5FD_multi_get_handle, /*get_handle */ - H5FD_multi_read, /*read */ - H5FD_multi_write, /*write */ - H5FD_multi_flush, /*flush */ - H5FD_multi_truncate, /*truncate */ - H5FD_multi_lock, /*lock */ - H5FD_multi_unlock, /*unlock */ - NULL, /*dedup */ - H5FD_FLMAP_DEFAULT /*fl_map */ + "multi", /* name */ + HADDR_MAX, /* maxaddr */ + H5F_CLOSE_WEAK, /* fc_degree */ + H5FD_multi_term, /* terminate */ + H5FD_multi_sb_size, /* sb_size */ + H5FD_multi_sb_encode, /* sb_encode */ + H5FD_multi_sb_decode, /* sb_decode */ + sizeof(H5FD_multi_fapl_t), /* fapl_size */ + H5FD_multi_fapl_get, /* fapl_get */ + H5FD_multi_fapl_copy, /* fapl_copy */ + H5FD_multi_fapl_free, /* fapl_free */ + 0, /* dxpl_size */ + NULL, /* dxpl_copy */ + NULL, /* dxpl_free */ + H5FD_multi_open, /* open */ + H5FD_multi_close, /* close */ + H5FD_multi_cmp, /* cmp */ + H5FD_multi_query, /* query */ + H5FD_multi_get_type_map, /* get_type_map */ + H5FD_multi_alloc, /* alloc */ + H5FD_multi_free, /* free */ + H5FD_multi_get_eoa, /* get_eoa */ + H5FD_multi_set_eoa, /* set_eoa */ + H5FD_multi_get_eof, /* get_eof */ + H5FD_multi_get_handle, /* get_handle */ + H5FD_multi_read, /* read */ + H5FD_multi_write, /* write */ + H5FD_multi_flush, /* flush */ + H5FD_multi_truncate, /* truncate */ + H5FD_multi_lock, /* lock */ + H5FD_multi_unlock, /* unlock */ + H5FD_multi_delete, /* del */ + NULL, /* dedup */ + H5FD_FLMAP_DEFAULT /* fl_map */ }; /*------------------------------------------------------------------------- @@ -1995,6 +1997,53 @@ open_members(H5FD_multi_t *file) return 0; } + +/*------------------------------------------------------------------------- + * Function: H5FD_multi_delete + * + * Purpose: Delete a file + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ +static herr_t +H5FD_multi_delete(const char *filename, hid_t fapl_id) +{ + char full_filename[H5FD_MULT_MAX_FILE_NAME_LEN]; + int nchars; + const H5FD_multi_fapl_t *fa; + static const char * func = "H5FD_multi_delete"; /* Function Name for error reporting */ + + /* Clear the error stack */ + H5Eclear2(H5E_DEFAULT); + + assert(filename); + + /* Quiet compiler */ + (void)fapl_id; + + /* Get the driver info */ + fa = (const H5FD_multi_fapl_t *)H5Pget_driver_info(fapl_id); + assert(fa); + + /* Delete each member file using the underlying fapl */ + UNIQUE_MEMBERS (fa->memb_map, mt) { + assert(fa->memb_name[mt]); + assert(fa->memb_fapl[mt] >= 0); + + nchars = snprintf(full_filename, sizeof(full_filename), fa->memb_name[mt], filename); + if (nchars < 0 || nchars >= (int)sizeof(full_filename)) + H5Epush_ret(func, H5E_ERR_CLS, H5E_VFL, H5E_BADVALUE, + "filename is too long and would be truncated", -1); + + if (H5FDdelete(full_filename, fa->memb_fapl[mt]) < 0) + H5Epush_ret(func, H5E_ERR_CLS, H5E_VFL, H5E_BADVALUE, "error deleting member files", -1); + } + END_MEMBERS; + + return 0; +} /* end H5FD_multi_delete() */ H5_GCC_DIAG_ON("format-nonliteral") #ifdef H5private_H diff --git a/src/H5FDprivate.h b/src/H5FDprivate.h index adf900a..645436b 100644 --- a/src/H5FDprivate.h +++ b/src/H5FDprivate.h @@ -350,6 +350,7 @@ H5_DLL herr_t H5FD_flush(H5FD_t *file, hbool_t closing); H5_DLL herr_t H5FD_truncate(H5FD_t *file, hbool_t closing); H5_DLL herr_t H5FD_lock(H5FD_t *file, hbool_t rw); H5_DLL herr_t H5FD_unlock(H5FD_t *file); +H5_DLL herr_t H5FD_delete(const char *name, hid_t fapl_id); H5_DLL herr_t H5FD_get_fileno(const H5FD_t *file, unsigned long *filenum); H5_DLL herr_t H5FD_get_vfd_handle(H5FD_t *file, hid_t fapl, void **file_handle); H5_DLL herr_t H5FD_set_base_addr(H5FD_t *file, haddr_t base_addr); diff --git a/src/H5FDpublic.h b/src/H5FDpublic.h index f642f41..2f172e8 100644 --- a/src/H5FDpublic.h +++ b/src/H5FDpublic.h @@ -299,6 +299,7 @@ typedef struct H5FD_class_t { herr_t (*truncate)(H5FD_t *file, hid_t dxpl_id, hbool_t closing); herr_t (*lock)(H5FD_t *file, hbool_t rw); herr_t (*unlock)(H5FD_t *file); + herr_t (*del)(const char *name, hid_t fapl); H5FD_t *(*dedup)(H5FD_t *, H5FD_t *, hid_t); H5FD_mem_t fl_map[H5FD_MEM_NTYPES]; } H5FD_class_t; @@ -382,6 +383,7 @@ H5_DLL herr_t H5FDflush(H5FD_t *file, hid_t dxpl_id, hbool_t closing); H5_DLL herr_t H5FDtruncate(H5FD_t *file, hid_t dxpl_id, hbool_t closing); H5_DLL herr_t H5FDlock(H5FD_t *file, hbool_t rw); H5_DLL herr_t H5FDunlock(H5FD_t *file); +H5_DLL herr_t H5FDdelete(const char *name, hid_t fapl_id); /* Allows querying a VFD ID for features before the file is opened */ H5_DLL herr_t H5FDdriver_query(hid_t driver_id, unsigned long *flags /*out*/); diff --git a/src/H5FDros3.c b/src/H5FDros3.c index e3c0794..0303b50 100644 --- a/src/H5FDros3.c +++ b/src/H5FDros3.c @@ -266,6 +266,7 @@ static const H5FD_class_t H5FD_ros3_g = { H5FD__ros3_truncate, /* truncate */ NULL, /* lock */ NULL, /* unlock */ + NULL, /* del */ NULL, /* dedup */ H5FD_FLMAP_DICHOTOMY /* fl_map */ }; diff --git a/src/H5FDsec2.c b/src/H5FDsec2.c index 816381d..c694190 100644 --- a/src/H5FDsec2.c +++ b/src/H5FDsec2.c @@ -138,6 +138,7 @@ static herr_t H5FD__sec2_write(H5FD_t *_file, H5FD_mem_t type, hid_t fapl_id, h static herr_t H5FD__sec2_truncate(H5FD_t *_file, hid_t dxpl_id, hbool_t closing); static herr_t H5FD__sec2_lock(H5FD_t *_file, hbool_t rw); static herr_t H5FD__sec2_unlock(H5FD_t *_file); +static herr_t H5FD__sec2_delete(const char *filename, hid_t fapl_id); static const H5FD_class_t H5FD_sec2_g = { "sec2", /* name */ @@ -171,7 +172,8 @@ static const H5FD_class_t H5FD_sec2_g = { H5FD__sec2_truncate, /* truncate */ H5FD__sec2_lock, /* lock */ H5FD__sec2_unlock, /* unlock */ - NULL, /* dedup */ + H5FD__sec2_delete, /* del */ + NULL, /* dedup */ H5FD_FLMAP_DICHOTOMY /* fl_map */ }; @@ -1042,3 +1044,28 @@ H5FD__sec2_unlock(H5FD_t *_file) done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__sec2_unlock() */ + +/*------------------------------------------------------------------------- + * Function: H5FD__sec2_delete + * + * Purpose: Delete a file + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ +static herr_t +H5FD__sec2_delete(const char *filename, hid_t H5_ATTR_UNUSED fapl_id) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + HDassert(filename); + + if (HDremove(filename) < 0) + HSYS_GOTO_ERROR(H5E_VFL, H5E_CANTDELETEFILE, FAIL, "unable to delete file") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5FD__sec2_delete() */ diff --git a/src/H5FDsplitter.c b/src/H5FDsplitter.c index a839441..99d7100 100644 --- a/src/H5FDsplitter.c +++ b/src/H5FDsplitter.c @@ -162,6 +162,7 @@ static const H5FD_class_t H5FD_splitter_g = { H5FD__splitter_truncate, /* truncate */ H5FD__splitter_lock, /* lock */ H5FD__splitter_unlock, /* unlock */ + NULL, /* del */ NULL, /* dedup */ H5FD_FLMAP_DICHOTOMY /* fl_map */ }; diff --git a/src/H5FDstdio.c b/src/H5FDstdio.c index 12475e7..f9faf53 100644 --- a/src/H5FDstdio.c +++ b/src/H5FDstdio.c @@ -180,6 +180,7 @@ static herr_t H5FD_stdio_flush(H5FD_t *_file, hid_t dxpl_id, hbool_t closing); static herr_t H5FD_stdio_truncate(H5FD_t *_file, hid_t dxpl_id, hbool_t closing); static herr_t H5FD_stdio_lock(H5FD_t *_file, hbool_t rw); static herr_t H5FD_stdio_unlock(H5FD_t *_file); +static herr_t H5FD_stdio_delete(const char *filename, hid_t fapl_id); static const H5FD_class_t H5FD_stdio_g = { "stdio", /* name */ @@ -213,6 +214,7 @@ static const H5FD_class_t H5FD_stdio_g = { H5FD_stdio_truncate, /* truncate */ H5FD_stdio_lock, /* lock */ H5FD_stdio_unlock, /* unlock */ + H5FD_stdio_delete, /* del */ NULL, /* dedup */ H5FD_FLMAP_DICHOTOMY /* fl_map */ }; @@ -1201,6 +1203,34 @@ H5FD_stdio_unlock(H5FD_t *_file) return 0; } /* end H5FD_stdio_unlock() */ +/*------------------------------------------------------------------------- + * Function: H5FD_stdio_delete + * + * Purpose: Delete a file + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +static herr_t +H5FD_stdio_delete(const char *filename, hid_t /*UNUSED*/ fapl_id) +{ + static const char *func = "H5FD_stdio_delete"; /* Function Name for error reporting */ + + /* Clear the error stack */ + H5Eclear2(H5E_DEFAULT); + + assert(filename); + + /* Quiet compiler */ + (void)fapl_id; + + if (remove(filename) < 0) + H5Epush_ret(func, H5E_ERR_CLS, H5E_VFL, H5E_CANTDELETEFILE, "can't delete file)", -1); + + return 0; +} /* end H5FD_stdio_delete() */ + #ifdef H5private_H /* * This is not related to the functionality of the driver code. diff --git a/src/H5FDvfd_swmr.c b/src/H5FDvfd_swmr.c index c409c52..316ca6d 100644 --- a/src/H5FDvfd_swmr.c +++ b/src/H5FDvfd_swmr.c @@ -128,7 +128,8 @@ static const H5FD_class_t H5FD_vfd_swmr_g = { H5FD_vfd_swmr_truncate, /* truncate */ H5FD_vfd_swmr_lock, /* lock */ H5FD_vfd_swmr_unlock, /* unlock */ - H5FD_vfd_swmr_dedup, /* dedup */ + NULL, /* del */ + H5FD_vfd_swmr_dedup, /* dedup */ H5FD_FLMAP_DICHOTOMY /* fl_map */ }; diff --git a/src/H5Fint.c b/src/H5Fint.c index b8a2626..f5dc85d 100644 --- a/src/H5Fint.c +++ b/src/H5Fint.c @@ -413,16 +413,16 @@ H5F_get_access_plist(H5F_t *f, hbool_t app_ref) if (f->shared->efc) efc_size = H5F__efc_max_nfiles(f->shared->efc); if (H5P_set(new_plist, H5F_ACS_EFC_SIZE_NAME, &efc_size) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTGET, H5I_INVALID_HID, "can't set elink file cache size") + HGOTO_ERROR(H5E_FILE, H5E_CANTSET, H5I_INVALID_HID, "can't set elink file cache size") if (f->shared->pb_ptr != NULL) { if (H5P_set(new_plist, H5F_ACS_PAGE_BUFFER_SIZE_NAME, &(f->shared->pb_ptr->max_size)) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTGET, H5I_INVALID_HID, "can't set page buffer size") + HGOTO_ERROR(H5E_FILE, H5E_CANTSET, H5I_INVALID_HID, "can't set page buffer size") if (H5P_set(new_plist, H5F_ACS_PAGE_BUFFER_MIN_META_PERC_NAME, &(f->shared->pb_ptr->min_meta_perc)) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, H5I_INVALID_HID, "can't set minimum metadata fraction of page buffer") if (H5P_set(new_plist, H5F_ACS_PAGE_BUFFER_MIN_RAW_PERC_NAME, &(f->shared->pb_ptr->min_raw_perc)) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTGET, H5I_INVALID_HID, + HGOTO_ERROR(H5E_FILE, H5E_CANTSET, H5I_INVALID_HID, "can't set minimum raw data fraction of page buffer") } /* end if */ @@ -431,9 +431,9 @@ H5F_get_access_plist(H5F_t *f, hbool_t app_ref) #ifdef H5_HAVE_PARALLEL if (H5P_set(new_plist, H5_COLL_MD_READ_FLAG_NAME, &(f->shared->coll_md_read)) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTGET, H5I_INVALID_HID, "can't set collective metadata read flag") + HGOTO_ERROR(H5E_FILE, H5E_CANTSET, H5I_INVALID_HID, "can't set collective metadata read flag") if (H5P_set(new_plist, H5F_ACS_COLL_MD_WRITE_FLAG_NAME, &(f->shared->coll_md_write)) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTGET, H5I_INVALID_HID, "can't set collective metadata read flag") + HGOTO_ERROR(H5E_FILE, H5E_CANTSET, H5I_INVALID_HID, "can't set collective metadata read flag") #endif /* H5_HAVE_PARALLEL */ if (H5P_set(new_plist, H5F_ACS_META_CACHE_INIT_IMAGE_CONFIG_NAME, &(f->shared->mdc_initCacheImageCfg)) < 0) @@ -2442,6 +2442,31 @@ done: } /* end H5F__close() */ /*------------------------------------------------------------------------- + * Function: H5F_delete + * + * Purpose: Deletes a file. + * + * Return: SUCCEED/FAIL + *------------------------------------------------------------------------- + */ +herr_t +H5F_delete(const char *filename, hid_t fapl_id) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + HDassert(filename); + + /* Delete the file */ + if (H5FD_delete(filename, fapl_id) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTDELETEFILE, FAIL, "unable to delete file") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5F_delete() */ + +/*------------------------------------------------------------------------- * Function: H5F_try_close * * Purpose: Attempts to close a file due to one of several actions: diff --git a/src/H5VLnative_file.c b/src/H5VLnative_file.c index 55cd1db..b9a1e4e 100644 --- a/src/H5VLnative_file.c +++ b/src/H5VLnative_file.c @@ -387,8 +387,13 @@ H5VL__native_file_specific(void *obj, H5VL_file_specific_t specific_type, hid_t /* H5Fdelete */ case H5VL_FILE_DELETE: { - HGOTO_ERROR(H5E_FILE, H5E_UNSUPPORTED, FAIL, - "H5Fdelete() is currently not supported in the native VOL connector") + hid_t fapl_id = HDva_arg(arguments, hid_t); + const char *name = HDva_arg(arguments, const char *); + herr_t * ret = HDva_arg(arguments, herr_t *); + + /* Call private routine */ + if ((*ret = H5F_delete(name, fapl_id)) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTDELETEFILE, FAIL, "error in HDF5 file check") break; } diff --git a/test/h5test.c b/test/h5test.c index 0d9fccd..92bc781 100644 --- a/test/h5test.c +++ b/test/h5test.c @@ -183,8 +183,6 @@ h5_clean_files(const char *base_name[], hid_t fapl) /* Close the FAPL used to access the file */ H5Pclose(fapl); - - return; } /* end h5_clean_files() */ /*------------------------------------------------------------------------- @@ -204,66 +202,22 @@ h5_clean_files(const char *base_name[], hid_t fapl) * *------------------------------------------------------------------------- */ -/* Disable warning for "format not a string literal" here -QAK */ -/* - * This pragma only needs to surround the snprintf() calls with - * sub_filename in the code below, but early (4.4.7, at least) gcc only - * allows diagnostic pragmas to be toggled outside of functions. - */ -H5_GCC_DIAG_OFF("format-nonliteral") void h5_delete_test_file(const char *base_name, hid_t fapl) { - char filename[1024]; /* VFD-dependent filename to delete */ - char sub_filename[2048]; /* sub-files in multi & family VFDs */ - hid_t driver = -1; /* VFD ID */ + char filename[1024]; /* VFD-dependent filename to delete */ /* Get the VFD-dependent filename */ if (NULL == h5_fixname(base_name, fapl, filename, sizeof(filename))) return; - driver = H5Pget_driver(fapl); - - if (driver == H5FD_FAMILY) { - int j; - for (j = 0; /*void*/; j++) { - HDsnprintf(sub_filename, sizeof(sub_filename), filename, j); - - /* If we can't access the file, it probably doesn't exist - * and we are done deleting the sub-files. - */ - if (HDaccess(sub_filename, F_OK) < 0) - break; - - HDremove(sub_filename); - } /* end for */ - } - else if (driver == H5FD_CORE) { - hbool_t backing; /* Whether the core file has backing store */ - - H5Pget_fapl_core(fapl, NULL, &backing); - - /* If the file was stored to disk with bacing store, remove it */ - if (backing) - HDremove(filename); - } - else if (driver == H5FD_MULTI) { - H5FD_mem_t mt; - - HDassert(HDstrlen(multi_letters) == H5FD_MEM_NTYPES); - - for (mt = H5FD_MEM_DEFAULT; mt < H5FD_MEM_NTYPES; mt++) { - HDsnprintf(sub_filename, sizeof(sub_filename), "%s-%c.h5", filename, multi_letters[mt]); - HDremove(sub_filename); - } + H5E_BEGIN_TRY + { + H5Fdelete(filename, fapl); } - else { - HDremove(filename); - } /* end driver selection tree */ + H5E_END_TRY; - return; } /* end h5_delete_test_file() */ -H5_GCC_DIAG_ON("format-nonliteral") /*------------------------------------------------------------------------- * Function: h5_delete_all_test_files @@ -294,7 +248,6 @@ h5_delete_all_test_files(const char *base_name[], hid_t fapl) h5_delete_test_file(base_name[i], fapl); } /* end for */ - return; } /* end h5_delete_all_test_files() */ /*------------------------------------------------------------------------- @@ -353,8 +306,6 @@ h5_test_shutdown(void) /* Restore the original error reporting routine */ h5_restore_err(); - - return; } /* end h5_test_shutdown() */ /*------------------------------------------------------------------------- @@ -461,8 +412,6 @@ h5_test_init(void) HDassert(err_func == NULL); H5Eget_auto2(H5E_DEFAULT, &err_func, NULL); H5Eset_auto2(H5E_DEFAULT, h5_errors, NULL); - - return; } /* end h5_test_init() */ /*------------------------------------------------------------------------- @@ -1983,6 +1932,7 @@ static const H5FD_class_t H5FD_dummy_g = { NULL, /* truncate */ NULL, /* lock */ NULL, /* unlock */ + NULL, /* del */ NULL, /* dedup */ H5FD_FLMAP_DICHOTOMY /* fl_map */ }; diff --git a/test/tfile.c b/test/tfile.c index e22e730..19263e8 100644 --- a/test/tfile.c +++ b/test/tfile.c @@ -1923,10 +1923,6 @@ test_file_delete(hid_t fapl_id) /* HDF5 FILE */ /*************/ - /* This is just a placeholder until the native VOL connector supports - * H5Fdelete(). - */ - /* Get fapl-dependent filename */ h5_fixname(FILE_DELETE, fapl_id, filename, sizeof(filename)); @@ -1942,19 +1938,20 @@ test_file_delete(hid_t fapl_id) is_hdf5 = H5Fis_accessible(filename, fapl_id); VERIFY(is_hdf5, TRUE, "H5Fis_accessible"); - /* Attempt to delete the file - should fail */ + /* Delete the file */ + ret = H5Fdelete(filename, fapl_id); + VERIFY(ret, SUCCEED, "H5Fdelete"); + + /* Verify that the file is NO LONGER an HDF5 file */ + /* This should fail since there is no file */ H5E_BEGIN_TRY { - ret = H5Fdelete(filename, fapl_id); + is_hdf5 = H5Fis_accessible(filename, fapl_id); } H5E_END_TRY; - VERIFY(ret, FAIL, "H5Fdelete"); - - /* Verify that the file still exists */ - is_hdf5 = H5Fis_accessible(filename, fapl_id); - VERIFY(is_hdf5, TRUE, "H5Fis_accessible"); + VERIFY(is_hdf5, FAIL, "H5Fis_accessible"); - /* Actually delete the test file */ + /* Just in case deletion fails - silent on errors */ h5_delete_test_file(FILE_DELETE, fapl_id); /*****************/ diff --git a/test/vfd.c b/test/vfd.c index 56bbe1b..8484bfd 100644 --- a/test/vfd.c +++ b/test/vfd.c @@ -99,7 +99,7 @@ static int splitter_create_single_file_at(const char *filename, hid_t fapl_id, const struct splitter_dataset_def *data); static int splitter_compare_expected_data(hid_t file_id, const struct splitter_dataset_def *data); static int run_splitter_test(const struct splitter_dataset_def *data, hbool_t ignore_wo_errors, - hbool_t provide_logfile_path, hid_t sub_fapl_ids[2]); + hbool_t provide_logfile_path, const hid_t sub_fapl_ids[2]); static int splitter_RO_test(const struct splitter_dataset_def *data, hid_t child_fapl_id); static int splitter_tentative_open_test(hid_t child_fapl_id); static int file_exists(const char *filename, hid_t fapl_id); @@ -340,7 +340,7 @@ test_core(void) if ((fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id)) < 0) TEST_ERROR; - /* Retrieve the access property list... */ + /* Retrieve the access property list */ if ((fapl_id_out = H5Fget_access_plist(fid)) < 0) TEST_ERROR; @@ -553,6 +553,38 @@ test_core(void) TEST_ERROR; h5_delete_test_file(FILENAME[1], fapl_id); + /************************************************************************ + * Check that delete behavior works correctly + ************************************************************************/ + + /* Create and close a file */ + if (H5Pset_fapl_core(fapl_id, (size_t)CORE_INCREMENT, TRUE) < 0) + TEST_ERROR; + if ((fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id)) < 0) + TEST_ERROR; + if (H5Fclose(fid) < 0) + TEST_ERROR; + + /* Try to delete the file with the backing store off (shouldn't delete anything) */ + if (H5Pset_fapl_core(fapl_id, (size_t)CORE_INCREMENT, FALSE) < 0) + TEST_ERROR; + if (H5Fdelete(filename, fapl_id) < 0) + TEST_ERROR; + if (-1 == HDaccess(filename, F_OK)) + FAIL_PUTS_ERROR("file deleted when backing store set to FALSE"); + + /* Try to delete the file with the backing store on (should work) */ + if (H5Pset_fapl_core(fapl_id, (size_t)CORE_INCREMENT, TRUE) < 0) + TEST_ERROR; + if (H5Fdelete(filename, fapl_id) < 0) + TEST_ERROR; + if (0 == HDaccess(filename, F_OK)) + FAIL_PUTS_ERROR("file not deleted when backing store set to TRUE"); + + /************************************************************************ + * Clean up + ************************************************************************/ + /* Close the fapl */ if (H5Pclose(fapl_id) < 0) TEST_ERROR; @@ -1835,12 +1867,23 @@ test_log(void) hsize_t file_size = 0; unsigned int flags = H5FD_LOG_ALL; size_t buf_size = 4 * KB; + herr_t ret = SUCCEED; TESTING("LOG file driver"); - /* Set property list and file name for log driver. */ if ((fapl = H5Pcreate(H5P_FILE_ACCESS)) < 0) TEST_ERROR; + + /* Make sure calling with an invalid fapl doesn't crash */ + H5E_BEGIN_TRY + { + ret = H5Pset_fapl_log(H5I_INVALID_HID, LOG_FILENAME, 0, 0); + } + H5E_END_TRY; + if (SUCCEED == ret) + TEST_ERROR; + + /* Set property list and file name for log driver. */ if (H5Pset_fapl_log(fapl, LOG_FILENAME, flags, buf_size) < 0) TEST_ERROR; h5_fixname(FILENAME[6], fapl, filename, sizeof filename); @@ -2180,14 +2223,12 @@ static herr_t test_ros3(void) { #ifdef H5_HAVE_ROS3_VFD - hid_t fid = -1; /* file ID */ - hid_t fapl_id = -1; /* file access property list ID */ - hid_t fapl_id_out = -1; /* from H5Fget_access_plist */ - hid_t driver_id = -1; /* ID for this VFD */ - unsigned long driver_flags = 0; /* VFD feature flags */ - char filename[1024]; /* filename */ - void * os_file_handle = NULL; /* OS file handle */ - hsize_t file_size; /* file size */ + hid_t fid = -1; /* file ID */ + hid_t fapl_id = -1; /* file access property list ID */ + hid_t fapl_id_out = -1; /* from H5Fget_access_plist */ + hid_t driver_id = -1; /* ID for this VFD */ + unsigned long driver_flags = 0; /* VFD feature flags */ + char filename[1024]; /* filename */ H5FD_ros3_fapl_t test_ros3_fa; H5FD_ros3_fapl_t ros3_fa_0 = { /* version = */ H5FD_CURR_ROS3_FAPL_T_VERSION, @@ -2219,9 +2260,9 @@ test_ros3(void) /* need a macro to compare instances of H5FD_ros3_fapl_t */ if ((test_ros3_fa.version != ros3_fa_0.version) || (test_ros3_fa.authenticate != ros3_fa_0.authenticate) || - (strcmp(test_ros3_fa.aws_region, ros3_fa_0.aws_region) != 0) || - (strcmp(test_ros3_fa.secret_id, ros3_fa_0.secret_id) != 0) || - (strcmp(test_ros3_fa.secret_key, ros3_fa_0.secret_key) != 0)) + (HDstrcmp(test_ros3_fa.aws_region, ros3_fa_0.aws_region) != 0) || + (HDstrcmp(test_ros3_fa.secret_id, ros3_fa_0.secret_id) != 0) || + (HDstrcmp(test_ros3_fa.secret_key, ros3_fa_0.secret_key) != 0)) TEST_ERROR; h5_fixname(FILENAME[10], fapl_id, filename, sizeof(filename)); @@ -2270,7 +2311,7 @@ error: AT(); \ HDfprintf(stderr, mesg); \ H5Eprint2(H5E_DEFAULT, stderr); \ - fflush(stderr); \ + HDfflush(stderr); \ ret_value = -1; \ goto done; \ } @@ -2289,46 +2330,51 @@ error: static int compare_splitter_config_info(hid_t fapl_id, H5FD_splitter_vfd_config_t *info) { - int ret_value = 0; - H5FD_splitter_vfd_config_t fetched_info; + int ret_value = 0; + H5FD_splitter_vfd_config_t *fetched_info = NULL; + + if (NULL == (fetched_info = HDcalloc(1, sizeof(H5FD_splitter_vfd_config_t)))) + SPLITTER_TEST_FAULT("memory allocation for fetched_info struct failed"); - fetched_info.magic = H5FD_SPLITTER_MAGIC; - fetched_info.version = H5FD_CURR_SPLITTER_VFD_CONFIG_VERSION; - fetched_info.rw_fapl_id = H5I_INVALID_HID; - fetched_info.wo_fapl_id = H5I_INVALID_HID; + fetched_info->magic = H5FD_SPLITTER_MAGIC; + fetched_info->version = H5FD_CURR_SPLITTER_VFD_CONFIG_VERSION; + fetched_info->rw_fapl_id = H5I_INVALID_HID; + fetched_info->wo_fapl_id = H5I_INVALID_HID; - if (H5Pget_fapl_splitter(fapl_id, &fetched_info) < 0) { - SPLITTER_TEST_FAULT("can't get splitter info\n"); + if (H5Pget_fapl_splitter(fapl_id, fetched_info) < 0) { + SPLITTER_TEST_FAULT("can't get splitter info"); } if (info->rw_fapl_id == H5P_DEFAULT) { - if (H5Pget_driver(fetched_info.rw_fapl_id) != H5Pget_driver(H5P_FILE_ACCESS_DEFAULT)) { + if (H5Pget_driver(fetched_info->rw_fapl_id) != H5Pget_driver(H5P_FILE_ACCESS_DEFAULT)) { SPLITTER_TEST_FAULT("Read-Write driver mismatch (default)\n"); } } else { - if (H5Pget_driver(fetched_info.rw_fapl_id) != H5Pget_driver(info->rw_fapl_id)) { + if (H5Pget_driver(fetched_info->rw_fapl_id) != H5Pget_driver(info->rw_fapl_id)) { SPLITTER_TEST_FAULT("Read-Write driver mismatch\n"); } } if (info->wo_fapl_id == H5P_DEFAULT) { - if (H5Pget_driver(fetched_info.wo_fapl_id) != H5Pget_driver(H5P_FILE_ACCESS_DEFAULT)) { + if (H5Pget_driver(fetched_info->wo_fapl_id) != H5Pget_driver(H5P_FILE_ACCESS_DEFAULT)) { SPLITTER_TEST_FAULT("Write-Only driver mismatch (default)\n"); } } else { - if (H5Pget_driver(fetched_info.wo_fapl_id) != H5Pget_driver(info->wo_fapl_id)) { + if (H5Pget_driver(fetched_info->wo_fapl_id) != H5Pget_driver(info->wo_fapl_id)) { SPLITTER_TEST_FAULT("Write-Only driver mismatch\n"); } } - if ((HDstrlen(info->wo_path) != HDstrlen(fetched_info.wo_path)) || - HDstrncmp(info->wo_path, fetched_info.wo_path, H5FD_SPLITTER_PATH_MAX)) { - HDfprintf(stderr, "MISMATCH: '%s' :: '%s'\n", info->wo_path, fetched_info.wo_path); + if ((HDstrlen(info->wo_path) != HDstrlen(fetched_info->wo_path)) || + HDstrncmp(info->wo_path, fetched_info->wo_path, H5FD_SPLITTER_PATH_MAX) != 0) { + HDfprintf(stderr, "MISMATCH: '%s' :: '%s'\n", info->wo_path, fetched_info->wo_path); HEXPRINT(H5FD_SPLITTER_PATH_MAX, info->wo_path); - HEXPRINT(H5FD_SPLITTER_PATH_MAX, fetched_info.wo_path); + HEXPRINT(H5FD_SPLITTER_PATH_MAX, fetched_info->wo_path); SPLITTER_TEST_FAULT("Write-Only file path mismatch\n"); } done: + HDfree(fetched_info); + return ret_value; } /* end compare_splitter_config_info() */ @@ -2351,45 +2397,50 @@ done: */ static int run_splitter_test(const struct splitter_dataset_def *data, hbool_t ignore_wo_errors, - hbool_t provide_logfile_path, hid_t sub_fapl_ids[2]) + hbool_t provide_logfile_path, const hid_t sub_fapl_ids[2]) { - hid_t file_id = H5I_INVALID_HID; - hid_t fapl_id = H5I_INVALID_HID; - hid_t dset_id = H5I_INVALID_HID; - hid_t space_id = H5I_INVALID_HID; - hid_t fapl_id_out = H5I_INVALID_HID; - hid_t fapl_id_cpy = H5I_INVALID_HID; - H5FD_splitter_vfd_config_t vfd_config; - char filename_rw[H5FD_SPLITTER_PATH_MAX + 1]; - FILE * logfile = NULL; - int ret_value = 0; - - vfd_config.magic = H5FD_SPLITTER_MAGIC; - vfd_config.version = H5FD_CURR_SPLITTER_VFD_CONFIG_VERSION; - vfd_config.ignore_wo_errs = ignore_wo_errors; - vfd_config.rw_fapl_id = sub_fapl_ids[0]; - vfd_config.wo_fapl_id = sub_fapl_ids[1]; - - if (splitter_prepare_file_paths(&vfd_config, filename_rw) < 0) { + hid_t file_id = H5I_INVALID_HID; + hid_t fapl_id = H5I_INVALID_HID; + hid_t dset_id = H5I_INVALID_HID; + hid_t space_id = H5I_INVALID_HID; + hid_t fapl_id_out = H5I_INVALID_HID; + hid_t fapl_id_cpy = H5I_INVALID_HID; + H5FD_splitter_vfd_config_t *vfd_config = NULL; + char * filename_rw = NULL; + FILE * logfile = NULL; + int ret_value = 0; + + if (NULL == (vfd_config = HDcalloc(1, sizeof(H5FD_splitter_vfd_config_t)))) + SPLITTER_TEST_FAULT("memory allocation for vfd_config struct failed"); + if (NULL == (filename_rw = HDcalloc(H5FD_SPLITTER_PATH_MAX + 1, sizeof(char)))) + SPLITTER_TEST_FAULT("memory allocation for filename_rw string failed"); + + vfd_config->magic = H5FD_SPLITTER_MAGIC; + vfd_config->version = H5FD_CURR_SPLITTER_VFD_CONFIG_VERSION; + vfd_config->ignore_wo_errs = ignore_wo_errors; + vfd_config->rw_fapl_id = sub_fapl_ids[0]; + vfd_config->wo_fapl_id = sub_fapl_ids[1]; + + if (splitter_prepare_file_paths(vfd_config, filename_rw) < 0) { SPLITTER_TEST_FAULT("can't prepare file paths\n"); } if (provide_logfile_path == FALSE) { - *vfd_config.log_file_path = '\0'; /* reset as empty string */ + vfd_config->log_file_path[0] = '\0'; /* reset as empty string */ } /* Create a new fapl to use the SPLITTER file driver */ if ((fapl_id = H5Pcreate(H5P_FILE_ACCESS)) == H5I_INVALID_HID) { SPLITTER_TEST_FAULT("can't create FAPL ID\n"); } - if (H5Pset_fapl_splitter(fapl_id, &vfd_config) < 0) { + if (H5Pset_fapl_splitter(fapl_id, vfd_config) < 0) { SPLITTER_TEST_FAULT("can't set splitter FAPL\n"); } if (H5Pget_driver(fapl_id) != H5FD_SPLITTER) { SPLITTER_TEST_FAULT("set FAPL not SPLITTER\n"); } - if (compare_splitter_config_info(fapl_id, &vfd_config) < 0) { + if (compare_splitter_config_info(fapl_id, vfd_config) < 0) { SPLITTER_TEST_FAULT("information mismatch\n"); } @@ -2402,7 +2453,7 @@ run_splitter_test(const struct splitter_dataset_def *data, hbool_t ignore_wo_err if (H5I_INVALID_HID == fapl_id_cpy) { SPLITTER_TEST_FAULT("can't copy FAPL\n"); } - if (compare_splitter_config_info(fapl_id_cpy, &vfd_config) < 0) { + if (compare_splitter_config_info(fapl_id_cpy, vfd_config) < 0) { SPLITTER_TEST_FAULT("information mismatch\n"); } if (H5Pclose(fapl_id_cpy) < 0) { @@ -2428,7 +2479,7 @@ run_splitter_test(const struct splitter_dataset_def *data, hbool_t ignore_wo_err if (H5Pget_driver(fapl_id_out) != H5FD_SPLITTER) { SPLITTER_TEST_FAULT("wrong file FAPL driver\n"); } - if (compare_splitter_config_info(fapl_id_out, &vfd_config) < 0) { + if (compare_splitter_config_info(fapl_id_out, vfd_config) < 0) { SPLITTER_TEST_FAULT("information mismatch\n"); } if (H5Pclose(fapl_id_out) < 0) { @@ -2467,12 +2518,12 @@ run_splitter_test(const struct splitter_dataset_def *data, hbool_t ignore_wo_err } /* Verify that the R/W and W/O files are identical */ - if (h5_compare_file_bytes(filename_rw, vfd_config.wo_path) < 0) { + if (h5_compare_file_bytes(filename_rw, vfd_config->wo_path) < 0) { SPLITTER_TEST_FAULT("files are not byte-for-byte equivalent\n"); } /* Verify existence of logfile if appropriate */ - logfile = fopen(vfd_config.log_file_path, "r"); + logfile = HDfopen(vfd_config->log_file_path, "r"); if ((TRUE == provide_logfile_path && NULL == logfile) || (FALSE == provide_logfile_path && NULL != logfile)) { SPLITTER_TEST_FAULT("no logfile when one was expected\n"); @@ -2482,20 +2533,23 @@ done: if (ret_value < 0) { H5E_BEGIN_TRY { - (void)H5Dclose(dset_id); - (void)H5Sclose(space_id); - (void)H5Pclose(fapl_id_out); - (void)H5Pclose(fapl_id_cpy); - (void)H5Pclose(fapl_id); - (void)H5Fclose(file_id); + H5Dclose(dset_id); + H5Sclose(space_id); + H5Pclose(fapl_id_out); + H5Pclose(fapl_id_cpy); + H5Pclose(fapl_id); + H5Fclose(file_id); } H5E_END_TRY; } - if (logfile != NULL) { - fclose(logfile); - } - return ret_value; + if (logfile != NULL) + HDfclose(logfile); + + HDfree(vfd_config); + HDfree(filename_rw); + + return ret_value; } /* end run_splitter_test() */ /*------------------------------------------------------------------------- @@ -2516,26 +2570,29 @@ done: static int driver_is_splitter_compatible(hid_t fapl_id) { - H5FD_splitter_vfd_config_t vfd_config; - hid_t split_fapl_id = H5I_INVALID_HID; - herr_t ret = SUCCEED; - int ret_value = 0; + H5FD_splitter_vfd_config_t *vfd_config = NULL; + hid_t split_fapl_id = H5I_INVALID_HID; + herr_t ret = SUCCEED; + int ret_value = 0; - split_fapl_id = H5Pcreate(H5P_FILE_ACCESS); - if (H5I_INVALID_HID == split_fapl_id) { + if (NULL == (vfd_config = HDcalloc(1, sizeof(H5FD_splitter_vfd_config_t)))) { + FAIL_PUTS_ERROR("memory allocation for vfd_config struct failed"); + } + + if (H5I_INVALID_HID == (split_fapl_id = H5Pcreate(H5P_FILE_ACCESS))) { FAIL_PUTS_ERROR("Can't create contained FAPL"); } - vfd_config.magic = H5FD_SPLITTER_MAGIC; - vfd_config.version = H5FD_CURR_SPLITTER_VFD_CONFIG_VERSION; - vfd_config.ignore_wo_errs = FALSE; - vfd_config.rw_fapl_id = H5P_DEFAULT; - vfd_config.wo_fapl_id = fapl_id; - HDstrncpy(vfd_config.wo_path, "nonesuch", H5FD_SPLITTER_PATH_MAX); - *vfd_config.log_file_path = '\0'; + vfd_config->magic = H5FD_SPLITTER_MAGIC; + vfd_config->version = H5FD_CURR_SPLITTER_VFD_CONFIG_VERSION; + vfd_config->ignore_wo_errs = FALSE; + vfd_config->rw_fapl_id = H5P_DEFAULT; + vfd_config->wo_fapl_id = fapl_id; + HDstrncpy(vfd_config->wo_path, "nonesuch", H5FD_SPLITTER_PATH_MAX); + vfd_config->log_file_path[0] = '\0'; H5E_BEGIN_TRY { - ret = H5Pset_fapl_splitter(split_fapl_id, &vfd_config); + ret = H5Pset_fapl_splitter(split_fapl_id, vfd_config); } H5E_END_TRY; if (SUCCEED == ret) { @@ -2547,14 +2604,19 @@ driver_is_splitter_compatible(hid_t fapl_id) } split_fapl_id = H5I_INVALID_HID; + HDfree(vfd_config); + return ret_value; error: H5E_BEGIN_TRY { - (void)H5Pclose(split_fapl_id); + H5Pclose(split_fapl_id); } H5E_END_TRY; + + HDfree(vfd_config); + return -1; } /* end driver_is_splitter_compatible() */ @@ -2574,19 +2636,24 @@ error: static int splitter_RO_test(const struct splitter_dataset_def *data, hid_t child_fapl_id) { - char filename_rw[H5FD_SPLITTER_PATH_MAX + 1]; - H5FD_splitter_vfd_config_t vfd_config; - hid_t fapl_id = H5I_INVALID_HID; - int ret_value = 0; - hid_t file_id = H5I_INVALID_HID; - - vfd_config.magic = H5FD_SPLITTER_MAGIC; - vfd_config.version = H5FD_CURR_SPLITTER_VFD_CONFIG_VERSION; - vfd_config.ignore_wo_errs = FALSE; - vfd_config.rw_fapl_id = child_fapl_id; - vfd_config.wo_fapl_id = child_fapl_id; - - if (splitter_prepare_file_paths(&vfd_config, filename_rw) < 0) { + char * filename_rw = NULL; + H5FD_splitter_vfd_config_t *vfd_config = NULL; + hid_t fapl_id = H5I_INVALID_HID; + hid_t file_id = H5I_INVALID_HID; + int ret_value = 0; + + if (NULL == (vfd_config = HDcalloc(1, sizeof(H5FD_splitter_vfd_config_t)))) + SPLITTER_TEST_FAULT("memory allocation for vfd_config struct failed"); + if (NULL == (filename_rw = HDcalloc(H5FD_SPLITTER_PATH_MAX + 1, sizeof(char)))) + SPLITTER_TEST_FAULT("memory allocation for filename_rw string failed"); + + vfd_config->magic = H5FD_SPLITTER_MAGIC; + vfd_config->version = H5FD_CURR_SPLITTER_VFD_CONFIG_VERSION; + vfd_config->ignore_wo_errs = FALSE; + vfd_config->rw_fapl_id = child_fapl_id; + vfd_config->wo_fapl_id = child_fapl_id; + + if (splitter_prepare_file_paths(vfd_config, filename_rw) < 0) { SPLITTER_TEST_FAULT("can't prepare splitter file paths\n"); } @@ -2595,7 +2662,7 @@ splitter_RO_test(const struct splitter_dataset_def *data, hid_t child_fapl_id) if (H5I_INVALID_HID == fapl_id) { SPLITTER_TEST_FAULT("can't create FAPL ID\n"); } - if (H5Pset_fapl_splitter(fapl_id, &vfd_config) < 0) { + if (H5Pset_fapl_splitter(fapl_id, vfd_config) < 0) { SPLITTER_TEST_FAULT("can't set splitter FAPL\n"); } if (H5Pget_driver(fapl_id) != H5FD_SPLITTER) { @@ -2619,7 +2686,7 @@ splitter_RO_test(const struct splitter_dataset_def *data, hid_t child_fapl_id) * Should fail. */ - if (splitter_create_single_file_at(vfd_config.wo_path, vfd_config.wo_fapl_id, data) < 0) { + if (splitter_create_single_file_at(vfd_config->wo_path, vfd_config->wo_fapl_id, data) < 0) { SPLITTER_TEST_FAULT("can't write W/O file\n"); } H5E_BEGIN_TRY @@ -2630,13 +2697,13 @@ splitter_RO_test(const struct splitter_dataset_def *data, hid_t child_fapl_id) if (file_id >= 0) { SPLITTER_TEST_FAULT("R/O open with extant W/O file unexpectedly successful\n"); } - HDremove(vfd_config.wo_path); + HDremove(vfd_config->wo_path); /* Attempt R/O open when only R/W file exists * Should fail. */ - if (splitter_create_single_file_at(filename_rw, vfd_config.rw_fapl_id, data) < 0) { + if (splitter_create_single_file_at(filename_rw, vfd_config->rw_fapl_id, data) < 0) { SPLITTER_TEST_FAULT("can't create R/W file\n"); } H5E_BEGIN_TRY @@ -2651,7 +2718,7 @@ splitter_RO_test(const struct splitter_dataset_def *data, hid_t child_fapl_id) /* Attempt R/O open when both R/W and W/O files exist */ - if (splitter_create_single_file_at(vfd_config.wo_path, vfd_config.wo_fapl_id, data) < 0) { + if (splitter_create_single_file_at(vfd_config->wo_path, vfd_config->wo_fapl_id, data) < 0) { SPLITTER_TEST_FAULT("can't create W/O file\n"); } file_id = H5Fopen(filename_rw, H5F_ACC_RDONLY, fapl_id); @@ -2678,11 +2745,15 @@ done: if (ret_value < 0) { H5E_BEGIN_TRY { - (void)H5Pclose(fapl_id); - (void)H5Fclose(file_id); + H5Pclose(fapl_id); + H5Fclose(file_id); } H5E_END_TRY; - } /* end if error */ + } + + HDfree(vfd_config); + HDfree(filename_rw); + return ret_value; } /* end splitter_RO_test() */ @@ -2812,9 +2883,9 @@ done: if (ret_value < 0) { H5E_BEGIN_TRY { - (void)H5Dclose(dset_id); - (void)H5Sclose(space_id); - (void)H5Fclose(file_id); + H5Dclose(dset_id); + H5Sclose(space_id); + H5Fclose(file_id); } H5E_END_TRY; } /* end if error */ @@ -2875,7 +2946,7 @@ done: if (ret_value < 0) { H5E_BEGIN_TRY { - (void)H5Dclose(dset_id); + H5Dclose(dset_id); } H5E_END_TRY; } @@ -2908,11 +2979,11 @@ done: static int splitter_tentative_open_test(hid_t child_fapl_id) { - const char filename_tmp[H5FD_SPLITTER_PATH_MAX + 1] = "splitter_tmp.h5"; - char filename_rw[H5FD_SPLITTER_PATH_MAX + 1]; - H5FD_splitter_vfd_config_t vfd_config; - hid_t fapl_id = H5I_INVALID_HID; - hid_t file_id = H5I_INVALID_HID; + const char * filename_tmp = "splitter_tmp.h5"; + char * filename_rw = NULL; + H5FD_splitter_vfd_config_t *vfd_config = NULL; + hid_t fapl_id = H5I_INVALID_HID; + hid_t file_id = H5I_INVALID_HID; int buf[SPLITTER_SIZE][SPLITTER_SIZE]; /* for comparison */ hsize_t dims[2] = {SPLITTER_SIZE, SPLITTER_SIZE}; /* for comparison */ int i = 0; /* for comparison */ @@ -2920,6 +2991,11 @@ splitter_tentative_open_test(hid_t child_fapl_id) struct splitter_dataset_def data; /* for comparison */ int ret_value = 0; + if (NULL == (vfd_config = HDcalloc(1, sizeof(H5FD_splitter_vfd_config_t)))) + SPLITTER_TEST_FAULT("memory allocation for vfd_config struct failed"); + if (NULL == (filename_rw = HDcalloc(H5FD_SPLITTER_PATH_MAX + 1, sizeof(char)))) + SPLITTER_TEST_FAULT("memory allocation for filename_rw string failed"); + /* pre-fill data buffer to write */ for (i = 0; i < SPLITTER_SIZE; i++) { for (j = 0; j < SPLITTER_SIZE; j++) { @@ -2934,13 +3010,13 @@ splitter_tentative_open_test(hid_t child_fapl_id) data.n_dims = 2; data.dset_name = SPLITTER_DATASET_NAME; - vfd_config.magic = H5FD_SPLITTER_MAGIC; - vfd_config.version = H5FD_CURR_SPLITTER_VFD_CONFIG_VERSION; - vfd_config.ignore_wo_errs = FALSE; - vfd_config.rw_fapl_id = child_fapl_id; - vfd_config.wo_fapl_id = child_fapl_id; + vfd_config->magic = H5FD_SPLITTER_MAGIC; + vfd_config->version = H5FD_CURR_SPLITTER_VFD_CONFIG_VERSION; + vfd_config->ignore_wo_errs = FALSE; + vfd_config->rw_fapl_id = child_fapl_id; + vfd_config->wo_fapl_id = child_fapl_id; - if (splitter_prepare_file_paths(&vfd_config, filename_rw) < 0) { + if (splitter_prepare_file_paths(vfd_config, filename_rw) < 0) { SPLITTER_TEST_FAULT("can't prepare splitter file paths\n"); } @@ -2948,7 +3024,7 @@ splitter_tentative_open_test(hid_t child_fapl_id) if ((fapl_id = H5Pcreate(H5P_FILE_ACCESS)) == H5I_INVALID_HID) { SPLITTER_TEST_FAULT("can't create FAPL ID\n"); } - if (H5Pset_fapl_splitter(fapl_id, &vfd_config) < 0) { + if (H5Pset_fapl_splitter(fapl_id, vfd_config) < 0) { SPLITTER_TEST_FAULT("can't set splitter FAPL\n"); } if (H5Pget_driver(fapl_id) != H5FD_SPLITTER) { @@ -2980,7 +3056,7 @@ splitter_tentative_open_test(hid_t child_fapl_id) if (file_exists(filename_rw, child_fapl_id)) { SPLITTER_TEST_FAULT("R/W file unexpectedly created\n"); } - if (file_exists(vfd_config.wo_path, child_fapl_id)) { + if (file_exists(vfd_config->wo_path, child_fapl_id)) { SPLITTER_TEST_FAULT("W/O file unexpectedly created\n"); } @@ -2990,7 +3066,7 @@ splitter_tentative_open_test(hid_t child_fapl_id) * Should fail. */ - if (h5_duplicate_file_by_bytes(filename_tmp, vfd_config.wo_path) < 0) { + if (h5_duplicate_file_by_bytes(filename_tmp, vfd_config->wo_path) < 0) { SPLITTER_TEST_FAULT("Can't create W/O file copy.\n"); } H5E_BEGIN_TRY @@ -3004,11 +3080,11 @@ splitter_tentative_open_test(hid_t child_fapl_id) if (file_exists(filename_rw, child_fapl_id)) { SPLITTER_TEST_FAULT("R/W file unexpectedly created\n"); } - if (!file_exists(vfd_config.wo_path, child_fapl_id)) { + if (!file_exists(vfd_config->wo_path, child_fapl_id)) { SPLITTER_TEST_FAULT("W/O file mysteriously disappeared\n"); } - HDremove(vfd_config.wo_path); - if (file_exists(vfd_config.wo_path, child_fapl_id)) { + HDremove(vfd_config->wo_path); + if (file_exists(vfd_config->wo_path, child_fapl_id)) { SPLITTER_TEST_FAULT("failed to remove W/O file\n"); } @@ -3032,7 +3108,7 @@ splitter_tentative_open_test(hid_t child_fapl_id) if (!file_exists(filename_rw, child_fapl_id)) { SPLITTER_TEST_FAULT("R/W file mysteriously disappeared\n"); } - if (file_exists(vfd_config.wo_path, child_fapl_id)) { + if (file_exists(vfd_config->wo_path, child_fapl_id)) { SPLITTER_TEST_FAULT("W/O file unexpectedly created\n"); } @@ -3041,7 +3117,7 @@ splitter_tentative_open_test(hid_t child_fapl_id) * Both files present. */ - if (h5_duplicate_file_by_bytes(filename_tmp, vfd_config.wo_path) < 0) { + if (h5_duplicate_file_by_bytes(filename_tmp, vfd_config->wo_path) < 0) { SPLITTER_TEST_FAULT("Can't create W/O file copy.\n"); } file_id = H5Fopen(filename_rw, H5F_ACC_RDWR, fapl_id); @@ -3055,7 +3131,7 @@ splitter_tentative_open_test(hid_t child_fapl_id) if (!file_exists(filename_rw, child_fapl_id)) { SPLITTER_TEST_FAULT("R/W file mysteriously disappared\n"); } - if (!file_exists(vfd_config.wo_path, child_fapl_id)) { + if (!file_exists(vfd_config->wo_path, child_fapl_id)) { SPLITTER_TEST_FAULT("W/O file mysteriously disappeared\n"); } @@ -3075,14 +3151,14 @@ splitter_tentative_open_test(hid_t child_fapl_id) if (!file_exists(filename_rw, child_fapl_id)) { SPLITTER_TEST_FAULT("R/W file mysteriously disappared\n"); } - if (!file_exists(vfd_config.wo_path, child_fapl_id)) { + if (!file_exists(vfd_config->wo_path, child_fapl_id)) { SPLITTER_TEST_FAULT("W/O file mysteriously disappeared\n"); } - if (h5_compare_file_bytes(filename_rw, vfd_config.wo_path) < 0) { + if (h5_compare_file_bytes(filename_rw, vfd_config->wo_path) < 0) { SPLITTER_TEST_FAULT("files are not byte-for-byte equivalent\n"); } HDremove(filename_rw); - HDremove(vfd_config.wo_path); + HDremove(vfd_config->wo_path); /* * H5Fcreate() with TRUNC access. @@ -3092,7 +3168,7 @@ splitter_tentative_open_test(hid_t child_fapl_id) if (h5_duplicate_file_by_bytes(filename_tmp, filename_rw) < 0) { SPLITTER_TEST_FAULT("Can't create R/W file copy.\n"); } - if (file_exists(vfd_config.wo_path, child_fapl_id)) { + if (file_exists(vfd_config->wo_path, child_fapl_id)) { SPLITTER_TEST_FAULT("failed to remove W/O file\n"); } file_id = H5Fcreate(filename_rw, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id); @@ -3106,21 +3182,21 @@ splitter_tentative_open_test(hid_t child_fapl_id) if (!file_exists(filename_rw, child_fapl_id)) { SPLITTER_TEST_FAULT("R/W file mysteriously disappared\n"); } - if (!file_exists(vfd_config.wo_path, child_fapl_id)) { + if (!file_exists(vfd_config->wo_path, child_fapl_id)) { SPLITTER_TEST_FAULT("W/O file mysteriously disappeared\n"); } - if (h5_compare_file_bytes(filename_rw, vfd_config.wo_path) < 0) { + if (h5_compare_file_bytes(filename_rw, vfd_config->wo_path) < 0) { SPLITTER_TEST_FAULT("files are not byte-for-byte equivalent\n"); } HDremove(filename_rw); - HDremove(vfd_config.wo_path); + HDremove(vfd_config->wo_path); /* * H5Fcreate() with TRUNC access. * Only W/O present. */ - if (h5_duplicate_file_by_bytes(filename_tmp, vfd_config.wo_path) < 0) { + if (h5_duplicate_file_by_bytes(filename_tmp, vfd_config->wo_path) < 0) { SPLITTER_TEST_FAULT("Can't create W/O file copy.\n"); } if (file_exists(filename_rw, child_fapl_id)) { @@ -3137,14 +3213,14 @@ splitter_tentative_open_test(hid_t child_fapl_id) if (!file_exists(filename_rw, child_fapl_id)) { SPLITTER_TEST_FAULT("R/W file mysteriously disappared\n"); } - if (!file_exists(vfd_config.wo_path, child_fapl_id)) { + if (!file_exists(vfd_config->wo_path, child_fapl_id)) { SPLITTER_TEST_FAULT("W/O file mysteriously disappeared\n"); } - if (h5_compare_file_bytes(filename_rw, vfd_config.wo_path) < 0) { + if (h5_compare_file_bytes(filename_rw, vfd_config->wo_path) < 0) { SPLITTER_TEST_FAULT("files are not byte-for-byte equivalent\n"); } HDremove(filename_rw); - HDremove(vfd_config.wo_path); + HDremove(vfd_config->wo_path); /* H5Fcreate with both files absent is tested elsewhere */ @@ -3160,11 +3236,15 @@ done: if (ret_value < 0) { H5E_BEGIN_TRY { - (void)H5Pclose(fapl_id); - (void)H5Fclose(file_id); + H5Pclose(fapl_id); + H5Fclose(file_id); } H5E_END_TRY; - } /* end if error */ + } + + HDfree(vfd_config); + HDfree(filename_rw); + return ret_value; } /* end splitter_tentative_open_test() */ @@ -3203,7 +3283,7 @@ file_exists(const char *filename, hid_t fapl_id) error: H5E_BEGIN_TRY { - (void)H5Fclose(file_id); + H5Fclose(file_id); } H5E_END_TRY; return ret_value; @@ -3310,9 +3390,9 @@ test_splitter(void) return 0; error: - if (child_fapl_id != H5I_INVALID_HID) { - (void)H5Pclose(child_fapl_id); - } + if (child_fapl_id != H5I_INVALID_HID) + H5Pclose(child_fapl_id); + return -1; } /* end test_splitter() */ diff --git a/testpar/t_file.c b/testpar/t_file.c index ec8726f..d749978 100644 --- a/testpar/t_file.c +++ b/testpar/t_file.c @@ -950,3 +950,58 @@ test_file_properties(void) VRFY((mpi_ret >= 0), "MPI_Info_free succeeded"); } /* end test_file_properties() */ + +void +test_delete(void) +{ + hid_t fid = H5I_INVALID_HID; /* HDF5 file ID */ + hid_t fapl_id = H5I_INVALID_HID; /* File access plist */ + hbool_t is_coll; + const char *filename = NULL; + MPI_Comm comm = MPI_COMM_WORLD; + MPI_Info info = MPI_INFO_NULL; + htri_t is_hdf5 = FAIL; /* Whether a file is an HDF5 file */ + herr_t ret; /* Generic return value */ + + filename = (const char *)GetTestParameters(); + + /* set up MPI parameters */ + MPI_Comm_size(MPI_COMM_WORLD, &mpi_size); + MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank); + + /* setup file access plist */ + fapl_id = H5Pcreate(H5P_FILE_ACCESS); + VRFY((fapl_id != H5I_INVALID_HID), "H5Pcreate"); + ret = H5Pset_fapl_mpio(fapl_id, comm, info); + VRFY((SUCCEED == ret), "H5Pset_fapl_mpio"); + + /* create the file */ + fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id); + VRFY((fid != H5I_INVALID_HID), "H5Fcreate"); + + /* close the file */ + ret = H5Fclose(fid); + VRFY((SUCCEED == ret), "H5Fclose"); + + /* Verify that the file is an HDF5 file */ + is_hdf5 = H5Fis_accessible(filename, fapl_id); + VRFY((TRUE == is_hdf5), "H5Fis_accessible"); + + /* Delete the file */ + ret = H5Fdelete(filename, fapl_id); + VRFY((SUCCEED == ret), "H5Fdelete"); + + /* Verify that the file is NO LONGER an HDF5 file */ + /* This should fail since there is no file */ + H5E_BEGIN_TRY + { + is_hdf5 = H5Fis_accessible(filename, fapl_id); + } + H5E_END_TRY; + VRFY((is_hdf5 != SUCCEED), "H5Fis_accessible"); + + /* Release file-access plist */ + ret = H5Pclose(fapl_id); + VRFY((SUCCEED == ret), "H5Pclose"); + +} /* end test_delete() */ diff --git a/testpar/testphdf5.c b/testpar/testphdf5.c index e693bc0..cce8aff 100644 --- a/testpar/testphdf5.c +++ b/testpar/testphdf5.c @@ -353,6 +353,8 @@ main(int argc, char **argv) AddTest("props", test_file_properties, NULL, "Coll Metadata file property settings", PARATESTFILE); + AddTest("delete", test_delete, NULL, "MPI-IO VFD file delete", PARATESTFILE); + AddTest("idsetw", dataset_writeInd, NULL, "dataset independent write", PARATESTFILE); AddTest("idsetr", dataset_readInd, NULL, "dataset independent read", PARATESTFILE); diff --git a/testpar/testphdf5.h b/testpar/testphdf5.h index d1469df..56b966d 100644 --- a/testpar/testphdf5.h +++ b/testpar/testphdf5.h @@ -237,6 +237,7 @@ extern int dxfer_coll_type; void test_plist_ed(void); void zero_dim_dset(void); void test_file_properties(void); +void test_delete(void); void multiple_dset_write(void); void multiple_group_write(void); void multiple_group_read(void); diff --git a/tools/src/misc/CMakeLists.txt b/tools/src/misc/CMakeLists.txt index ea30c98..8811f97 100644 --- a/tools/src/misc/CMakeLists.txt +++ b/tools/src/misc/CMakeLists.txt @@ -38,11 +38,20 @@ if (NOT ONLY_SHARED_LIBS) set_target_properties (h5clear PROPERTIES FOLDER tools) set_global_variable (HDF5_UTILS_TO_EXPORT "${HDF5_UTILS_TO_EXPORT};h5clear") + add_executable (h5delete ${HDF5_TOOLS_SRC_MISC_SOURCE_DIR}/h5delete.c) + target_include_directories (h5delete PRIVATE "${HDF5_TOOLS_DIR}/lib;${HDF5_SRC_DIR};${HDF5_SRC_BINARY_DIR};$<$:${MPI_C_INCLUDE_DIRS}>") + target_compile_options(h5delete PRIVATE "${HDF5_CMAKE_C_FLAGS}") + TARGET_C_PROPERTIES (h5delete STATIC) + target_link_libraries (h5delete PRIVATE ${HDF5_TOOLS_LIB_TARGET} ${HDF5_LIB_TARGET}) + set_target_properties (h5delete PROPERTIES FOLDER tools) + set_global_variable (HDF5_UTILS_TO_EXPORT "${HDF5_UTILS_TO_EXPORT};h5delete") + set (H5_DEP_EXECUTABLES h5debug h5repart h5mkgrp - h5clear + h5clear + h5delete ) endif () if (BUILD_SHARED_LIBS) @@ -78,11 +87,20 @@ if (BUILD_SHARED_LIBS) set_target_properties (h5clear-shared PROPERTIES FOLDER tools) set_global_variable (HDF5_UTILS_TO_EXPORT "${HDF5_UTILS_TO_EXPORT};h5clear-shared") + add_executable (h5delete-shared ${HDF5_TOOLS_SRC_MISC_SOURCE_DIR}/h5delete.c) + target_include_directories (h5delete-shared PRIVATE "${HDF5_TOOLS_DIR}/lib;${HDF5_SRC_DIR};${HDF5_SRC_BINARY_DIR};$<$:${MPI_C_INCLUDE_DIRS}>") + target_compile_options(h5delete-shared PRIVATE "${HDF5_CMAKE_C_FLAGS}") + TARGET_C_PROPERTIES (h5delete-shared SHARED) + target_link_libraries (h5delete-shared PRIVATE ${HDF5_TOOLS_LIBSH_TARGET} ${HDF5_LIBSH_TARGET}) + set_target_properties (h5delete-shared PROPERTIES FOLDER tools) + set_global_variable (HDF5_UTILS_TO_EXPORT "${HDF5_UTILS_TO_EXPORT};h5delete-shared") + set (H5_DEP_EXECUTABLES ${H5_DEP_EXECUTABLES} h5debug-shared h5repart-shared h5mkgrp-shared h5clear-shared + h5delete-shared ) endif () @@ -95,11 +113,13 @@ if (HDF5_ENABLE_FORMATTERS) clang_format (HDF5_H5REPART_SRC_FORMAT h5repart) clang_format (HDF5_H5MKGRP_SRC_FORMAT h5mkgrp) clang_format (HDF5_H5CLEAR_SRC_FORMAT h5clear) + clang_format (HDF5_H5DELETE_SRC_FORMAT h5delete) else () clang_format (HDF5_H5DEBUG_SRC_FORMAT h5debug-shared) clang_format (HDF5_H5REPART_SRC_FORMAT h5repart-shared) clang_format (HDF5_H5MKGRP_SRC_FORMAT h5mkgrp-shared) clang_format (HDF5_H5CLEAR_SRC_FORMAT h5clear-shared) + clang_format (HDF5_H5DELETE_SRC_FORMAT h5delete-shared) endif () endif () diff --git a/tools/src/misc/Makefile.am b/tools/src/misc/Makefile.am index e8ee947..cad13c1 100644 --- a/tools/src/misc/Makefile.am +++ b/tools/src/misc/Makefile.am @@ -22,13 +22,14 @@ include $(top_srcdir)/config/commence.am AM_CPPFLAGS+=-I$(top_srcdir)/src -I$(top_srcdir)/tools/lib # These are our main targets, the tools -bin_PROGRAMS=h5debug h5repart h5mkgrp h5clear +bin_PROGRAMS=h5debug h5repart h5mkgrp h5clear h5delete # Add h5debug, h5repart, and h5mkgrp specific linker flags here h5debug_LDFLAGS = $(LT_STATIC_EXEC) $(AM_LDFLAGS) h5repart_LDFLAGS = $(LT_STATIC_EXEC) $(AM_LDFLAGS) h5mkgrp_LDFLAGS = $(LT_STATIC_EXEC) $(AM_LDFLAGS) h5clear_LDFLAGS = $(LT_STATIC_EXEC) $(AM_LDFLAGS) +h5delete_LDFLAGS = $(LT_STATIC_EXEC) $(AM_LDFLAGS) # All programs rely on hdf5 library and h5tools library LDADD=$(LIBH5TOOLS) $(LIBHDF5) diff --git a/tools/src/misc/h5delete.c b/tools/src/misc/h5delete.c new file mode 100644 index 0000000..3c4f8d5 --- /dev/null +++ b/tools/src/misc/h5delete.c @@ -0,0 +1,66 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * 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 COPYING file, which can be found at the root of the source code * + * distribution tree, or in https://www.hdfgroup.org/licenses. * + * If you do not have access to either file, you may request a copy from * + * help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* h5delete tool + * + * Deletes storage via H5Fdelete() using the VOL connector specified in the + * environment variable. + */ + +#include "H5private.h" +#include "H5Eprivate.h" +#include "H5Pprivate.h" + +static void usage(void); + +static void +usage(void) +{ + HDfprintf(stderr, "Usage: h5delete [-f] \n"); +} + +int +main(int argc, const char *argv[]) +{ + hbool_t quiet = FALSE; + const char *name = NULL; + int ret = 0; + + switch (argc) { + case 3: + if (HDstrcmp(argv[1], "-f") != 0) { + usage(); + return EXIT_FAILURE; + } + quiet = TRUE; + name = argv[2]; + break; + case 2: + name = argv[1]; + break; + default: + usage(); + return EXIT_FAILURE; + } + + H5E_BEGIN_TRY + { + /* Only uses the environment variable at this time */ + ret = (int)H5Fdelete(name, H5P_DEFAULT); + } + H5E_END_TRY; + + if (ret < 0 && !quiet) + HDfprintf(stderr, "Unable to delete storage at: %s\n", name); + + return ret < 0 ? EXIT_FAILURE : EXIT_SUCCESS; +} diff --git a/tools/src/misc/h5repart.c b/tools/src/misc/h5repart.c index e3f00af..f4cef6a 100644 --- a/tools/src/misc/h5repart.c +++ b/tools/src/misc/h5repart.c @@ -12,7 +12,7 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* - * Programmer: Robb Matzke + * Programmer: Robb Matzke * Wednesday, May 13, 1998 * * Purpose: Repartitions a file family. This program can be used to @@ -64,10 +64,10 @@ usage(const char *progname) "(windows or sec2)\n"); HDfprintf(stderr, " SRC The name of the source file\n"); HDfprintf(stderr, " DST The name of the destination files\n"); - HDfprintf(stderr, "Sizes may be suffixed with `g' for GB, `m' for MB or " - "`k' for kB.\n"); + HDfprintf(stderr, "Sizes may be suffixed with 'g' for GB, 'm' for MB or " + "'k' for kB.\n"); HDfprintf(stderr, "File family names include an integer printf " - "format such as `%%d'\n"); + "format such as '%%d'\n"); HDexit(EXIT_FAILURE); } @@ -97,7 +97,7 @@ static off_t get_size(const char *progname, int *argno, int argc, char *argv[]) { off_t retval = -1; - char *suffix; + char *suffix = NULL; if (isdigit((int)(argv[*argno][2]))) { retval = HDstrtol(argv[*argno] + 2, &suffix, 10); -- cgit v0.12