Skip to content

Commit 41baf43

Browse files
committed
Merge branch 'format-compat-on-reopen' of https://github.com/Dave-Allured/netcdf-c into Dave-Allured-format-compat-on-reopen
2 parents 9b5e662 + 158f290 commit 41baf43

6 files changed

+129
-39
lines changed

include/hdf5internal.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Copyright 2018-2018 University Corporation for Atmospheric
1+
/* Copyright 2018-2022 University Corporation for Atmospheric
22
Research/Unidata. */
33
/**
44
* @file This header file contains macros, types, and prototypes for
@@ -216,4 +216,6 @@ extern int nc4_find_default_chunksizes2(NC_GRP_INFO_T *grp, NC_VAR_INFO_T *var);
216216
EXTERNL hid_t nc4_H5Fopen(const char *filename, unsigned flags, hid_t fapl_id);
217217
EXTERNL hid_t nc4_H5Fcreate(const char *filename, unsigned flags, hid_t fcpl_id, hid_t fapl_id);
218218

219+
int hdf5set_format_compatibility(hid_t fapl_id);
220+
219221
#endif /* _HDF5INTERNAL_ */

libhdf5/CMakeLists.txt

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
## This is a CMake file, part of Unidata's netCDF package.
2-
# Copyright 2018, see the COPYRIGHT file for more information.
2+
# Copyright 2018-2022, see the COPYRIGHT file for more information.
33
#
44
# This builds the HDF5 dispatch layer.
55
#
@@ -9,13 +9,13 @@
99
SET(libnchdf5_SOURCES nc4hdf.c nc4info.c hdf5file.c hdf5attr.c
1010
hdf5dim.c hdf5grp.c hdf5type.c hdf5internal.c hdf5create.c hdf5open.c
1111
hdf5var.c nc4mem.c nc4memcb.c hdf5dispatch.c hdf5filter.c
12-
hdf5debug.c)
12+
hdf5set_format_compatibility.c hdf5debug.c)
1313

1414
IF(ENABLE_BYTERANGE)
1515
SET(libnchdf5_SOURCES ${libnchdf5_SOURCES} H5FDhttp.c)
1616
ENDIF()
1717

18-
# Build the HDF4 dispatch layer as a library that will be included in
18+
# Build the HDF5 dispatch layer as a library that will be included in
1919
# the netCDF library.
2020
add_library(netcdfhdf5 OBJECT ${libnchdf5_SOURCES})
2121

libhdf5/Makefile.am

+3-8
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
# This is part of Unidata's netCDF package. Copyright 2018, see the
2-
# COPYRIGHT file for more information.
1+
# This is part of Unidata's netCDF package. Copyright 2018-2022,
2+
# see the COPYRIGHT file for more information.
33

44
# Build the HDF5 dispatch layer.
55

@@ -16,16 +16,11 @@ noinst_LTLIBRARIES = libnchdf5.la
1616
libnchdf5_la_SOURCES = nc4hdf.c nc4info.c hdf5file.c hdf5attr.c \
1717
hdf5dim.c hdf5grp.c hdf5type.c hdf5internal.c hdf5create.c hdf5open.c \
1818
hdf5var.c nc4mem.c nc4memcb.c hdf5dispatch.c hdf5filter.c \
19-
hdf5debug.c hdf5debug.h hdf5err.h
19+
hdf5set_format_compatibility.c hdf5debug.c hdf5debug.h hdf5err.h
2020

2121
if ENABLE_BYTERANGE
2222
libnchdf5_la_SOURCES += H5FDhttp.c H5FDhttp.h
2323
endif
2424

2525
# Package this for cmake build.
2626
EXTRA_DIST = CMakeLists.txt
27-
28-
29-
30-
31-

libhdf5/hdf5create.c

+16-23
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Copyright 2003-2018, University Corporation for Atmospheric
1+
/* Copyright 2003-2022, University Corporation for Atmospheric
22
* Research. See COPYRIGHT file for copying and redistribution
33
* conditions. */
44
/**
@@ -117,18 +117,19 @@ nc4_create_file(const char *path, int cmode, size_t initialsz,
117117
}
118118
}
119119

120-
/* Need this access plist to control how HDF5 handles open objects
121-
* on file close. (Setting H5F_CLOSE_WEAK will cause H5Fclose not to
122-
* fail if there are any open objects in the file. This may happen when virtual
120+
/* Need this FILE ACCESS plist to control how HDF5 handles open
121+
* objects on file close; as well as for other controls below.
122+
* (Setting H5F_CLOSE_WEAK will cause H5Fclose not to fail if there
123+
* are any open objects in the file. This may happen when virtual
123124
* datasets are opened). */
124125
if ((fapl_id = H5Pcreate(H5P_FILE_ACCESS)) < 0)
125126
BAIL(NC_EHDFERR);
126127
if (H5Pset_fclose_degree(fapl_id, H5F_CLOSE_WEAK))
127128
BAIL(NC_EHDFERR);
128129

