AFS_CFLAGS = @AFS_CFLAGS@
AFS_LIBS = @AFS_LIBS@
+GPFS_CFLAGS = @GPFS_CFLAGS@
ACLOBJS = @ACLOBJS@
XATTROBJS = @XATTROBJS@
IOKITLIBS = @IOKITLIBS@
#
SVRSRCS = filed.c authenticate.c backup.c crypto.c \
win_efs.c estimate.c fdcollect.c \
- fd_plugins.c accurate.c \
+ fd_plugins.c accurate.c bacgpfs.c \
filed_conf.c runres_conf.c heartbeat.c hello.c job.c fd_snapshot.c \
restore.c status.c verify.c verify_vol.c fdcallsdir.c suspend.c $(EXTRA_SRCS) \
$(ACLOBJS) $(XATTROBJS)
EXTRAOBJS = @OBJLIST@
CAP_LIBS = @CAP_LIBS@
-FDLIBS = @FDLIBS@ # extra libs for File daemon
+FDLIBS = @FDLIBS@ # extra libs for File daemon
ZLIBS = @ZLIBS@
LZO_LIBS = @LZO_LIBS@
LZO_INC= @LZO_INC@
@echo "==== Make of filed is good ===="
@echo " "
-bacl.o: bacl.c
+bacgpfs.o: bacgpfs.c bacgpfs.h
@echo "Compiling $<"
- $(NO_ECHO)$(CXX) $(DEFS) $(DEBUG) -c $(WCFLAGS) $(CPPFLAGS) $(LZO_INC) -I$(srcdir) -I$(basedir) $(DINCLUDE) $(CFLAGS) $(AFS_CFLAGS) $<
+ $(NO_ECHO)$(CXX) $(DEFS) $(DEBUG) -c $(WCFLAGS) $(CPPFLAGS) $(LZO_INC) -I$(srcdir) -I$(basedir) $(DINCLUDE) $(CFLAGS) $(AFS_CFLAGS) $(GPFS_CFLAGS) $<
+
+bacl.o: bacl.c bacgpfs.o
+ @echo "Compiling $<"
+ $(NO_ECHO)$(CXX) $(DEFS) $(DEBUG) -c $(WCFLAGS) $(CPPFLAGS) $(LZO_INC) -I$(srcdir) -I$(basedir) $(DINCLUDE) $(CFLAGS) $(AFS_CFLAGS)$<
+
+bxattr.o: bxattr.c bacgpfs.o
+ @echo "Compiling $<"
+ $(NO_ECHO)$(CXX) $(DEFS) $(DEBUG) -c $(WCFLAGS) $(CPPFLAGS) $(LZO_INC) -I$(srcdir) -I$(basedir) $(DINCLUDE) $(CFLAGS)$<
win32/winlib.a:
@if test -f win32/Makefile -a "${GMAKE}" != "none"; then \
--- /dev/null
+/*
+ Bacula(R) - The Network Backup Solution
+
+ Copyright (C) 2000-2020 Kern Sibbald
+
+ The original author of Bacula is Kern Sibbald, with contributions
+ from many others, a complete list can be found in the file AUTHORS.
+
+ You may use this file and others of this release according to the
+ license defined in the LICENSE file, which includes the Affero General
+ Public License, v3.0 ("AGPLv3") and some additional permissions and
+ terms pursuant to its AGPLv3 Section 7.
+
+ This notice must be preserved when any source code is
+ conveyed and/or propagated.
+
+ Bacula(R) is a registered trademark of Kern Sibbald.
+ */
+/*
+ * This is a Bacula support for GPFS.
+ * Author: Radoslaw Korzeniewski, radekk@inteos.pl, Inteos Sp. z o.o.
+ */
+
+#include "bacula.h"
+#include "filed.h"
+#ifdef HAVE_SYS_TYPES_H
+ #include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+ #include <sys/stat.h>
+#endif
+#ifdef HAVE_UNISTD_H
+ #include <unistd.h>
+#endif
+
+#ifdef HAVE_DLFCN_H
+ #include <dlfcn.h>
+#endif
+
+
+#if defined(HAVE_LINUX_OS)
+ #define GPFSLIB_LIB "libgpfs.so"
+ #define GPFSLIB_PATH "/usr/lpp/mmfs/lib/libgpfs.so"
+#elif defined(HAVE_AIX_OS)
+ #define GPFSLIB_LIB "libgpfs.a"
+ #define GPFSLIB_PATH "/usr/lpp/mmfs/lib/libgpfs.a"
+#endif
+
+
+/**
+ * @brief
+ *
+ */
+void GPFSLIB::initialize()
+{
+#if defined(HAVE_GPFS_ACL) && defined(HAVE_DLFCN_H)
+#ifdef HAVE_LINUX_OS
+
+ /**
+ * @brief The static location of the library and search list
+ */
+ static const char * gpfslib_paths[] =
+ {
+#if defined(GPFSLIB_CUSTOM_PATH)
+ GPFSLIB_CUSTOM_PATH,
+#endif
+ GPFSLIB_PATH,
+ GPFSLIB_LIB,
+ NULL,
+ };
+
+ const char * gpfs_path;
+ bool still_search = true;
+ int path_indx = 0;
+ const char * _path = gpfslib_paths[path_indx];
+
+ // iterate through all library locations
+ while (still_search){
+ gpfs_path = _path;
+ Dmsg1(200, "Try to load GPFS library at: %s\n", gpfs_path);
+ handle = dlopen(gpfs_path, RTLD_NOW | RTLD_GLOBAL);
+ _path = gpfslib_paths[++path_indx];
+ still_search = handle == NULL && _path != NULL;
+ }
+
+ // check if dlopen was successful in some point
+ if (handle != NULL){
+ Dmsg1(200, "Loaded GPFS library: %s\n", gpfs_path);
+ // resolve required symbols
+
+ _gpfs_getacl = (_gpfs_getacl_func_t) dlsym(handle, GPFSLIB_SYM_GETACL);
+ // check symbol resolution
+ if (_gpfs_getacl != NULL){
+ _gpfs_putacl = (_gpfs_putacl_func_t) dlsym(handle, GPFSLIB_SYM_PUTACL);
+ // check symbol resolution
+ if (_gpfs_putacl != NULL){
+ Dmsg4(200, "Successfully mapped symbols: %s=%p %s=%p\n",
+ GPFSLIB_SYM_GETACL, _gpfs_getacl,
+ GPFSLIB_SYM_PUTACL, _gpfs_putacl);
+ return;
+ }
+ }
+
+ // error rollback all operations
+ release();
+
+ } else {
+ // show error if any
+#ifdef HAVE_DLERROR
+ char *err = dlerror();
+ if (err != NULL){
+ Dmsg2(1, "Error loading GPFS Library: %s, Err=%s\n", GPFSLIB_PATH, NPRT(err));
+ }
+#else
+ Dmsg1(1, "Error loading GPFS Library: %s!\n", GPFSLIB_PATH);
+#endif
+
+ }
+
+#endif
+#endif
+};
+
+/**
+ * @brief
+ *
+ */
+void GPFSLIB::release()
+{
+ if (handle != NULL){
+ int rc = 0;
+
+ _gpfs_getacl = NULL;
+ _gpfs_putacl = NULL;
+
+#ifdef HAVE_DLFCN_H
+ rc = dlclose(handle);
+#endif
+
+ if (rc != 0){
+
+#ifdef HAVE_DLERROR
+ char *err = dlerror();
+ if (err != NULL){
+ Dmsg1(1, "Error releasing GPFS Library, Err=%s\n", NPRT(err));
+ }
+#else
+ Dmsg0(1, "Error releasing GPFS Library!\n");
+#endif
+
+ }
+ handle = NULL;
+ }
+};
+
+/**
+ * @brief
+ *
+ * @param jcr
+ * @param ff_pkt
+ * @param acl_type
+ * @param content
+ * @param content_len
+ * @return bRC_GPFSLIB
+ */
+bRC_GPFSLIB GPFSLIB::_gpfs_backup_acl_data(JCR *jcr, FF_PKT *ff_pkt, unsigned char acl_type, POOLMEM *content, uint32_t &content_len)
+{
+#if defined(HAVE_GPFS_ACL)
+ int rc;
+
+ content_len = 0;
+ if (_gpfs_getacl != NULL){
+ /*
+ * first we have to check what space is required,
+ * this is achieved by forcing smal sized buffer
+ */
+ gpfs_opaque_acl_t acltmp;
+ acltmp.acl_buffer_len = sizeof(gpfs_opaque_acl_t);
+ acltmp.acl_type = acl_type;
+ rc = _gpfs_getacl(ff_pkt->fname, 0, &acltmp);
+
+ /*
+ * We expect that the first gpfs_getacl will return with error when it will have at least a single acl entry,
+ * and assume if there is no error then no acl entry available.
+ */
+ if (rc < 0){
+ berrno be;
+ gpfs_opaque_acl_t * aclp;
+ int acl_len;
+
+ switch (be.code()){
+ case ENOSPC:
+ // size of required buffer is at acltmp.acl_buffer_len
+ acl_len = acltmp.acl_buffer_len + sizeof(gpfs_opaque_acl_t);
+
+ // prepare required buffer
+ content = check_pool_memory_size(content, acl_len);
+
+ // fill required data
+ aclp = (gpfs_opaque_acl_t*)content;
+ aclp->acl_buffer_len = acl_len;
+ aclp->acl_version = 0;
+ aclp->acl_type = acl_type;
+
+ rc = _gpfs_getacl(ff_pkt->fname, 0, content);
+ if (rc < 0){
+ // error reading acl
+ berrno be;
+ switch (be.code()){
+ case ENOENT:
+ case ENODATA:
+ return bRC_GPFSLIB_ok;
+
+ default:
+ Mmsg2(jcr->errmsg, _("gpfs_getacl error on file \"%s\": ERR=%s\n"), ff_pkt->fname, be.bstrerror());
+ Dmsg2(100, "gpfs_getacl error file=%s ERR=%s\n", ff_pkt->fname, be.bstrerror());
+ return bRC_GPFSLIB_error;
+ }
+ }
+ content_len = acl_len;
+ break;
+
+ case ENOENT:
+ case EINVAL:
+ case ENODATA:
+ return bRC_GPFSLIB_ok;
+
+ default:
+ // this is a real error, report
+ Mmsg2(jcr->errmsg, _("gpfs_getacl error on file \"%s\": ERR=%s\n"), ff_pkt->fname, be.bstrerror());
+ Dmsg2(100, "gpfs_getacl error file=%s ERR=%s\n", ff_pkt->fname, be.bstrerror());
+ return bRC_GPFSLIB_error;
+ }
+ }
+ }
+#endif
+
+ return bRC_GPFSLIB_ok;
+};
+
+/**
+ * @brief
+ *
+ * @param jcr
+ * @param stream
+ * @param content
+ * @param content_len
+ * @return bRC_GPFSLIB
+ */
+bRC_GPFSLIB GPFSLIB::_gpfs_restore_acl_data(JCR *jcr, int stream, POOLMEM *content, uint32_t content_len)
+{
+#if defined(HAVE_GPFS_ACL)
+ int rc;
+
+ if (_gpfs_putacl != NULL){
+ /* check input data */
+ if (jcr == NULL || content == NULL){
+ return bRC_GPFSLIB_fatal;
+ }
+
+ if (content_len > 0 && jcr->last_type != FT_LNK){
+ rc = _gpfs_putacl(jcr->last_fname, 0, content);
+ if (rc < 0){
+ // error saving acl
+ berrno be;
+ switch (be.code()){
+ case ENOSYS:
+
+ return bRC_GPFSLIB_error;
+ default:
+ // this is a real error, report
+ Mmsg2(jcr->errmsg, _("gpfs_getacl error on file \"%s\": ERR=%s\n"), jcr->last_fname, be.bstrerror());
+ Dmsg2(100, "gpfs_getacl error file=%s ERR=%s\n", jcr->last_fname, be.bstrerror());
+ return bRC_GPFSLIB_error;
+ }
+ }
+ }
+ }
+#endif
+
+ return bRC_GPFSLIB_ok;
+};
--- /dev/null
+/*
+ Bacula(R) - The Network Backup Solution
+
+ Copyright (C) 2000-2020 Kern Sibbald
+
+ The original author of Bacula is Kern Sibbald, with contributions
+ from many others, a complete list can be found in the file AUTHORS.
+
+ You may use this file and others of this release according to the
+ license defined in the LICENSE file, which includes the Affero General
+ Public License, v3.0 ("AGPLv3") and some additional permissions and
+ terms pursuant to its AGPLv3 Section 7.
+
+ This notice must be preserved when any source code is
+ conveyed and/or propagated.
+
+ Bacula(R) is a registered trademark of Kern Sibbald.
+ */
+/*
+ * This is a Bacula support for GPFS.
+ * Author: Radoslaw Korzeniewski, radekk@inteos.pl, Inteos Sp. z o.o.
+ */
+
+#ifndef _BAC_GPFS_H_
+#define _BAC_GPFS_H_
+
+#if defined(HAVE_GPFS_ACL)
+ #include <gpfs.h>
+#endif
+
+#ifndef GPFS_ACL_TYPE_ACCESS
+#define GPFS_ACL_TYPE_ACCESS 1
+#endif
+#ifndef GPFS_ACL_TYPE_DEFAULT
+#define GPFS_ACL_TYPE_DEFAULT 2
+#endif
+#ifndef GPFS_ACL_TYPE_NFS4
+#define GPFS_ACL_TYPE_NFS4 3
+#endif
+
+#ifndef GPFS_SUPER_MAGIC
+#define GPFS_SUPER_MAGIC 0x47504653
+#endif
+
+
+/*
+ * Define a function pointer types for better pointer handling
+ */
+typedef int (*_gpfs_getacl_func_t)(char *pathname, int flags, void *aclP);
+typedef int (*_gpfs_putacl_func_t)(char *pathname, int flags, void *aclP);
+
+#define GPFSLIB_SYM_GETACL "gpfs_getacl"
+#define GPFSLIB_SYM_PUTACL "gpfs_putacl"
+
+enum bRC_GPFSLIB
+{
+ bRC_GPFSLIB_ok,
+ bRC_GPFSLIB_error,
+ bRC_GPFSLIB_fatal,
+};
+
+/**
+ * @brief
+ *
+ */
+class GPFSLIB : public SMARTALLOC
+{
+#if defined(HAVE_LINUX_OS) || defined(HAVE_AIX_OS)
+ _gpfs_getacl_func_t _gpfs_getacl; // this is function pointer
+ _gpfs_putacl_func_t _gpfs_putacl;
+#else
+ void * _gpfs_getacl;
+ void * _gpfs_putacl;
+#endif
+
+ void *handle; // this is a dlopen handle
+
+ /**
+ * @brief Construct a new GPFSLIB object
+ *
+ */
+ GPFSLIB() : _gpfs_getacl(NULL), _gpfs_putacl(NULL), handle(NULL) {};
+#if __cplusplus > 201103L
+ GPFSLIB(const GPFSLIB&) = delete;
+#endif
+
+ void initialize();
+ void release();
+ bRC_GPFSLIB _gpfs_backup_acl_data(JCR *jcr, FF_PKT *ff_pkt, unsigned char acl_type, POOLMEM *content, uint32_t &content_len);
+ bRC_GPFSLIB _gpfs_restore_acl_data(JCR *jcr, int stream, POOLMEM *content, uint32_t content_len);
+
+public:
+
+ /**
+ * @brief Destroy the GPFSLIB object
+ *
+ */
+ ~GPFSLIB()
+ {
+ release();
+ };
+
+ /**
+ * @brief This is a main singleton method of the GPFSLIB class.
+ * The Singleton is a class compound with an object instance instantinated in this
+ * compilation section, see: https://en.wikipedia.org/wiki/Singleton_pattern
+ *
+ * @return GPFSLIB& a reference to the singleton object of GPFSLIB
+ */
+ static GPFSLIB& Get()
+ {
+ static GPFSLIB _singleton_instance;
+ return _singleton_instance;
+ };
+
+ /**
+ * @brief
+ *
+ */
+ static void Init() { Get().initialize(); };
+
+ /**
+ * @brief
+ *
+ */
+ static void Release() { Get().release(); };
+
+ /**
+ * @brief
+ *
+ * @param jcr
+ * @param ff_pkt
+ * @param acl_type
+ * @param content
+ * @param content_len
+ * @return bRC_GPFSLIB
+ */
+ static bRC_GPFSLIB gpfs_backup_acl_data(JCR *jcr, FF_PKT *ff_pkt, unsigned char acl_type, POOLMEM *content, uint32_t &content_len)
+ {
+ return Get()._gpfs_backup_acl_data(jcr, ff_pkt, acl_type, content, content_len);
+ };
+
+ /**
+ * @brief
+ *
+ * @param jcr
+ * @param stream
+ * @param content
+ * @param content_len
+ * @return bRC_GPFSLIB
+ */
+ static bRC_GPFSLIB gpfs_restore_acl_data(JCR *jcr, int stream, POOLMEM *content, uint32_t content_len)
+ {
+ return Get()._gpfs_restore_acl_data(jcr, stream, content, content_len);
+ };
+
+};
+
+#endif /* _BAC_GPFS_H_ */
\ No newline at end of file
#include "bacula.h"
#include "filed.h"
#include "fd_plugins.h"
+#include "bacgpfs.h"
/* check if ACL support is enabled */
#if defined(HAVE_ACL)
+#if defined(HAVE_AFS_ACL)
+ static const bool have_afs_acl_flag = true;
+#else
+ static const bool have_afs_acl_flag = false;
+#endif
+
+#if defined(HAVE_GPFS_ACL)
+ static const bool have_gpfs_acl_flag = true;
+#else
+ static const bool have_gpfs_acl_flag = false;
+#endif
+
/*
* This is a constructor of the base BACL class which is OS independent
*
* out:
* internal flags status set
*/
-void BACL::check_dev (JCR *jcr, FF_PKT *ff, uint32_t dev){
-
+void BACL::check_dev (JCR *jcr, FF_PKT *ff, uint32_t dev)
+{
/* sanity check of input variables */
if (jcr == NULL || jcr->last_fname == NULL){
return;
if (current_dev != dev){
flags = BACL_FLAG_NONE;
-#if defined(HAVE_AFS_ACL)
- /* handle special fs: AFS */
- if (fstype_equals(jcr->last_fname, "afs")){
+ if (have_afs_acl_flag && check_current_fs(jcr->last_fname, jcr->ff, "afs")){
set_flag(BACL_FLAG_AFS);
+ } else if (have_gpfs_acl_flag && check_current_fs(jcr->last_fname, jcr->ff, GPFS_SUPER_MAGIC)){
+ set_flag(BACL_FLAG_GPFS);
} else {
set_flag(BACL_FLAG_NATIVE);
}
-#else
- set_flag(BACL_FLAG_NATIVE);
-#endif
current_dev = dev;
}
};
}
/* send the buffer to the storage daemon */
- Dmsg1(400, "Backing up ACL: %i\n", content_len);
+ Dmsg1(400, "Backing up ACL size: %i\n", content_len);
#if 0
POOL_MEM tmp(PM_FNAME);
pm_memcpy(tmp, content, content_len);
return bRC_BACL_fatal;
}
- Dmsg1(200, "ACL of file: %s successfully backed up!\n", jcr->last_fname);
+ Dmsg1(200, "ACL of: %s successfully backed up!\n", jcr->last_fname);
return bRC_BACL_ok;
};
*/
bRC_BACL BACL::backup_acl (JCR *jcr, FF_PKT *ff_pkt)
{
-#if !defined(HAVE_ACL) && !defined(HAVE_AFS_ACL)
- Jmsg(jcr, M_FATAL, 0, "ACL backup requested but not configured in Bacula.\n");
- return bRC_BACL_fatal;
-#else
/* sanity check of input variables and verify if engine is enabled */
if (acl_ena && jcr != NULL && ff_pkt != NULL){
/* acl engine enabled, proceed */
- bRC_BACL rc;
+ bRC_BACL rc = bRC_BACL_ok;
jcr->errmsg[0] = 0;
/* check if we have a plugin generated backup */
}
#endif
-#if defined(HAVE_ACL)
+#if defined(HAVE_GPFS_ACL)
+ if (flags & BACL_FLAG_GPFS){
+ Dmsg0(400, "make GPFS ACL call\n");
+ rc = gpfs_backup_acl(jcr, ff_pkt);
+ goto bail_out;
+ }
+#endif
+
if (flags & BACL_FLAG_NATIVE){
Dmsg0(400, "make Native ACL call\n");
rc = os_backup_acl(jcr, ff_pkt);
/* skip acl backup */
return bRC_BACL_ok;
}
-#endif
}
-#if defined(HAVE_AFS_ACL)
+#if defined(HAVE_AFS_ACL) || defined(HAVE_GPFS_ACL)
bail_out:
#endif
- if (rc == bRC_BACL_error){
+
+ // TODO: This routine should be optimized
+ if (rc != bRC_BACL_ok){
if (acl_nr_errors < ACL_MAX_ERROR_PRINT_PER_JOB){
if (!jcr->errmsg[0]){
Jmsg(jcr, M_WARNING, 0, "No OS ACL configured.\n");
}
return rc;
}
+
return bRC_BACL_ok;
-#endif
};
/*
*/
bRC_BACL BACL::restore_acl (JCR *jcr, int stream, char *data, uint32_t length)
{
-#if !defined(HAVE_ACL) && !defined(HAVE_AFS_ACL)
- Jmsg(jcr, M_FATAL, 0, "ACL restore requested but not configured in Bacula.\n");
- return bRC_BACL_fatal;
-#else
/* sanity check of input variables and verify if engine is enabled */
if (acl_ena && jcr != NULL && data != NULL){
/* acl engine enabled, proceed */
set_content(data, length);
switch (stream){
+ case STREAM_XACL_PLUGIN_ACL:
+ return restore_plugin_acl(jcr);
+
#if defined(HAVE_AFS_ACL)
- case STREAM_BACL_AFS_TEXT:
+ case STREAM_XACL_AFS_TEXT:
if (flags & BACL_FLAG_AFS){
return afs_restore_acl(jcr, stream);
} else {
return bRC_BACL_ok;
}
#endif
-#if defined(HAVE_ACL)
+
+#if defined(HAVE_GPFS_ACL)
+ case STREAM_XACL_GPFS_ACL_ACCESS:
+ case STREAM_XACL_GPFS_ACL_DEFAULT:
+ if (flags & BACL_FLAG_GPFS){
+ return gpfs_restore_acl(jcr, stream);
+ } else {
+ /*
+ * Increment error count but don't log an error again for the same filesystem.
+ */
+ inc_acl_errors();
+ return bRC_BACL_ok;
+ }
+#endif
+
case STREAM_UNIX_ACCESS_ACL:
case STREAM_UNIX_DEFAULT_ACL:
if (flags & BACL_FLAG_NATIVE){
return os_restore_acl(jcr, stream, content, content_len);
} else {
+ /*
+ * Increment error count but don't log an error again for the same filesystem.
+ */
inc_acl_errors();
return bRC_BACL_ok;
}
break;
- case STREAM_XACL_PLUGIN_ACL:
- return restore_plugin_acl(jcr);
default:
if (flags & BACL_FLAG_NATIVE){
Dmsg0(400, "make Native ACL call\n");
}
}
} else {
+ /*
+ * Increment error count but don't log an error again for the same filesystem.
+ */
inc_acl_errors();
return bRC_BACL_ok;
}
break;
-#else
- default:
- break;
-#endif
}
/* cannot find a valid stream to support */
Qmsg2(jcr, M_WARNING, 0, _("Can't restore ACLs of %s - incompatible acl stream encountered - %d\n"), jcr->last_fname, stream);
return bRC_BACL_error;
}
+
return bRC_BACL_ok;
-#endif
};
/*
return bRC_BACL_ok;
};
+/*
+ * Performs a GPFS ACL backup using FS specific API.
+ *
+ * in:
+ * jcr - Job Control Record
+ * ff_pkt - file to backup control package
+ * out:
+ * bRC_BACL_ok - backup of acl's was successful
+ * bRC_BACL_fatal - was an error during acl backup
+ */
+bRC_BACL BACL::gpfs_backup_acl (JCR *jcr, FF_PKT *ff_pkt)
+{
+ /* sanity check of input variables */
+ if (jcr == NULL || ff_pkt == NULL){
+ return bRC_BACL_inval;
+ }
+
+ if (GPFSLIB::gpfs_backup_acl_data(jcr, ff_pkt, GPFS_ACL_TYPE_ACCESS, content, content_len) == bRC_GPFSLIB_fatal){
+ return bRC_BACL_fatal;
+ }
+
+ if (content_len > 0){
+ if (send_acl_stream(jcr, STREAM_XACL_GPFS_ACL_ACCESS) == bRC_BACL_fatal){
+ return bRC_BACL_fatal;
+ }
+ }
+
+ if (ff_pkt->type == FT_DIREND){
+ if (GPFSLIB::gpfs_backup_acl_data(jcr, ff_pkt, GPFS_ACL_TYPE_DEFAULT, content, content_len) == bRC_GPFSLIB_fatal){
+ return bRC_BACL_fatal;
+ }
+ if (content_len > 0){
+ if (send_acl_stream(jcr, STREAM_XACL_GPFS_ACL_DEFAULT) == bRC_BACL_fatal){
+ return bRC_BACL_fatal;
+ }
+ }
+ }
+
+ return bRC_BACL_error;
+};
+
+
/*
* Performs a generic ACL restore using OS specific methods for
* setting acl data on file.
* bRC_BACL_fatal - was a fatal error during acl restore or input data
* is invalid
*/
-bRC_BACL BACL::generic_restore_acl (JCR *jcr, int stream){
-
+bRC_BACL BACL::generic_restore_acl (JCR *jcr, int stream)
+{
unsigned int count;
/* sanity check of input variables */
return bRC_BACL_error;
};
+#if defined(HAVE_GPFS_ACL)
+/*
+ * Performs a GPFS ACL backup using FS specific API.
+ *
+ * in:
+ * jcr - Job Control Record
+ * ff_pkt - file to backup control package
+ * out:
+ * bRC_BACL_ok - backup of acl's was successful
+ * bRC_BACL_fatal - was an error during acl backup
+ */
+bRC_BACL BACL::gpfs_backup_acl (JCR *jcr, FF_PKT *ff_pkt)
+{
+ /* sanity check of input variables */
+ if (jcr == NULL || ff_pkt == NULL){
+ return bRC_BACL_inval;
+ }
+
+ if (GPFSLIB::gpfs_backup_acl_data(jcr, ff_pkt, GPFS_ACL_TYPE_ACCESS, content, content_len) != bRC_GPFSLIB_ok){
+ return bRC_BACL_fatal;
+ }
+
+ if (content_len > 0){
+ if (send_acl_stream(jcr, STREAM_XACL_GPFS_ACL_ACCESS) == bRC_BACL_fatal){
+ return bRC_BACL_fatal;
+ }
+ }
+
+ if (ff_pkt->type == FT_DIREND){
+ if (GPFSLIB::gpfs_backup_acl_data(jcr, ff_pkt, GPFS_ACL_TYPE_DEFAULT, content, content_len) != bRC_GPFSLIB_ok){
+ return bRC_BACL_fatal;
+ }
+
+ if (content_len > 0){
+ if (send_acl_stream(jcr, STREAM_XACL_GPFS_ACL_DEFAULT) == bRC_BACL_fatal){
+ return bRC_BACL_fatal;
+ }
+ }
+ }
+
+ return bRC_BACL_ok;
+};
+
+/*
+ * Performs a GPFS ACL restore using FS specific API.
+ *
+ * in:
+ * jcr - Job Control Record
+ * stream - a stream number to restore
+ * out:
+ * bRC_BACL_ok - restore of acl's was successful
+ * bRC_BACL_error - was an error during acl restore
+ * bRC_BACL_fatal - was a fatal error during acl restore or input data
+ * is invalid
+ */
+bRC_BACL BACL::gpfs_restore_acl (JCR *jcr, int stream)
+{
+ /* sanity check of input variables */
+ if (jcr == NULL){
+ return bRC_BACL_inval;
+ }
+
+ if (GPFSLIB::gpfs_restore_acl_data(jcr, stream, content, content_len) != bRC_GPFSLIB_ok){
+ /* error */
+ return bRC_BACL_error;
+ }
+
+ return bRC_BACL_ok;
+};
+#endif
+
+
/*
* Perform a generic ACL backup using a plugin. It calls the plugin API to
* get required acl data from plugin.
* bRC_BACL_ok - backup finish without problems
* bRC_BACL_error - when you can't backup acl data because some error
*/
-bRC_BACL BACL::afs_backup_acl (JCR *jcr, FF_PKT *ff_pkt){
-
+bRC_BACL BACL::afs_backup_acl (JCR *jcr, FF_PKT *ff_pkt)
+{
int rc;
struct ViceIoctl vip;
char data[BUFSIZ];
* bRC_BACL_ok - backup finish without problems
* bRC_BACL_error - when you can't backup acl data because some error
*/
-bRC_BACL BACL::afs_restore_acl (JCR *jcr, int stream){
-
+bRC_BACL BACL::afs_restore_acl (JCR *jcr, int stream)
+{
int rc;
struct ViceIoctl vip;
*
*/
-#ifndef __BACL_H_
-#define __BACL_H_
+#ifndef _BACL_H_
+#define _BACL_H_
/* check if ACL support is enabled */
#if defined(HAVE_ACL)
#define BACL_FLAG_NATIVE 0x01
#define BACL_FLAG_AFS 0x02
#define BACL_FLAG_PLUGIN 0x04
+#define BACL_FLAG_GPFS 0x08
/*
* Ensure we have none
/*
* Basic ACL class which is a foundation for any other OS specific implementation.
*
- * This class cannot be used directly as it is an abstraction class with a lot
- * of virtual methods laying around. As a basic class it has all public API
- * available for backup and restore functionality. As a bonus it handles all
+ * This class cannot be used directly as it is an abstraction class with a lot
+ * of virtual methods laying around. As a basic class it has all public API
+ * available for backup and restore functionality. As a bonus it handles all
* ACL generic functions and OS independent API, i.e. for AFS ACL or Plugins ACL
* (future functionality).
*/
* bRC_BACL_ok - backup performed without problems
* any other - some error occurred
*/
- virtual bRC_BACL os_backup_acl (JCR *jcr, FF_PKT *ff_pkt){return bRC_BACL_fatal;};
+ virtual bRC_BACL os_backup_acl (JCR *jcr, FF_PKT *ff_pkt) { return bRC_BACL_fatal; };
/**
* Perform OS specific ACL restore. Runtime is called only when stream is supported by OS.
* bRC_BACL_ok - backup performed without problems
* any other - some error occurred
*/
- virtual bRC_BACL os_restore_acl (JCR *jcr, int stream, char *content, uint32_t length){return bRC_BACL_fatal;};
+ virtual bRC_BACL os_restore_acl (JCR *jcr, int stream, char *content, uint32_t length) { return bRC_BACL_fatal; };
/**
* Low level OS specific runtime to get ACL data from file. The ACL data is set in internal content buffer.
* bRC_BACL_ok -
* bRC_BACL_error/fatal - an error or fatal error occurred
*/
- virtual bRC_BACL os_get_acl (JCR *jcr, BACL_type bacltype){return bRC_BACL_fatal;};
+ virtual bRC_BACL os_get_acl (JCR *jcr, BACL_type bacltype) { return bRC_BACL_fatal; };
/**
* Low level OS specific runtime to set ACL data on file.
* bRC_BACL_ok -
* bRC_BACL_error/fatal - an error or fatal error occurred
*/
- virtual bRC_BACL os_set_acl (JCR *jcr, BACL_type bacltype, char *content, uint32_t length){return bRC_BACL_fatal;};
+ virtual bRC_BACL os_set_acl (JCR *jcr, BACL_type bacltype, char *content, uint32_t length) { return bRC_BACL_fatal; };
void inc_acl_errors(){ acl_nr_errors++;};
bRC_BACL check_dev (JCR *jcr);
void check_dev (JCR *jcr, FF_PKT *ff, uint32_t dev);
+ // bRC_BACL gpfs_backup_acl_data(JCR *jcr, FF_PKT *ff_pkt, unsigned char acl_type);
public:
BACL ();
bRC_BACL afs_restore_acl (JCR *jcr, int stream);
bRC_BACL backup_plugin_acl (JCR *jcr, FF_PKT *ff_pkt);
bRC_BACL restore_plugin_acl (JCR *jcr);
+ bRC_BACL gpfs_backup_acl (JCR *jcr, FF_PKT *ff_pkt);
+ bRC_BACL gpfs_restore_acl (JCR *jcr, int stream);
};
void *new_bacl();
#endif /* HAVE_ACL */
-#endif /* __BACL_H_ */
+#endif /* _BACL_H_ */
/* check if XATTR support is enabled */
#if defined(HAVE_XATTR)
+#if defined(HAVE_GPFS_XATTR)
+ #include <gpfs.h>
+ static const bool have_gpfs_xattr_flag = true;
+#else
+ static const bool have_gpfs_xattr_flag = false;
+#endif
+
+#ifndef GPFS_SUPER_MAGIC
+#define GPFS_SUPER_MAGIC 0x47504653
+#endif
+
/*
* This is a constructor of the base BXATTR class which is OS independent
*
* bRC_BXATTR_skip - cannot verify device - no file found
* bRC_BXATTR_inval - invalid input data
*/
-bRC_BXATTR BXATTR::check_dev (JCR *jcr){
+bRC_BXATTR BXATTR::check_dev (JCR *jcr)
+{
int lst;
struct stat st;
* out:
* internal flags status set
*/
-void BXATTR::check_dev (JCR *jcr, FF_PKT *ff, uint32_t dev){
+void BXATTR::check_dev (JCR *jcr, FF_PKT *ff, uint32_t dev)
+{
+
+#if defined(HAVE_GPFS_XATTR)
+ static const bool have_gpfs_xattr_flag = true;
+#else
+ static const bool have_gpfs_xattr_flag = false;
+#endif
/* sanity check of input variables */
if (jcr == NULL || jcr->last_fname == NULL){
if (current_dev != dev){
flags = BXATTR_FLAG_NONE;
- set_flag(BXATTR_FLAG_NATIVE);
+ jcr->ff->last_fstype = 0;
+ if (have_gpfs_xattr_flag && check_current_fs(jcr->last_fname, jcr->ff, GPFS_SUPER_MAGIC)){
+ set_flag(BXATTR_FLAG_GPFS);
+ } else {
+ set_flag(BXATTR_FLAG_NATIVE);
+ }
current_dev = dev;
/* We can check for some specific ACLs depending on the FS type */
if (!fstype(ff, current_fs, sizeof(current_fs))) {
* bRC_BXATTR_fatal - when we can't send data to the SD
* bRC_BXATTR_ok - send finish without errors
*/
-bRC_BXATTR BXATTR::send_xattr_stream(JCR *jcr, int stream){
-
+bRC_BXATTR BXATTR::send_xattr_stream(JCR *jcr, int stream)
+{
BSOCK * sd;
POOLMEM * msgsave;
#ifdef FD_NO_SEND_TEST
/* send the buffer to the storage daemon */
Dmsg1(400, "Backing up XATTR: %i\n", content_len);
-#if 0
- POOL_MEM tmp(PM_FNAME);
- pm_memcpy(tmp, content, content_len);
- Dmsg2(400, "Backing up XATTR: (%i) <%s>\n", strlen(tmp.addr()), tmp.c_str());
-#endif
msgsave = sd->msg;
sd->msg = content;
sd->msglen = content_len;
* bRC_BXATTR_ok - backup finish without problems
* bRC_BXATTR_error - when you can't backup xattr data because some error
*/
-bRC_BXATTR BXATTR::backup_xattr (JCR *jcr, FF_PKT *ff_pkt){
-
-#if !defined(HAVE_XATTR)
+bRC_BXATTR BXATTR::backup_xattr (JCR *jcr, FF_PKT *ff_pkt)
+{
+#if !defined(HAVE_XATTR) && !defined(HAVE_GPFS_XATTR)
Jmsg(jcr, M_FATAL, 0, "XATTR backup requested but not configured in Bacula.\n");
return bRC_BXATTR_fatal;
#else
check_dev(jcr, ff_pkt, ff_pkt->statp.st_dev);
+#if defined(HAVE_GPFS_XATTR)
+ if (flags & BXATTR_FLAG_GPFS){
+ Dmsg0(400, "make GPFS XATTR call\n");
+ rc = gpfs_backup_xattr(jcr, ff_pkt);
+ goto bail_out;
+ }
+#endif
+
+#if defined(HAVE_XATTR)
if (flags & BXATTR_FLAG_NATIVE){
Dmsg0(400, "make Native XATTR call\n");
rc = os_backup_xattr(jcr, ff_pkt);
/* skip xattr backup */
return bRC_BXATTR_ok;
}
-
+#endif
}
+#ifdef HAVE_GPFS_XATTR
+ bail_out:
+#endif
+
if (rc == bRC_BXATTR_error){
if (xattr_nr_errors < XATTR_MAX_ERROR_PRINT_PER_JOB){
if (!jcr->errmsg[0]){
switch (stream){
case STREAM_XACL_PLUGIN_XATTR:
return restore_plugin_xattr(jcr);
+
+#if defined(HAVE_GPFS_XATTR)
+ case STREAM_XACL_GPFS_XATTR:
+ return gpfs_restore_xattr(jcr, stream);
+#endif
+
default:
if (flags & BXATTR_FLAG_NATIVE){
for (a = 0; xattr_streams[a] > 0; a++){
}
}
} else {
+ /*
+ * Increment error count but don't log an error again for the same filesystem.
+ */
inc_xattr_errors();
return bRC_BXATTR_ok;
}
* bRC_BXATTR_error/fatal - an error or fatal error occurred
* bRC_BXATTR_inval - input variables was invalid
*/
-bRC_BXATTR BXATTR::generic_backup_xattr (JCR *jcr, FF_PKT *ff_pkt){
-
+bRC_BXATTR BXATTR::generic_backup_xattr (JCR *jcr, FF_PKT *ff_pkt)
+{
bRC_BXATTR rc;
POOLMEM *xlist;
uint32_t xlen;
return rc;
};
+/*
+ * Performs GPFS XATTR backup using FS specific API.
+ *
+ * in:
+ * jcr - Job Control Record
+ * ff_pkt - file to backup control package
+ * out:
+ * bRC_BXATTR_ok - xattr backup ok or no xattr to backup found
+ * bRC_BXATTR_error/fatal - an error or fatal error occurred
+ * bRC_BXATTR_inval - input variables was invalid
+ */
+bRC_BXATTR BXATTR::gpfs_backup_xattr (JCR *jcr, FF_PKT *ff_pkt)
+{
+ return bRC_BXATTR_error;
+}
+
/*
* Performs a generic XATTR restore using OS specific methods for
* setting XATTR data on file.
* bRC_BXATTR_fatal - was a fatal error during xattr restore
* bRC_BXATTR_inval - input variables was invalid
*/
-bRC_BXATTR BXATTR::generic_restore_xattr (JCR *jcr, int stream){
-
+bRC_BXATTR BXATTR::generic_restore_xattr (JCR *jcr, int stream)
+{
bRC_BXATTR rc = bRC_BXATTR_ok;
alist *xattr_list;
BXATTR_xattr *xattr;
return rc;
};
+/*
+ * Performs a GPFS XATTR restore using FS specific API.
+ *
+ * in:
+ * jcr - Job Control Record
+ * stream - a stream number to restore
+ * out:
+ * bRC_BXATTR_ok - restore of acl's was successful
+ * bRC_BXATTR_error - was an error during xattr restore
+ * bRC_BXATTR_fatal - was a fatal error during xattr restore
+ * bRC_BXATTR_inval - input variables was invalid
+ */
+bRC_BXATTR BXATTR::gpfs_restore_xattr (JCR *jcr, int stream)
+{
+
+ return bRC_BXATTR_error;
+}
+
/*
* Perform a generic XATTR backup using a plugin. It calls the plugin API to
* get required xattr data from plugin.
*
*/
-#ifndef __BXATTR_H_
-#define __BXATTR_H_
+#ifndef _BXATTR_H_
+#define _BXATTR_H_
/* check if XATTR support is enabled */
#if defined(HAVE_XATTR)
* (greater or equal to zero).
*/
enum bRC_BXATTR {
- bRC_BXATTR_inval = -3, // input data invalid
- bRC_BXATTR_fatal = -2, // a fatal error
- bRC_BXATTR_error = -1, // standard error
- bRC_BXATTR_ok = 0, // success
- bRC_BXATTR_skip = 1, // processing should skip current runtime
- bRC_BXATTR_cont = 2 // processing should skip current element
- // and continue with next one
+ bRC_BXATTR_inval = -3, // input data invalid
+ bRC_BXATTR_fatal = -2, // a fatal error
+ bRC_BXATTR_error = -1, // standard error
+ bRC_BXATTR_ok = 0, // success
+ bRC_BXATTR_skip = 1, // processing should skip current runtime
+ bRC_BXATTR_cont = 2 // processing should skip current element
+ // and continue with next one
};
/*
* Flags which control what XATTR engine
* to use for backup/restore
*/
-#define BXATTR_FLAG_NONE 0
-#define BXATTR_FLAG_NATIVE 0x01
-#define BXATTR_FLAG_AFS 0x02
-#define BXATTR_FLAG_PLUGIN 0x04
+#define BXATTR_FLAG_NONE 0
+#define BXATTR_FLAG_NATIVE 0x01
+#define BXATTR_FLAG_AFS 0x02
+#define BXATTR_FLAG_PLUGIN 0x04
+#define BXATTR_FLAG_GPFS 0x08
/*
* Extended attribute (xattr) list element.
bRC_BXATTR generic_restore_xattr (JCR *jcr, int stream);
bRC_BXATTR backup_plugin_xattr (JCR *jcr, FF_PKT *ff_pkt);
bRC_BXATTR restore_plugin_xattr (JCR *jcr);
+ bRC_BXATTR gpfs_backup_xattr (JCR *jcr, FF_PKT *ff_pkt);
+ bRC_BXATTR gpfs_restore_xattr (JCR *jcr, int stream);
};
void *new_bxattr();
#endif /* HAVE_XATTR */
-#endif /* __BXATTR_H_ */
+#endif /* _BXATTR_H_ */
events_send_msg(NULL, "FD0001",
EVENTS_TYPE_DAEMON, "*Daemon*",
(intptr_t)get_first_port_host_order(me->FDaddrs), "Filed startup");
+ GPFSLIB::Init();
server_tid = pthread_self();
}
}
}
-
+
UnlockRes();
if (OK) {
#include "fd_plugins.h"
#include "fd_snapshot.h"
#include "findlib/find.h"
+#include "bacgpfs.h"
#include "bacl.h"
#include "bxattr.h"
#include "jcr.h"
case STREAM_XACL_HURD_DEFAULT:
case STREAM_XACL_HURD_ACCESS:
case STREAM_XACL_PLUGIN_ACL:
+ case STREAM_XACL_GPFS_ACL_DEFAULT:
+ case STREAM_XACL_GPFS_ACL_ACCESS:
if (!do_restore_acl(jcr, rds->stream, rds->content, rds->content_length)) {
goto get_out;
}
case STREAM_XACL_HURD_DEFAULT:
case STREAM_XACL_HURD_ACCESS:
case STREAM_XACL_PLUGIN_ACL:
+ case STREAM_XACL_GPFS_ACL_DEFAULT:
+ case STREAM_XACL_GPFS_ACL_ACCESS:
/*
* Do not restore ACLs when
* a) The current file is not extracted
#include "find.h"
#include <sys/types.h>
#include <sys/stat.h>
+#if defined(HAVE_LINUX_OS) || defined(HAVE_FREEBSD_OS) || defined(HAVE_AIX_OS)
+ #include <paths.h>
+#endif
+#ifdef HAVE_DARWIN_OS
+ #include <sys/paths.h>
+#endif
+
#ifdef HAVE_SUN_OS
#include <sys/mnttab.h>
#endif
}
}
-
/*
* These functions should be implemented for each OS
*
#include <sys/param.h>
#include <sys/mount.h>
+/*
+ * simple return fs type magic number or zero when error
+ */
+uint32_t fstypeid(char *fname, FF_PKT *ff_pkt)
+{
+ struct statfs st;
+
+ if (statfs(fname, &st) == 0) {
+ return st.f_type;
+ }
+ return 0;
+}
+
bool fstype(FF_PKT *ff_pkt, char *fs, int fslen)
{
char *fname = ff_pkt->fname;
#define statvfs statfs
#endif
+/*
+ * simple return fs type magic number or zero when error
+ */
+uint32_t fstypeid(char *fname, FF_PKT *ff_pkt)
+{
+ struct statvfs st;
+
+ if (statvfs(fname, &st) == 0) {
+ return st.f_type;
+ }
+ return 0;
+}
+
bool fstype(FF_PKT *ff_pkt, char *fs, int fslen)
{
char *fname = ff_pkt->fname;
#include <sys/types.h>
#include <sys/statvfs.h>
+/*
+ * TODO: RPK: is HP-UX version really working as I cannot find required API in HP-UX docs.
+ */
+
+/*
+ * simple return fs type magic number or zero when error
+ */
+uint32_t fstypeid(char *fname, FF_PKT *ff_pkt)
+{
+ struct statfs st;
+
+ if (statfs(fname, &st) == 0) {
+ return st.f_fsid;
+ }
+ return 0;
+}
+
bool fstype(FF_PKT *ff_pkt, char *fs, int fslen)
{
char *fname = ff_pkt->fname;
#include <sys/vfs.h>
#include <mntent.h>
+
+/*
+ * simple return fs type magic number or zero when error
+ */
+uint32_t fstypeid(char *fname, FF_PKT *ff_pkt)
+{
+ struct statfs st;
+
+ if (statfs(fname, &st) == 0) {
+ return st.f_type;
+ }
+ return 0;
+}
+
/*
* Linux statfs() does not return the filesystem name type. It
* only returns a binary fstype, so we must look up the type name
* in mtab.
*/
-bool fstype(FF_PKT *ff_pkt, char *fs, int fslen)
+bool fstype(char *fname, FF_PKT *ff_pkt, char *fs, int fslen)
{
- char *fname = ff_pkt->fname; /* fname is a better here than snap_fname */
struct statfs st;
const char *fstype;
if (!fname) {
#include <sys/types.h>
#include <sys/stat.h>
+/*
+ * simple return fs type magic number
+ */
+uint32_t fstypeid(char *fname, FF_PKT *ff_pkt)
+{
+ struct statvfs st;
+
+ if (statvfs(fname, &st) == 0) {
+ return st.f_fsid;
+ }
+ return 0;
+}
+
bool fstype(FF_PKT *ff_pkt, char *fs, int fslen)
{
/* Solaris has the filesystem type name in the lstat packet */
#include <sys/stat.h>
#include <sys/mount.h>
+/*
+ * TODO: RPK: Tru64 is already dead!
+ */
+
+/*
+ * simple return fs type magic number
+ */
+uint32_t fstypeid(char *fname, FF_PKT *ff_pkt)
+{
+ struct statfs st;
+
+ if (statfs((char *)fname, &st) == 0){
+ return st.f_type;
+ }
+ return 0;
+}
+
bool fstype(FF_PKT *ff_pkt, char *fs, int fslen)
{
char *fname = ff_pkt->fname;
struct statfs st;
- if (statfs((char *)fname, &st) == 0) {
+ if (statfs((char *)fname, &st) == 0){
switch (st.f_type) {
/* Known good values */
case 0xa: bstrncpy(fs, "advfs", fslen); return true; /* Tru64 AdvFS */
#else /* No recognised OS */
+uint32_t fstypeid(char *fname, FF_PKT *ff_pkt)
+{
+ Dmsg0(10, "!!! fstypeid() not implemented for this OS. !!!\n");
+ return 0;
+}
+
bool fstype(FF_PKT *ff_pkt, char *fs, int fslen)
{
- char *fname = ff_pkt->fname;
Dmsg0(10, "!!! fstype() not implemented for this OS. !!!\n");
return false;
}
return true;
}
+/*
+ * Parameter wrapper for fstype
+ */
+bool fstype(FF_PKT *ff_pkt, char *fs, int fslen)
+{
+ return fstype(ff_pkt->fname, ff_pkt, fs, fslen);
+}
+
+/*
+ * compares current fstype from FF_PKT for required fstype_name
+ */
+bool check_current_fs(char *fname, FF_PKT *ff, const char *fstype_name)
+{
+ if (fstype_name != NULL){
+ // read current fs name and compare it to required
+ char fsname[NAME_MAX];
+ if (fstype(fname, ff, fsname, NAME_MAX)){
+ return bstrcmp(fsname, fstype_name);
+ }
+ }
+ return false;
+};
+
+/*
+ * compares current fstype from FF_PKT for required fstype_magic
+ */
+bool check_current_fs(char *fname, FF_PKT *ff, uint32_t fstype_magic)
+{
+ uint32_t fsid;
+
+ if (fstype_magic > 0){
+ // get fsid for file
+ if (ff->last_fstype != 0){
+ fsid = ff->last_fstype;
+ } else {
+ fsid = fstypeid(fname, ff);
+ ff->last_fstype = fsid;
+ }
+ if (fsid != 0){
+ return fsid == fstype_magic;
+ }
+ }
+ return false;
+}
+
#ifdef TEST_PROGRAM
int main(int argc, char **argv)
{
/* from fstype.c */
bool fstype(FF_PKT *ff_pkt, char *fs, int fslen);
-bool fstype_equals(const char *fname, const char *fstype_name);
+bool fstype(char *fname, FF_PKT *ff_pkt, char *fs, int fslen);
+uint32_t fstypeid(char *fname, FF_PKT *ff_pkt);
+bool check_current_fs(char *fname, FF_PKT *ff, const char *fstype_name);
+bool check_current_fs(char *fname, FF_PKT *ff, uint32_t fstype_magic);
/* from drivetype.c */
bool drivetype(const char *fname, char *fs, int fslen);
#define STREAMBITS_TYPE 11 /* type bit size */
#define STREAMMASK_TYPE (~((~0uL)<< STREAMBITS_TYPE) << STREAMBASE_TYPE)
/*
- * Note additional base, bits, and masks can be defined for new
+ * Note additional base, bits, and masks can be defined for new
* ranges or subranges of stream attributes.
*/
#define STREAM_PLUGIN_DATA 27 /* Plugin specific data */
#define STREAM_RESTORE_OBJECT 28 /* Plugin restore object */
/*
- * Non-gzip compressed streams. Those streams can handle arbitrary
- * compression algorithm data as an additional header is stored
- * at the beginning of the stream. See comp_stream_header definition
+ * Non-gzip compressed streams. Those streams can handle arbitrary
+ * compression algorithm data as an additional header is stored
+ * at the beginning of the stream. See comp_stream_header definition
* in ch.h for more details.
*/
#define STREAM_COMPRESSED_DATA 29 /* Compressed file data */
#define STREAM_XACL_HURD_DEFAULT 1018 /* GNU HURD acl_t string of acl_to_text (POSIX acl) for default acls */
#define STREAM_XACL_HURD_ACCESS 1019 /* GNU HURD acl_t string of acl_to_text (POSIX acl) for access acls */
#define STREAM_XACL_PLUGIN_ACL 1020 /* Plugin ACL data for plugin specific acls */
+#define STREAM_XACL_GPFS_ACL_DEFAULT 1021 /* GPFS Default ACL data using gpfs_getacl()/gpfs_putacl() */
+#define STREAM_XACL_GPFS_ACL_ACCESS 1022 /* GPFS Access ACL data using gpfs_getacl()/gpfs_putacl() */
+#define STREAM_XACL_GPFS_XATTR 1987 /* GPFS XATTR data using gpfs_fgetattrs()/gpfs_fputattrs() */
#define STREAM_XACL_PLUGIN_XATTR 1988 /* Plugin XATTR data for plugin specific xattrs */
#define STREAM_XACL_HURD_XATTR 1989 /* GNU HURD extended attributes */
#define STREAM_XACL_IRIX_XATTR 1990 /* IRIX extended attributes */