|
10 | 10 | #include "config.h" |
11 | 11 | #include <stddef.h> |
12 | 12 | #include <stdlib.h> |
| 13 | +#include <string.h> |
13 | 14 | #ifdef HAVE_UNISTD_H |
14 | 15 | #include <unistd.h> |
15 | 16 | #endif |
16 | 17 | #ifdef HAVE_SYS_TYPES_H |
17 | 18 | #include <sys/types.h> |
18 | 19 | #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 |
19 | 28 |
|
20 | 29 | #include "ncdispatch.h" |
21 | 30 | #include "ncpathmgr.h" |
|
33 | 42 | #ifndef nulldup |
34 | 43 | #define nulldup(x) ((x)?strdup(x):(x)) |
35 | 44 | #endif |
36 | | -#ifndef _WIN32 |
37 | | -#ifdef USE_HDF5 |
38 | | -#include <unistd.h> |
39 | | -#include <hdf5.h> |
40 | | -#endif /* USE_HDF5 */ |
41 | | -#endif /* _WIN32 */ |
42 | 45 |
|
43 | 46 | #undef DEBUG |
44 | 47 |
|
@@ -234,6 +237,7 @@ static int replacemode(NClist* envv, const char* newval); |
234 | 237 | static void infernext(NClist* current, NClist* next); |
235 | 238 | static int negateone(const char* mode, NClist* modes); |
236 | 239 | static void cleanstringlist(NClist* strs, int caseinsensitive); |
| 240 | +static int isdaoscontainer(const char* path); |
237 | 241 |
|
238 | 242 | /* |
239 | 243 | If the path looks like a URL, then parse it, reformat it. |
@@ -851,45 +855,6 @@ NC_infermodel(const char* path, int* omodep, int iscreate, int useparallel, void |
851 | 855 | NClist* modeargs = nclistnew(); |
852 | 856 | char* sfrag = NULL; |
853 | 857 | const char* modeval = NULL; |
854 | | - |
855 | | - /* Check for a DAOS container */ |
856 | | -#ifndef _WIN32 |
857 | | -#ifdef USE_HDF5 |
858 | | -#if H5_VERSION_GE(1,12,0) |
859 | | - hid_t fapl_id; |
860 | | - if ((fapl_id = H5Pcreate(H5P_FILE_ACCESS)) < 0) goto done; |
861 | | - H5Pset_fapl_sec2(fapl_id); |
862 | | - |
863 | | - htri_t accessible; |
864 | | - accessible = H5Fis_accessible(path, fapl_id); |
865 | | - if(accessible > 0) { |
866 | | - int rc=0; |
867 | | - FILE *fp; |
868 | | - char *cmd; |
869 | | - cmd = (char*)malloc((strlen(path)+28)*sizeof(char)); |
870 | | - strcpy(cmd, "getfattr "); |
871 | | - strcat(cmd, path); |
872 | | - strcat(cmd, " | grep -c '.daos'"); |
873 | | - |
874 | | - if((fp = popen(cmd, "r")) != NULL) { |
875 | | - fscanf(fp, "%d", &rc); |
876 | | - pclose(fp); |
877 | | - } |
878 | | - free(cmd); |
879 | | - if(rc == 1) { |
880 | | - /* Is a DAOS container */ |
881 | | - model->impl = NC_FORMATX_NC4; |
882 | | - model->format = NC_FORMAT_NETCDF4; |
883 | | - if (H5Pclose(fapl_id) < 0) goto done; |
884 | | - goto done; |
885 | | - } |
886 | | - } |
887 | | - if (H5Pclose(fapl_id) < 0) goto done; |
888 | | -#endif |
889 | | -#endif |
890 | | -#endif |
891 | | - |
892 | | - |
893 | 858 | char* abspath = NULL; |
894 | 859 | NClist* tmp = NULL; |
895 | 860 |
|
@@ -1011,15 +976,22 @@ NC_infermodel(const char* path, int* omodep, int iscreate, int useparallel, void |
1011 | 976 | if((stat = NC_omodeinfer(useparallel,omode,model))) goto done; |
1012 | 977 | } |
1013 | 978 |
|
1014 | | - /* Phase 9: Infer from file content, if possible; |
1015 | | - this has highest precedence, so it may override |
1016 | | - previous decisions. Note that we do this last |
1017 | | - because we need previously determined model info |
1018 | | - to guess if this file is readable. |
1019 | | - */ |
1020 | | - if(!iscreate && isreadable(uri,model)) { |
1021 | | - /* Ok, we need to try to read the file */ |
1022 | | - 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 | + } |
1023 | 995 | } |
1024 | 996 |
|
1025 | 997 | /* Need a decision */ |
@@ -1610,6 +1582,94 @@ NC_interpret_magic_number(char* magic, NCmodel* model) |
1610 | 1582 | return check(status); |
1611 | 1583 | } |
1612 | 1584 |
|
| 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 | + FILE *fp; |
| 1653 | + char cmd[4096]; |
| 1654 | + memset(cmd,0,sizeof(cmd)); |
| 1655 | + snprintf(cmd,sizeof(cmd),"getfattr %s | grep -c '.daos'",path); |
| 1656 | + if((fp = popen(cmd, "r")) != NULL) { |
| 1657 | + fscanf(fp, "%d", &rc); |
| 1658 | + pclose(fp); |
| 1659 | + } |
| 1660 | + } |
| 1661 | +#endif /*HAVE_SYS_XATTR_H*/ |
| 1662 | + } |
| 1663 | + /* Test for DAOS container */ |
| 1664 | + stat = (rc == 1 ? NC_NOERR : NC_ENOTNC); |
| 1665 | +done: |
| 1666 | +#endif |
| 1667 | +#endif |
| 1668 | +#endif |
| 1669 | + errno = 0; /* reset */ |
| 1670 | + return stat; |
| 1671 | +} |
| 1672 | + |
1613 | 1673 | #ifdef DEBUG |
1614 | 1674 | static void |
1615 | 1675 | printmagic(const char* tag, char* magic, struct MagicFile* f) |
|
0 commit comments