Skip to content

Commit 150db23

Browse files
authored
Merge pull request #2021 from brtnfld/DAOS_sync
Check if HDF5 "file" is a DAOS object
2 parents aff08d8 + b67745e commit 150db23

5 files changed

Lines changed: 150 additions & 15 deletions

File tree

.github/workflows/run_tests_win_cygwin.yml

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ jobs:
4141
libhdf4-devel zipinfo libxml2-devel perl zlib-devel
4242
libzstd-devel libbz2-devel libaec-devel libzip-devel
4343
libdeflate-devel gcc-core gcc-g++ libcurl-devel libiconv-devel
44-
libssl-devel libcrypt-devel
44+
libssl-devel libcrypt-devel attr libattr-devel
4545
4646
- name: (Autotools) Run autoconf and friends
4747
run: |
@@ -78,10 +78,15 @@ jobs:
7878
if [ $(find /tmp/pretend-root/$(pwd) -type f | wc -l) -gt 0 ]; then exit 1; fi
7979
fi
8080
81-
- name: (Autotools) Build and run tests
81+
- name: (Autotools) Build tests
8282
timeout-minutes: 30
8383
run: |
84-
make check -j8 SHELL=/bin/dash
84+
make check -j$(nproc) TESTS="" SHELL=/bin/dash
85+
86+
- name: (Autotools) Run tests
87+
timeout-minutes: 30
88+
run: |
89+
make check -j$(nproc) SHELL=/bin/dash
8590
8691
build-and-test-cmake:
8792
name: Cygwin-based CMake tests

CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,11 @@ if(UNAME)
8787
set(TMP_BUILDNAME "${osname}-${osrel}-${cpu}")
8888
endif()
8989

90+
find_program(GETFATTR NAMES getfattr)
91+
if(GETFATTR)
92+
set(HAVE_GETFATTR TRUE)
93+
endif()
94+
9095
# Define some Platforms
9196
if(osname MATCHES "CYGWIN.*")
9297
set(ISCYGWIN yes)
@@ -1151,6 +1156,7 @@ CHECK_INCLUDE_file("io.h" HAVE_IO_H)
11511156
endif(MSVC)
11521157
CHECK_INCLUDE_file("stdlib.h" HAVE_STDLIB_H)
11531158
CHECK_INCLUDE_file("ctype.h" HAVE_CTYPE_H)
1159+
CHECK_INCLUDE_file("sys/xattr_h" HAVE_SYS_XATTR_H)
11541160
CHECK_INCLUDE_file("stdarg.h" HAVE_STDARG_H)
11551161
CHECK_INCLUDE_file("strings.h" HAVE_STRINGS_H)
11561162
CHECK_INCLUDE_file("signal.h" HAVE_SIGNAL_H)

config.h.cmake.in

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,12 @@ are set when opening a binary file on Windows. */
373373
/* Define to 1 if you have the <ctype.h> header file. */
374374
#cmakedefine HAVE_CTYPE_H 1
375375

376+
/* Define to 1 if you have the getfattr command line utility. */
377+
#cmakedefine HAVE_GETFATTR 1
378+
379+
/* Define to 1 if you have the <sys/xattr.h> header file. */
380+
#cmakedefine HAVE_SYS_XATTR_H
381+
376382
/* Define to 1 if you have the <strings.h> header file. */
377383
#cmakedefine HAVE_STRINGS_H 1
378384

configure.ac

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,14 @@ AC_LANG_POP([C])
8282
if test $have_no_strict_aliasing = no; then
8383
CFLAGS=$SAVE_CFLAGS
8484
fi
85+
86+
##
87+
# Check to see if we have getfattr
88+
##
89+
AC_CHECK_PROGS([HAVE_GETFATTR], [getfattr])
90+
if test -n "$HAVE_GETFATTR"; then
91+
AC_DEFINE_UNQUOTED([HAVE_GETFATTR],[1],[getfattr is available])
92+
fi
8593
##
8694
# Some files need to exist in build directories
8795
# that do not correspond to their source directory, or
@@ -1292,7 +1300,7 @@ AC_CHECK_HEADERS([sys/param.h])
12921300
AC_CHECK_HEADERS([libgen.h])
12931301
#AC_CHECK_HEADERS([locale.h])
12941302
AC_HEADER_STDC
1295-
AC_CHECK_HEADERS([locale.h stdio.h stdarg.h fcntl.h malloc.h stdlib.h string.h strings.h unistd.h sys/stat.h getopt.h sys/time.h sys/types.h time.h dirent.h stdint.h ctype.h])
1303+
AC_CHECK_HEADERS([locale.h stdio.h stdarg.h fcntl.h malloc.h stdlib.h string.h strings.h unistd.h sys/stat.h getopt.h sys/time.h sys/types.h time.h dirent.h stdint.h ctype.h sys/xattr_h])
12961304

