diff --git a/src/H5FD.c b/src/H5FD.c index 11cbdc4868c..f6dae0ddbd4 100644 --- a/src/H5FD.c +++ b/src/H5FD.c @@ -1886,3 +1886,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 3bb95f724ec..dba3d46d696 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 */ H5FD_FLMAP_DICHOTOMY /* fl_map */ }; @@ -1708,3 +1710,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 35da1f17f76..a1b7b7e9248 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 */ H5FD_FLMAP_DICHOTOMY /* fl_map */ }; @@ -1380,4 +1382,29 @@ H5FD__direct_unlock(H5FD_t *_file) 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 adfa1a31aa7..2f18016d160 100644 --- a/src/H5FDfamily.c +++ b/src/H5FDfamily.c @@ -101,40 +101,42 @@ 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 = { - "family", /* name */ - HADDR_MAX, /* maxaddr */ - H5F_CLOSE_WEAK, /* fc_degree */ + "family", /* name */ + HADDR_MAX, /* maxaddr */ + H5F_CLOSE_WEAK, /* fc_degree */ H5FD__family_term, /* terminate */ - H5FD__family_sb_size, /* sb_size */ - H5FD__family_sb_encode, /* sb_encode */ - H5FD__family_sb_decode, /* sb_decode */ - sizeof(H5FD_family_fapl_t), /* fapl_size */ - H5FD__family_fapl_get, /* fapl_get */ - H5FD__family_fapl_copy, /* fapl_copy */ - H5FD__family_fapl_free, /* fapl_free */ - 0, /* dxpl_size */ - NULL, /* dxpl_copy */ - NULL, /* dxpl_free */ - H5FD__family_open, /* open */ - H5FD__family_close, /* close */ - H5FD__family_cmp, /* cmp */ - H5FD__family_query, /* query */ - NULL, /* get_type_map */ - NULL, /* alloc */ - NULL, /* free */ - H5FD__family_get_eoa, /* get_eoa */ - H5FD__family_set_eoa, /* set_eoa */ - H5FD__family_get_eof, /* get_eof */ + H5FD__family_sb_size, /* sb_size */ + H5FD__family_sb_encode, /* sb_encode */ + H5FD__family_sb_decode, /* sb_decode */ + sizeof(H5FD_family_fapl_t), /* fapl_size */ + H5FD__family_fapl_get, /* fapl_get */ + H5FD__family_fapl_copy, /* fapl_copy */ + H5FD__family_fapl_free, /* fapl_free */ + 0, /* dxpl_size */ + NULL, /* dxpl_copy */ + NULL, /* dxpl_free */ + H5FD__family_open, /* open */ + H5FD__family_close, /* close */ + H5FD__family_cmp, /* cmp */ + H5FD__family_query, /* query */ + NULL, /* get_type_map */ + NULL, /* alloc */ + NULL, /* free */ + H5FD__family_get_eoa, /* get_eoa */ + H5FD__family_set_eoa, /* set_eoa */ + H5FD__family_get_eof, /* get_eof */ H5FD__family_get_handle, /* get_handle */ - H5FD__family_read, /* read */ - H5FD__family_write, /* write */ - H5FD__family_flush, /* flush */ - H5FD__family_truncate, /* truncate */ + H5FD__family_read, /* read */ + H5FD__family_write, /* write */ + H5FD__family_flush, /* flush */ + H5FD__family_truncate, /* truncate */ H5FD__family_lock, /* lock */ H5FD__family_unlock, /* unlock */ + H5FD__family_delete, /* del */ H5FD_FLMAP_DICHOTOMY /* fl_map */ }; @@ -1343,3 +1345,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/H5FDint.c b/src/H5FDint.c index 25d77d174e1..f13f2229e5f 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 aa2d6db5dd3..94762c15ea1 100644 --- a/src/H5FDlog.c +++ b/src/H5FDlog.c @@ -177,40 +177,42 @@ 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 */ - MAXADDR, /* maxaddr */ - H5F_CLOSE_WEAK, /* fc_degree */ - H5FD__log_term, /* terminate */ - NULL, /* sb_size */ - NULL, /* sb_encode */ - NULL, /* sb_decode */ - sizeof(H5FD_log_fapl_t), /* fapl_size */ - H5FD__log_fapl_get, /* fapl_get */ - H5FD__log_fapl_copy, /* fapl_copy */ - H5FD__log_fapl_free, /* fapl_free */ - 0, /* dxpl_size */ - NULL, /* dxpl_copy */ - NULL, /* dxpl_free */ - H5FD__log_open, /* open */ - H5FD__log_close, /* close */ - H5FD__log_cmp, /* cmp */ - H5FD__log_query, /* query */ - NULL, /* get_type_map */ - H5FD__log_alloc, /* alloc */ - H5FD__log_free, /* free */ - H5FD__log_get_eoa, /* get_eoa */ - H5FD__log_set_eoa, /* set_eoa */ - H5FD__log_get_eof, /* get_eof */ - H5FD__log_get_handle, /* get_handle */ - H5FD__log_read, /* read */ - H5FD__log_write, /* write */ - NULL, /* flush */ - H5FD__log_truncate, /* truncate */ - H5FD__log_lock, /* lock */ - H5FD__log_unlock, /* unlock */ - H5FD_FLMAP_DICHOTOMY /* fl_map */ + "log", /* name */ + MAXADDR, /* maxaddr */ + H5F_CLOSE_WEAK, /* fc_degree */ + H5FD__log_term, /* terminate */ + NULL, /* sb_size */ + NULL, /* sb_encode */ + NULL, /* sb_decode */ + sizeof(H5FD_log_fapl_t), /* fapl_size */ + H5FD__log_fapl_get, /* fapl_get */ + H5FD__log_fapl_copy, /* fapl_copy */ + H5FD__log_fapl_free, /* fapl_free */ + 0, /* dxpl_size */ + NULL, /* dxpl_copy */ + NULL, /* dxpl_free */ + H5FD__log_open, /* open */ + H5FD__log_close, /* close */ + H5FD__log_cmp, /* cmp */ + H5FD__log_query, /* query */ + NULL, /* get_type_map */ + H5FD__log_alloc, /* alloc */ + H5FD__log_free, /* free */ + H5FD__log_get_eoa, /* get_eoa */ + H5FD__log_set_eoa, /* set_eoa */ + H5FD__log_get_eof, /* get_eof */ + H5FD__log_get_handle, /* get_handle */ + H5FD__log_read, /* read */ + H5FD__log_write, /* write */ + NULL, /* flush */ + H5FD__log_truncate, /* truncate */ + H5FD__log_lock, /* lock */ + H5FD__log_unlock, /* unlock */ + H5FD__log_delete, /* del */ + H5FD_FLMAP_DICHOTOMY /* fl_map */ }; /* Declare a free list to manage the H5FD_log_t struct */ @@ -1772,3 +1774,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 f604eaf6dd3..79ee0e18a27 100644 --- a/src/H5FDmirror.c +++ b/src/H5FDmirror.c @@ -191,6 +191,7 @@ static const H5FD_class_t H5FD_mirror_g = { H5FD__mirror_truncate, /* truncate */ H5FD__mirror_lock, /* lock */ H5FD__mirror_unlock, /* unlock */ + NULL, /* del */ H5FD_FLMAP_DICHOTOMY /* fl_map */ }; diff --git a/src/H5FDmpio.c b/src/H5FDmpio.c index c0b14ce3b6a..a42f19d47ad 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,42 +95,43 @@ 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 */ - 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 */ + 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 @@ -1741,6 +1743,60 @@ H5FD__mpio_truncate(H5FD_t *_file, hid_t H5_ATTR_UNUSED dxpl_id, hbool_t H5_ATTR FUNC_LEAVE_NOAPI(ret_value) } /* 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 * diff --git a/src/H5FDmulti.c b/src/H5FDmulti.c index 168bbe162eb..9ba7c0ba134 100644 --- a/src/H5FDmulti.c +++ b/src/H5FDmulti.c @@ -134,41 +134,43 @@ 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 */ - 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 */ + H5FD_FLMAP_DEFAULT /* fl_map */ }; /*------------------------------------------------------------------------- @@ -1972,8 +1974,8 @@ compute_next(H5FD_multi_t *file) * *------------------------------------------------------------------------- */ -/* Disable warning for "format not a string literal" here -QAK */ -/* +/* Disable warning for "format not a string literal" here + * * This pragma only needs to surround the snprintf() call with * tmp in the code below, but early (4.4.7, at least) gcc only * allows diagnostic pragmas to be toggled outside of functions. @@ -1984,7 +1986,8 @@ open_members(H5FD_multi_t *file) { char tmp[H5FD_MULT_MAX_FILE_NAME_LEN]; int nerrors = 0; - static const char *func = "(H5FD_multi)open_members"; /* Function Name for error reporting */ + int nchars; + static const char *func = "(H5FD_multi)open_members"; /* Function Name for error reporting */ /* Clear the error stack */ H5Eclear2(H5E_DEFAULT); @@ -1993,11 +1996,11 @@ open_members(H5FD_multi_t *file) if (file->memb[mt]) continue; /*already open*/ assert(file->fa.memb_name[mt]); - /* Note: This truncates the user's filename down to only sizeof(tmp) - * characters. -QK & JK, 2013/01/17 - */ - sprintf(tmp, file->fa.memb_name[mt], file->name); - tmp[sizeof(tmp) - 1] = '\0'; + + nchars = snprintf(tmp, sizeof(tmp), file->fa.memb_name[mt], file->name); + if (nchars < 0 || nchars >= (int)sizeof(tmp)) + H5Epush_ret(func, H5E_ERR_CLS, H5E_VFL, H5E_BADVALUE, + "filename is too long and would be truncated", -1); H5E_BEGIN_TRY { @@ -2015,6 +2018,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 10d8069fa10..6dfb7b42318 100644 --- a/src/H5FDprivate.h +++ b/src/H5FDprivate.h @@ -135,6 +135,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 edcea527dee..0fcfcf373c9 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_mem_t fl_map[H5FD_MEM_NTYPES]; } H5FD_class_t; @@ -377,6 +378,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/H5FDsec2.c b/src/H5FDsec2.c index 6fe12822559..d823e3cb2b8 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,6 +172,7 @@ static const H5FD_class_t H5FD_sec2_g = { H5FD__sec2_truncate, /* truncate */ H5FD__sec2_lock, /* lock */ H5FD__sec2_unlock, /* unlock */ + H5FD__sec2_delete, /* del */ H5FD_FLMAP_DICHOTOMY /* fl_map */ }; @@ -1041,3 +1043,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 93ba154217d..649dce4dc3b 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 */ H5FD_FLMAP_DICHOTOMY /* fl_map */ }; diff --git a/src/H5FDstdio.c b/src/H5FDstdio.c index 3d0332fcc54..663132509f1 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 */ H5FD_FLMAP_DICHOTOMY /* fl_map */ }; @@ -1200,6 +1202,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/H5Fint.c b/src/H5Fint.c index a8039b2e853..41980922502 100644 --- a/src/H5Fint.c +++ b/src/H5Fint.c @@ -2352,6 +2352,31 @@ H5F__close(H5F_t *f) FUNC_LEAVE_NOAPI(ret_value) } /* 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 * diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h index 5c5937b038a..7044835b686 100644 --- a/src/H5Fprivate.h +++ b/src/H5Fprivate.h @@ -830,6 +830,7 @@ H5_DLL herr_t H5F_init(void); H5_DLL H5F_t *H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id); H5_DLL herr_t H5F_try_close(H5F_t *f, hbool_t *was_closed /*out*/); H5_DLL hid_t H5F_get_file_id(H5VL_object_t *vol_obj, H5I_type_t obj_type, hbool_t app_ref); +H5_DLL herr_t H5F_delete(const char *filename, hid_t fapl_id); /* Functions that retrieve values from the file struct */ H5_DLL H5F_libver_t H5F_get_low_bound(const H5F_t *f); diff --git a/src/H5VLnative_file.c b/src/H5VLnative_file.c index a2dd0582ea3..690b6dee4b7 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/cache_logging.c b/test/cache_logging.c index 448e12b1fcc..93d450511d1 100644 --- a/test/cache_logging.c +++ b/test/cache_logging.c @@ -16,7 +16,8 @@ #include "h5test.h" #define LOG_LOCATION "cache_logging.out" -#define FILE_NAME "cache_logging" + +const char *FILENAME[] = {"cache_logging", NULL}; #define N_GROUPS 100 @@ -50,7 +51,7 @@ test_logging_api(void) TESTING("metadata cache log api calls"); fapl = h5_fileaccess(); - h5_fixname(FILE_NAME, fapl, filename, sizeof filename); + h5_fixname(FILENAME[0], fapl, filename, sizeof filename); /* Set up metadata cache logging */ is_enabled = TRUE; @@ -84,8 +85,6 @@ test_logging_api(void) TEST_ERROR; if ((fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR; - if (H5Pclose(fapl) < 0) - TEST_ERROR; /* Check to see if the logging flags were set correctly */ is_enabled = FALSE; @@ -127,10 +126,19 @@ test_logging_api(void) if (H5Fclose(fid) < 0) TEST_ERROR; + HDremove(LOG_LOCATION); + h5_clean_files(FILENAME, fapl); + PASSED(); return 0; error: + H5E_BEGIN_TRY + { + H5Pclose(fapl); + } + H5E_END_TRY + return 1; } /* test_logging_api() */ diff --git a/test/h5test.c b/test/h5test.c index b37409acf64..6999f1cfdaf 100644 --- a/test/h5test.c +++ b/test/h5test.c @@ -189,65 +189,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; } /* end h5_delete_test_file() */ -H5_GCC_DIAG_ON("format-nonliteral") /*------------------------------------------------------------------------- * Function: h5_delete_all_test_files @@ -1962,6 +1919,7 @@ static const H5FD_class_t H5FD_dummy_g = { NULL, /* truncate */ NULL, /* lock */ NULL, /* unlock */ + NULL, /* del */ H5FD_FLMAP_DICHOTOMY /* fl_map */ }; diff --git a/test/tfile.c b/test/tfile.c index 796a99b8819..0df78583f52 100644 --- a/test/tfile.c +++ b/test/tfile.c @@ -1918,10 +1918,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)); @@ -1937,19 +1933,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 f129c5d3e9b..6b851a271fe 100644 --- a/test/vfd.c +++ b/test/vfd.c @@ -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; diff --git a/testpar/t_file.c b/testpar/t_file.c index 8bef7ae8eed..b3a3d2c4f0f 100644 --- a/testpar/t_file.c +++ b/testpar/t_file.c @@ -948,3 +948,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 e24e1e43923..1ead1b826ae 100644 --- a/testpar/testphdf5.c +++ b/testpar/testphdf5.c @@ -350,6 +350,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 007fac062fa..10e30272974 100644 --- a/testpar/testphdf5.h +++ b/testpar/testphdf5.h @@ -236,6 +236,7 @@ void test_plist_ed(void); void external_links(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);