129130
#ifdef USE_PARALLEL4
130-
/* If this is a parallel file create, set up the file creation
131-
property list. */
131+
/* If this is a parallel file create, set up the file access
132+
property list for MPI/IO. */
132133
if (mpiinfo != NULL) {
133134
nc4_info->parallel = NC_TRUE;
134135
LOG((4, "creating parallel file with MPI/IO"));
@@ -164,31 +165,23 @@ nc4_create_file(const char *path, int cmode, size_t initialsz,
164165
nc4_chunk_cache_preemption));
165166
}
166167

167-
#if H5_VERSION_GE(1,10,2)
168-
/* lib versions 1.10.2 and higher */
169-
if (H5Pset_libver_bounds(fapl_id, H5F_LIBVER_V18, H5F_LIBVER_LATEST) < 0)
170-
#else
171-
#if H5_VERSION_GE(1,10,0)
172-
/* lib versions 1.10.0, 1.10.1 */
173-
if (H5Pset_libver_bounds(fapl_id, H5F_LIBVER_EARLIEST, H5F_LIBVER_LATEST) < 0)
174-
#else
175-
/* all HDF5 1.8 lib versions */
176-
if (H5Pset_libver_bounds(fapl_id, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST) < 0)
177-
#endif
178-
#endif
179-
BAIL(NC_EHDFERR);
168+
/* Set HDF5 format compatibility in the FILE ACCESS property list.
169+
* Compatibility is transient and must be reselected every time
170+
* a file is opened for writing. */
171+
retval = hdf5set_format_compatibility(fapl_id);
172+
if (retval != NC_NOERR)
173+
BAIL(retval);
180174

181-
/* Create the property list. */
175+
/* Begin setup for the FILE CREATION property list. */
182176
if ((fcpl_id = H5Pcreate(H5P_FILE_CREATE)) < 0)
183177
BAIL(NC_EHDFERR);
184178

185179
/* RJ: this suppose to be FALSE that is defined in H5 private.h as 0 */
186180
if (H5Pset_obj_track_times(fcpl_id,0)<0)
187181
BAIL(NC_EHDFERR);
188182

189-
/* Set latest_format in access propertly list and
190-
* H5P_CRT_ORDER_TRACKED in the creation property list. This turns
191-
* on HDF5 creation ordering. */
183+
/* Set H5P_CRT_ORDER_TRACKED in the creation property list.
184+
* This turns on HDF5 creation ordering. */
192185
if (H5Pset_link_creation_order(fcpl_id, (H5P_CRT_ORDER_TRACKED |
193186
H5P_CRT_ORDER_INDEXED)) < 0)
194187
BAIL(NC_EHDFERR);

libhdf5/hdf5open.c

+12-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Copyright 2003-2018, University Corporation for Atmospheric
1+
/* Copyright 2003-2022, University Corporation for Atmospheric
22
* Research. See COPYRIGHT file for copying and redistribution
33
* conditions. */
44
/**
@@ -765,9 +765,10 @@ nc4_open_file(const char *path, int mode, void* parameters, int ncid)
765765
mpiinfo = (NC_MPI_INFO *)parameters; /* assume, may be changed if inmemory is true */
766766
#endif /* !USE_PARALLEL4 */
767767

768-
/* Need this access plist to control how HDF5 handles open objects
769-
* on file close. (Setting H5F_CLOSE_WEAK will cause H5Fclose not to
770-
* fail if there are any open objects in the file. This may happen when virtual
768+
/* Need this FILE ACCESS plist to control how HDF5 handles open
769+
* objects on file close; as well as for other controls below.
770+
* (Setting H5F_CLOSE_WEAK will cause H5Fclose not to fail if there
771+
* are any open objects in the file. This may happen when virtual
771772
* datasets are opened). */
772773
if ((fapl_id = H5Pcreate(H5P_FILE_ACCESS)) < 0)
773774
BAIL(NC_EHDFERR);
@@ -820,6 +821,13 @@ nc4_open_file(const char *path, int mode, void* parameters, int ncid)
820821
nc4_chunk_cache_preemption));
821822
}
822823

