From 643021dcf823d2615c65a22aa82439cdd2579f93 Mon Sep 17 00:00:00 2001 From: Marco van Wieringen Date: Sun, 26 Sep 2010 14:37:42 +0200 Subject: [PATCH] Added first try at supporting IRIX extended attributes. --- bacula/src/baconfig.h | 1 + bacula/src/filed/restore.c | 1 + bacula/src/filed/xattr.c | 178 +++++++++++++++++++++++++++++++++++++ bacula/src/findlib/bfile.c | 2 + 4 files changed, 182 insertions(+) diff --git a/bacula/src/baconfig.h b/bacula/src/baconfig.h index b4f62ff649..6ee46a32c9 100644 --- a/bacula/src/baconfig.h +++ b/bacula/src/baconfig.h @@ -306,6 +306,7 @@ void InitWinAPIWrapper(); #define STREAM_ACL_AIX_NFS4 1016 /* AIX specific string representation from * aclx_printStr (NFSv4 acl) */ +#define STREAM_XATTR_IRIX 1990 /* IRIX specific extended attributes */ #define STREAM_XATTR_TRU64 1991 /* TRU64 specific extended attributes */ #define STREAM_XATTR_AIX 1992 /* AIX specific extended attributes */ #define STREAM_XATTR_OPENBSD 1993 /* OpenBSD specific extended attributes */ diff --git a/bacula/src/filed/restore.c b/bacula/src/filed/restore.c index c06d0c5e85..1eff06734d 100644 --- a/bacula/src/filed/restore.c +++ b/bacula/src/filed/restore.c @@ -687,6 +687,7 @@ void do_restore(JCR *jcr) } break; + case STREAM_XATTR_IRIX: case STREAM_XATTR_TRU64: case STREAM_XATTR_AIX: case STREAM_XATTR_OPENBSD: diff --git a/bacula/src/filed/xattr.c b/bacula/src/filed/xattr.c index 5c937a5c25..474bfff75c 100644 --- a/bacula/src/filed/xattr.c +++ b/bacula/src/filed/xattr.c @@ -34,6 +34,7 @@ * Currently we support the following OSes: * - AIX (Extended Attributes) * - Darwin (Extended Attributes) + * - IRIX (Extended Attributes) * - Linux (Extended Attributes) * - NetBSD (Extended Attributes) * - FreeBSD (Extended Attributes) @@ -599,6 +600,183 @@ bail_out: static bxattr_exit_code (*os_build_xattr_streams)(JCR *jcr, FF_PKT *ff_pkt) = aix_xattr_build_streams; static bxattr_exit_code (*os_parse_xattr_streams)(JCR *jcr, int stream) = aix_xattr_parse_streams; +#elif defined(HAVE_IRIX_OS) + +/* + * Define the supported XATTR streams for this OS + */ +static int os_default_xattr_streams[1] = { STREAM_XATTR_IRIX }; +static const char *xattr_acl_skiplist[1] = { NULL }; +static const char *xattr_skiplist[1] = { NULL }; + +struct xattr_naming_space { + const char *name; + int flags; +}; + +static xattr_naming_space xattr_naming_spaces[] = { + { "user", ATTR_DONTFOLLOW }, + { "root", ATTR_ROOT | ATTR_DONTFOLLOW }, + { NULL, 0 } +}; + +static bxattr_exit_code irix_xattr_build_streams(JCR *jcr, FF_PKT *ff_pkt) +{ + int cnt, xattr_count = 0; + POOLMEM *xattrbuf = get_memory(ATTR_MAX_VALUELEN); + bxattr_exit_code retval = bxattr_exit_error; + attrlist_cursor_t cursor; + attrlist_t *attrlist; + attrlist_ent_t *attrlist_ent; + alist *xattr_value_list = NULL; + + xattr_value_list = New(alist(10, not_owned_by_alist)); + + for (cnt = 0; xattr_naming_spaces[cnt]->name != NULL; cnt++) { + memset(cursor, 0, sizeof(attrlist_cursor_t)); + while (1) { + if (attr_list(jcr->last_fname, xattrbuf, ATTR_MAX_VALUELEN, + xattr_naming_spaces[cnt]->flags, &cursor) != 0) { + switch (errno) { + case ENOENT: + retval = bxattr_exit_ok; + goto bail_out; + default: + Mmsg2(jcr->errmsg, _("attr_list error on file \"%s\": ERR=%s\n"), + jcr->last_fname, be.bstrerror()); + Dmsg2(100, "attr_list error file=%s ERR=%s\n", + jcr->last_fname, be.bstrerror()); + goto bail_out; + } + } + + attrlist = (attrlist_t *)xattrbuf; + + /** + * Walk the available attributes. + */ + for (cnt = 0; cnt < attrlist->al_count; cnt++) { + attrlist_ent = ATTR_ENTRY(xattrbuf, cnt); + + /* + * Each xattr valuepair starts with a magic so we can parse it easier. + */ + current_xattr = (xattr_t *)malloc(sizeof(xattr_t)); + current_xattr->magic = XATTR_MAGIC; + expected_serialize_len += sizeof(current_xattr->magic); + + /* + * Allocate space for storing the name. + * We store the name as . + */ + current_xattr->name_length = strlen(xattr_naming_spaces[cnt]->name) + strlen(attrlist_ent->a_name) + 2; + current_xattr->name = (char *)malloc(current_xattr->name_length); + bsnprintf(current_xattr->name, current_xattr->name_length, "%s.%s", + xattr_naming_spaces[cnt]->name, attrlist_ent->a_name); + + expected_serialize_len += sizeof(current_xattr->name_length) + current_xattr->name_length; + + current_xattr->value_length = attrlist_ent->a_valuelen; + current_xattr->value = (char *)malloc(current_xattr->value_length); + memset((caddr_t)current_xattr->value, 0, current_xattr->value_length); + + /** + * Retrieve the actual value of the xattr. + */ + if (attr_get(jcr->last_fname, attrlist_ent->a_name, current_xattr->value, + current_xattr->value_length, xattr_naming_spaces[cnt]->flags) != 0) { + switch (errno) { + case ENOENT: + case ENOATTR: + free(current_xattr->value); + free(current_xattr->name); + free(current_xattr); + retval = bxattr_exit_ok; + goto bail_out; + case E2BIG: + break; + default: + free(current_xattr->value); + free(current_xattr->name); + free(current_xattr); + Mmsg2(jcr->errmsg, _("attr_list error on file \"%s\": ERR=%s\n"), + jcr->last_fname, be.bstrerror()); + Dmsg2(100, "attr_list error file=%s ERR=%s\n", + jcr->last_fname, be.bstrerror()); + goto bail_out; + } + } + + expected_serialize_len += sizeof(current_xattr->value_length) + current_xattr->value_length; + + /* + * Protect ourself against things getting out of hand. + */ + if (expected_serialize_len >= MAX_XATTR_STREAM) { + Mmsg2(jcr->errmsg, _("Xattr stream on file \"%s\" exceeds maximum size of %d bytes\n"), + jcr->last_fname, MAX_XATTR_STREAM); + goto bail_out; + } + + xattr_value_list->append(current_xattr); + xattr_count++; + } + + /** + * See if there are more attributes available for a next run of attr_list. + */ + if (attrlist->al_more == 0) { + break; + } + } + } + + /* + * If we found any xattr send them to the SD. + */ + if (xattr_count > 0) { + /* + * Serialize the datastream. + */ + if (serialize_xattr_stream(jcr, expected_serialize_len, xattr_value_list) < expected_serialize_len) { + Mmsg1(jcr->errmsg, _("Failed to serialize extended attributes on file \"%s\"\n"), + jcr->last_fname); + Dmsg1(100, "Failed to serialize extended attributes on file \"%s\"\n", + jcr->last_fname); + goto bail_out; + } + + xattr_drop_internal_table(xattr_value_list); + + /* + * Send the datastream to the SD. + */ + return send_xattr_stream(jcr, os_default_xattr_streams[0]); + } else { + xattr_drop_internal_table(xattr_value_list); + + return bxattr_exit_ok; + } + +bail_out: + free_pool_memory(xattrbuf); + + if (xattr_value_list != NULL) { + xattr_drop_internal_table(xattr_value_list); + } + return retval; +} + +static bxattr_exit_code irix_xattr_parse_streams(JCR *jcr, int stream) +{ +} + +/* + * Function pointers to the build and parse function to use for these xattrs. + */ +static bxattr_exit_code (*os_build_xattr_streams)(JCR *jcr, FF_PKT *ff_pkt) = irix_xattr_build_streams; +static bxattr_exit_code (*os_parse_xattr_streams)(JCR *jcr, int stream) = irix_xattr_parse_streams; + #elif defined(HAVE_DARWIN_OS) || \ defined(HAVE_LINUX_OS) diff --git a/bacula/src/findlib/bfile.c b/bacula/src/findlib/bfile.c index 584902c380..c6fecfb134 100644 --- a/bacula/src/findlib/bfile.c +++ b/bacula/src/findlib/bfile.c @@ -173,6 +173,8 @@ const char *stream_to_ascii(int stream) return _("AIX Specific ACL attribs"); case STREAM_ACL_AIX_NFS4: return _("AIX Specific ACL attribs"); + case STREAM_XATTR_IRIX: + return _("IRIX Specific Extended attribs"); case STREAM_XATTR_TRU64: return _("TRU64 Specific Extended attribs"); case STREAM_XATTR_AIX: -- 2.39.5