Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Renamed Attribute in dense storage can't be deleted #1388

Closed
kmuehlbauer opened this issue Jan 25, 2022 · 5 comments
Closed

Renamed Attribute in dense storage can't be deleted #1388

kmuehlbauer opened this issue Jan 25, 2022 · 5 comments
Assignees
Labels
Component - C Library Core C library issues (usually in the src directory) Priority - 1. High 🔼 These are important issues that should be resolved in the next release Type - Bug Please report security issues to help@hdfgroup.org instead of creating an issue on GitHub

Comments

@kmuehlbauer
Copy link

kmuehlbauer commented Jan 25, 2022

If I add

    /* Delete last attribute */
    ret = H5Adelete(dataset, attrname);
    CHECK(ret, FAIL, "H5Adelete");

before Dataset close in this test file, the Attribute can't be deleted. This could be another manifestation of https://forum.hdfgroup.org/t/bug-h5arename-fails-unexpectedly/4881

hdf5/test/tattr.c

Lines 2807 to 2810 in 4d45d05

/* Close Dataset */
ret = H5Dclose(dataset);
CHECK(ret, FAIL, "H5Dclose");

More context:

  • creation order tracking enabled
  • attributes which are created in dense storage can be renamed since this fix 4e05249
  • renamed attributes can't be deleted anymore
  • attributes which are not renamed, can be deleted

Conclusion:

Something is going wrong in H5A__dense_rename. The above fix was introduced by @vchoi-hdfgroup, so maybe @vchoi-hdfgroup can give some insight here?

hdf5/src/H5Adense.c

Lines 858 to 1027 in 4d45d05