824+
/* Set HDF5 format compatibility in the FILE ACCESS property list.
825+
* Compatibility is transient and must be reselected every time
826+
* a file is opened for writing. */
827+
retval = hdf5set_format_compatibility(fapl_id);
828+
if (retval != NC_NOERR)
829+
BAIL(retval);
830+
823831
/* Process NC_INMEMORY */
824832
if(nc4_info->mem.inmemory) {
825833
NC_memio* memio;
+92
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
/* Copyright 2022, University Corporation for Atmospheric Research.
2+
* See COPYRIGHT file for copying and redistribution conditions. */
3+
/**
4+
* @file
5+
* @internal This function selects the best HDF5 file format options
6+
* to create netCDF-4 files that can be read and written by older
7+
* library versions.
8+
*
9+
* Format compatibility is transient, not baked in to an HDF5 file
10+
* at creation time. Therefore the desired compatibilty options
11+
* must be selected every time a file is opened for writing.
12+
*
13+
* This function should be called before every call to create a new
14+
* netCDF-4 file, or to open an existing netCDF-4 file for writing.
15+
* This function has no effect when opening a file for read only.
16+
*
17+
* This function should work correctly with all HDF5 library versions
18+
* from 1.8.0 through 1.13.0 and beyond, with no further changes.
19+
* This assumes that HDF5 versioning controls remain consistent
20+
* into the future.
21+
*
22+
* The basic functionality is to select the traditional HDF5 v1.8
23+
* format compatibility, whenever possible. The less desirable
24+
* v1.6 compatibily is selected in a few strange cases when it is
25+
* not possible to select v1.8.
26+
*
27+
* Files created or updated with v1.10 and higher compatibility are
28+
* not legal netCDF-4 format, as of 2022 January. They are not
29+
* readable by any netCDF library version linked with any HDF5 v1.8
30+
* or older library version. However, it is possible for advanced
31+
* or experimental software to deliberately override these default
32+
* format settings, to create advanced format files for special
33+
* purposes.
34+
*
35+
* Files created with v1.6 compatibility have superblock version 0.
36+
* Files created with v1.8 compatibility have superblock version 2.
37+
* Files created with v1.10 compatibility have superblock version 3,
38+
* and are avoided by default. Et cetera.
39+
*
40+
* The superblock version is locked in when a file is first created.
41+
* It is then possible to get a mix of v1.6 and v1.8 internal
42+
* object versions, when an existing netCDF-4 file is modified by
43+
* a different software version than the one that originally
44+
* created the file. Mixed-object files of this nature are common
45+
* and do not suffer any serious problems.
46+
*
47+
* See netcdf-c github issues #250 and #951 for more details about
48+
* the rationale and evolution of netCDF-4 format compatibility.
49+
*
50+
* See HDF5 documentation for H5Pset_libver_bounds and related RFC's,
51+
* for more details about HDF5 file object versioning.
52+
*
53+
* @author Dave Allured, NOAA/PSL/CIRES @date 2022 January 11
54+
*/
55+
56+
#include "config.h"
57+
#include "hdf5internal.h"
58+
59+
/**
60+
* @internal Function to set HDF5 file access options for backward
61+
* format compatibility. Call this before every call to H5Fcreate
62+
* or H5Fopen.
63+
*
64+
* @param fapl_id Identifier for valid file access property list to
65+
* be used in the next call to H5Fcreate or H5Fopen.
66+
*
67+
* @return ::NC_NOERR No error.
68+
* @return ::NC_EHDFERR HDF5 returned error.
69+
*
70+
* @author Dave Allured, NOAA/PSL/CIRES @date 2022 January 11
71+
*/
72+
int
73+
hdf5set_format_compatibility(hid_t fapl_id)
74+
{
75+
#if H5_VERSION_GE(1,10,2)
76+
/* lib versions 1.10.2 and higher */
77+
if (H5Pset_libver_bounds(fapl_id, H5F_LIBVER_V18, H5F_LIBVER_LATEST) < 0)
78+
79+
#else
80+
#if H5_VERSION_GE(1,10,0)
81+
/* lib versions 1.10.0, 1.10.1 */
82+
if (H5Pset_libver_bounds(fapl_id, H5F_LIBVER_EARLIEST, H5F_LIBVER_LATEST) < 0)
83+
84+
#else
85+
/* all HDF5 1.8 lib versions */
86+
if (H5Pset_libver_bounds(fapl_id, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST) < 0)
87+
#endif
88+
#endif
89+
return NC_EHDFERR; /* failure exit */
90+
91+
return NC_NOERR; /* normal exit */
92+
}

0 commit comments

Comments
 (0)