12971305
# Do sys/resource.h separately
12981306
#AC_CHECK_HEADERS([sys/resource.h],[havesysresource=1],[havesysresource=0])

libdispatch/dinfermodel.c

Lines changed: 121 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,24 @@
77
* Copyright 2018 University Corporation for Atmospheric
88
* Research/Unidata. See COPYRIGHT file for more info.
99
*/
10-
1110
#include "config.h"
1211
#include <stddef.h>
1312
#include <stdlib.h>
13+
#include <string.h>
1414
#ifdef HAVE_UNISTD_H
1515
#include <unistd.h>
1616
#endif
1717
#ifdef HAVE_SYS_TYPES_H
1818
#include <sys/types.h>
1919
#endif
20+
#ifndef _WIN32
21+
#ifdef USE_HDF5
22+
#include <hdf5.h>
23+
#endif /* USE_HDF5 */
24+
#endif /* _WIN32 */
25+
#ifdef HAVE_SYS_XATTR_H
26+
#include <sys/xattr.h>
27+
#endif
2028

2129
#include "ncdispatch.h"
2230
#include "ncpathmgr.h"
@@ -229,6 +237,7 @@ static int replacemode(NClist* envv, const char* newval);
229237
static void infernext(NClist* current, NClist* next);
230238
static int negateone(const char* mode, NClist* modes);
231239
static void cleanstringlist(NClist* strs, int caseinsensitive);
240+
static int isdaoscontainer(const char* path);
232241

233242
/*
234243
If the path looks like a URL, then parse it, reformat it.
@@ -848,7 +857,7 @@ NC_infermodel(const char* path, int* omodep, int iscreate, int useparallel, void
848857
const char* modeval = NULL;
849858
char* abspath = NULL;
850859
NClist* tmp = NULL;
851-
860+
852861
/* Phase 1:
853862
1. convert special protocols to http|https
854863
2. begin collecting fragments
@@ -967,15 +976,22 @@ NC_infermodel(const char* path, int* omodep, int iscreate, int useparallel, void
967976
if((stat = NC_omodeinfer(useparallel,omode,model))) goto done;
968977
}
969978

970-
/* Phase 9: Infer from file content, if possible;
971-
this has highest precedence, so it may override
972-
previous decisions. Note that we do this last
973-
because we need previously determined model info
974-
to guess if this file is readable.
975-
*/
976-
if(!iscreate && isreadable(uri,model)) {
977-
/* Ok, we need to try to read the file */
978-
if((stat = check_file_type(path, omode, useparallel, params, model, uri))) goto done;
979+
/* Phase 9: Special case for file stored in DAOS container */
980+
if(isdaoscontainer(path) == NC_NOERR) {
981+
/* This is a DAOS container, so immediately assume it is HDF5. */
982+
model->impl = NC_FORMATX_NC_HDF5;
983+
model->format = NC_FORMAT_NETCDF4;
984+
} else {
985+
/* Phase 10: Infer from file content, if possible;
986+
this has highest precedence, so it may override
987+
previous decisions. Note that we do this last
988+
because we need previously determined model info
989+
to guess if this file is readable.
990+
*/
991+
if(!iscreate && isreadable(uri,model)) {
992+
/* Ok, we need to try to read the file */
993+
if((stat = check_file_type(path, omode, useparallel, params, model, uri))) goto done;
994+
}
979995
}
980996

981997
/* Need a decision */
@@ -1566,6 +1582,100 @@ NC_interpret_magic_number(char* magic, NCmodel* model)
15661582
return check(status);
15671583
}
15681584