*/
herr_t
H5A__dense_rename(H5F_t *f, const H5O_ainfo_t *ainfo, const char *old_name, const char *new_name)
{
H5A_bt2_ud_common_t udata; /* User data for v2 B-tree modify */
H5HF_t * fheap = NULL; /* Fractal heap handle */
H5HF_t * shared_fheap = NULL; /* Fractal heap handle for shared header messages */
H5B2_t * bt2_name = NULL; /* v2 B-tree handle for name index */
H5B2_t * bt2_corder = NULL; /* v2 B-tree handle for creation order ndex */
H5A_t * attr_copy = NULL; /* Copy of attribute to rename */
htri_t attr_sharable; /* Flag indicating attributes are shareable */
htri_t shared_mesg; /* Should this message be stored in the Shared Message table? */
hbool_t attr_exists; /* Attribute exists in v2 B-tree */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_PACKAGE
/* Check arguments */
HDassert(f);
HDassert(ainfo);
HDassert(old_name);
HDassert(new_name);
/* Check if attributes are shared in this file */
if ((attr_sharable = H5SM_type_shared(f, H5O_ATTR_ID)) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't determine if attributes are shared")
/* Get handle for shared message heap, if attributes are shareable */
if (attr_sharable) {
haddr_t shared_fheap_addr; /* Address of fractal heap to use */
/* Retrieve the address of the shared message's fractal heap */
if (H5SM_get_fheap_addr(f, H5O_ATTR_ID, &shared_fheap_addr) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't get shared message heap address")
/* Check if there are any shared messages currently */
if (H5F_addr_defined(shared_fheap_addr)) {
/* Open the fractal heap for shared header messages */
if (NULL == (shared_fheap = H5HF_open(f, shared_fheap_addr)))
HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open fractal heap")
} /* end if */
} /* end if */
/* Open the fractal heap */
if (NULL == (fheap = H5HF_open(f, ainfo->fheap_addr)))
HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open fractal heap")
/* Open the name index v2 B-tree */
if (NULL == (bt2_name = H5B2_open(f, ainfo->name_bt2_addr, NULL)))
HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for name index")
/* Create the "udata" information for v2 B-tree record modify */
udata.f = f;
udata.fheap = fheap;
udata.shared_fheap = shared_fheap;
udata.name = old_name;
udata.name_hash = H5_checksum_lookup3(old_name, HDstrlen(old_name), 0);
udata.flags = 0;
udata.corder = 0;
udata.found_op = H5A__dense_fnd_cb; /* v2 B-tree comparison callback */
udata.found_op_data = &attr_copy;
/* Get copy of attribute through 'name' tracking v2 B-tree */
attr_exists = FALSE;
if (H5B2_find(bt2_name, &udata, &attr_exists, NULL, NULL) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_NOTFOUND, FAIL, "can't search for attribute in name index")
if (attr_exists == FALSE)
HGOTO_ERROR(H5E_ATTR, H5E_NOTFOUND, FAIL, "can't locate attribute in name index")
HDassert(attr_copy);
/* Check if message is already shared */
if ((shared_mesg = H5O_msg_is_shared(H5O_ATTR_ID, attr_copy)) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "error determining if message is shared")
else if (shared_mesg > 0) {
/* Reset shared status of copy */
/* (so it will get shared again if necessary) */
attr_copy->sh_loc.type = H5O_SHARE_TYPE_UNSHARED;
} /* end if */
/* Change name of attribute */
H5MM_xfree(attr_copy->shared->name);
attr_copy->shared->name = H5MM_xstrdup(new_name);
/* Recompute the version to encode the attribute with */
if (H5A__set_version(f, attr_copy) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, FAIL, "unable to update attribute version")
/* Need to remove the attribute from the creation order index v2 B-tree */
if (ainfo->index_corder) {
hbool_t corder_attr_exists; /* Attribute exists in v2 B-tree */
/* Open the creation order index v2 B-tree */
HDassert(H5F_addr_defined(ainfo->corder_bt2_addr));
if (NULL == (bt2_corder = H5B2_open(f, ainfo->corder_bt2_addr, NULL)))
HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for creation index")
/* Set up the creation order to search for */
udata.corder = attr_copy->shared->crt_idx;
corder_attr_exists = FALSE;
if (H5B2_find(bt2_corder, &udata, &corder_attr_exists, NULL, NULL) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_NOTFOUND, FAIL, "can't search for attribute in name index")
if (corder_attr_exists) {
H5A_bt2_ud_rm_t rm_udata;
/* Set up the creation order in user data for the v2 B-tree 'record remove' callback */
rm_udata.common.corder = attr_copy->shared->crt_idx;
/* Remove the record from the creation order index v2 B-tree */
if (H5B2_remove(bt2_corder, &rm_udata, NULL, NULL) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTREMOVE, FAIL,
"unable to remove attribute from creation order index v2 B-tree")
}
}
/* Insert renamed attribute back into dense storage */
/* (Possibly making it shared) */
if (H5A__dense_insert(f, ainfo, attr_copy) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, FAIL, "unable to add to dense storage")
/* Was this attribute shared? */
if ((shared_mesg = H5O_msg_is_shared(H5O_ATTR_ID, attr_copy)) > 0) {
hsize_t attr_rc; /* Attribute's ref count in shared message storage */
/* Retrieve ref count for shared attribute */
if (H5SM_get_refcount(f, H5O_ATTR_ID, &attr_copy->sh_loc, &attr_rc) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't retrieve shared message ref count")
/* If the newly shared attribute needs to share "ownership" of the shared
* components (ie. its reference count is 1), increment the reference
* count on any shared components of the attribute, so that they won't
* be removed from the file. (Essentially a "copy on write" operation).
*
* *ick* -QAK, 2007/01/08
*/
if (attr_rc == 1) {
/* Increment reference count on attribute components */
if (H5O__attr_link(f, NULL, attr_copy) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_LINKCOUNT, FAIL, "unable to adjust attribute link count")
} /* end if */
} /* end if */
else if (shared_mesg == 0) {
/* Increment reference count on attribute components */
/* (so that they aren't deleted when the attribute is removed shortly) */
if (H5O__attr_link(f, NULL, attr_copy) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_LINKCOUNT, FAIL, "unable to adjust attribute link count")
} /* end if */
else if (shared_mesg < 0)
HGOTO_ERROR(H5E_ATTR, H5E_WRITEERROR, FAIL, "error determining if message should be shared")
/* Delete old attribute from dense storage */
if (H5A__dense_remove(f, ainfo, old_name) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTDELETE, FAIL, "unable to delete attribute in dense storage")
done:
/* Release resources */
if (shared_fheap && H5HF_close(shared_fheap) < 0)
HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close fractal heap")
if (fheap && H5HF_close(fheap) < 0)
HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close fractal heap")
if (bt2_name && H5B2_close(bt2_name) < 0)
HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close v2 B-tree for name index")
if (bt2_corder && H5B2_close(bt2_corder) < 0)
HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close v2 B-tree for creation order index")
if (attr_copy)
H5O_msg_free(H5O_ATTR_ID, attr_copy);
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5A__dense_rename() */

@kmuehlbauer
Copy link
Author

I've added a possible fix to #1389. The testsuite runs smoothly, and downstream works nicely too.

@epourmal
Copy link

Thank you for the proposed fix. We will be reviewing it shortly.

@kmuehlbauer
Copy link
Author

@epourmal Thanks for the heads-up.

@kmuehlbauer kmuehlbauer changed the title Renamed Attribute in dense storage can't be deleted [BUG] Renamed Attribute in dense storage can't be deleted Jan 12, 2023
@kmuehlbauer
Copy link
Author

#1389 doesn't solve the problem and I'm not able to fix this. I'd very much appreciate if HDF5 group could prioritize here to find some working solution for this annoying issue. At least a time line would be good.

HDFFV-10579

Downstream we constantly get bug reports which can be tracked to this very bug:

h5netcdf

h5py

other

Downstream already tried to workaround that issue, but finally the problem is only shifted to a later point in hdf5-file lifetime.

C-Examples showing the problem can be found here and there.

Beside that issue, thanks for providing such a great library! 💯 👍

@derobins derobins changed the title [BUG] Renamed Attribute in dense storage can't be deleted Renamed Attribute in dense storage can't be deleted May 4, 2023
@derobins derobins added Priority - 1. High 🔼 These are important issues that should be resolved in the next release Component - C Library Core C library issues (usually in the src directory) Type - Bug Please report security issues to help@hdfgroup.org instead of creating an issue on GitHub labels May 4, 2023
vchoi-hdfgroup added a commit to vchoi-hdfgroup/hdf5 that referenced this issue May 3, 2024
…ute with corder tracking enabled

The problem occurs in step 3(b) below which will delete the attribute with corder x
from the creation order index v2 B-tree.

The rename sequence in H5A__dense_rename() occurs in the following order:
1) The old attribute with corder x was removed from the creation order index v2 B-tree
2) The new renamed attribute was inserted via H5A__dense_insert():
(a) insert the attribute with new name j into the name index v2 B-tree
(b) insert the attribute with corder x into the creation order index v2 B-tree
3) The old attribute was removed via H5A__dense_remove():
(a) remove the attribute with old name k from the name index v2 B-tree
(b) remove the attribute with coorder x from the creation order index v2 B-tree

Fix: deactivate the "corder_bt2_addr" field so that H5A__dense_remove()
won't delete the attribute with corder x from the creation order index v2 B-tree.
lrknox pushed a commit that referenced this issue May 17, 2024
…corder tracking enabled (#4462)

* Fix for github issue #1388: can't delete renamed dense attribute with corder tracking enabled

The problem occurs in step 3(b) below which will delete the attribute with corder x
from the creation order index v2 B-tree.

The rename sequence in H5A__dense_rename() occurs in the following order:
1) The old attribute with corder x was removed from the creation order index v2 B-tree
2) The new renamed attribute was inserted via H5A__dense_insert():
(a) insert the attribute with new name j into the name index v2 B-tree
(b) insert the attribute with corder x into the creation order index v2 B-tree
3) The old attribute was removed via H5A__dense_remove():
(a) remove the attribute with old name k from the name index v2 B-tree
(b) remove the attribute with coorder x from the creation order index v2 B-tree