1585+
/* Return NC_NOERR if path is a DAOS container; return NC_EXXX otherwise */
1586+
static int
1587+
isdaoscontainer(const char* path)
1588+
{
1589+
int stat = NC_ENOTNC; /* default is that this is not a DAOS container */
1590+
#ifndef _WIN32
1591+
#ifdef USE_HDF5
1592+
#if H5_VERSION_GE(1,12,0)
1593+
htri_t accessible;
1594+
hid_t fapl_id;
1595+
int rc;
1596+
/* Check for a DAOS container */
1597+
if((fapl_id = H5Pcreate(H5P_FILE_ACCESS)) < 0) {stat = NC_EHDFERR; goto done;}
1598+
H5Pset_fapl_sec2(fapl_id);
1599+
accessible = H5Fis_accessible(path, fapl_id);
1600+
H5Pclose(fapl_id); /* Ignore any error */
1601+
rc = 0;
1602+
if(accessible > 0) {
1603+
#ifdef HAVE_SYS_XATTR_H
1604+
ssize_t xlen;
1605+
#ifdef __APPLE__
1606+
xlen = listxattr(path, NULL, 0, 0);
1607+
#else
1608+
xlen = listxattr(path, NULL, 0);
1609+
#endif
1610+
if(xlen > 0) {
1611+
char* xlist = NULL;
1612+
char* xvalue = NULL;
1613+
char* p;
1614+
char* endp;
1615+
if((xlist = (char*)calloc(1,(size_t)xlen))==NULL)
1616+
{stat = NC_ENOMEM; goto done;}
1617+
#ifdef __APPLE__
1618+
(void)listxattr(path, xlist, (size_t)xlen, 0); /* Get xattr names */
1619+
#else
1620+
(void)listxattr(path, xlist, (size_t)xlen); /* Get xattr names */
1621+
#endif
1622+
p = xlist; endp = p + xlen; /* delimit names */
1623+
/* walk the list of xattr names */
1624+
for(;p < endp;p += (strlen(p)+1)) {
1625+
/* The popen version looks for the string ".daos";
1626+
It would be nice if we know whether that occurred
1627+
int the xattr's name or it value.
1628+
Oh well, we will do the general search */
1629+
/* Look for '.daos' in the key */
1630+
if(strstr(p,".daos") != NULL) {rc = 1; break;} /* success */
1631+
/* Else get the p'th xattr's value size */
1632+
#ifdef __APPLE__
1633+
xlen = getxattr(path, p, NULL, 0, 0, 0);
1634+
#else
1635+
xlen = getxattr(path, p, NULL, 0);
1636+
#endif
1637+
if((xvalue = (char*)calloc(1,(size_t)xlen))==NULL)
1638+
{stat = NC_ENOMEM; goto done;}
1639+
/* Read the value */
1640+
#ifdef __APPLE__
1641+
(void)getxattr(path, p, xvalue, (size_t)xlen, 0, 0);
1642+
#else
1643+
(void)getxattr(path, p, xvalue, (size_t)xlen);
1644+
#endif
1645+
fprintf(stderr,"@@@ %s=|%s|\n",p,xvalue);
1646+
/* Look for '.daos' in the value */
1647+
if(strstr(xvalue,".daos") != NULL) {rc = 1; break;} /* success */
1648+
}
1649+
}
1650+
#else /*!HAVE_SYS_XATTR_H*/
1651+
1652+
#ifdef HAVE_GETFATTR
1653+
{
1654+
FILE *fp;
1655+
char cmd[4096];
1656+
memset(cmd,0,sizeof(cmd));
1657+
snprintf(cmd,sizeof(cmd),"getfattr %s | grep -c '.daos'",path);
1658+
if((fp = popen(cmd, "r")) != NULL) {
1659+
fscanf(fp, "%d", &rc);
1660+
pclose(fp);
1661+
}
1662+
}
1663+
#else /*!HAVE_GETFATTR*/
1664+
/* We just can't test for DAOS container.*/
1665+
stat = 0;
1666+
#endif /*HAVE_GETFATTR*/
1667+
#endif /*HAVE_SYS_XATTR_H*/
1668+
}
1669+
/* Test for DAOS container */
1670+
stat = (rc == 1 ? NC_NOERR : NC_ENOTNC);
1671+
done:
1672+
#endif
1673+
#endif
1674+
#endif
1675+
errno = 0; /* reset */
1676+
return stat;
1677+
}
1678+
15691679
#ifdef DEBUG
15701680
static void
15711681
printmagic(const char* tag, char* magic, struct MagicFile* f)

0 commit comments

Comments
 (0)