Fix: deactivate the "corder_bt2_addr" field so that H5A__dense_remove()
won't delete the attribute with corder x from the creation order index v2 B-tree.
@kmuehlbauer
Copy link
Author

kmuehlbauer commented May 17, 2024

Great! Thank you very much all involved at HDFGroup for fixing this issue. 🎉 🚀

lrknox pushed a commit to lrknox/hdf5 that referenced this issue May 20, 2024
…te with corder tracking enabled (HDFGroup#4462)

* Fix for github issue HDFGroup#1388: can't delete renamed dense attribute with corder tracking enabled

The problem occurs in step 3(b) below which will delete the attribute with corder x
from the creation order index v2 B-tree.

The rename sequence in H5A__dense_rename() occurs in the following order:
1) The old attribute with corder x was removed from the creation order index v2 B-tree
2) The new renamed attribute was inserted via H5A__dense_insert():
(a) insert the attribute with new name j into the name index v2 B-tree
(b) insert the attribute with corder x into the creation order index v2 B-tree
3) The old attribute was removed via H5A__dense_remove():
(a) remove the attribute with old name k from the name index v2 B-tree
(b) remove the attribute with coorder x from the creation order index v2 B-tree

Fix: deactivate the "corder_bt2_addr" field so that H5A__dense_remove()
won't delete the attribute with corder x from the creation order index v2 B-tree.
lrknox added a commit that referenced this issue May 23, 2024
* win32defs: Fix Wundef warning (#4467)

* Refactor error handling code to eliminate internal ID calls (#4453)

All calls to the H5I routines are now made in API routines (sometimes in
FUNC_ENTER/LEAVE_* macros), except for some calls to H5E_clear_stack() within
the library, but I'm planning to remove those over time.

Also, made all the library internal error messages into static const variables,
instead of malloc'ing them, which means that they can just be referenced
and not copied.

Several new and updated auto-generated header files were necessary to enable
this.

* CMake: Fix mingw/fortran build (#4466)

* Update for blosc2 in plugins and prefix hdf5 cmake varnames (#4468)

* Fix an issue where compound datatype member IDs can be leaked during conversion (#4459)

Also fixes issues with handling of partially initialized datatypes during library shutdown

* H5Group: Fix operator= (#4473)

Closes #4472

* Fix github issue #2523: doxygen -- fix grammatically incorrect sentence alias (#4474)

* Remove env step not used by CI in testing (#4476)

* Add H5fortkit dependecy for H5Rff.F90 (#4482)

* Properly clean up cache when failing to load an object header (#4477)

* Properly clean up cache when failing to load an object header

* Don't check message type a second time in H5G__open_oid if the first attempt returns error

* Add more asserts to H5O__assert() to avoid segfaults

---------

Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>

* Add a missing image from the original document (#4490)

* Disable EOF checks for SWMR readers in more cases. (#4489)

Fixes a race condition where the reader opens the file and sets its EOF from the
file's size (from the stat() call in the driver open callback).  Then, before
the reader can read the file's superblock, a SWMR writer races in, extends the
file, and closes the file, writing an updated superblock with the 'writer' and
'SWMR writer' flags in the superblock off (appropriately).  Then the reader
proceeds to read the superblock, and flags the EOF as wrong.  Taking out the
check for the 'writer' and 'SWMR writer' flags will cause SWMR readers to avoid
flagging the file as incorrect.

* Remove unnecessary fortran install (#4498)

* Only one version of binaries is produced for platforms (#4496)

* Fix for github issue #2220. (#4497)

Document the limitation in the Passthrough Conncector section of the VOL Connector Author Guide.
The limitation is posted by Neil in the github issue on Dec 22, 2022.

* Release asset tarballs with no version filenames (#4494)

* Improve spec. reading superblock into cache (a little) by using v2 size (#4491)

* Improve spec. reading superblock into cache (a little) by using v2 size

Instead of reading the absolute minimal possible, use the likely value of
a v2+ superblock w/8-byte addresses & lengths.

* Fix for github Issue #1388 can't delete renamed dense attribute with corder tracking enabled (#4462)

* Fix for github issue #1388: can't delete renamed dense attribute with corder tracking enabled

The problem occurs in step 3(b) below which will delete the attribute with corder x
from the creation order index v2 B-tree.

The rename sequence in H5A__dense_rename() occurs in the following order:
1) The old attribute with corder x was removed from the creation order index v2 B-tree
2) The new renamed attribute was inserted via H5A__dense_insert():
(a) insert the attribute with new name j into the name index v2 B-tree
(b) insert the attribute with corder x into the creation order index v2 B-tree
3) The old attribute was removed via H5A__dense_remove():
(a) remove the attribute with old name k from the name index v2 B-tree
(b) remove the attribute with coorder x from the creation order index v2 B-tree

Fix: deactivate the "corder_bt2_addr" field so that H5A__dense_remove()
won't delete the attribute with corder x from the creation order index v2 B-tree.

* Fix/revert a libtool sed hack (#4501)

* Revert "Remove Autotools sed hack (#3848)"

This reverts commit 8b3ffde.

* Fix libtool sed cleanup on MacOS

Convert sed -i line to sed > libtool.bak && mv libtool.bak libtool
to avoid non-portable -i option.

* Update src/H5public.h

* Set H5 specific vars immediately if legacy find (#4512)

* Correct find process vars (vs in-line build)

* Correct SZIP find

* Everything is libaec 1.0.6 or newer

* Correct option help text
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Component - C Library Core C library issues (usually in the src directory) Priority - 1. High 🔼 These are important issues that should be resolved in the next release Type - Bug Please report security issues to help@hdfgroup.org instead of creating an issue on GitHub
Projects
None yet
Development

No branches or pull requests

4 participants