From 934297a8f86e491bbdeb63883e5a7291686a1232 Mon Sep 17 00:00:00 2001 From: Marco van Wieringen Date: Fri, 6 Jan 2012 19:31:30 +0100 Subject: [PATCH] Don't copy xattr and acl streams. - With the new delayed restore of xattr and acl streams we copy the stream twice. First from the SD buffer to the stack and then again from the stack when we pop an element into a JCR POOLMEM. This can be done a bit more efficient. So we break the JCR struct into an union one for a build of xattr and acl streams and one for a parse of them. We pass the content and content_length now as arguments along the parse (restore) code path. This saves for the delayed version one copy and for a directory copying is not done at all. - Reformatted some code along the way, - functions with more then 2 arguments are splitted over multiple lines. - The stream arrays etc are formated a bit differently so they are better readable and easy to extend. - The build and parse function pointers are formated a bit differently so they span multiple lines and should be better readable. - reformated long lines - Fixed Tru64 acl code. --- bacula/src/filed/acl.c | 519 +++++++++++++++--------- bacula/src/filed/acl.h | 19 +- bacula/src/filed/backup.c | 34 +- bacula/src/filed/protos.h | 4 +- bacula/src/filed/restore.c | 63 ++- bacula/src/filed/xattr.c | 800 +++++++++++++++++++++++++------------ bacula/src/filed/xattr.h | 23 +- 7 files changed, 966 insertions(+), 496 deletions(-) diff --git a/bacula/src/filed/acl.c b/bacula/src/filed/acl.c index 27696fdc52..cf0f442ceb 100644 --- a/bacula/src/filed/acl.c +++ b/bacula/src/filed/acl.c @@ -1,7 +1,7 @@ /* Bacula® - The Network Backup Solution - Copyright (C) 2004-2010 Free Software Foundation Europe e.V. + Copyright (C) 2004-2012 Free Software Foundation Europe e.V. The main author of Bacula is Kern Sibbald, with contributions from many others, a complete list can be found in the file AUTHORS. @@ -55,8 +55,9 @@ * certain platforms and if they use they same encoding we might allow * different platform streams to be decoded on an other similar platform. * - * Original written by Preben 'Peppe' Guldberg, December MMIV - * Major rewrite by Marco van Wieringen, November MMVIII + * Original written by Preben 'Peppe' Guldberg, December 2004 + * Major rewrite by Marco van Wieringen, November 2008 + * Major overhaul by Marco van Wieringen, January 2012 */ #include "bacula.h" @@ -71,7 +72,10 @@ bacl_exit_code build_acl_streams(JCR *jcr, FF_PKT *ff_pkt) return bacl_exit_fatal; } -bacl_exit_code parse_acl_streams(JCR *jcr, int stream) +bacl_exit_code parse_acl_streams(JCR *jcr, + int stream, + char *content, + uint32_t content_length) { return bacl_exit_fatal; } @@ -90,7 +94,7 @@ static bacl_exit_code send_acl_stream(JCR *jcr, int stream) /* * Sanity check */ - if (jcr->acl_data->content_length <= 0) { + if (jcr->acl_data->u.build->content_length <= 0) { return bacl_exit_ok; } @@ -106,10 +110,10 @@ static bacl_exit_code send_acl_stream(JCR *jcr, int stream) /* * Send the buffer to the storage deamon */ - Dmsg1(400, "Backing up ACL <%s>\n", jcr->acl_data->content); + Dmsg1(400, "Backing up ACL <%s>\n", jcr->acl_data->u.build->content); msgsave = sd->msg; - sd->msg = jcr->acl_data->content; - sd->msglen = jcr->acl_data->content_length + 1; + sd->msg = jcr->acl_data->u.build->content; + sd->msglen = jcr->acl_data->u.build->content_length + 1; if (!sd->send()) { sd->msg = msgsave; sd->msglen = 0; @@ -154,8 +158,14 @@ static bool acl_nfs4_is_trivial(nfs4_acl_int_t *acl) /* * Define the supported ACL streams for this OS */ -static int os_access_acl_streams[3] = { STREAM_ACL_AIX_TEXT, STREAM_ACL_AIX_AIXC, STREAM_ACL_AIX_NFS4 }; -static int os_default_acl_streams[1] = { -1 }; +static int os_access_acl_streams[3] = { + STREAM_ACL_AIX_TEXT, + STREAM_ACL_AIX_AIXC, + STREAM_ACL_AIX_NFS4 +}; +static int os_default_acl_streams[1] = { + -1 +}; static bacl_exit_code aix_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt) { @@ -176,7 +186,8 @@ static bacl_exit_code aix_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt) retval = bacl_exit_ok; goto bail_out; default: - Mmsg2(jcr->errmsg, _("aclx_get error on file \"%s\": ERR=%s\n"), + Mmsg2(jcr->errmsg, + _("aclx_get error on file \"%s\": ERR=%s\n"), jcr->last_fname, be.bstrerror()); Dmsg2(100, "aclx_get error file=%s ERR=%s\n", jcr->last_fname, be.bstrerror()); @@ -198,7 +209,8 @@ static bacl_exit_code aix_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt) retval = bacl_exit_ok; goto bail_out; default: - Mmsg2(jcr->errmsg, _("aclx_get error on file \"%s\": ERR=%s\n"), + Mmsg2(jcr->errmsg, + _("aclx_get error on file \"%s\": ERR=%s\n"), jcr->last_fname, be.bstrerror()); Dmsg2(100, "aclx_get error file=%s ERR=%s\n", jcr->last_fname, be.bstrerror()); @@ -223,7 +235,8 @@ static bacl_exit_code aix_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt) } break; default: - Mmsg2(jcr->errmsg, _("Unknown acl type encountered on file \"%s\": %ld\n"), + Mmsg2(jcr->errmsg, + _("Unknown acl type encountered on file \"%s\": %ld\n"), jcr->last_fname, type.u64); Dmsg2(100, "Unknown acl type encountered on file \"%s\": %ld\n", jcr->last_fname, type.u64); @@ -233,8 +246,8 @@ static bacl_exit_code aix_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt) /* * We have a non-trivial acl lets convert it into some ASCII form. */ - acltxtsize = sizeof_pool_memory(jcr->acl_data->content); - if (aclx_printStr(jcr->acl_data->content, &acltxtsize, aclbuf, + acltxtsize = sizeof_pool_memory(jcr->acl_data->u.build->content); + if (aclx_printStr(jcr->acl_data->u.build->content, &acltxtsize, aclbuf, aclsize, type, jcr->last_fname, 0) < 0) { switch (errno) { case ENOSPC: @@ -242,10 +255,12 @@ static bacl_exit_code aix_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt) * Our buffer is not big enough, acltxtsize should be updated with the value * the aclx_printStr really need. So we increase the buffer and try again. */ - jcr->acl_data->content = check_pool_memory_size(jcr->acl_data->content, acltxtsize + 1); - if (aclx_printStr(jcr->acl_data->content, &acltxtsize, aclbuf, + jcr->acl_data->u.build->content = + check_pool_memory_size(jcr->acl_data->u.build->content, acltxtsize + 1); + if (aclx_printStr(jcr->acl_data->u.build->content, &acltxtsize, aclbuf, aclsize, type, jcr->last_fname, 0) < 0) { - Mmsg1(jcr->errmsg, _("Failed to convert acl into text on file \"%s\"\n"), + Mmsg1(jcr->errmsg, + _("Failed to convert acl into text on file \"%s\"\n"), jcr->last_fname); Dmsg2(100, "Failed to convert acl into text on file \"%s\": %ld\n", jcr->last_fname, type.u64); @@ -253,7 +268,8 @@ static bacl_exit_code aix_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt) } break; default: - Mmsg1(jcr->errmsg, _("Failed to convert acl into text on file \"%s\"\n"), + Mmsg1(jcr->errmsg, + _("Failed to convert acl into text on file \"%s\"\n"), jcr->last_fname); Dmsg2(100, "Failed to convert acl into text on file \"%s\": %ld\n", jcr->last_fname, type.u64); @@ -261,7 +277,7 @@ static bacl_exit_code aix_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt) } } - jcr->acl_data->content_length = strlen(jcr->acl_data->content) + 1; + jcr->acl_data->u.build->u.build->content_length = strlen(jcr->acl_data->u.build->content) + 1; switch (type.u64) { case ACL_AIXC: retval = send_acl_stream(jcr, STREAM_ACL_AIX_AIXC); @@ -275,7 +291,10 @@ bail_out: return retval; } -static bacl_exit_code aix_parse_acl_streams(JCR *jcr, int stream) +static bacl_exit_code aix_parse_acl_streams(JCR *jcr, + int stream, + char *content, + uint32_t content_length) { int cnt; berrno be; @@ -289,7 +308,7 @@ static bacl_exit_code aix_parse_acl_streams(JCR *jcr, int stream) /* * Handle the old stream using the old system call for now. */ - if (acl_put(jcr->last_fname, jcr->acl_data->content, 0) != 0) { + if (acl_put(jcr->last_fname, content, 0) != 0) { retval = bacl_exit_error; goto bail_out; } @@ -309,9 +328,9 @@ static bacl_exit_code aix_parse_acl_streams(JCR *jcr, int stream) * Set the acl buffer to an initial size. For now we set it * to the same size as the ASCII representation. */ - aclbuf = check_pool_memory_size(aclbuf, jcr->acl_data->content_length); - aclsize = jcr->acl_data->content_length; - if (aclx_scanStr(jcr->acl_data->content, aclbuf, &aclsize, type) < 0) { + aclbuf = check_pool_memory_size(aclbuf, content_length); + aclsize = content_length; + if (aclx_scanStr(content, aclbuf, &aclsize, type) < 0) { switch (errno) { case ENOSPC: /* @@ -324,7 +343,7 @@ static bacl_exit_code aix_parse_acl_streams(JCR *jcr, int stream) aclsize = 2 * aclsize; aclbuf = check_pool_memory_size(aclbuf, aclsize); - if (aclx_scanStr(jcr->acl_data->content, aclbuf, &aclsize, type) == 0) { + if (aclx_scanStr(content, aclbuf, &aclsize, type) == 0) { break; } @@ -339,7 +358,8 @@ static bacl_exit_code aix_parse_acl_streams(JCR *jcr, int stream) } /* FALL THROUGH */ default: - Mmsg2(jcr->errmsg, _("aclx_scanStr error on file \"%s\": ERR=%s\n"), + Mmsg2(jcr->errmsg, + _("aclx_scanStr error on file \"%s\": ERR=%s\n"), jcr->last_fname, be.bstrerror()); Dmsg2(100, "aclx_scanStr error file=%s ERR=%s\n", jcr->last_fname, be.bstrerror()); @@ -348,7 +368,8 @@ static bacl_exit_code aix_parse_acl_streams(JCR *jcr, int stream) } break; default: - Mmsg2(jcr->errmsg, _("aclx_scanStr error on file \"%s\": ERR=%s\n"), + Mmsg2(jcr->errmsg, + _("aclx_scanStr error on file \"%s\": ERR=%s\n"), jcr->last_fname, be.bstrerror()); Dmsg2(100, "aclx_scanStr error file=%s ERR=%s\n", jcr->last_fname, be.bstrerror()); @@ -361,7 +382,8 @@ static bacl_exit_code aix_parse_acl_streams(JCR *jcr, int stream) retval = bacl_exit_ok; goto bail_out; default: - Mmsg2(jcr->errmsg, _("aclx_put error on file \"%s\": ERR=%s\n"), + Mmsg2(jcr->errmsg, + _("aclx_put error on file \"%s\": ERR=%s\n"), jcr->last_fname, be.bstrerror()); Dmsg2(100, "aclx_put error file=%s ERR=%s\n", jcr->last_fname, be.bstrerror()); @@ -384,24 +406,32 @@ bail_out: /* * Define the supported ACL streams for this OS */ -static int os_access_acl_streams[1] = { STREAM_ACL_AIX_TEXT }; -static int os_default_acl_streams[1] = { -1 }; +static int os_access_acl_streams[1] = { + STREAM_ACL_AIX_TEXT +}; +static int os_default_acl_streams[1] = { + -1 +}; static bacl_exit_code aix_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt) { char *acl_text; if ((acl_text = acl_get(jcr->last_fname)) != NULL) { - jcr->acl_data->content_length = pm_strcpy(jcr->acl_data->content, acl_text); + jcr->acl_data->u.build->content_length = + pm_strcpy(jcr->acl_data->u.build->content, acl_text); actuallyfree(acl_text); return send_acl_stream(jcr, STREAM_ACL_AIX_TEXT); } return bacl_exit_error; } -static bacl_exit_code aix_parse_acl_streams(JCR *jcr, int stream) +static bacl_exit_code aix_parse_acl_streams(JCR *jcr, + int stream, + char *content, + uint32_t content_length) { - if (acl_put(jcr->last_fname, jcr->acl_data->content, 0) != 0) { + if (acl_put(jcr->last_fname, content, 0) != 0) { return bacl_exit_error; } return bacl_exit_ok; @@ -411,8 +441,12 @@ static bacl_exit_code aix_parse_acl_streams(JCR *jcr, int stream) /* * For this OS setup the build and parse function pointer to the OS specific functions. */ -static bacl_exit_code (*os_build_acl_streams)(JCR *jcr, FF_PKT *ff_pkt) = aix_build_acl_streams; -static bacl_exit_code (*os_parse_acl_streams)(JCR *jcr, int stream) = aix_parse_acl_streams; +static bacl_exit_code (*os_build_acl_streams) + (JCR *jcr, FF_PKT *ff_pkt) = + aix_build_acl_streams; +static bacl_exit_code (*os_parse_acl_streams) + (JCR *jcr, int stream, char *content, uint32_t content_length) = + aix_parse_acl_streams; #elif defined(HAVE_DARWIN_OS) || \ defined(HAVE_FREEBSD_OS) || \ @@ -683,13 +717,15 @@ static bacl_exit_code generic_get_acl_from_os(JCR *jcr, bacl_type acltype) * Convert the internal acl representation into a text representation. */ if ((acl_text = acl_to_text(acl, NULL)) != NULL) { - jcr->acl_data->content_length = pm_strcpy(jcr->acl_data->content, acl_text); + jcr->acl_data->u.build->content_length = + pm_strcpy(jcr->acl_data->u.build->content, acl_text); acl_free(acl); acl_free(acl_text); return bacl_exit_ok; } - Mmsg2(jcr->errmsg, _("acl_to_text error on file \"%s\": ERR=%s\n"), + Mmsg2(jcr->errmsg, + _("acl_to_text error on file \"%s\": ERR=%s\n"), jcr->last_fname, be.bstrerror()); Dmsg2(100, "acl_to_text error file=%s ERR=%s\n", jcr->last_fname, be.bstrerror()); @@ -716,7 +752,8 @@ static bacl_exit_code generic_get_acl_from_os(JCR *jcr, bacl_type acltype) goto bail_out; default: /* Some real error */ - Mmsg2(jcr->errmsg, _("acl_get_file error on file \"%s\": ERR=%s\n"), + Mmsg2(jcr->errmsg, + _("acl_get_file error on file \"%s\": ERR=%s\n"), jcr->last_fname, be.bstrerror()); Dmsg2(100, "acl_get_file error file=%s ERR=%s\n", jcr->last_fname, be.bstrerror()); @@ -730,15 +767,18 @@ bail_out: if (acl) { acl_free(acl); } - pm_strcpy(jcr->acl_data->content, ""); - jcr->acl_data->content_length = 0; + pm_strcpy(jcr->acl_data->u.build->content, ""); + jcr->acl_data->u.build->content_length = 0; return retval; } /** * Generic wrapper around acl_set_file call. */ -static bacl_exit_code generic_set_acl_on_os(JCR *jcr, bacl_type acltype) +static bacl_exit_code generic_set_acl_on_os(JCR *jcr, + bacl_type acltype, + char *content, + uint32_t content_length) { acl_t acl; acl_type_t ostype; @@ -748,7 +788,7 @@ static bacl_exit_code generic_set_acl_on_os(JCR *jcr, bacl_type acltype) * If we get empty default ACLs, clear ACLs now */ ostype = bac_to_os_acltype(acltype); - if (ostype == ACL_TYPE_DEFAULT && strlen(jcr->acl_data->content) == 0) { + if (ostype == ACL_TYPE_DEFAULT && strlen(content) == 0) { if (acl_delete_def_file(jcr->last_fname) == 0) { return bacl_exit_ok; } @@ -764,23 +804,26 @@ static bacl_exit_code generic_set_acl_on_os(JCR *jcr, bacl_type acltype) * when we change from one filesystem to an other. */ jcr->acl_data->flags &= ~BACL_FLAG_RESTORE_NATIVE; - Mmsg1(jcr->errmsg, _("acl_delete_def_file error on file \"%s\": filesystem doesn't support ACLs\n"), + Mmsg1(jcr->errmsg, + _("acl_delete_def_file error on file \"%s\": filesystem doesn't support ACLs\n"), jcr->last_fname); return bacl_exit_error; #endif default: - Mmsg2(jcr->errmsg, _("acl_delete_def_file error on file \"%s\": ERR=%s\n"), + Mmsg2(jcr->errmsg, + _("acl_delete_def_file error on file \"%s\": ERR=%s\n"), jcr->last_fname, be.bstrerror()); return bacl_exit_error; } } - acl = acl_from_text(jcr->acl_data->content); + acl = acl_from_text(content); if (acl == NULL) { - Mmsg2(jcr->errmsg, _("acl_from_text error on file \"%s\": ERR=%s\n"), + Mmsg2(jcr->errmsg, + _("acl_from_text error on file \"%s\": ERR=%s\n"), jcr->last_fname, be.bstrerror()); Dmsg3(100, "acl_from_text error acl=%s file=%s ERR=%s\n", - jcr->acl_data->content, jcr->last_fname, be.bstrerror()); + content, jcr->last_fname, be.bstrerror()); return bacl_exit_error; } @@ -790,10 +833,11 @@ static bacl_exit_code generic_set_acl_on_os(JCR *jcr, bacl_type acltype) * As it does the right thing, given valid input, just ignore acl_valid(). */ if (acl_valid(acl) != 0) { - Mmsg2(jcr->errmsg, _("acl_valid error on file \"%s\": ERR=%s\n"), + Mmsg2(jcr->errmsg, + _("acl_valid error on file \"%s\": ERR=%s\n"), jcr->last_fname, be.bstrerror()); Dmsg3(100, "acl_valid error acl=%s file=%s ERR=%s\n", - jcr->acl_data->content, jcr->last_fname, be.bstrerror()); + content, jcr->last_fname, be.bstrerror()); acl_free(acl); return bacl_exit_error; } @@ -819,18 +863,20 @@ static bacl_exit_code generic_set_acl_on_os(JCR *jcr, bacl_type acltype) * when we change from one filesystem to an other. */ jcr->acl_data->flags &= ~BACL_FLAG_RESTORE_NATIVE; - Mmsg1(jcr->errmsg, _("acl_set_file error on file \"%s\": filesystem doesn't support ACLs\n"), + Mmsg1(jcr->errmsg, + _("acl_set_file error on file \"%s\": filesystem doesn't support ACLs\n"), jcr->last_fname); Dmsg2(100, "acl_set_file error acl=%s file=%s filesystem doesn't support ACLs\n", - jcr->acl_data->content, jcr->last_fname); + content, jcr->last_fname); acl_free(acl); return bacl_exit_error; #endif default: - Mmsg2(jcr->errmsg, _("acl_set_file error on file \"%s\": ERR=%s\n"), + Mmsg2(jcr->errmsg, + _("acl_set_file error on file \"%s\": ERR=%s\n"), jcr->last_fname, be.bstrerror()); Dmsg3(100, "acl_set_file error acl=%s file=%s ERR=%s\n", - jcr->acl_data->content, jcr->last_fname, be.bstrerror()); + content, jcr->last_fname, be.bstrerror()); acl_free(acl); return bacl_exit_error; } @@ -846,8 +892,12 @@ static bacl_exit_code generic_set_acl_on_os(JCR *jcr, bacl_type acltype) /** * Define the supported ACL streams for this OS */ -static int os_access_acl_streams[1] = { STREAM_ACL_DARWIN_ACCESS_ACL }; -static int os_default_acl_streams[1] = { -1 }; +static int os_access_acl_streams[1] = { + STREAM_ACL_DARWIN_ACCESS_ACL +}; +static int os_default_acl_streams[1] = { + -1 +}; static bacl_exit_code darwin_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt) { @@ -871,33 +921,45 @@ static bacl_exit_code darwin_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt) return bacl_exit_fatal; #endif - if (jcr->acl_data->content_length > 0) { + if (jcr->acl_data->u.build->content_length > 0) { return send_acl_stream(jcr, STREAM_ACL_DARWIN_ACCESS_ACL); } return bacl_exit_ok; } -static bacl_exit_code darwin_parse_acl_streams(JCR *jcr, int stream) +static bacl_exit_code darwin_parse_acl_streams(JCR *jcr, + int stream, + char *content, + uint32_t content_length) { #if defined(HAVE_ACL_TYPE_EXTENDED) - return generic_set_acl_on_os(jcr, BACL_TYPE_EXTENDED); + return generic_set_acl_on_os(jcr, BACL_TYPE_EXTENDED, content, content_length); #else - return generic_set_acl_on_os(jcr, BACL_TYPE_ACCESS); + return generic_set_acl_on_os(jcr, BACL_TYPE_ACCESS, content, content_length); #endif } /* * For this OS setup the build and parse function pointer to the OS specific functions. */ -static bacl_exit_code (*os_build_acl_streams)(JCR *jcr, FF_PKT *ff_pkt) = darwin_build_acl_streams; -static bacl_exit_code (*os_parse_acl_streams)(JCR *jcr, int stream) = darwin_parse_acl_streams; +static bacl_exit_code (*os_build_acl_streams) + (JCR *jcr, FF_PKT *ff_pkt) = + darwin_build_acl_streams; +static bacl_exit_code (*os_parse_acl_streams) + (JCR *jcr, int stream, char *content, uint32_t content_length) = + darwin_parse_acl_streams; #elif defined(HAVE_FREEBSD_OS) /* * Define the supported ACL streams for these OSes */ -static int os_access_acl_streams[2] = { STREAM_ACL_FREEBSD_ACCESS_ACL, STREAM_ACL_FREEBSD_NFS4_ACL }; -static int os_default_acl_streams[1] = { STREAM_ACL_FREEBSD_DEFAULT_ACL }; +static int os_access_acl_streams[2] = { + STREAM_ACL_FREEBSD_ACCESS_ACL, + STREAM_ACL_FREEBSD_NFS4_ACL +}; +static int os_default_acl_streams[1] = { + STREAM_ACL_FREEBSD_DEFAULT_ACL +}; static bacl_exit_code freebsd_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt) { @@ -916,7 +978,8 @@ static bacl_exit_code freebsd_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt) case ENOENT: return bacl_exit_ok; default: - Mmsg2(jcr->errmsg, _("pathconf error on file \"%s\": ERR=%s\n"), + Mmsg2(jcr->errmsg, + _("pathconf error on file \"%s\": ERR=%s\n"), jcr->last_fname, be.bstrerror()); Dmsg2(100, "pathconf error file=%s ERR=%s\n", jcr->last_fname, be.bstrerror()); @@ -941,7 +1004,8 @@ static bacl_exit_code freebsd_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt) case ENOENT: return bacl_exit_ok; default: - Mmsg2(jcr->errmsg, _("pathconf error on file \"%s\": ERR=%s\n"), + Mmsg2(jcr->errmsg, + _("pathconf error on file \"%s\": ERR=%s\n"), jcr->last_fname, be.bstrerror()); Dmsg2(100, "pathconf error file=%s ERR=%s\n", jcr->last_fname, be.bstrerror()); @@ -963,8 +1027,8 @@ static bacl_exit_code freebsd_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt) */ if (acl_enabled == 0) { jcr->acl_data->flags &= ~BACL_FLAG_SAVE_NATIVE; - pm_strcpy(jcr->acl_data->content, ""); - jcr->acl_data->content_length = 0; + pm_strcpy(jcr->acl_data->u.build->content, ""); + jcr->acl_data->u.build->content_length = 0; return bacl_exit_ok; } @@ -979,7 +1043,7 @@ static bacl_exit_code freebsd_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt) if (generic_get_acl_from_os(jcr, BACL_TYPE_NFS4) == bacl_exit_fatal) return bacl_exit_fatal; - if (jcr->acl_data->content_length > 0) { + if (jcr->acl_data->u.build->content_length > 0) { if (send_acl_stream(jcr, STREAM_ACL_FREEBSD_NFS4_ACL) == bacl_exit_fatal) return bacl_exit_fatal; } @@ -991,7 +1055,7 @@ static bacl_exit_code freebsd_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt) if (generic_get_acl_from_os(jcr, BACL_TYPE_ACCESS) == bacl_exit_fatal) return bacl_exit_fatal; - if (jcr->acl_data->content_length > 0) { + if (jcr->acl_data->u.build->content_length > 0) { if (send_acl_stream(jcr, STREAM_ACL_FREEBSD_ACCESS_ACL) == bacl_exit_fatal) return bacl_exit_fatal; } @@ -1002,7 +1066,7 @@ static bacl_exit_code freebsd_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt) if (ff_pkt->type == FT_DIREND) { if (generic_get_acl_from_os(jcr, BACL_TYPE_DEFAULT) == bacl_exit_fatal) return bacl_exit_fatal; - if (jcr->acl_data->content_length > 0) { + if (jcr->acl_data->u.build->content_length > 0) { if (send_acl_stream(jcr, STREAM_ACL_FREEBSD_DEFAULT_ACL) == bacl_exit_fatal) return bacl_exit_fatal; } @@ -1015,7 +1079,10 @@ static bacl_exit_code freebsd_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt) return bacl_exit_ok; } -static bacl_exit_code freebsd_parse_acl_streams(JCR *jcr, int stream) +static bacl_exit_code freebsd_parse_acl_streams(JCR *jcr, + int stream, + char *content, + uint32_t content_length) { int acl_enabled = 0; const char *acl_type_name; @@ -1049,10 +1116,11 @@ static bacl_exit_code freebsd_parse_acl_streams(JCR *jcr, int stream) case ENOENT: return bacl_exit_ok; default: - Mmsg2(jcr->errmsg, _("pathconf error on file \"%s\": ERR=%s\n"), + Mmsg2(jcr->errmsg, + _("pathconf error on file \"%s\": ERR=%s\n"), jcr->last_fname, be.bstrerror()); Dmsg3(100, "pathconf error acl=%s file=%s ERR=%s\n", - jcr->acl_data->content, jcr->last_fname, be.bstrerror()); + content, jcr->last_fname, be.bstrerror()); return bacl_exit_error; } case 0: @@ -1063,7 +1131,8 @@ static bacl_exit_code freebsd_parse_acl_streams(JCR *jcr, int stream) * when we change from one filesystem to an other. */ jcr->acl_data->flags &= ~BACL_FLAG_SAVE_NATIVE; - Mmsg2(jcr->errmsg, _("Trying to restore acl on file \"%s\" on filesystem without %s acl support\n"), + Mmsg2(jcr->errmsg, + _("Trying to restore acl on file \"%s\" on filesystem without %s acl support\n"), jcr->last_fname, acl_type_name); return bacl_exit_error; default: @@ -1076,12 +1145,12 @@ static bacl_exit_code freebsd_parse_acl_streams(JCR *jcr, int stream) switch (stream) { case STREAM_UNIX_ACCESS_ACL: case STREAM_ACL_FREEBSD_ACCESS_ACL: - return generic_set_acl_on_os(jcr, BACL_TYPE_ACCESS); + return generic_set_acl_on_os(jcr, BACL_TYPE_ACCESS, content, content_length); case STREAM_UNIX_DEFAULT_ACL: case STREAM_ACL_FREEBSD_DEFAULT_ACL: - return generic_set_acl_on_os(jcr, BACL_TYPE_DEFAULT); + return generic_set_acl_on_os(jcr, BACL_TYPE_DEFAULT, content, content_length); case STREAM_ACL_FREEBSD_NFS4_ACL: - return generic_set_acl_on_os(jcr, BACL_TYPE_NFS4); + return generic_set_acl_on_os(jcr, BACL_TYPE_NFS4, content, content_length); default: break; } @@ -1091,8 +1160,12 @@ static bacl_exit_code freebsd_parse_acl_streams(JCR *jcr, int stream) /* * For this OSes setup the build and parse function pointer to the OS specific functions. */ -static bacl_exit_code (*os_build_acl_streams)(JCR *jcr, FF_PKT *ff_pkt) = freebsd_build_acl_streams; -static bacl_exit_code (*os_parse_acl_streams)(JCR *jcr, int stream) = freebsd_parse_acl_streams; +static bacl_exit_code (*os_build_acl_streams) + (JCR *jcr, FF_PKT *ff_pkt) = + freebsd_build_acl_streams; +static bacl_exit_code (*os_parse_acl_streams) + (JCR *jcr, int stream, char *content, uint32_t content_length) = + freebsd_parse_acl_streams; #elif defined(HAVE_IRIX_OS) || \ defined(HAVE_LINUX_OS) @@ -1100,11 +1173,19 @@ static bacl_exit_code (*os_parse_acl_streams)(JCR *jcr, int stream) = freebsd_pa * Define the supported ACL streams for these OSes */ #if defined(HAVE_IRIX_OS) -static int os_access_acl_streams[1] = { STREAM_ACL_IRIX_ACCESS_ACL }; -static int os_default_acl_streams[1] = { STREAM_ACL_IRIX_DEFAULT_ACL }; +static int os_access_acl_streams[1] = { + STREAM_ACL_IRIX_ACCESS_ACL +}; +static int os_default_acl_streams[1] = { + STREAM_ACL_IRIX_DEFAULT_ACL +}; #elif defined(HAVE_LINUX_OS) -static int os_access_acl_streams[1] = { STREAM_ACL_LINUX_ACCESS_ACL }; -static int os_default_acl_streams[1] = { STREAM_ACL_LINUX_DEFAULT_ACL }; +static int os_access_acl_streams[1] = { + STREAM_ACL_LINUX_ACCESS_ACL +}; +static int os_default_acl_streams[1] = { + STREAM_ACL_LINUX_DEFAULT_ACL +}; #endif static bacl_exit_code generic_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt) @@ -1115,7 +1196,7 @@ static bacl_exit_code generic_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt) if (generic_get_acl_from_os(jcr, BACL_TYPE_ACCESS) == bacl_exit_fatal) return bacl_exit_fatal; - if (jcr->acl_data->content_length > 0) { + if (jcr->acl_data->u.build->content_length > 0) { if (send_acl_stream(jcr, os_access_acl_streams[0]) == bacl_exit_fatal) return bacl_exit_fatal; } @@ -1126,7 +1207,7 @@ static bacl_exit_code generic_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt) if (ff_pkt->type == FT_DIREND) { if (generic_get_acl_from_os(jcr, BACL_TYPE_DEFAULT) == bacl_exit_fatal) return bacl_exit_fatal; - if (jcr->acl_data->content_length > 0) { + if (jcr->acl_data->u.build->content_length > 0) { if (send_acl_stream(jcr, os_default_acl_streams[0]) == bacl_exit_fatal) return bacl_exit_fatal; } @@ -1134,27 +1215,30 @@ static bacl_exit_code generic_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt) return bacl_exit_ok; } -static bacl_exit_code generic_parse_acl_streams(JCR *jcr, int stream) +static bacl_exit_code generic_parse_acl_streams(JCR *jcr, + int stream, + char *content, + uint32_t content_length) { unsigned int cnt; switch (stream) { case STREAM_UNIX_ACCESS_ACL: - return generic_set_acl_on_os(jcr, BACL_TYPE_ACCESS); + return generic_set_acl_on_os(jcr, BACL_TYPE_ACCESS, content, content_length); case STREAM_UNIX_DEFAULT_ACL: - return generic_set_acl_on_os(jcr, BACL_TYPE_DEFAULT); + return generic_set_acl_on_os(jcr, BACL_TYPE_DEFAULT, content, content_length); default: /* * See what type of acl it is. */ for (cnt = 0; cnt < sizeof(os_access_acl_streams) / sizeof(int); cnt++) { if (os_access_acl_streams[cnt] == stream) { - return generic_set_acl_on_os(jcr, BACL_TYPE_ACCESS); + return generic_set_acl_on_os(jcr, BACL_TYPE_ACCESS, content, content_length); } } for (cnt = 0; cnt < sizeof(os_default_acl_streams) / sizeof(int); cnt++) { if (os_default_acl_streams[cnt] == stream) { - return generic_set_acl_on_os(jcr, BACL_TYPE_DEFAULT); + return generic_set_acl_on_os(jcr, BACL_TYPE_DEFAULT, content, content_length); } } break; @@ -1165,25 +1249,34 @@ static bacl_exit_code generic_parse_acl_streams(JCR *jcr, int stream) /* * For this OSes setup the build and parse function pointer to the OS specific functions. */ -static bacl_exit_code (*os_build_acl_streams)(JCR *jcr, FF_PKT *ff_pkt) = generic_build_acl_streams; -static bacl_exit_code (*os_parse_acl_streams)(JCR *jcr, int stream) = generic_parse_acl_streams; +static bacl_exit_code (*os_build_acl_streams) + (JCR *jcr, FF_PKT *ff_pkt) = + generic_build_acl_streams; +static bacl_exit_code (*os_parse_acl_streams) + (JCR *jcr, int stream, char *content, uint32_t content_length) = + generic_parse_acl_streams; #elif defined(HAVE_OSF1_OS) /* * Define the supported ACL streams for this OS */ -static int os_access_acl_streams[1] = { STREAM_ACL_TRU64_ACCESS_ACL }; -static int os_default_acl_streams[2] = { STREAM_ACL_TRU64_DEFAULT_ACL, STREAM_ACL_TRU64_DEFAULT_DIR_ACL }; +static int os_access_acl_streams[1] = { + STREAM_ACL_TRU64_ACCESS_ACL +}; +static int os_default_acl_streams[2] = { + STREAM_ACL_TRU64_DEFAULT_ACL, + STREAM_ACL_TRU64_DEFAULT_DIR_ACL +}; static bacl_exit_code tru64_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt) { /* * Read access ACLs for files, dirs and links */ - if ((jcr->acl_data->content_length = generic_get_acl_from_os(jcr, BACL_TYPE_ACCESS)) < 0) + if (generic_get_acl_from_os(jcr, BACL_TYPE_ACCESS) == bacl_exit_fatal) { return bacl_exit_error; - if (jcr->acl_data->content_length > 0) { + if (jcr->acl_data->u.build->content_length > 0) { if (!send_acl_stream(jcr, STREAM_ACL_TRU64_ACCESS_ACL)) return bacl_exit_error; } @@ -1191,9 +1284,9 @@ static bacl_exit_code tru64_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt) * Directories can have default ACLs too */ if (ff_pkt->type == FT_DIREND) { - if ((jcr->acl_data->content_length = generic_get_acl_from_os(jcr, BACL_TYPE_DEFAULT)) < 0) + if (generic_get_acl_from_os(jcr, BACL_TYPE_DEFAULT) == bacl_exit_fatal) { return bacl_exit_error; - if (jcr->acl_data->content_length > 0) { + if (jcr->acl_data->u.build->content_length > 0) { if (!send_acl_stream(jcr, STREAM_ACL_TRU64_DEFAULT_ACL)) return bacl_exit_error; } @@ -1203,9 +1296,9 @@ static bacl_exit_code tru64_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt) * See http://www.helsinki.fi/atk/unix/dec_manuals/DOC_40D/AQ0R2DTE/DOCU_018.HTM * Section 21.5 Default ACLs */ - if ((jcr->acl_data->content_length = generic_get_acl_from_os(jcr, BACL_TYPE_DEFAULT_DIR)) < 0) + if (generic_get_acl_from_os(jcr, BACL_TYPE_DEFAULT_DIR) == bacl_exit_fatal) { return bacl_exit_error; - if (jcr->acl_data->content_length > 0) { + if (jcr->acl_data->u.build->content_length > 0) { if (!send_acl_stream(jcr, STREAM_ACL_TRU64_DEFAULT_DIR_ACL)) return bacl_exit_error; } @@ -1213,24 +1306,31 @@ static bacl_exit_code tru64_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt) return bacl_exit_ok; } -static bacl_exit_code tru64_parse_acl_streams(JCR *jcr, int stream) +static bacl_exit_code tru64_parse_acl_streams(JCR *jcr, + int stream, + char *content, + uint32_t content_length) { switch (stream) { case STREAM_UNIX_ACCESS_ACL: case STREAM_ACL_TRU64_ACCESS_ACL: - return generic_set_acl_on_os(jcr, BACL_TYPE_ACCESS); + return generic_set_acl_on_os(jcr, BACL_TYPE_ACCESS, content, content_length); case STREAM_UNIX_DEFAULT_ACL: case STREAM_ACL_TRU64_DEFAULT_ACL: - return generic_set_acl_on_os(jcr, BACL_TYPE_DEFAULT); + return generic_set_acl_on_os(jcr, BACL_TYPE_DEFAULT, content, content_length); case STREAM_ACL_TRU64_DEFAULT_DIR_ACL: - return generic_set_acl_on_os(jcr, BACL_TYPE_DEFAULT_DIR); + return generic_set_acl_on_os(jcr, BACL_TYPE_DEFAULT_DIR, content, content_length); } /* * For this OS setup the build and parse function pointer to the OS specific functions. */ -static bacl_exit_code (*os_build_acl_streams)(JCR *jcr, FF_PKT *ff_pkt) = tru64_build_acl_streams; -static bacl_exit_code (*os_parse_acl_streams)(JCR *jcr, int stream) = tru64_parse_acl_streams; +static bacl_exit_code (*os_build_acl_streams) + (JCR *jcr, FF_PKT *ff_pkt) = + tru64_build_acl_streams; +static bacl_exit_code (*os_parse_acl_streams) + (JCR *jcr, int stream, char *content, uint32_t content_length) = + tru64_parse_acl_streams; #endif @@ -1246,8 +1346,12 @@ static bacl_exit_code (*os_parse_acl_streams)(JCR *jcr, int stream) = tru64_pars /* * Define the supported ACL streams for this OS */ -static int os_access_acl_streams[1] = { STREAM_ACL_HPUX_ACL_ENTRY }; -static int os_default_acl_streams[1] = { -1 }; +static int os_access_acl_streams[1] = { + STREAM_ACL_HPUX_ACL_ENTRY +}; +static int os_default_acl_streams[1] = { + -1 +}; /* * See if an acl is a trivial one (e.g. just the stat bits encoded as acl.) @@ -1294,28 +1398,29 @@ static bacl_exit_code hpux_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt) * when we change from one filesystem to an other. */ jcr->acl_data->flags &= ~BACL_FLAG_SAVE_NATIVE; - pm_strcpy(jcr->acl_data->content, ""); - jcr->acl_data->content_length = 0; + pm_strcpy(jcr->acl_data->u.build->content, ""); + jcr->acl_data->u.build->content_length = 0; return bacl_exit_ok; #endif case ENOENT: - pm_strcpy(jcr->acl_data->content, ""); - jcr->acl_data->content_length = 0; + pm_strcpy(jcr->acl_data->u.build->content, ""); + jcr->acl_data->u.build->content_length = 0; return bacl_exit_ok; default: - Mmsg2(jcr->errmsg, _("getacl error on file \"%s\": ERR=%s\n"), + Mmsg2(jcr->errmsg, + _("getacl error on file \"%s\": ERR=%s\n"), jcr->last_fname, be.bstrerror()); Dmsg2(100, "getacl error file=%s ERR=%s\n", jcr->last_fname, be.bstrerror()); - pm_strcpy(jcr->acl_data->content, ""); - jcr->acl_data->content_length = 0; + pm_strcpy(jcr->acl_data->u.build->content, ""); + jcr->acl_data->u.build->content_length = 0; return bacl_exit_error; } } if (n == 0) { - pm_strcpy(jcr->acl_data->content, ""); - jcr->acl_data->content_length = 0; + pm_strcpy(jcr->acl_data->u.build->content, ""); + jcr->acl_data->u.build->content_length = 0; return bacl_exit_ok; } if ((n = getacl(jcr->last_fname, n, acls)) > 0) { @@ -1324,44 +1429,51 @@ static bacl_exit_code hpux_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt) * The ACLs simply reflect the (already known) standard permissions * So we don't send an ACL stream to the SD. */ - pm_strcpy(jcr->acl_data->content, ""); - jcr->acl_data->content_length = 0; + pm_strcpy(jcr->acl_data->u.build->content, ""); + jcr->acl_data->u.build->content_length = 0; return bacl_exit_ok; } if ((acl_text = acltostr(n, acls, FORM_SHORT)) != NULL) { - jcr->acl_data->content_length = pm_strcpy(jcr->acl_data->content, acl_text); + jcr->acl_data->u.build->content_length = + pm_strcpy(jcr->acl_data->u.build->content, acl_text); actuallyfree(acl_text); return send_acl_stream(jcr, STREAM_ACL_HPUX_ACL_ENTRY); } - Mmsg2(jcr->errmsg, _("acltostr error on file \"%s\": ERR=%s\n"), + Mmsg2(jcr->errmsg, + _("acltostr error on file \"%s\": ERR=%s\n"), jcr->last_fname, be.bstrerror()); Dmsg3(100, "acltostr error acl=%s file=%s ERR=%s\n", - jcr->acl_data->content, jcr->last_fname, be.bstrerror()); + jcr->acl_data->u.build->content, jcr->last_fname, be.bstrerror()); return bacl_exit_error; } return bacl_exit_error; } -static bacl_exit_code hpux_parse_acl_streams(JCR *jcr, int stream) +static bacl_exit_code hpux_parse_acl_streams(JCR *jcr, + int stream, + char *content, + uint32_t content_length) { int n, stat; struct acl_entry acls[NACLENTRIES]; berrno be; - n = strtoacl(jcr->acl_data->content, 0, NACLENTRIES, acls, ACL_FILEOWNER, ACL_FILEGROUP); + n = strtoacl(content, 0, NACLENTRIES, acls, ACL_FILEOWNER, ACL_FILEGROUP); if (n <= 0) { - Mmsg2(jcr->errmsg, _("strtoacl error on file \"%s\": ERR=%s\n"), + Mmsg2(jcr->errmsg, + _("strtoacl error on file \"%s\": ERR=%s\n"), jcr->last_fname, be.bstrerror()); Dmsg3(100, "strtoacl error acl=%s file=%s ERR=%s\n", - jcr->acl_data->content, jcr->last_fname, be.bstrerror()); + content, jcr->last_fname, be.bstrerror()); return bacl_exit_error; } - if (strtoacl(jcr->acl_data->content, n, NACLENTRIES, acls, ACL_FILEOWNER, ACL_FILEGROUP) != n) { - Mmsg2(jcr->errmsg, _("strtoacl error on file \"%s\": ERR=%s\n"), + if (strtoacl(content, n, NACLENTRIES, acls, ACL_FILEOWNER, ACL_FILEGROUP) != n) { + Mmsg2(jcr->errmsg, + _("strtoacl error on file \"%s\": ERR=%s\n"), jcr->last_fname, be.bstrerror()); Dmsg3(100, "strtoacl error acl=%s file=%s ERR=%s\n", - jcr->acl_data->content, jcr->last_fname, be.bstrerror()); + content, jcr->last_fname, be.bstrerror()); return bacl_exit_error; } @@ -1371,7 +1483,8 @@ static bacl_exit_code hpux_parse_acl_streams(JCR *jcr, int stream) * This is only true for the old acl streams as in the new implementation we * don't save acls of symlinks (which cannot have acls anyhow) */ - if (setacl(jcr->last_fname, n, acls) != 0 && jcr->last_type != FT_LNK) { + if (setacl(jcr->last_fname, n, acls) != 0 && + jcr->last_type != FT_LNK) { switch (errno) { case ENOENT: return bacl_exit_ok; @@ -1384,17 +1497,19 @@ static bacl_exit_code hpux_parse_acl_streams(JCR *jcr, int stream) * when we change from one filesystem to an other. */ jcr->acl_data->flags &= ~BACL_FLAG_SAVE_NATIVE; - Mmsg1(jcr->errmsg, _("setacl error on file \"%s\": filesystem doesn't support ACLs\n"), + Mmsg1(jcr->errmsg, + _("setacl error on file \"%s\": filesystem doesn't support ACLs\n"), jcr->last_fname); Dmsg2(100, "setacl error acl=%s file=%s filesystem doesn't support ACLs\n", - jcr->acl_data->content, jcr->last_fname); + content, jcr->last_fname); return bacl_exit_error; #endif default: - Mmsg2(jcr->errmsg, _("setacl error on file \"%s\": ERR=%s\n"), + Mmsg2(jcr->errmsg, + _("setacl error on file \"%s\": ERR=%s\n"), jcr->last_fname, be.bstrerror()); Dmsg3(100, "setacl error acl=%s file=%s ERR=%s\n", - jcr->acl_data->content, jcr->last_fname, be.bstrerror()); + content, jcr->last_fname, be.bstrerror()); return bacl_exit_error; } } @@ -1404,8 +1519,12 @@ static bacl_exit_code hpux_parse_acl_streams(JCR *jcr, int stream) /* * For this OS setup the build and parse function pointer to the OS specific functions. */ -static bacl_exit_code (*os_build_acl_streams)(JCR *jcr, FF_PKT *ff_pkt) = hpux_build_acl_streams; -static bacl_exit_code (*os_parse_acl_streams)(JCR *jcr, int stream) = hpux_parse_acl_streams; +static bacl_exit_code (*os_build_acl_streams) + (JCR *jcr, FF_PKT *ff_pkt) = + hpux_build_acl_streams; +static bacl_exit_code (*os_parse_acl_streams) + (JCR *jcr, int stream, char *content, uint32_t content_length) = + hpux_parse_acl_streams; #elif defined(HAVE_SUN_OS) #ifdef HAVE_SYS_ACL_H @@ -1445,8 +1564,13 @@ char *acl_strerror(int); /* * Define the supported ACL streams for this OS */ -static int os_access_acl_streams[2] = { STREAM_ACL_SOLARIS_ACLENT, STREAM_ACL_SOLARIS_ACE }; -static int os_default_acl_streams[1] = { -1 }; +static int os_access_acl_streams[2] = { + STREAM_ACL_SOLARIS_ACLENT, + STREAM_ACL_SOLARIS_ACE +}; +static int os_default_acl_streams[1] = { + -1 +}; /** * As the new libsec interface with acl_totext and acl_fromtext also handles @@ -1475,15 +1599,16 @@ static bacl_exit_code solaris_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt) * when we change from one filesystem to an other. */ jcr->acl_data->flags &= ~BACL_FLAG_SAVE_NATIVE; - pm_strcpy(jcr->acl_data->content, ""); - jcr->acl_data->content_length = 0; + pm_strcpy(jcr->acl_data->u.build->content, ""); + jcr->acl_data->u.build->content_length = 0; return bacl_exit_ok; case -1: switch (errno) { case ENOENT: return bacl_exit_ok; default: - Mmsg2(jcr->errmsg, _("pathconf error on file \"%s\": ERR=%s\n"), + Mmsg2(jcr->errmsg, + _("pathconf error on file \"%s\": ERR=%s\n"), jcr->last_fname, be.bstrerror()); Dmsg2(100, "pathconf error file=%s ERR=%s\n", jcr->last_fname, be.bstrerror()); @@ -1501,7 +1626,8 @@ static bacl_exit_code solaris_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt) case ENOENT: return bacl_exit_ok; default: - Mmsg2(jcr->errmsg, _("acl_get error on file \"%s\": ERR=%s\n"), + Mmsg2(jcr->errmsg, + _("acl_get error on file \"%s\": ERR=%s\n"), jcr->last_fname, acl_strerror(errno)); Dmsg2(100, "acl_get error file=%s ERR=%s\n", jcr->last_fname, acl_strerror(errno)); @@ -1514,8 +1640,8 @@ static bacl_exit_code solaris_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt) * The ACLs simply reflect the (already known) standard permissions * So we don't send an ACL stream to the SD. */ - pm_strcpy(jcr->acl_data->content, ""); - jcr->acl_data->content_length = 0; + pm_strcpy(jcr->acl_data->u.build->content, ""); + jcr->acl_data->u.build->content_length = 0; return bacl_exit_ok; } @@ -1529,7 +1655,8 @@ static bacl_exit_code solaris_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt) #endif /* ACL_SID_FMT */ if ((acl_text = acl_totext(aclp, flags)) != NULL) { - jcr->acl_data->content_length = pm_strcpy(jcr->acl_data->content, acl_text); + jcr->acl_data->u.build->content_length = + pm_strcpy(jcr->acl_data->u.build->content, acl_text); actuallyfree(acl_text); switch (acl_type(aclp)) { @@ -1548,7 +1675,10 @@ static bacl_exit_code solaris_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt) return stream_status; } -static bacl_exit_code solaris_parse_acl_streams(JCR *jcr, int stream) +static bacl_exit_code solaris_parse_acl_streams(JCR *jcr, + int stream, + char *content, + uint32_t content_length) { acl_t *aclp; int acl_enabled, error; @@ -1571,7 +1701,8 @@ static bacl_exit_code solaris_parse_acl_streams(JCR *jcr, int stream) * when we change from one filesystem to an other. */ jcr->acl_data->flags &= ~BACL_FLAG_RESTORE_NATIVE; - Mmsg1(jcr->errmsg, _("Trying to restore acl on file \"%s\" on filesystem without acl support\n"), + Mmsg1(jcr->errmsg, + _("Trying to restore acl on file \"%s\" on filesystem without acl support\n"), jcr->last_fname); return bacl_exit_error; case -1: @@ -1579,10 +1710,11 @@ static bacl_exit_code solaris_parse_acl_streams(JCR *jcr, int stream) case ENOENT: return bacl_exit_ok; default: - Mmsg2(jcr->errmsg, _("pathconf error on file \"%s\": ERR=%s\n"), + Mmsg2(jcr->errmsg, + _("pathconf error on file \"%s\": ERR=%s\n"), jcr->last_fname, be.bstrerror()); Dmsg3(100, "pathconf error acl=%s file=%s ERR=%s\n", - jcr->acl_data->content, jcr->last_fname, be.bstrerror()); + content, jcr->last_fname, be.bstrerror()); return bacl_exit_error; } default: @@ -1595,7 +1727,8 @@ static bacl_exit_code solaris_parse_acl_streams(JCR *jcr, int stream) * An aclent can be restored on filesystems with _ACL_ACLENT_ENABLED or _ACL_ACE_ENABLED support. */ if ((acl_enabled & (_ACL_ACLENT_ENABLED | _ACL_ACE_ENABLED)) == 0) { - Mmsg1(jcr->errmsg, _("Trying to restore acl on file \"%s\" on filesystem without aclent acl support\n"), + Mmsg1(jcr->errmsg, + _("Trying to restore acl on file \"%s\" on filesystem without aclent acl support\n"), jcr->last_fname); return bacl_exit_error; } @@ -1605,7 +1738,8 @@ static bacl_exit_code solaris_parse_acl_streams(JCR *jcr, int stream) * An ace can only be restored on a filesystem with _ACL_ACE_ENABLED support. */ if ((acl_enabled & _ACL_ACE_ENABLED) == 0) { - Mmsg1(jcr->errmsg, _("Trying to restore acl on file \"%s\" on filesystem without ace acl support\n"), + Mmsg1(jcr->errmsg, + _("Trying to restore acl on file \"%s\" on filesystem without ace acl support\n"), jcr->last_fname); return bacl_exit_error; } @@ -1619,11 +1753,12 @@ static bacl_exit_code solaris_parse_acl_streams(JCR *jcr, int stream) break; } - if ((error = acl_fromtext(jcr->acl_data->content, &aclp)) != 0) { - Mmsg2(jcr->errmsg, _("acl_fromtext error on file \"%s\": ERR=%s\n"), + if ((error = acl_fromtext(content, &aclp)) != 0) { + Mmsg2(jcr->errmsg, + _("acl_fromtext error on file \"%s\": ERR=%s\n"), jcr->last_fname, acl_strerror(error)); Dmsg3(100, "acl_fromtext error acl=%s file=%s ERR=%s\n", - jcr->acl_data->content, jcr->last_fname, acl_strerror(error)); + content, jcr->last_fname, acl_strerror(error)); return bacl_exit_error; } @@ -1633,14 +1768,16 @@ static bacl_exit_code solaris_parse_acl_streams(JCR *jcr, int stream) switch (stream) { case STREAM_ACL_SOLARIS_ACLENT: if (acl_type(aclp) != ACLENT_T) { - Mmsg1(jcr->errmsg, _("wrong encoding of acl type in acl stream on file \"%s\"\n"), + Mmsg1(jcr->errmsg, + _("wrong encoding of acl type in acl stream on file \"%s\"\n"), jcr->last_fname); return bacl_exit_error; } break; case STREAM_ACL_SOLARIS_ACE: if (acl_type(aclp) != ACE_T) { - Mmsg1(jcr->errmsg, _("wrong encoding of acl type in acl stream on file \"%s\"\n"), + Mmsg1(jcr->errmsg, + _("wrong encoding of acl type in acl stream on file \"%s\"\n"), jcr->last_fname); return bacl_exit_error; } @@ -1664,10 +1801,11 @@ static bacl_exit_code solaris_parse_acl_streams(JCR *jcr, int stream) acl_free(aclp); return bacl_exit_ok; default: - Mmsg2(jcr->errmsg, _("acl_set error on file \"%s\": ERR=%s\n"), + Mmsg2(jcr->errmsg, + _("acl_set error on file \"%s\": ERR=%s\n"), jcr->last_fname, acl_strerror(error)); Dmsg3(100, "acl_set error acl=%s file=%s ERR=%s\n", - jcr->acl_data->content, jcr->last_fname, acl_strerror(error)); + content, jcr->last_fname, acl_strerror(error)); acl_free(aclp); return bacl_exit_error; } @@ -1685,8 +1823,12 @@ static bacl_exit_code solaris_parse_acl_streams(JCR *jcr, int stream) /* * Define the supported ACL streams for this OS */ -static int os_access_acl_streams[2] = { STREAM_ACL_SOLARIS_ACLENT }; -static int os_default_acl_streams[1] = { -1 }; +static int os_access_acl_streams[1] = { + STREAM_ACL_SOLARIS_ACLENT +}; +static int os_default_acl_streams[1] = { + -1 +}; /* * See if an acl is a trivial one (e.g. just the stat bits encoded as acl.) @@ -1731,40 +1873,46 @@ static bacl_exit_code solaris_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt) * So we don't send an ACL stream to the SD. */ free(acls); - pm_strcpy(jcr->acl_data->content, ""); - jcr->acl_data->content_length = 0; + pm_strcpy(jcr->acl_data->u.build->content, ""); + jcr->acl_data->u.build->content_length = 0; return bacl_exit_ok; } if ((acl_text = acltotext(acls, n)) != NULL) { - jcr->acl_data->content_length = pm_strcpy(jcr->acl_data->content, acl_text); + jcr->acl_data->u.build->content_length = + pm_strcpy(jcr->acl_data->u.build->content, acl_text); actuallyfree(acl_text); free(acls); return send_acl_stream(jcr, STREAM_ACL_SOLARIS_ACLENT); } - Mmsg2(jcr->errmsg, _("acltotext error on file \"%s\": ERR=%s\n"), + Mmsg2(jcr->errmsg, + _("acltotext error on file \"%s\": ERR=%s\n"), jcr->last_fname, be.bstrerror()); Dmsg3(100, "acltotext error acl=%s file=%s ERR=%s\n", - jcr->acl_data->content, jcr->last_fname, be.bstrerror()); + jcr->acl_data->u.build->content, jcr->last_fname, be.bstrerror()); } free(acls); return bacl_exit_error; } -static bacl_exit_code solaris_parse_acl_streams(JCR *jcr, int stream) +static bacl_exit_code solaris_parse_acl_streams(JCR *jcr, + int stream, + char *content, + uint32_t content_length) { int n; aclent_t *acls; berrno be; - acls = aclfromtext(jcr->acl_data->content, &n); + acls = aclfromtext(content, &n); if (!acls) { - Mmsg2(jcr->errmsg, _("aclfromtext error on file \"%s\": ERR=%s\n"), + Mmsg2(jcr->errmsg, + _("aclfromtext error on file \"%s\": ERR=%s\n"), jcr->last_fname, be.bstrerror()); Dmsg3(100, "aclfromtext error acl=%s file=%s ERR=%s\n", - jcr->acl_data->content, jcr->last_fname, be.bstrerror()); + content, jcr->last_fname, be.bstrerror()); return bacl_exit_error; } @@ -1778,10 +1926,11 @@ static bacl_exit_code solaris_parse_acl_streams(JCR *jcr, int stream) actuallyfree(acls); return bacl_exit_ok; default: - Mmsg2(jcr->errmsg, _("acl(SETACL) error on file \"%s\": ERR=%s\n"), + Mmsg2(jcr->errmsg, + _("acl(SETACL) error on file \"%s\": ERR=%s\n"), jcr->last_fname, be.bstrerror()); Dmsg3(100, "acl(SETACL) error acl=%s file=%s ERR=%s\n", - jcr->acl_data->content, jcr->last_fname, be.bstrerror()); + content, jcr->last_fname, be.bstrerror()); actuallyfree(acls); return bacl_exit_error; } @@ -1794,8 +1943,12 @@ static bacl_exit_code solaris_parse_acl_streams(JCR *jcr, int stream) /* * For this OS setup the build and parse function pointer to the OS specific functions. */ -static bacl_exit_code (*os_build_acl_streams)(JCR *jcr, FF_PKT *ff_pkt) = solaris_build_acl_streams; -static bacl_exit_code (*os_parse_acl_streams)(JCR *jcr, int stream) = solaris_parse_acl_streams; +static bacl_exit_code (*os_build_acl_streams) + (JCR *jcr, FF_PKT *ff_pkt) = + solaris_build_acl_streams; +static bacl_exit_code (*os_parse_acl_streams) + (JCR *jcr, int stream, char *content, uint32_t content_length) = + solaris_parse_acl_streams; #endif /* HAVE_SUN_OS */ #endif /* HAVE_ACL */ @@ -1848,7 +2001,10 @@ bacl_exit_code build_acl_streams(JCR *jcr, FF_PKT *ff_pkt) return bacl_exit_error; } -bacl_exit_code parse_acl_streams(JCR *jcr, int stream) +bacl_exit_code parse_acl_streams(JCR *jcr, + int stream, + char *content, + uint32_t content_length) { int ret; berrno be; @@ -1868,7 +2024,8 @@ bacl_exit_code parse_acl_streams(JCR *jcr, int stream) case ENOENT: return bacl_exit_ok; default: - Mmsg2(jcr->errmsg, _("Unable to stat file \"%s\": ERR=%s\n"), + Mmsg2(jcr->errmsg, + _("Unable to stat file \"%s\": ERR=%s\n"), jcr->last_fname, be.bstrerror()); Dmsg2(100, "Unable to stat file \"%s\": ERR=%s\n", jcr->last_fname, be.bstrerror()); @@ -1899,12 +2056,12 @@ bacl_exit_code parse_acl_streams(JCR *jcr, int stream) * Handle legacy ACL streams. */ if ((jcr->acl_data->flags & BACL_FLAG_RESTORE_NATIVE) && os_parse_acl_streams) { - return os_parse_acl_streams(jcr, stream); + return os_parse_acl_streams(jcr, stream, content, content_length); } else { /* * Increment error count but don't log an error again for the same filesystem. */ - jcr->acl_data->nr_errors++; + jcr->acl_data->u.parse->nr_errors++; return bacl_exit_ok; } break; @@ -1915,7 +2072,7 @@ bacl_exit_code parse_acl_streams(JCR *jcr, int stream) */ for (cnt = 0; cnt < sizeof(os_access_acl_streams) / sizeof(int); cnt++) { if (os_access_acl_streams[cnt] == stream) { - return os_parse_acl_streams(jcr, stream); + return os_parse_acl_streams(jcr, stream, content, content_length); } } /* @@ -1923,14 +2080,14 @@ bacl_exit_code parse_acl_streams(JCR *jcr, int stream) */ for (cnt = 0; cnt < sizeof(os_default_acl_streams) / sizeof(int); cnt++) { if (os_default_acl_streams[cnt] == stream) { - return os_parse_acl_streams(jcr, stream); + return os_parse_acl_streams(jcr, stream, content, content_length); } } } else { /* * Increment error count but don't log an error again for the same filesystem. */ - jcr->acl_data->nr_errors++; + jcr->acl_data->u.parse->nr_errors++; return bacl_exit_ok; } break; diff --git a/bacula/src/filed/acl.h b/bacula/src/filed/acl.h index c5432d3df7..fddc90b0cf 100644 --- a/bacula/src/filed/acl.h +++ b/bacula/src/filed/acl.h @@ -72,15 +72,26 @@ typedef enum { #define BACL_FLAG_RESTORE_NATIVE 0x04 #define BACL_FLAG_RESTORE_AFS 0x08 +struct acl_build_data_t { + uint32_t nr_errors; + uint32_t content_length; + POOLMEM *content; +}; + +struct acl_parse_data_t { + uint32_t nr_errors; +}; + /* * Internal tracking data. */ struct acl_data_t { - POOLMEM *content; - uint32_t content_length; - uint32_t nr_errors; - uint32_t current_dev; uint32_t flags; /* See BACL_FLAG_* */ + uint32_t current_dev; + union { + struct acl_build_data_t *build; + struct acl_parse_data_t *parse; + } u; }; #endif diff --git a/bacula/src/filed/backup.c b/bacula/src/filed/backup.c index c43660b264..e9242a06de 100644 --- a/bacula/src/filed/backup.c +++ b/bacula/src/filed/backup.c @@ -170,14 +170,18 @@ bool blast_data_to_storage_daemon(JCR *jcr, char *addr) if (have_acl) { jcr->acl_data = (acl_data_t *)malloc(sizeof(acl_data_t)); - memset((caddr_t)jcr->acl_data, 0, sizeof(acl_data_t)); - jcr->acl_data->content = get_pool_memory(PM_MESSAGE); + memset(jcr->acl_data, 0, sizeof(acl_data_t)); + jcr->acl_data->u.build = (acl_build_data_t *)malloc(sizeof(acl_build_data_t)); + memset(jcr->acl_data->u.build, 0, sizeof(acl_build_data_t)); + jcr->acl_data->u.build->content = get_pool_memory(PM_MESSAGE); } if (have_xattr) { jcr->xattr_data = (xattr_data_t *)malloc(sizeof(xattr_data_t)); - memset((caddr_t)jcr->xattr_data, 0, sizeof(xattr_data_t)); - jcr->xattr_data->content = get_pool_memory(PM_MESSAGE); + memset(jcr->xattr_data, 0, sizeof(xattr_data_t)); + jcr->xattr_data->u.build = (xattr_build_data_t *)malloc(sizeof(xattr_build_data_t)); + memset(jcr->xattr_data->u.build, 0, sizeof(xattr_build_data_t)); + jcr->xattr_data->u.build->content = get_pool_memory(PM_MESSAGE); } /** Subroutine save_file() is called for each file */ @@ -186,13 +190,13 @@ bool blast_data_to_storage_daemon(JCR *jcr, char *addr) jcr->setJobStatus(JS_ErrorTerminated); } - if (have_acl && jcr->acl_data->nr_errors > 0) { + if (have_acl && jcr->acl_data->u.build->nr_errors > 0) { Jmsg(jcr, M_WARNING, 0, _("Encountered %ld acl errors while doing backup\n"), - jcr->acl_data->nr_errors); + jcr->acl_data->u.build->nr_errors); } - if (have_xattr && jcr->xattr_data->nr_errors > 0) { + if (have_xattr && jcr->xattr_data->u.build->nr_errors > 0) { Jmsg(jcr, M_WARNING, 0, _("Encountered %ld xattr errors while doing backup\n"), - jcr->xattr_data->nr_errors); + jcr->xattr_data->u.build->nr_errors); } close_vss_backup_session(jcr); @@ -204,12 +208,14 @@ bool blast_data_to_storage_daemon(JCR *jcr, char *addr) sd->signal(BNET_EOD); /* end of sending data */ if (have_acl && jcr->acl_data) { - free_pool_memory(jcr->acl_data->content); + free_pool_memory(jcr->acl_data->u.build->content); + free(jcr->acl_data->u.build); free(jcr->acl_data); jcr->acl_data = NULL; } if (have_xattr && jcr->xattr_data) { - free_pool_memory(jcr->xattr_data->content); + free_pool_memory(jcr->xattr_data->u.build->content); + free(jcr->xattr_data->u.build); free(jcr->xattr_data); jcr->xattr_data = NULL; } @@ -706,10 +712,10 @@ int save_file(JCR *jcr, FF_PKT *ff_pkt, bool top_level) * ACL_REPORT_ERR_MAX_PER_JOB print the error message set by the * lower level routine in jcr->errmsg. */ - if (jcr->acl_data->nr_errors < ACL_REPORT_ERR_MAX_PER_JOB) { + if (jcr->acl_data->u.build->nr_errors < ACL_REPORT_ERR_MAX_PER_JOB) { Jmsg(jcr, M_WARNING, 0, "%s", jcr->errmsg); } - jcr->acl_data->nr_errors++; + jcr->acl_data->u.build->nr_errors++; break; case bacl_exit_ok: break; @@ -732,10 +738,10 @@ int save_file(JCR *jcr, FF_PKT *ff_pkt, bool top_level) * XATTR_REPORT_ERR_MAX_PER_JOB print the error message set by the * lower level routine in jcr->errmsg. */ - if (jcr->xattr_data->nr_errors < XATTR_REPORT_ERR_MAX_PER_JOB) { + if (jcr->xattr_data->u.build->nr_errors < XATTR_REPORT_ERR_MAX_PER_JOB) { Jmsg(jcr, M_WARNING, 0, "%s", jcr->errmsg); } - jcr->xattr_data->nr_errors++; + jcr->xattr_data->u.build->nr_errors++; break; case bxattr_exit_ok: break; diff --git a/bacula/src/filed/protos.h b/bacula/src/filed/protos.h index e9304b09e9..dc793b9259 100644 --- a/bacula/src/filed/protos.h +++ b/bacula/src/filed/protos.h @@ -49,7 +49,7 @@ void stop_dir_heartbeat(JCR *jcr); /* From acl.c */ bacl_exit_code build_acl_streams(JCR *jcr, FF_PKT *ff_pkt); -bacl_exit_code parse_acl_streams(JCR *jcr, int stream); +bacl_exit_code parse_acl_streams(JCR *jcr, int stream, char *content, uint32_t content_length); /* from accurate.c */ bool accurate_finish(JCR *jcr); @@ -64,7 +64,7 @@ void unstrip_path(FF_PKT *ff_pkt); /* from xattr.c */ bxattr_exit_code build_xattr_streams(JCR *jcr, FF_PKT *ff_pkt); -bxattr_exit_code parse_xattr_streams(JCR *jcr, int stream); +bxattr_exit_code parse_xattr_streams(JCR *jcr, int stream, char *content, uint32_t content_length); /* from job.c */ findINCEXE *new_exclude(JCR *jcr); diff --git a/bacula/src/filed/restore.c b/bacula/src/filed/restore.c index 1abc791e0a..3833c50581 100644 --- a/bacula/src/filed/restore.c +++ b/bacula/src/filed/restore.c @@ -198,9 +198,12 @@ static inline void push_delayed_restore_stream(r_ctx &rctx, BSOCK *sd) * This can either be a delayed restore or direct restore. */ static inline bool do_restore_acl(JCR *jcr, - int stream) + int stream, + char *content, + uint32_t content_length) + { - switch (parse_acl_streams(jcr, stream)) { + switch (parse_acl_streams(jcr, stream, content, content_length)) { case bacl_exit_fatal: return false; case bacl_exit_error: @@ -208,10 +211,10 @@ static inline bool do_restore_acl(JCR *jcr, * Non-fatal errors, count them and when the number is under ACL_REPORT_ERR_MAX_PER_JOB * print the error message set by the lower level routine in jcr->errmsg. */ - if (jcr->acl_data->nr_errors < ACL_REPORT_ERR_MAX_PER_JOB) { + if (jcr->acl_data->u.parse->nr_errors < ACL_REPORT_ERR_MAX_PER_JOB) { Jmsg(jcr, M_WARNING, 0, "%s", jcr->errmsg); } - jcr->acl_data->nr_errors++; + jcr->acl_data->u.parse->nr_errors++; break; case bacl_exit_ok: break; @@ -224,9 +227,11 @@ static inline bool do_restore_acl(JCR *jcr, * This can either be a delayed restore or direct restore. */ static inline bool do_restore_xattr(JCR *jcr, - int stream) + int stream, + char *content, + uint32_t content_length) { - switch (parse_xattr_streams(jcr, stream)) { + switch (parse_xattr_streams(jcr, stream, content, content_length)) { case bxattr_exit_fatal: return false; case bxattr_exit_error: @@ -234,10 +239,10 @@ static inline bool do_restore_xattr(JCR *jcr, * Non-fatal errors, count them and when the number is under XATTR_REPORT_ERR_MAX_PER_JOB * print the error message set by the lower level routine in jcr->errmsg. */ - if (jcr->xattr_data->nr_errors < XATTR_REPORT_ERR_MAX_PER_JOB) { + if (jcr->xattr_data->u.parse->nr_errors < XATTR_REPORT_ERR_MAX_PER_JOB) { Jmsg(jcr, M_WARNING, 0, "%s", jcr->errmsg); } - jcr->xattr_data->nr_errors++; + jcr->xattr_data->u.parse->nr_errors++; break; case bxattr_exit_ok: break; @@ -297,9 +302,7 @@ static inline bool pop_delayed_data_streams(JCR *jcr, r_ctx &rctx) case STREAM_ACL_AIX_AIXC: case STREAM_ACL_AIX_NFS4: case STREAM_ACL_FREEBSD_NFS4_ACL: - pm_memcpy(jcr->acl_data->content, rds->content, rds->content_length); - jcr->acl_data->content_length = rds->content_length; - if (!do_restore_acl(jcr, rds->stream)) { + if (!do_restore_acl(jcr, rds->stream, rds->content, rds->content_length)) { goto bail_out; } free(rds->content); @@ -313,9 +316,7 @@ static inline bool pop_delayed_data_streams(JCR *jcr, r_ctx &rctx) case STREAM_XATTR_FREEBSD: case STREAM_XATTR_LINUX: case STREAM_XATTR_NETBSD: - pm_memcpy(jcr->xattr_data->content, rds->content, rds->content_length); - jcr->xattr_data->content_length = rds->content_length; - if (!do_restore_xattr(jcr, rds->stream)) { + if (!do_restore_xattr(jcr, rds->stream, rds->content, rds->content_length)) { goto bail_out; } free(rds->content); @@ -457,13 +458,15 @@ void do_restore(JCR *jcr) attr = rctx.attr = new_attr(jcr); if (have_acl) { jcr->acl_data = (acl_data_t *)malloc(sizeof(acl_data_t)); - memset((caddr_t)jcr->acl_data, 0, sizeof(acl_data_t)); - jcr->acl_data->content = get_pool_memory(PM_MESSAGE); + memset(jcr->acl_data, 0, sizeof(acl_data_t)); + jcr->acl_data->u.parse = (acl_parse_data_t *)malloc(sizeof(acl_parse_data_t)); + memset(jcr->acl_data->u.parse, 0, sizeof(acl_parse_data_t)); } if (have_xattr) { jcr->xattr_data = (xattr_data_t *)malloc(sizeof(xattr_data_t)); - memset((caddr_t)jcr->xattr_data, 0, sizeof(xattr_data_t)); - jcr->xattr_data->content = get_pool_memory(PM_MESSAGE); + memset(jcr->xattr_data, 0, sizeof(xattr_data_t)); + jcr->xattr_data->u.parse = (xattr_parse_data_t *)malloc(sizeof(xattr_parse_data_t)); + memset(jcr->xattr_data->u.parse, 0, sizeof(xattr_parse_data_t)); } while (bget_msg(sd) >= 0 && !job_canceled(jcr)) { @@ -908,9 +911,7 @@ void do_restore(JCR *jcr) if (jcr->last_type != FT_DIREND) { push_delayed_restore_stream(rctx, sd); } else { - pm_memcpy(jcr->acl_data->content, sd->msg, sd->msglen); - jcr->acl_data->content_length = sd->msglen; - if (!do_restore_acl(jcr, rctx.stream)) { + if (!do_restore_acl(jcr, rctx.stream, sd->msg, sd->msglen)) { goto bail_out; } } @@ -947,9 +948,7 @@ void do_restore(JCR *jcr) if (jcr->last_type != FT_DIREND) { push_delayed_restore_stream(rctx, sd); } else { - pm_memcpy(jcr->xattr_data->content, sd->msg, sd->msglen); - jcr->xattr_data->content_length = sd->msglen; - if (!do_restore_xattr(jcr, rctx.stream)) { + if (!do_restore_xattr(jcr, rctx.stream, sd->msg, sd->msglen)) { goto bail_out; } } @@ -971,9 +970,7 @@ void do_restore(JCR *jcr) break; } if (have_xattr) { - pm_memcpy(jcr->xattr_data->content, sd->msg, sd->msglen); - jcr->xattr_data->content_length = sd->msglen; - if (!do_restore_xattr(jcr, rctx.stream)) { + if (!do_restore_xattr(jcr, rctx.stream, sd->msg, sd->msglen)) { goto bail_out; } } else { @@ -1057,13 +1054,13 @@ ok_out: */ Dmsg2(10, "End Do Restore. Files=%d Bytes=%s\n", jcr->JobFiles, edit_uint64(jcr->JobBytes, ec1)); - if (have_acl && jcr->acl_data->nr_errors > 0) { + if (have_acl && jcr->acl_data->u.parse->nr_errors > 0) { Jmsg(jcr, M_WARNING, 0, _("Encountered %ld acl errors while doing restore\n"), - jcr->acl_data->nr_errors); + jcr->acl_data->u.parse->nr_errors); } - if (have_xattr && jcr->xattr_data->nr_errors > 0) { + if (have_xattr && jcr->xattr_data->u.parse->nr_errors > 0) { Jmsg(jcr, M_WARNING, 0, _("Encountered %ld xattr errors while doing restore\n"), - jcr->xattr_data->nr_errors); + jcr->xattr_data->u.parse->nr_errors); } if (non_support_data > 1 || non_support_attr > 1) { Jmsg(jcr, M_WARNING, 0, _("%d non-supported data streams and %d non-supported attrib streams ignored.\n"), @@ -1127,13 +1124,13 @@ ok_out: } if (have_acl && jcr->acl_data) { - free_pool_memory(jcr->acl_data->content); + free(jcr->acl_data->u.parse); free(jcr->acl_data); jcr->acl_data = NULL; } if (have_xattr && jcr->xattr_data) { - free_pool_memory(jcr->xattr_data->content); + free(jcr->xattr_data->u.parse); free(jcr->xattr_data); jcr->xattr_data = NULL; } diff --git a/bacula/src/filed/xattr.c b/bacula/src/filed/xattr.c index c2bd304cd5..93108fdf78 100644 --- a/bacula/src/filed/xattr.c +++ b/bacula/src/filed/xattr.c @@ -1,7 +1,7 @@ /* Bacula® - The Network Backup Solution - Copyright (C) 2008-2011 Free Software Foundation Europe e.V. + Copyright (C) 2008-2012 Free Software Foundation Europe e.V. The main author of Bacula is Kern Sibbald, with contributions from many others, a complete list can be found in the file AUTHORS. @@ -47,7 +47,8 @@ * - Solaris (Extended Attributes and Extensible Attributes) * - Tru64 (Extended Attributes) * - * Written by Marco van Wieringen, November MMVIII + * Written by Marco van Wieringen, November 2008 + * Major overhaul January 2012 */ #include "bacula.h" @@ -62,7 +63,10 @@ bxattr_exit_code build_xattr_streams(JCR *jcr, FF_PKT *ff_pkt) return bxattr_exit_fatal; } -bxattr_exit_code parse_xattr_streams(JCR *jcr, int stream) +bxattr_exit_code parse_xattr_streams(JCR *jcr, + int stream, + char *content, + uint32_t content_length) { return bxattr_exit_fatal; } @@ -81,7 +85,7 @@ static bxattr_exit_code send_xattr_stream(JCR *jcr, int stream) /* * Sanity check */ - if (jcr->xattr_data->content_length <= 0) { + if (jcr->xattr_data->u.build->content_length <= 0) { return bxattr_exit_ok; } @@ -97,10 +101,10 @@ static bxattr_exit_code send_xattr_stream(JCR *jcr, int stream) /* * Send the buffer to the storage deamon */ - Dmsg1(400, "Backing up XATTR <%s>\n", jcr->xattr_data->content); + Dmsg1(400, "Backing up XATTR <%s>\n", jcr->xattr_data->u.build->content); msgsave = sd->msg; - sd->msg = jcr->xattr_data->content; - sd->msglen = jcr->xattr_data->content_length; + sd->msg = jcr->xattr_data->u.build->content; + sd->msglen = jcr->xattr_data->u.build->content_length; if (!sd->send()) { sd->msg = msgsave; sd->msglen = 0; @@ -164,7 +168,9 @@ static void xattr_drop_internal_table(alist *xattr_value_list) * This is repeated 1 or more times. * */ -static uint32_t serialize_xattr_stream(JCR *jcr, uint32_t expected_serialize_len, alist *xattr_value_list) +static uint32_t serialize_xattr_stream(JCR *jcr, + uint32_t expected_serialize_len, + alist *xattr_value_list) { xattr_t *current_xattr; ser_declare; @@ -173,8 +179,11 @@ static uint32_t serialize_xattr_stream(JCR *jcr, uint32_t expected_serialize_len * Make sure the serialized stream fits in the poolmem buffer. * We allocate some more to be sure the stream is gonna fit. */ - jcr->xattr_data->content = check_pool_memory_size(jcr->xattr_data->content, expected_serialize_len + 10); - ser_begin(jcr->xattr_data->content, expected_serialize_len + 10); + jcr->xattr_data->u.build->content = + check_pool_memory_size(jcr->xattr_data->u.build->content, + expected_serialize_len + 10); + ser_begin(jcr->xattr_data->u.build->content, + expected_serialize_len + 10); /* * Walk the list of xattrs and serialize the data. @@ -201,13 +210,17 @@ static uint32_t serialize_xattr_stream(JCR *jcr, uint32_t expected_serialize_len } } - ser_end(jcr->xattr_data->content, expected_serialize_len + 10); - jcr->xattr_data->content_length = ser_length(jcr->xattr_data->content); + ser_end(jcr->xattr_data->u.build->content, expected_serialize_len + 10); + jcr->xattr_data->u.build->content_length = + ser_length(jcr->xattr_data->u.build->content); - return jcr->xattr_data->content_length; + return jcr->xattr_data->u.build->content_length; } -static bxattr_exit_code unserialize_xattr_stream(JCR *jcr, alist *xattr_value_list) +static bxattr_exit_code unserialize_xattr_stream(JCR *jcr, + char *content, + uint32_t content_length, + alist *xattr_value_list) { unser_declare; xattr_t *current_xattr; @@ -219,8 +232,8 @@ static bxattr_exit_code unserialize_xattr_stream(JCR *jcr, alist *xattr_value_li * Start unserializing the data. We keep on looping while we have not * unserialized all bytes in the stream. */ - unser_begin(jcr->xattr_data->content, jcr->xattr_data->content_length); - while (unser_length(jcr->xattr_data->content) < jcr->xattr_data->content_length) { + unser_begin(content, content_length); + while (unser_length(content) < content_length) { /* * First make sure the magic is present. This way we can easily catch corruption. * Any missing MAGIC is fatal we do NOT try to continue. @@ -228,7 +241,8 @@ static bxattr_exit_code unserialize_xattr_stream(JCR *jcr, alist *xattr_value_li current_xattr = (xattr_t *)malloc(sizeof(xattr_t)); unser_uint32(current_xattr->magic); if (current_xattr->magic != XATTR_MAGIC) { - Mmsg1(jcr->errmsg, _("Illegal xattr stream, no XATTR_MAGIC on file \"%s\"\n"), + Mmsg1(jcr->errmsg, + _("Illegal xattr stream, no XATTR_MAGIC on file \"%s\"\n"), jcr->last_fname); Dmsg1(100, "Illegal xattr stream, no XATTR_MAGIC on file \"%s\"\n", jcr->last_fname); @@ -241,7 +255,8 @@ static bxattr_exit_code unserialize_xattr_stream(JCR *jcr, alist *xattr_value_li */ unser_uint32(current_xattr->name_length); if (current_xattr->name_length == 0) { - Mmsg1(jcr->errmsg, _("Illegal xattr stream, xattr name length <= 0 on file \"%s\"\n"), + Mmsg1(jcr->errmsg, + _("Illegal xattr stream, xattr name length <= 0 on file \"%s\"\n"), jcr->last_fname); Dmsg1(100, "Illegal xattr stream, xattr name length <= 0 on file \"%s\"\n", jcr->last_fname); @@ -282,7 +297,7 @@ static bxattr_exit_code unserialize_xattr_stream(JCR *jcr, alist *xattr_value_li xattr_value_list->append(current_xattr); } - unser_end(jcr->xattr_data->content, jcr->xattr_data->content_length); + unser_end(content, content_length); return retval; } #endif @@ -307,7 +322,9 @@ static bxattr_exit_code unserialize_xattr_stream(JCR *jcr, alist *xattr_value_li /* * Define the supported XATTR streams for this OS */ -static int os_default_xattr_streams[1] = { STREAM_XATTR_AIX }; +static int os_default_xattr_streams[1] = { + STREAM_XATTR_AIX +}; /* * Fallback to the non l-functions when those are not available. @@ -356,7 +373,8 @@ static bxattr_exit_code aix_xattr_build_streams(JCR *jcr, FF_PKT *ff_pkt) jcr->xattr_data->flags &= ~BXATTR_FLAG_SAVE_NATIVE; return bxattr_exit_ok; default: - Mmsg2(jcr->errmsg, _("llistea error on file \"%s\": ERR=%s\n"), + Mmsg2(jcr->errmsg, + _("llistea error on file \"%s\": ERR=%s\n"), jcr->last_fname, be.bstrerror()); Dmsg2(100, "llistea error file=%s ERR=%s\n", jcr->last_fname, be.bstrerror()); @@ -373,7 +391,7 @@ static bxattr_exit_code aix_xattr_build_streams(JCR *jcr, FF_PKT *ff_pkt) * Allocate room for the extented attribute list. */ xattr_list = (char *)malloc(xattr_list_len + 1); - memset((caddr_t)xattr_list, 0, xattr_list_len + 1); + memset(xattr_list, 0, xattr_list_len + 1); /* * Get the actual list of extended attributes names for a file. @@ -387,7 +405,8 @@ static bxattr_exit_code aix_xattr_build_streams(JCR *jcr, FF_PKT *ff_pkt) retval = bxattr_exit_ok; goto bail_out; default: - Mmsg2(jcr->errmsg, _("llistea error on file \"%s\": ERR=%s\n"), + Mmsg2(jcr->errmsg, + _("llistea error on file \"%s\": ERR=%s\n"), jcr->last_fname, be.bstrerror()); Dmsg2(100, "llistea error file=%s ERR=%s\n", jcr->last_fname, be.bstrerror()); @@ -433,9 +452,10 @@ static bxattr_exit_code aix_xattr_build_streams(JCR *jcr, FF_PKT *ff_pkt) */ current_xattr->name_length = name_length; current_xattr->name = (char *)malloc(current_xattr->name_length); - memcpy((caddr_t)current_xattr->name, (caddr_t)bp, current_xattr->name_length); + memcpy(current_xattr->name, bp, current_xattr->name_length); - expected_serialize_len += sizeof(current_xattr->name_length) + current_xattr->name_length; + expected_serialize_len += sizeof(current_xattr->name_length) + + current_xattr->name_length; /* * First see how long the value is for the extended attribute. @@ -449,7 +469,8 @@ static bxattr_exit_code aix_xattr_build_streams(JCR *jcr, FF_PKT *ff_pkt) retval = bxattr_exit_ok; goto bail_out; default: - Mmsg2(jcr->errmsg, _("lgetea error on file \"%s\": ERR=%s\n"), + Mmsg2(jcr->errmsg, + _("lgetea error on file \"%s\": ERR=%s\n"), jcr->last_fname, be.bstrerror()); Dmsg2(100, "lgetea error file=%s ERR=%s\n", jcr->last_fname, be.bstrerror()); @@ -466,7 +487,7 @@ static bxattr_exit_code aix_xattr_build_streams(JCR *jcr, FF_PKT *ff_pkt) * Allocate space for storing the value. */ current_xattr->value = (char *)malloc(xattr_value_len); - memset((caddr_t)current_xattr->value, 0, xattr_value_len); + memset(current_xattr->value, 0, xattr_value_len); xattr_value_len = lgetea(jcr->last_fname, bp, current_xattr->value, xattr_value_len); if (xattr_value_len < 0) { @@ -476,7 +497,8 @@ static bxattr_exit_code aix_xattr_build_streams(JCR *jcr, FF_PKT *ff_pkt) retval = bxattr_exit_ok; goto bail_out; default: - Mmsg2(jcr->errmsg, _("lgetea error on file \"%s\": ERR=%s\n"), + Mmsg2(jcr->errmsg, + _("lgetea error on file \"%s\": ERR=%s\n"), jcr->last_fname, be.bstrerror()); Dmsg2(100, "lgetea error file=%s ERR=%s\n", jcr->last_fname, be.bstrerror()); @@ -487,13 +509,15 @@ static bxattr_exit_code aix_xattr_build_streams(JCR *jcr, FF_PKT *ff_pkt) * Store the actual length of the value. */ current_xattr->value_length = xattr_value_len; - expected_serialize_len += sizeof(current_xattr->value_length) + current_xattr->value_length; + 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"), + Mmsg2(jcr->errmsg, + _("Xattr stream on file \"%s\" exceeds maximum size of %d bytes\n"), jcr->last_fname, MAX_XATTR_STREAM); goto bail_out; } @@ -520,8 +544,11 @@ static bxattr_exit_code aix_xattr_build_streams(JCR *jcr, FF_PKT *ff_pkt) /* * 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"), + 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); @@ -555,7 +582,10 @@ bail_out: return retval; } -static bxattr_exit_code aix_xattr_parse_streams(JCR *jcr, int stream) +static bxattr_exit_code aix_parse_xattr_streams(JCR *jcr, + int stream, + char *content, + uint32_t content_length) { xattr_t *current_xattr; alist *xattr_value_list; @@ -563,28 +593,36 @@ static bxattr_exit_code aix_xattr_parse_streams(JCR *jcr, int stream) xattr_value_list = New(alist(10, not_owned_by_alist)); - if (unserialize_xattr_stream(jcr, xattr_value_list) != bxattr_exit_ok) { + if (unserialize_xattr_stream(jcr, + content, + content_length, + xattr_value_list) != bxattr_exit_ok) { xattr_drop_internal_table(xattr_value_list); return bxattr_exit_error; } foreach_alist(current_xattr, xattr_value_list) { - if (lsetea(jcr->last_fname, current_xattr->name, current_xattr->value, current_xattr->value_length, 0) != 0) { + if (lsetea(jcr->last_fname, + current_xattr->name, + current_xattr->value, + current_xattr->value_length, 0) != 0) { switch (errno) { case ENOENT: case EFORMAT: goto bail_out; case ENOTSUP: /* - * If the filesystem reports it doesn't support XATTRs we clear the - * BXATTR_FLAG_RESTORE_NATIVE flag so we skip XATTR restores on all other files - * on the same filesystem. The BXATTR_FLAG_RESTORE_NATIVE flags gets sets again - * when we change from one filesystem to an other. + * If the filesystem reports it doesn't support XATTRs we clear + * the BXATTR_FLAG_RESTORE_NATIVE flag so we skip XATTR restores + * on all other files on the same filesystem. The + * BXATTR_FLAG_RESTORE_NATIVE flags gets sets again when we + * change from one filesystem to an other. */ jcr->xattr_data->flags &= ~BXATTR_FLAG_RESTORE_NATIVE; goto bail_out; default: - Mmsg2(jcr->errmsg, _("lsetea error on file \"%s\": ERR=%s\n"), + Mmsg2(jcr->errmsg, + _("lsetea error on file \"%s\": ERR=%s\n"), jcr->last_fname, be.bstrerror()); Dmsg2(100, "lsetea error file=%s ERR=%s\n", jcr->last_fname, be.bstrerror()); @@ -604,8 +642,12 @@ bail_out: /* * 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) = aix_xattr_build_streams; -static bxattr_exit_code (*os_parse_xattr_streams)(JCR *jcr, int stream) = aix_xattr_parse_streams; +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, char *content, uint32_t content_length) = + aix_parse_xattr_streams; #elif defined(HAVE_IRIX_OS) @@ -614,9 +656,15 @@ static bxattr_exit_code (*os_parse_xattr_streams)(JCR *jcr, int stream) = aix_xa /* * 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 }; +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; @@ -624,9 +672,16 @@ struct xattr_naming_space { }; static xattr_naming_space xattr_naming_spaces[] = { - { "user.", ATTR_DONTFOLLOW }, - { "root.", ATTR_ROOT | ATTR_DONTFOLLOW }, - { NULL, 0 } + { + "user.", + ATTR_DONTFOLLOW + }, { + "root.", + ATTR_ROOT | ATTR_DONTFOLLOW + }, { + NULL, + 0 + } }; static bxattr_exit_code irix_xattr_build_streams(JCR *jcr, FF_PKT *ff_pkt) @@ -652,7 +707,8 @@ static bxattr_exit_code irix_xattr_build_streams(JCR *jcr, FF_PKT *ff_pkt) retval = bxattr_exit_ok; goto bail_out; default: - Mmsg2(jcr->errmsg, _("attr_list error on file \"%s\": ERR=%s\n"), + 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()); @@ -679,12 +735,14 @@ static bxattr_exit_code irix_xattr_build_streams(JCR *jcr, FF_PKT *ff_pkt) * 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) + 1; + current_xattr->name_length = strlen(xattr_naming_spaces[cnt].name) + + strlen(attrlist_ent->a_name) + 1; 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; + 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); @@ -716,7 +774,8 @@ static bxattr_exit_code irix_xattr_build_streams(JCR *jcr, FF_PKT *ff_pkt) retval = bxattr_exit_ok; goto bail_out; default: - Mmsg2(jcr->errmsg, _("attr_list error on file \"%s\": ERR=%s\n"), + 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()); @@ -727,7 +786,8 @@ static bxattr_exit_code irix_xattr_build_streams(JCR *jcr, FF_PKT *ff_pkt) } break; default: - Mmsg2(jcr->errmsg, _("attr_list error on file \"%s\": ERR=%s\n"), + 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()); @@ -737,13 +797,15 @@ static bxattr_exit_code irix_xattr_build_streams(JCR *jcr, FF_PKT *ff_pkt) current_xattr->value_length = length; } - expected_serialize_len += sizeof(current_xattr->value_length) + current_xattr->value_length; + 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"), + Mmsg2(jcr->errmsg, + _("Xattr stream on file \"%s\" exceeds maximum size of %d bytes\n"), jcr->last_fname, MAX_XATTR_STREAM); goto bail_out; } @@ -773,8 +835,11 @@ static bxattr_exit_code irix_xattr_build_streams(JCR *jcr, FF_PKT *ff_pkt) /* * 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"), + 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); @@ -807,7 +872,10 @@ bail_out: return retval; } -static bxattr_exit_code irix_xattr_parse_streams(JCR *jcr, int stream) +static bxattr_exit_code irix_parse_xattr_streams(JCR *jcr, + int stream, + char *content, + uint32_t content_length) { char *bp; int cnt, cmp_size, name_space_index, flags; @@ -818,7 +886,10 @@ static bxattr_exit_code irix_xattr_parse_streams(JCR *jcr, int stream) xattr_value_list = New(alist(10, not_owned_by_alist)); - if (unserialize_xattr_stream(jcr, xattr_value_list) != bxattr_exit_ok) { + if (unserialize_xattr_stream(jcr, + content, + content_length, + xattr_value_list) != bxattr_exit_ok) { xattr_drop_internal_table(xattr_value_list); return bxattr_exit_error; } @@ -842,7 +913,8 @@ static bxattr_exit_code irix_xattr_parse_streams(JCR *jcr, int stream) * If we got a xattr that doesn't belong to an valid namespace complain. */ if (name_space_index == 0) { - Mmsg2(jcr->errmsg, _("Received illegal xattr named %s on file \"%s\"\n"), + Mmsg2(jcr->errmsg, + _("Received illegal xattr named %s on file \"%s\"\n"), current_xattr->name, jcr->last_fname); Dmsg2(100, "Received illegal xattr named %s on file \"%s\"\n", current_xattr->name, jcr->last_fname); @@ -872,7 +944,8 @@ static bxattr_exit_code irix_xattr_parse_streams(JCR *jcr, int stream) retval = bxattr_exit_ok; goto bail_out; default: - Mmsg2(jcr->errmsg, _("attr_set error on file \"%s\": ERR=%s\n"), + Mmsg2(jcr->errmsg, + _("attr_set error on file \"%s\": ERR=%s\n"), jcr->last_fname, be.bstrerror()); Dmsg2(100, "attr_set error file=%s ERR=%s\n", jcr->last_fname, be.bstrerror()); @@ -881,7 +954,8 @@ static bxattr_exit_code irix_xattr_parse_streams(JCR *jcr, int stream) } break; default: - Mmsg2(jcr->errmsg, _("attr_set error on file \"%s\": ERR=%s\n"), + Mmsg2(jcr->errmsg, + _("attr_set error on file \"%s\": ERR=%s\n"), jcr->last_fname, be.bstrerror()); Dmsg2(100, "attr_set error file=%s ERR=%s\n", jcr->last_fname, be.bstrerror()); @@ -901,8 +975,12 @@ bail_out: /* * 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; +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, char *content, uint32_t content_length) = + irix_parse_xattr_streams; #elif defined(HAVE_DARWIN_OS) || \ defined(HAVE_LINUX_OS) @@ -923,13 +1001,29 @@ static bxattr_exit_code (*os_parse_xattr_streams)(JCR *jcr, int stream) = irix_x * Define the supported XATTR streams for this OS */ #if defined(HAVE_DARWIN_OS) -static int os_default_xattr_streams[1] = { STREAM_XATTR_DARWIN }; -static const char *xattr_acl_skiplist[2] = { "com.apple.system.Security", NULL }; -static const char *xattr_skiplist[3] = { "com.apple.system.extendedsecurity", "com.apple.ResourceFork", NULL }; +static int os_default_xattr_streams[1] = { + STREAM_XATTR_DARWIN +}; +static const char *xattr_acl_skiplist[2] = { + "com.apple.system.Security", + NULL +}; +static const char *xattr_skiplist[3] = { + "com.apple.system.extendedsecurity", + "com.apple.ResourceFork", + NULL +}; #elif defined(HAVE_LINUX_OS) -static int os_default_xattr_streams[1] = { STREAM_XATTR_LINUX }; -static const char *xattr_acl_skiplist[2] = { "system.posix_acl_access", NULL }; -static const char *xattr_skiplist[1] = { NULL }; +static int os_default_xattr_streams[1] = { + STREAM_XATTR_LINUX +}; +static const char *xattr_acl_skiplist[2] = { + "system.posix_acl_access", + NULL +}; +static const char *xattr_skiplist[1] = { + NULL +}; #endif /* @@ -939,9 +1033,12 @@ static const char *xattr_skiplist[1] = { NULL }; * XATTR_NOFOLLOW as the options value. */ #if defined(HAVE_DARWIN_OS) - #define llistxattr(path, list, size) listxattr((path), (list), (size), XATTR_NOFOLLOW) - #define lgetxattr(path, name, value, size) getxattr((path), (name), (value), (size), 0, XATTR_NOFOLLOW) - #define lsetxattr(path, name, value, size, flags) setxattr((path), (name), (value), (size), (flags), XATTR_NOFOLLOW) + #define llistxattr(path, list, size) \ + listxattr((path), (list), (size), XATTR_NOFOLLOW) + #define lgetxattr(path, name, value, size) \ + getxattr((path), (name), (value), (size), 0, XATTR_NOFOLLOW) + #define lsetxattr(path, name, value, size, flags) \ + setxattr((path), (name), (value), (size), (flags), XATTR_NOFOLLOW) #else /* * Fallback to the non l-functions when those are not available. @@ -982,15 +1079,17 @@ static bxattr_exit_code generic_xattr_build_streams(JCR *jcr, FF_PKT *ff_pkt) return bxattr_exit_ok; case BXATTR_ENOTSUP: /* - * If the filesystem reports it doesn't support XATTRs we clear the - * BXATTR_FLAG_SAVE_NATIVE flag so we skip XATTR saves on all other files - * on the same filesystem. The BXATTR_FLAG_SAVE_NATIVE flags gets sets again - * when we change from one filesystem to an other. + * If the filesystem reports it doesn't support XATTRs we clear + * the BXATTR_FLAG_RESTORE_NATIVE flag so we skip XATTR restores + * on all other files on the same filesystem. The + * BXATTR_FLAG_RESTORE_NATIVE flags gets sets again when we + * change from one filesystem to an other. */ jcr->xattr_data->flags &= ~BXATTR_FLAG_SAVE_NATIVE; return bxattr_exit_ok; default: - Mmsg2(jcr->errmsg, _("llistxattr error on file \"%s\": ERR=%s\n"), + Mmsg2(jcr->errmsg, + _("llistxattr error on file \"%s\": ERR=%s\n"), jcr->last_fname, be.bstrerror()); Dmsg2(100, "llistxattr error file=%s ERR=%s\n", jcr->last_fname, be.bstrerror()); @@ -1007,7 +1106,7 @@ static bxattr_exit_code generic_xattr_build_streams(JCR *jcr, FF_PKT *ff_pkt) * Allocate room for the extented attribute list. */ xattr_list = (char *)malloc(xattr_list_len + 1); - memset((caddr_t)xattr_list, 0, xattr_list_len + 1); + memset(xattr_list, 0, xattr_list_len + 1); /* * Get the actual list of extended attributes names for a file. @@ -1020,7 +1119,8 @@ static bxattr_exit_code generic_xattr_build_streams(JCR *jcr, FF_PKT *ff_pkt) retval = bxattr_exit_ok; goto bail_out; default: - Mmsg2(jcr->errmsg, _("llistxattr error on file \"%s\": ERR=%s\n"), + Mmsg2(jcr->errmsg, + _("llistxattr error on file \"%s\": ERR=%s\n"), jcr->last_fname, be.bstrerror()); Dmsg2(100, "llistxattr error file=%s ERR=%s\n", jcr->last_fname, be.bstrerror()); @@ -1085,7 +1185,7 @@ static bxattr_exit_code generic_xattr_build_streams(JCR *jcr, FF_PKT *ff_pkt) */ current_xattr->name_length = name_length; current_xattr->name = (char *)malloc(current_xattr->name_length); - memcpy((caddr_t)current_xattr->name, (caddr_t)bp, current_xattr->name_length); + memcpy(current_xattr->name, bp, current_xattr->name_length); expected_serialize_len += sizeof(current_xattr->name_length) + current_xattr->name_length; @@ -1100,7 +1200,8 @@ static bxattr_exit_code generic_xattr_build_streams(JCR *jcr, FF_PKT *ff_pkt) retval = bxattr_exit_ok; goto bail_out; default: - Mmsg2(jcr->errmsg, _("lgetxattr error on file \"%s\": ERR=%s\n"), + Mmsg2(jcr->errmsg, + _("lgetxattr error on file \"%s\": ERR=%s\n"), jcr->last_fname, be.bstrerror()); Dmsg2(100, "lgetxattr error file=%s ERR=%s\n", jcr->last_fname, be.bstrerror()); @@ -1117,7 +1218,7 @@ static bxattr_exit_code generic_xattr_build_streams(JCR *jcr, FF_PKT *ff_pkt) * Allocate space for storing the value. */ current_xattr->value = (char *)malloc(xattr_value_len); - memset((caddr_t)current_xattr->value, 0, xattr_value_len); + memset(current_xattr->value, 0, xattr_value_len); xattr_value_len = lgetxattr(jcr->last_fname, bp, current_xattr->value, xattr_value_len); if (xattr_value_len < 0) { @@ -1126,7 +1227,8 @@ static bxattr_exit_code generic_xattr_build_streams(JCR *jcr, FF_PKT *ff_pkt) retval = bxattr_exit_ok; goto bail_out; default: - Mmsg2(jcr->errmsg, _("lgetxattr error on file \"%s\": ERR=%s\n"), + Mmsg2(jcr->errmsg, + _("lgetxattr error on file \"%s\": ERR=%s\n"), jcr->last_fname, be.bstrerror()); Dmsg2(100, "lgetxattr error file=%s ERR=%s\n", jcr->last_fname, be.bstrerror()); @@ -1143,7 +1245,8 @@ static bxattr_exit_code generic_xattr_build_streams(JCR *jcr, FF_PKT *ff_pkt) * 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"), + Mmsg2(jcr->errmsg, + _("Xattr stream on file \"%s\" exceeds maximum size of %d bytes\n"), jcr->last_fname, MAX_XATTR_STREAM); goto bail_out; } @@ -1170,8 +1273,11 @@ static bxattr_exit_code generic_xattr_build_streams(JCR *jcr, FF_PKT *ff_pkt) /* * 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"), + 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); @@ -1205,7 +1311,10 @@ bail_out: return retval; } -static bxattr_exit_code generic_xattr_parse_streams(JCR *jcr, int stream) +static bxattr_exit_code generic_parse_xattr_streams(JCR *jcr, + int stream, + char *content, + uint32_t content_length) { xattr_t *current_xattr; alist *xattr_value_list; @@ -1213,7 +1322,10 @@ static bxattr_exit_code generic_xattr_parse_streams(JCR *jcr, int stream) xattr_value_list = New(alist(10, not_owned_by_alist)); - if (unserialize_xattr_stream(jcr, xattr_value_list) != bxattr_exit_ok) { + if (unserialize_xattr_stream(jcr, + content, + content_length, + xattr_value_list) != bxattr_exit_ok) { xattr_drop_internal_table(xattr_value_list); return bxattr_exit_error; } @@ -1225,15 +1337,17 @@ static bxattr_exit_code generic_xattr_parse_streams(JCR *jcr, int stream) goto bail_out; case BXATTR_ENOTSUP: /* - * If the filesystem reports it doesn't support XATTRs we clear the - * BXATTR_FLAG_RESTORE_NATIVE flag so we skip XATTR restores on all other files - * on the same filesystem. The BXATTR_FLAG_RESTORE_NATIVE flags gets sets again - * when we change from one filesystem to an other. + * If the filesystem reports it doesn't support XATTRs we clear + * the BXATTR_FLAG_RESTORE_NATIVE flag so we skip XATTR restores + * on all other files on the same filesystem. The + * BXATTR_FLAG_RESTORE_NATIVE flags gets sets again when we + * change from one filesystem to an other. */ jcr->xattr_data->flags &= ~BXATTR_FLAG_RESTORE_NATIVE; goto bail_out; default: - Mmsg2(jcr->errmsg, _("lsetxattr error on file \"%s\": ERR=%s\n"), + Mmsg2(jcr->errmsg, + _("lsetxattr error on file \"%s\": ERR=%s\n"), jcr->last_fname, be.bstrerror()); Dmsg2(100, "lsetxattr error file=%s ERR=%s\n", jcr->last_fname, be.bstrerror()); @@ -1253,8 +1367,12 @@ bail_out: /* * 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) = generic_xattr_build_streams; -static bxattr_exit_code (*os_parse_xattr_streams)(JCR *jcr, int stream) = generic_xattr_parse_streams; +static bxattr_exit_code (*os_build_xattr_streams) + (JCR *jcr, FF_PKT *ff_pkt) = + generic_xattr_build_streams; +static bxattr_exit_code (*os_parse_xattr_streams) + (JCR *jcr, int stream, char *content, uint32_t content_length) = + generic_parse_xattr_streams; #elif defined(HAVE_FREEBSD_OS) || \ defined(HAVE_NETBSD_OS) || \ @@ -1289,20 +1407,50 @@ static bxattr_exit_code (*os_parse_xattr_streams)(JCR *jcr, int stream) = generi #endif #if defined(HAVE_FREEBSD_OS) -static int os_default_xattr_streams[1] = { STREAM_XATTR_FREEBSD }; -static int os_default_xattr_namespaces[2] = { EXTATTR_NAMESPACE_USER, EXTATTR_NAMESPACE_SYSTEM }; -static const char *xattr_acl_skiplist[4] = { "system.posix1e.acl_access", "system.posix1e.acl_default", "system.nfs4.acl", NULL }; -static const char *xattr_skiplist[1] = { NULL }; +static int os_default_xattr_streams[1] = { + STREAM_XATTR_FREEBSD +}; +static int os_default_xattr_namespaces[2] = { + EXTATTR_NAMESPACE_USER, + EXTATTR_NAMESPACE_SYSTEM +}; +static const char *xattr_acl_skiplist[4] = { + "system.posix1e.acl_access", + "system.posix1e.acl_default", + "system.nfs4.acl", + NULL +}; +static const char *xattr_skiplist[1] = { + NULL +}; #elif defined(HAVE_NETBSD_OS) -static int os_default_xattr_streams[1] = { STREAM_XATTR_NETBSD }; -static int os_default_xattr_namespaces[2] = { EXTATTR_NAMESPACE_USER, EXTATTR_NAMESPACE_SYSTEM }; -static const char *xattr_acl_skiplist[1] = { NULL }; -static const char *xattr_skiplist[1] = { NULL }; +static int os_default_xattr_streams[1] = { + STREAM_XATTR_NETBSD +}; +static int os_default_xattr_namespaces[2] = { + EXTATTR_NAMESPACE_USER, + EXTATTR_NAMESPACE_SYSTEM +}; +static const char *xattr_acl_skiplist[1] = { + NULL +}; +static const char *xattr_skiplist[1] = { + NULL +}; #elif defined(HAVE_OPENBSD_OS) -static int os_default_xattr_streams[1] = { STREAM_XATTR_OPENBSD }; -static int os_default_xattr_namespaces[2] = { EXTATTR_NAMESPACE_USER, EXTATTR_NAMESPACE_SYSTEM }; -static const char *xattr_acl_skiplist[1] = { NULL }; -static const char *xattr_skiplist[1] = { NULL }; +static int os_default_xattr_streams[1] = { + STREAM_XATTR_OPENBSD +}; +static int os_default_xattr_namespaces[2] = { + EXTATTR_NAMESPACE_USER, + EXTATTR_NAMESPACE_SYSTEM +}; +static const char *xattr_acl_skiplist[1] = { + NULL +}; +static const char *xattr_skiplist[1] = { + NULL +}; #endif static bxattr_exit_code bsd_build_xattr_streams(JCR *jcr, FF_PKT *ff_pkt) @@ -1325,7 +1473,9 @@ static bxattr_exit_code bsd_build_xattr_streams(JCR *jcr, FF_PKT *ff_pkt) /* * Loop over all available xattr namespaces. */ - for (namespace_index = 0; namespace_index < sizeof(os_default_xattr_namespaces) / sizeof(int); namespace_index++) { + for (namespace_index = 0; + namespace_index < sizeof(os_default_xattr_namespaces) / sizeof(int); + namespace_index++) { attrnamespace = os_default_xattr_namespaces[namespace_index]; /* @@ -1353,7 +1503,8 @@ static bxattr_exit_code bsd_build_xattr_streams(JCR *jcr, FF_PKT *ff_pkt) * FALLTHROUGH */ default: - Mmsg2(jcr->errmsg, _("extattr_list_link error on file \"%s\": ERR=%s\n"), + Mmsg2(jcr->errmsg, + _("extattr_list_link error on file \"%s\": ERR=%s\n"), jcr->last_fname, be.bstrerror()); Dmsg2(100, "extattr_list_link error file=%s ERR=%s\n", jcr->last_fname, be.bstrerror()); @@ -1370,12 +1521,13 @@ static bxattr_exit_code bsd_build_xattr_streams(JCR *jcr, FF_PKT *ff_pkt) * Allocate room for the extented attribute list. */ xattr_list = (char *)malloc(xattr_list_len + 1); - memset((caddr_t)xattr_list, 0, xattr_list_len + 1); + memset(xattr_list, 0, xattr_list_len + 1); /* * Get the actual list of extended attributes names for a file. */ - xattr_list_len = extattr_list_link(jcr->last_fname, attrnamespace, xattr_list, xattr_list_len); + xattr_list_len = extattr_list_link(jcr->last_fname, attrnamespace, + xattr_list, xattr_list_len); switch (xattr_list_len) { case -1: switch (errno) { @@ -1383,7 +1535,8 @@ static bxattr_exit_code bsd_build_xattr_streams(JCR *jcr, FF_PKT *ff_pkt) retval = bxattr_exit_ok; goto bail_out; default: - Mmsg2(jcr->errmsg, _("extattr_list_link error on file \"%s\": ERR=%s\n"), + Mmsg2(jcr->errmsg, + _("extattr_list_link error on file \"%s\": ERR=%s\n"), jcr->last_fname, be.bstrerror()); Dmsg2(100, "extattr_list_link error file=%s ERR=%s\n", jcr->last_fname, be.bstrerror()); @@ -1396,11 +1549,13 @@ static bxattr_exit_code bsd_build_xattr_streams(JCR *jcr, FF_PKT *ff_pkt) xattr_list[xattr_list_len] = '\0'; /* - * Convert the numeric attrnamespace into a string representation and make a private copy of that string. - * The extattr_namespace_to_string functions returns a strdupped string which we need to free. + * Convert the numeric attrnamespace into a string representation and make + * a private copy of that string. The extattr_namespace_to_string functions + * returns a strdupped string which we need to free. */ if (extattr_namespace_to_string(attrnamespace, ¤t_attrnamespace) != 0) { - Mmsg2(jcr->errmsg, _("Failed to convert %d into namespace on file \"%s\"\n"), + Mmsg2(jcr->errmsg, + _("Failed to convert %d into namespace on file \"%s\"\n"), attrnamespace, jcr->last_fname); Dmsg2(100, "Failed to convert %d into namespace on file \"%s\"\n", attrnamespace, jcr->last_fname); @@ -1415,8 +1570,9 @@ static bxattr_exit_code bsd_build_xattr_streams(JCR *jcr, FF_PKT *ff_pkt) skip_xattr = false; /* - * Print the current name into the buffer as its not null terminated we need to - * use the length encoded in the string for copying only the needed bytes. + * Print the current name into the buffer as its not null terminated + * we need to use the length encoded in the string for copying only + * the needed bytes. */ cnt = xattr_list[index]; if (cnt > ((int)sizeof(current_attrname) - 1)) { @@ -1426,10 +1582,11 @@ static bxattr_exit_code bsd_build_xattr_streams(JCR *jcr, FF_PKT *ff_pkt) current_attrname[cnt] = '\0'; /* - * First make a xattr tuple of the current namespace and the name of the xattr. - * e.g. something like user. or system. + * First make a xattr tuple of the current namespace and the name of + * the xattr. e.g. something like user. or system. */ - bsnprintf(current_attrtuple, sizeof(current_attrtuple), "%s.%s", current_attrnamespace, current_attrname); + bsnprintf(current_attrtuple, sizeof(current_attrtuple), "%s.%s", + current_attrnamespace, current_attrname); /* * On some OSes you also get the acls in the extented attribute list. @@ -1446,7 +1603,8 @@ static bxattr_exit_code bsd_build_xattr_streams(JCR *jcr, FF_PKT *ff_pkt) } /* - * On some OSes we want to skip certain xattrs which are in the xattr_skiplist array. + * On some OSes we want to skip certain xattrs which are in the + * xattr_skiplist array. */ if (!skip_xattr) { for (cnt = 0; xattr_skiplist[cnt] != NULL; cnt++) { @@ -1474,14 +1632,16 @@ static bxattr_exit_code bsd_build_xattr_streams(JCR *jcr, FF_PKT *ff_pkt) */ current_xattr->name_length = strlen(current_attrtuple); current_xattr->name = (char *)malloc(current_xattr->name_length); - memcpy((caddr_t)current_xattr->name, (caddr_t)current_attrtuple, current_xattr->name_length); + memcpy(current_xattr->name, current_attrtuple, current_xattr->name_length); - expected_serialize_len += sizeof(current_xattr->name_length) + current_xattr->name_length; + expected_serialize_len += sizeof(current_xattr->name_length) + + current_xattr->name_length; /* * First see how long the value is for the extended attribute. */ - xattr_value_len = extattr_get_link(jcr->last_fname, attrnamespace, current_attrname, NULL, 0); + xattr_value_len = extattr_get_link(jcr->last_fname, attrnamespace, + current_attrname, NULL, 0); switch (xattr_value_len) { case -1: switch (errno) { @@ -1489,7 +1649,8 @@ static bxattr_exit_code bsd_build_xattr_streams(JCR *jcr, FF_PKT *ff_pkt) retval = bxattr_exit_ok; goto bail_out; default: - Mmsg2(jcr->errmsg, _("extattr_get_link error on file \"%s\": ERR=%s\n"), + Mmsg2(jcr->errmsg, + _("extattr_get_link error on file \"%s\": ERR=%s\n"), jcr->last_fname, be.bstrerror()); Dmsg2(100, "extattr_get_link error file=%s ERR=%s\n", jcr->last_fname, be.bstrerror()); @@ -1506,16 +1667,19 @@ static bxattr_exit_code bsd_build_xattr_streams(JCR *jcr, FF_PKT *ff_pkt) * Allocate space for storing the value. */ current_xattr->value = (char *)malloc(xattr_value_len); - memset((caddr_t)current_xattr->value, 0, xattr_value_len); + memset(current_xattr->value, 0, xattr_value_len); - xattr_value_len = extattr_get_link(jcr->last_fname, attrnamespace, current_attrname, current_xattr->value, xattr_value_len); + xattr_value_len = extattr_get_link(jcr->last_fname, attrnamespace, + current_attrname, current_xattr->value, + xattr_value_len); if (xattr_value_len < 0) { switch (errno) { case ENOENT: retval = bxattr_exit_ok; goto bail_out; default: - Mmsg2(jcr->errmsg, _("extattr_get_link error on file \"%s\": ERR=%s\n"), + Mmsg2(jcr->errmsg, + _("extattr_get_link error on file \"%s\": ERR=%s\n"), jcr->last_fname, be.bstrerror()); Dmsg2(100, "extattr_get_link error file=%s ERR=%s\n", jcr->last_fname, be.bstrerror()); @@ -1527,13 +1691,15 @@ static bxattr_exit_code bsd_build_xattr_streams(JCR *jcr, FF_PKT *ff_pkt) * Store the actual length of the value. */ current_xattr->value_length = xattr_value_len; - expected_serialize_len += sizeof(current_xattr->value_length) + current_xattr->value_length; + 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"), + Mmsg2(jcr->errmsg, + _("Xattr stream on file \"%s\" exceeds maximum size of %d bytes\n"), jcr->last_fname, MAX_XATTR_STREAM); goto bail_out; } @@ -1570,8 +1736,11 @@ static bxattr_exit_code bsd_build_xattr_streams(JCR *jcr, FF_PKT *ff_pkt) /* * 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"), + 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); @@ -1608,7 +1777,10 @@ bail_out: return retval; } -static bxattr_exit_code bsd_parse_xattr_streams(JCR *jcr, int stream) +static bxattr_exit_code bsd_parse_xattr_streams(JCR *jcr, + int stream, + char *content, + uint32_t content_length) { xattr_t *current_xattr; alist *xattr_value_list; @@ -1618,7 +1790,10 @@ static bxattr_exit_code bsd_parse_xattr_streams(JCR *jcr, int stream) xattr_value_list = New(alist(10, not_owned_by_alist)); - if (unserialize_xattr_stream(jcr, xattr_value_list) != bxattr_exit_ok) { + if (unserialize_xattr_stream(jcr, + content, + content_length, + xattr_value_list) != bxattr_exit_ok) { xattr_drop_internal_table(xattr_value_list); return bxattr_exit_error; } @@ -1630,7 +1805,8 @@ static bxattr_exit_code bsd_parse_xattr_streams(JCR *jcr, int stream) */ attrnamespace = current_xattr->name; if ((attrname = strchr(attrnamespace, '.')) == (char *)NULL) { - Mmsg2(jcr->errmsg, _("Failed to split %s into namespace and name part on file \"%s\"\n"), + Mmsg2(jcr->errmsg, + _("Failed to split %s into namespace and name part on file \"%s\"\n"), current_xattr->name, jcr->last_fname); Dmsg2(100, "Failed to split %s into namespace and name part on file \"%s\"\n", current_xattr->name, jcr->last_fname); @@ -1642,7 +1818,8 @@ static bxattr_exit_code bsd_parse_xattr_streams(JCR *jcr, int stream) * Make sure the attrnamespace makes sense. */ if (extattr_string_to_namespace(attrnamespace, ¤t_attrnamespace) != 0) { - Mmsg2(jcr->errmsg, _("Failed to convert %s into namespace on file \"%s\"\n"), + Mmsg2(jcr->errmsg, + _("Failed to convert %s into namespace on file \"%s\"\n"), attrnamespace, jcr->last_fname); Dmsg2(100, "Failed to convert %s into namespace on file \"%s\"\n", attrnamespace, jcr->last_fname); @@ -1660,7 +1837,8 @@ static bxattr_exit_code bsd_parse_xattr_streams(JCR *jcr, int stream) goto bail_out; break; default: - Mmsg2(jcr->errmsg, _("extattr_set_link error on file \"%s\": ERR=%s\n"), + Mmsg2(jcr->errmsg, + _("extattr_set_link error on file \"%s\": ERR=%s\n"), jcr->last_fname, be.bstrerror()); Dmsg2(100, "extattr_set_link error file=%s ERR=%s\n", jcr->last_fname, be.bstrerror()); @@ -1681,8 +1859,12 @@ bail_out: /* * 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) = bsd_build_xattr_streams; -static bxattr_exit_code (*os_parse_xattr_streams)(JCR *jcr, int stream) = bsd_parse_xattr_streams; +static bxattr_exit_code (*os_build_xattr_streams) + (JCR *jcr, FF_PKT *ff_pkt) = + bsd_build_xattr_streams; +static bxattr_exit_code (*os_parse_xattr_streams) + (JCR *jcr, int stream, char *content, uint32_t content_length) = + bsd_parse_xattr_streams; #elif defined(HAVE_OSF1_OS) @@ -1703,9 +1885,15 @@ static bxattr_exit_code (*os_parse_xattr_streams)(JCR *jcr, int stream) = bsd_pa /* * Define the supported XATTR streams for this OS */ -static int os_default_xattr_streams[1] = { STREAM_XATTR_TRU64 }; -static const char *xattr_acl_skiplist[1] = { NULL }; -static const char *xattr_skiplist[1] = { NULL }; +static int os_default_xattr_streams[1] = { + STREAM_XATTR_TRU64 +}; +static const char *xattr_acl_skiplist[1] = { + NULL +}; +static const char *xattr_skiplist[1] = { + NULL +}; static bxattr_exit_code tru64_build_xattr_streams(JCR *jcr, FF_PKT *ff_pkt) { @@ -1741,16 +1929,18 @@ static bxattr_exit_code tru64_build_xattr_streams(JCR *jcr, FF_PKT *ff_pkt) switch (errno) { case EOPNOTSUPP: /* - * If the filesystem reports it doesn't support XATTRs we clear the - * BXATTR_FLAG_SAVE_NATIVE flag so we skip XATTR saves on all other files - * on the same filesystem. The BXATTR_FLAG_SAVE_NATIVE flags gets sets again - * when we change from one filesystem to an other. + * If the filesystem reports it doesn't support XATTRs we clear + * the BXATTR_FLAG_RESTORE_NATIVE flag so we skip XATTR restores + * on all other files on the same filesystem. The + * BXATTR_FLAG_RESTORE_NATIVE flags gets sets again when we + * change from one filesystem to an other. */ jcr->xattr_data->flags &= ~BXATTR_FLAG_SAVE_NATIVE; retval = bxattr_exit_ok; goto bail_out; default: - Mmsg2(jcr->errmsg, _("getproplist error on file \"%s\": ERR=%s\n"), + Mmsg2(jcr->errmsg, + _("getproplist error on file \"%s\": ERR=%s\n"), jcr->last_fname, be.bstrerror()); Dmsg2(100, "getproplist error file=%s ERR=%s\n", jcr->last_fname, be.bstrerror()); @@ -1771,7 +1961,8 @@ static bxattr_exit_code tru64_build_xattr_streams(JCR *jcr, FF_PKT *ff_pkt) case -1: switch (errno) { default: - Mmsg2(jcr->errmsg, _("getproplist error on file \"%s\": ERR=%s\n"), + Mmsg2(jcr->errmsg, + _("getproplist error on file \"%s\": ERR=%s\n"), jcr->last_fname, be.bstrerror()); Dmsg2(100, "getproplist error file=%s ERR=%s\n", jcr->last_fname, be.bstrerror()); @@ -1855,19 +2046,22 @@ static bxattr_exit_code tru64_build_xattr_streams(JCR *jcr, FF_PKT *ff_pkt) current_xattr->name_length = strlen(xattr_name); current_xattr->name = bstrdup(xattr_name); - expected_serialize_len += sizeof(current_xattr->name_length) + current_xattr->name_length; + expected_serialize_len += sizeof(current_xattr->name_length) + + current_xattr->name_length; current_xattr->value_length = *xattr_value_len; current_xattr->value = (char *)malloc(current_xattr->value_length); memcpy(current_xattr->value, xattr_value, current_xattr->value_length); - expected_serialize_len += sizeof(current_xattr->value_length) + current_xattr->value_length; + 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"), + Mmsg2(jcr->errmsg, + _("Xattr stream on file \"%s\" exceeds maximum size of %d bytes\n"), jcr->last_fname, MAX_XATTR_STREAM); goto bail_out; } @@ -1888,8 +2082,11 @@ static bxattr_exit_code tru64_build_xattr_streams(JCR *jcr, FF_PKT *ff_pkt) /* * 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"), + 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); @@ -1920,7 +2117,10 @@ bail_out: return retval; } -static bxattr_exit_code tru64_parse_xattr_streams(JCR *jcr, int stream) +static bxattr_exit_code tru64_parse_xattr_streams(JCR *jcr, + int stream, + char *content, + uint32_t content_length) { char *bp, *xattrbuf = NULL; int32_t xattrbuf_size, cnt; @@ -1931,7 +2131,10 @@ static bxattr_exit_code tru64_parse_xattr_streams(JCR *jcr, int stream) xattr_value_list = New(alist(10, not_owned_by_alist)); - if (unserialize_xattr_stream(jcr, xattr_value_list) != bxattr_exit_ok) { + if (unserialize_xattr_stream(jcr, + content, + content_length, + xattr_value_list) != bxattr_exit_ok) { xattr_drop_internal_table(xattr_value_list); return bxattr_exit_error; } @@ -1960,7 +2163,8 @@ static bxattr_exit_code tru64_parse_xattr_streams(JCR *jcr, int stream) * Sanity check. */ if (cnt != xattrbuf_size) { - Mmsg1(jcr->errmsg, _("Unable create proper proplist to restore xattrs on file \"%s\"\n"), + Mmsg1(jcr->errmsg, + _("Unable create proper proplist to restore xattrs on file \"%s\"\n"), jcr->last_fname); Dmsg1(100, "Unable create proper proplist to restore xattrs on file \"%s\"\n", jcr->last_fname); @@ -1976,16 +2180,18 @@ static bxattr_exit_code tru64_parse_xattr_streams(JCR *jcr, int stream) switch (errno) { case EOPNOTSUPP: /* - * If the filesystem reports it doesn't support XATTRs we clear the - * BXATTR_FLAG_RESTORE_NATIVE flag so we skip XATTR restores on all other files - * on the same filesystem. The BXATTR_FLAG_RESTORE_NATIVE flags gets sets again - * when we change from one filesystem to an other. + * If the filesystem reports it doesn't support XATTRs we clear + * the BXATTR_FLAG_RESTORE_NATIVE flag so we skip XATTR restores + * on all other files on the same filesystem. The + * BXATTR_FLAG_RESTORE_NATIVE flags gets sets again when we + * change from one filesystem to an other. */ jcr->xattr_data->flags &= ~BXATTR_FLAG_RESTORE_NATIVE; retval = bxattr_exit_ok; goto bail_out; default: - Mmsg2(jcr->errmsg, _("setproplist error on file \"%s\": ERR=%s\n"), + Mmsg2(jcr->errmsg, + _("setproplist error on file \"%s\": ERR=%s\n"), jcr->last_fname, be.bstrerror()); Dmsg2(100, "setproplist error file=%s ERR=%s\n", jcr->last_fname, be.bstrerror()); @@ -2012,8 +2218,12 @@ bail_out: /* * 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) = tru64_build_xattr_streams; -static bxattr_exit_code (*os_parse_xattr_streams)(JCR *jcr, int stream) = tru64_parse_xattr_streams; +static bxattr_exit_code (*os_build_xattr_streams) + (JCR *jcr, FF_PKT *ff_pkt) = + tru64_build_xattr_streams; +static bxattr_exit_code (*os_parse_xattr_streams) + (JCR *jcr, int stream, char *content, uint32_t content_length) = + tru64_parse_xattr_streams; #elif defined(HAVE_SUN_OS) /* @@ -2122,9 +2332,14 @@ static bxattr_exit_code (*os_parse_xattr_streams)(JCR *jcr, int stream) = tru64_ * Define the supported XATTR streams for this OS */ #if defined(HAVE_SYS_NVPAIR_H) && defined(_PC_SATTR_ENABLED) -static int os_default_xattr_streams[2] = { STREAM_XATTR_SOLARIS, STREAM_XATTR_SOLARIS_SYS}; +static int os_default_xattr_streams[2] = { + STREAM_XATTR_SOLARIS, + STREAM_XATTR_SOLARIS_SYS +}; #else -static int os_default_xattr_streams[1] = { STREAM_XATTR_SOLARIS }; +static int os_default_xattr_streams[1] = { + STREAM_XATTR_SOLARIS +}; #endif /* defined(HAVE_SYS_NVPAIR_H) && defined(_PC_SATTR_ENABLED) */ /* @@ -2135,7 +2350,7 @@ static xattr_link_cache_entry_t *find_xattr_link_cache_entry(JCR *jcr, ino_t inu { xattr_link_cache_entry_t *ptr; - foreach_alist(ptr, jcr->xattr_data->link_cache) { + foreach_alist(ptr, jcr->xattr_data->u.build->link_cache) { if (ptr && ptr->inum == inum) { return ptr; } @@ -2148,10 +2363,14 @@ static void add_xattr_link_cache_entry(JCR *jcr, ino_t inum, char *target) xattr_link_cache_entry_t *ptr; ptr = (xattr_link_cache_entry_t *)malloc(sizeof(xattr_link_cache_entry_t)); - memset((caddr_t)ptr, 0, sizeof(xattr_link_cache_entry_t)); + memset(ptr, 0, sizeof(xattr_link_cache_entry_t)); ptr->inum = inum; bstrncpy(ptr->target, target, sizeof(ptr->target)); - jcr->xattr_data->link_cache->append(ptr); + + if (!jcr->xattr_data->u.build->link_cache) { + jcr->xattr_data->u.build->link_cache = New(alist(10, not_owned_by_alist)); + } + jcr->xattr_data->u.build->link_cache->append(ptr); } #if defined(HAVE_SYS_NVPAIR_H) && defined(_PC_SATTR_ENABLED) @@ -2271,7 +2490,8 @@ static bxattr_exit_code solaris_save_xattr_acl(JCR *jcr, int fd, const char *att case ENOENT: return bxattr_exit_ok; default: - Mmsg3(jcr->errmsg, _("Unable to get acl on xattr %s on file \"%s\": ERR=%s\n"), + Mmsg3(jcr->errmsg, + _("Unable to get acl on xattr %s on file \"%s\": ERR=%s\n"), attrname, jcr->last_fname, be.bstrerror()); Dmsg3(100, "facl_get/acl_get of xattr %s on \"%s\" failed: ERR=%s\n", attrname, jcr->last_fname, be.bstrerror()); @@ -2321,7 +2541,8 @@ static bxattr_exit_code solaris_save_xattr_acl(JCR *jcr, int fd, const char *att free(acls); return bxattr_exit_ok; default: - Mmsg3(jcr->errmsg, _("Unable to get acl on xattr %s on file \"%s\": ERR=%s\n"), + Mmsg3(jcr->errmsg, + _("Unable to get acl on xattr %s on file \"%s\": ERR=%s\n"), attrname, jcr->last_fname, be.bstrerror()); Dmsg3(100, "facl/acl of xattr %s on \"%s\" failed: ERR=%s\n", attrname, jcr->last_fname, be.bstrerror()); @@ -2335,7 +2556,8 @@ static bxattr_exit_code solaris_save_xattr_acl(JCR *jcr, int fd, const char *att */ if (!acl_is_trivial(n, acls)) { if ((*acl_text = acltotext(acls, n)) == NULL) { - Mmsg3(jcr->errmsg, _("Unable to get acl text on xattr %s on file \"%s\": ERR=%s\n"), + Mmsg3(jcr->errmsg, + _("Unable to get acl text on xattr %s on file \"%s\": ERR=%s\n"), attrname, jcr->last_fname, be.bstrerror()); Dmsg3(100, "acltotext of xattr %s on \"%s\" failed: ERR=%s\n", attrname, jcr->last_fname, be.bstrerror()); @@ -2404,7 +2626,8 @@ static bxattr_exit_code solaris_save_xattr(JCR *jcr, int fd, const char *xattr_n retval = bxattr_exit_ok; goto bail_out; default: - Mmsg3(jcr->errmsg, _("Unable to get status on xattr %s on file \"%s\": ERR=%s\n"), + Mmsg3(jcr->errmsg, + _("Unable to get status on xattr %s on file \"%s\": ERR=%s\n"), target_attrname, jcr->last_fname, be.bstrerror()); Dmsg3(100, "fstatat of xattr %s on \"%s\" failed: ERR=%s\n", target_attrname, jcr->last_fname, be.bstrerror()); @@ -2428,12 +2651,14 @@ static bxattr_exit_code solaris_save_xattr(JCR *jcr, int fd, const char *xattr_n goto bail_out; /* - * The current implementation of xattr on Solaris doesn't support this, but if it ever does we are prepared. + * The current implementation of xattr on Solaris doesn't support this, + * but if it ever does we are prepared. * Encode the stat struct into an ASCII representation. */ encode_stat(attribs, &st, sizeof(st), 0, stream); cnt = bsnprintf(buffer, sizeof(buffer), "%s%c%s%c%s%c", - target_attrname, 0, attribs, 0, (acl_text) ? acl_text : "", 0); + target_attrname, 0, attribs, 0, + (acl_text) ? acl_text : "", 0); break; case S_IFDIR: /* @@ -2447,27 +2672,31 @@ static bxattr_exit_code solaris_save_xattr(JCR *jcr, int fd, const char *xattr_n */ if (toplevel_hidden_dir) { /* - * Save the data for later storage when we encounter a real xattr. We store the data - * in the jcr->xattr_data->content buffer and flush that just before sending out the - * first real xattr. Encode the stat struct into an ASCII representation and jump + * Save the data for later storage when we encounter a real xattr. + * We store the data in the jcr->xattr_data->u.build->content buffer + * and flush that just before sending out the first real xattr. + * Encode the stat struct into an ASCII representation and jump * out of the function. */ encode_stat(attribs, &st, sizeof(st), 0, stream); cnt = bsnprintf(buffer, sizeof(buffer), "%s%c%s%c%s%c", - target_attrname, 0, attribs, 0, (acl_text) ? acl_text : "", 0); - pm_memcpy(jcr->xattr_data->content, buffer, cnt); - jcr->xattr_data->content_length = cnt; + target_attrname, 0, attribs, 0, + (acl_text) ? acl_text : "", 0); + pm_memcpy(jcr->xattr_data->u.build->content, buffer, cnt); + jcr->xattr_data->u.build->content_length = cnt; goto bail_out; } else { /* - * The current implementation of xattr on Solaris doesn't support this, but if it ever does we are prepared. + * The current implementation of xattr on Solaris doesn't support this, + * but if it ever does we are prepared. * Encode the stat struct into an ASCII representation. */ encode_stat(attribs, &st, sizeof(st), 0, stream); cnt = bsnprintf(buffer, sizeof(buffer), "%s%c%s%c%s%c", - target_attrname, 0, attribs, 0, (acl_text) ? acl_text : "", 0); + target_attrname, 0, attribs, 0, + (acl_text) ? acl_text : "", 0); } break; case S_IFREG: @@ -2486,12 +2715,13 @@ static bxattr_exit_code solaris_save_xattr(JCR *jcr, int fd, const char *xattr_n cnt = bsnprintf(buffer, sizeof(buffer), "%s%c%s%c%s%c", target_attrname, 0, attribs, 0, xlce->target, 0); - pm_memcpy(jcr->xattr_data->content, buffer, cnt); - jcr->xattr_data->content_length = cnt; + pm_memcpy(jcr->xattr_data->u.build->content, buffer, cnt); + jcr->xattr_data->u.build->content_length = cnt; retval = send_xattr_stream(jcr, stream); /* - * For a hard linked file we are ready now, no need to recursively save the attributes. + * For a hard linked file we are ready now, no need to recursively + * save the attributes. */ goto bail_out; } @@ -2527,7 +2757,8 @@ static bxattr_exit_code solaris_save_xattr(JCR *jcr, int fd, const char *xattr_n retval = bxattr_exit_ok; goto bail_out; default: - Mmsg3(jcr->errmsg, _("Unable to open xattr %s on \"%s\": ERR=%s\n"), + Mmsg3(jcr->errmsg, + _("Unable to open xattr %s on \"%s\": ERR=%s\n"), target_attrname, jcr->last_fname, be.bstrerror()); Dmsg3(100, "openat of xattr %s on \"%s\" failed: ERR=%s\n", target_attrname, jcr->last_fname, be.bstrerror()); @@ -2537,7 +2768,8 @@ static bxattr_exit_code solaris_save_xattr(JCR *jcr, int fd, const char *xattr_n break; case S_IFLNK: /* - * The current implementation of xattr on Solaris doesn't support this, but if it ever does we are prepared. + * The current implementation of xattr on Solaris doesn't support this, but if it + * ever does we are prepared. * Encode the stat struct into an ASCII representation. */ if (readlink(attrname, link_source, sizeof(link_source)) < 0) { @@ -2546,7 +2778,8 @@ static bxattr_exit_code solaris_save_xattr(JCR *jcr, int fd, const char *xattr_n retval = bxattr_exit_ok; goto bail_out; default: - Mmsg3(jcr->errmsg, _("Unable to read symlin %s on \"%s\": ERR=%s\n"), + Mmsg3(jcr->errmsg, + _("Unable to read symlin %s on \"%s\": ERR=%s\n"), target_attrname, jcr->last_fname, be.bstrerror()); Dmsg3(100, "readlink of xattr %s on \"%s\" failed: ERR=%s\n", target_attrname, jcr->last_fname, be.bstrerror()); @@ -2561,12 +2794,12 @@ static bxattr_exit_code solaris_save_xattr(JCR *jcr, int fd, const char *xattr_n cnt = bsnprintf(buffer, sizeof(buffer), "%s%c%s%c%s%c", target_attrname, 0, attribs, 0, link_source, 0); - pm_memcpy(jcr->xattr_data->content, buffer, cnt); - jcr->xattr_data->content_length = cnt; + pm_memcpy(jcr->xattr_data->u.build->content, buffer, cnt); + jcr->xattr_data->u.build->content_length = cnt; retval = send_xattr_stream(jcr, stream); if (retval == bxattr_exit_ok) { - jcr->xattr_data->nr_saved++; + jcr->xattr_data->u.build->nr_saved++; } /* @@ -2580,18 +2813,19 @@ static bxattr_exit_code solaris_save_xattr(JCR *jcr, int fd, const char *xattr_n /* * See if this is the first real xattr being saved. * If it is save the toplevel_hidden_dir attributes first. - * This is easy as its stored already in the jcr->xattr_data->content buffer. + * This is easy as its stored already in the + * jcr->xattr_data->u.build->content buffer. */ - if (jcr->xattr_data->nr_saved == 0) { + if (jcr->xattr_data->u.build->nr_saved == 0) { retval = send_xattr_stream(jcr, STREAM_XATTR_SOLARIS); if (retval != bxattr_exit_ok) { goto bail_out; } - jcr->xattr_data->nr_saved++; + jcr->xattr_data->u.build->nr_saved++; } - pm_memcpy(jcr->xattr_data->content, buffer, cnt); - jcr->xattr_data->content_length = cnt; + pm_memcpy(jcr->xattr_data->u.build->content, buffer, cnt); + jcr->xattr_data->u.build->content_length = cnt; /* * Only dump the content of regular files. @@ -2603,19 +2837,24 @@ static bxattr_exit_code solaris_save_xattr(JCR *jcr, int fd, const char *xattr_n * Protect ourself against things getting out of hand. */ if (st.st_size >= MAX_XATTR_STREAM) { - Mmsg2(jcr->errmsg, _("Xattr stream on file \"%s\" exceeds maximum size of %d bytes\n"), + Mmsg2(jcr->errmsg, + _("Xattr stream on file \"%s\" exceeds maximum size of %d bytes\n"), jcr->last_fname, MAX_XATTR_STREAM); goto bail_out; } while ((cnt = read(attrfd, buffer, sizeof(buffer))) > 0) { - jcr->xattr_data->content = check_pool_memory_size(jcr->xattr_data->content, jcr->xattr_data->content_length + cnt); - memcpy(jcr->xattr_data->content + jcr->xattr_data->content_length, buffer, cnt); - jcr->xattr_data->content_length += cnt; + jcr->xattr_data->u.build->content = + check_pool_memory_size(jcr->xattr_data->u.build->content, + jcr->xattr_data->u.build->content_length + cnt); + memcpy(jcr->xattr_data->u.build->content + + jcr->xattr_data->u.build->content_length, buffer, cnt); + jcr->xattr_data->u.build->content_length += cnt; } if (cnt < 0) { - Mmsg2(jcr->errmsg, _("Unable to read content of xattr %s on file \"%s\"\n"), + Mmsg2(jcr->errmsg, + _("Unable to read content of xattr %s on file \"%s\"\n"), target_attrname, jcr->last_fname); Dmsg2(100, "read of data from xattr %s on \"%s\" failed\n", target_attrname, jcr->last_fname); @@ -2631,7 +2870,7 @@ static bxattr_exit_code solaris_save_xattr(JCR *jcr, int fd, const char *xattr_n if (retval) { retval = send_xattr_stream(jcr, stream); if (retval == bxattr_exit_ok) { - jcr->xattr_data->nr_saved++; + jcr->xattr_data->u.build->nr_saved++; } } @@ -2651,7 +2890,8 @@ static bxattr_exit_code solaris_save_xattr(JCR *jcr, int fd, const char *xattr_n retval = bxattr_exit_ok; goto bail_out; default: - Mmsg2(jcr->errmsg, _("Unable to chdir to xattr space of file \"%s\": ERR=%s\n"), + Mmsg2(jcr->errmsg, + _("Unable to chdir to xattr space of file \"%s\": ERR=%s\n"), jcr->last_fname, be.bstrerror()); Dmsg3(100, "Unable to fchdir to xattr space of file \"%s\" using fd %d: ERR=%s\n", jcr->last_fname, fd, be.bstrerror()); @@ -2707,7 +2947,8 @@ static bxattr_exit_code solaris_save_xattrs(JCR *jcr, const char *xattr_namespac retval = bxattr_exit_ok; goto bail_out; default: - Mmsg2(jcr->errmsg, _("Unable to open file \"%s\": ERR=%s\n"), + Mmsg2(jcr->errmsg, + _("Unable to open file \"%s\": ERR=%s\n"), jcr->last_fname, be.bstrerror()); Dmsg2(100, "Unable to open file \"%s\": ERR=%s\n", jcr->last_fname, be.bstrerror()); @@ -2732,7 +2973,8 @@ static bxattr_exit_code solaris_save_xattrs(JCR *jcr, const char *xattr_namespac retval = bxattr_exit_ok; goto bail_out; default: - Mmsg3(jcr->errmsg, _("Unable to open xattr space %s on file \"%s\": ERR=%s\n"), + Mmsg3(jcr->errmsg, + _("Unable to open xattr space %s on file \"%s\": ERR=%s\n"), name, jcr->last_fname, be.bstrerror()); Dmsg3(100, "Unable to open xattr space %s on file \"%s\": ERR=%s\n", name, jcr->last_fname, be.bstrerror()); @@ -2745,7 +2987,8 @@ static bxattr_exit_code solaris_save_xattrs(JCR *jcr, const char *xattr_namespac * attributes should be saved. */ if (fchdir(attrdirfd) < 0) { - Mmsg2(jcr->errmsg, _("Unable to chdir to xattr space on file \"%s\": ERR=%s\n"), + Mmsg2(jcr->errmsg, + _("Unable to chdir to xattr space on file \"%s\": ERR=%s\n"), jcr->last_fname, be.bstrerror()); Dmsg3(100, "Unable to fchdir to xattr space on file \"%s\" using fd %d: ERR=%s\n", jcr->last_fname, attrdirfd, be.bstrerror()); @@ -2763,7 +3006,8 @@ static bxattr_exit_code solaris_save_xattrs(JCR *jcr, const char *xattr_namespac if ((fd = dup(attrdirfd)) == -1 || (dirp = fdopendir(fd)) == (DIR *)NULL) { - Mmsg2(jcr->errmsg, _("Unable to list the xattr space on file \"%s\": ERR=%s\n"), + Mmsg2(jcr->errmsg, + _("Unable to list the xattr space on file \"%s\": ERR=%s\n"), jcr->last_fname, be.bstrerror()); Dmsg3(100, "Unable to fdopendir xattr space on file \"%s\" using fd %d: ERR=%s\n", jcr->last_fname, fd, be.bstrerror()); @@ -2844,7 +3088,10 @@ bail_out: } #ifdef HAVE_ACL -static bxattr_exit_code solaris_restore_xattr_acl(JCR *jcr, int fd, const char *attrname, char *acl_text) +static bxattr_exit_code solaris_restore_xattr_acl(JCR *jcr, + int fd, + const char *attrname, + char *acl_text) { #ifdef HAVE_EXTENDED_ACL int error; @@ -2852,14 +3099,16 @@ static bxattr_exit_code solaris_restore_xattr_acl(JCR *jcr, int fd, const char * berrno be; if ((error = acl_fromtext(acl_text, &aclp)) != 0) { - Mmsg1(jcr->errmsg, _("Unable to convert acl from text on file \"%s\"\n"), + Mmsg1(jcr->errmsg, + _("Unable to convert acl from text on file \"%s\"\n"), jcr->last_fname); return bxattr_exit_error; } if ((fd != -1 && facl_set(fd, aclp) != 0) || acl_set(attrname, aclp) != 0) { - Mmsg3(jcr->errmsg, _("Unable to restore acl of xattr %s on file \"%s\": ERR=%s\n"), + Mmsg3(jcr->errmsg, + _("Unable to restore acl of xattr %s on file \"%s\": ERR=%s\n"), attrname, jcr->last_fname, be.bstrerror()); Dmsg3(100, "Unable to restore acl of xattr %s on file \"%s\": ERR=%s\n", attrname, jcr->last_fname, be.bstrerror()); @@ -2880,7 +3129,8 @@ static bxattr_exit_code solaris_restore_xattr_acl(JCR *jcr, int fd, const char * if (!acls) { if ((fd != -1 && facl(fd, SETACL, n, acls) != 0) || acl(attrname, SETACL, n, acls) != 0) { - Mmsg3(jcr->errmsg, _("Unable to restore acl of xattr %s on file \"%s\": ERR=%s\n"), + Mmsg3(jcr->errmsg, + _("Unable to restore acl of xattr %s on file \"%s\": ERR=%s\n"), attrname, jcr->last_fname, be.bstrerror()); Dmsg3(100, "Unable to restore acl of xattr %s on file \"%s\": ERR=%s\n", attrname, jcr->last_fname, be.bstrerror()); @@ -2898,10 +3148,14 @@ static bxattr_exit_code solaris_restore_xattr_acl(JCR *jcr, int fd, const char * } #endif /* HAVE_ACL */ -static bxattr_exit_code solaris_restore_xattrs(JCR *jcr, bool is_extensible) +static bxattr_exit_code solaris_restore_xattrs(JCR *jcr, + bool is_extensible, + char *content, + uint32_t content_length) + { int fd, filefd = -1, attrdirfd = -1, attrfd = -1; - int used_bytes, total_bytes, cnt; + int used_bytes, cnt; char *bp, *target_attrname, *attribs; char *linked_target = NULL; char *acl_text = NULL; @@ -2916,16 +3170,15 @@ static bxattr_exit_code solaris_restore_xattrs(JCR *jcr, bool is_extensible) * Parse the xattr stream. First the part that is the same for all xattrs. */ used_bytes = 0; - total_bytes = jcr->xattr_data->content_length; /* * The name of the target xattr has a leading / we are not interested * in that so skip it when decoding the string. We always start a the / * of the xattr space anyway. */ - target_attrname = jcr->xattr_data->content + 1; + target_attrname = content + 1; if ((bp = strchr(target_attrname, '\0')) == (char *)NULL || - (used_bytes = (bp - jcr->xattr_data->content)) >= (total_bytes - 1)) { + (used_bytes = (bp - content)) >= (int32_t)(content_length - 1)) { goto parse_error; } attribs = ++bp; @@ -2934,7 +3187,8 @@ static bxattr_exit_code solaris_restore_xattrs(JCR *jcr, bool is_extensible) * Open the file on which to restore the xattrs read-only. */ if ((filefd = open(jcr->last_fname, O_RDONLY | O_NONBLOCK)) < 0) { - Mmsg2(jcr->errmsg, _("Unable to open file \"%s\": ERR=%s\n"), + Mmsg2(jcr->errmsg, + _("Unable to open file \"%s\": ERR=%s\n"), jcr->last_fname, be.bstrerror()); Dmsg2(100, "Unable to open file \"%s\": ERR=%s\n", jcr->last_fname, be.bstrerror()); @@ -2945,7 +3199,8 @@ static bxattr_exit_code solaris_restore_xattrs(JCR *jcr, bool is_extensible) * Open the xattr naming space and make it the current working dir. */ if ((attrdirfd = openat(filefd, ".", O_RDONLY | O_XATTR)) < 0) { - Mmsg2(jcr->errmsg, _("Unable to open xattr space on file \"%s\": ERR=%s\n"), + Mmsg2(jcr->errmsg, + _("Unable to open xattr space on file \"%s\": ERR=%s\n"), jcr->last_fname, be.bstrerror()); Dmsg2(100, "Unable to open xattr space on file \"%s\": ERR=%s\n", jcr->last_fname, be.bstrerror()); @@ -2953,7 +3208,8 @@ static bxattr_exit_code solaris_restore_xattrs(JCR *jcr, bool is_extensible) } if (fchdir(attrdirfd) < 0) { - Mmsg2(jcr->errmsg, _("Unable to chdir to xattr space on file \"%s\": ERR=%s\n"), + Mmsg2(jcr->errmsg, + _("Unable to chdir to xattr space on file \"%s\": ERR=%s\n"), jcr->last_fname, be.bstrerror()); Dmsg3(100, "Unable to fchdir to xattr space on file \"%s\" using fd %d: ERR=%s\n", jcr->last_fname, attrdirfd, be.bstrerror()); @@ -2969,7 +3225,8 @@ static bxattr_exit_code solaris_restore_xattrs(JCR *jcr, bool is_extensible) *bp = '\0'; if ((fd = open(target_attrname, O_RDONLY | O_NONBLOCK)) < 0) { - Mmsg3(jcr->errmsg, _("Unable to open xattr %s on file \"%s\": ERR=%s\n"), + Mmsg3(jcr->errmsg, + _("Unable to open xattr %s on file \"%s\": ERR=%s\n"), target_attrname, jcr->last_fname, be.bstrerror()); Dmsg3(100, "Unable to open xattr %s on file \"%s\": ERR=%s\n", target_attrname, jcr->last_fname, be.bstrerror()); @@ -2983,7 +3240,8 @@ static bxattr_exit_code solaris_restore_xattrs(JCR *jcr, bool is_extensible) * Open the xattr naming space. */ if ((fd = openat(filefd, ".", O_RDONLY | O_XATTR)) < 0) { - Mmsg3(jcr->errmsg, _("Unable to open xattr space %s on file \"%s\": ERR=%s\n"), + Mmsg3(jcr->errmsg, + _("Unable to open xattr space %s on file \"%s\": ERR=%s\n"), target_attrname, jcr->last_fname, be.bstrerror()); Dmsg3(100, "Unable to open xattr space %s on file \"%s\": ERR=%s\n", target_attrname, jcr->last_fname, be.bstrerror()); @@ -2997,7 +3255,8 @@ static bxattr_exit_code solaris_restore_xattrs(JCR *jcr, bool is_extensible) * Make the xattr space our current workingdir. */ if (fchdir(attrdirfd) < 0) { - Mmsg3(jcr->errmsg, _("Unable to chdir to xattr space %s on file \"%s\": ERR=%s\n"), + Mmsg3(jcr->errmsg, + _("Unable to chdir to xattr space %s on file \"%s\": ERR=%s\n"), target_attrname, jcr->last_fname, be.bstrerror()); Dmsg4(100, "Unable to fchdir to xattr space %s on file \"%s\" using fd %d: ERR=%s\n", target_attrname, jcr->last_fname, attrdirfd, be.bstrerror()); @@ -3016,7 +3275,7 @@ static bxattr_exit_code solaris_restore_xattrs(JCR *jcr, bool is_extensible) * Decode the next field (acl_text). */ if ((bp = strchr(attribs, '\0')) == (char *)NULL || - (used_bytes = (bp - jcr->xattr_data->content)) >= (total_bytes - 1)) { + (used_bytes = (bp - content)) >= (int32_t)(content_length - 1)) { goto parse_error; } acl_text = ++bp; @@ -3029,11 +3288,13 @@ static bxattr_exit_code solaris_restore_xattrs(JCR *jcr, bool is_extensible) switch (st.st_mode & S_IFMT) { case S_IFIFO: /* - * The current implementation of xattr on Solaris doesn't support this, but if it ever does we are prepared. + * The current implementation of xattr on Solaris doesn't support this, + * but if it ever does we are prepared. */ unlinkat(attrdirfd, target_attrname, 0); if (mkfifo(target_attrname, st.st_mode) < 0) { - Mmsg3(jcr->errmsg, _("Unable to mkfifo xattr %s on file \"%s\": ERR=%s\n"), + Mmsg3(jcr->errmsg, + _("Unable to mkfifo xattr %s on file \"%s\": ERR=%s\n"), target_attrname, jcr->last_fname, be.bstrerror()); Dmsg3(100, "Unable to mkfifo xattr %s on file \"%s\": ERR=%s\n", target_attrname, jcr->last_fname, be.bstrerror()); @@ -3043,11 +3304,13 @@ static bxattr_exit_code solaris_restore_xattrs(JCR *jcr, bool is_extensible) case S_IFCHR: case S_IFBLK: /* - * The current implementation of xattr on Solaris doesn't support this, but if it ever does we are prepared. + * The current implementation of xattr on Solaris doesn't support this, + * but if it ever does we are prepared. */ unlinkat(attrdirfd, target_attrname, 0); if (mknod(target_attrname, st.st_mode, st.st_rdev) < 0) { - Mmsg3(jcr->errmsg, _("Unable to mknod xattr %s on file \"%s\": ERR=%s\n"), + Mmsg3(jcr->errmsg, + _("Unable to mknod xattr %s on file \"%s\": ERR=%s\n"), target_attrname, jcr->last_fname, be.bstrerror()); Dmsg3(100, "Unable to mknod xattr %s on file \"%s\": ERR=%s\n", target_attrname, jcr->last_fname, be.bstrerror()); @@ -3057,7 +3320,8 @@ static bxattr_exit_code solaris_restore_xattrs(JCR *jcr, bool is_extensible) case S_IFDIR: /* * If its not the hidden_dir create the entry. - * The current implementation of xattr on Solaris doesn't support this, but if it ever does we are prepared. + * The current implementation of xattr on Solaris doesn't support this, + * but if it ever does we are prepared. */ if (!bstrcmp(target_attrname, ".")) { unlinkat(attrdirfd, target_attrname, AT_REMOVEDIR); @@ -3079,7 +3343,8 @@ static bxattr_exit_code solaris_restore_xattrs(JCR *jcr, bool is_extensible) unlinkat(attrdirfd, target_attrname, 0); if (link(linked_target, target_attrname) < 0) { - Mmsg4(jcr->errmsg, _("Unable to link xattr %s to %s on file \"%s\": ERR=%s\n"), + Mmsg4(jcr->errmsg, + _("Unable to link xattr %s to %s on file \"%s\": ERR=%s\n"), target_attrname, linked_target, jcr->last_fname, be.bstrerror()); Dmsg4(100, "Unable to link xattr %s to %s on file \"%s\": ERR=%s\n", target_attrname, linked_target, jcr->last_fname, be.bstrerror()); @@ -3093,11 +3358,11 @@ static bxattr_exit_code solaris_restore_xattrs(JCR *jcr, bool is_extensible) goto bail_out; } else { if ((bp = strchr(acl_text, '\0')) == (char *)NULL || - (used_bytes = (bp - jcr->xattr_data->content)) >= total_bytes) { + (used_bytes = (bp - content)) >= (int32_t)content_length) { goto parse_error; } - if (used_bytes < (total_bytes - 1)) + if (used_bytes < (int32_t)(content_length - 1)) data = ++bp; /* @@ -3108,7 +3373,8 @@ static bxattr_exit_code solaris_restore_xattrs(JCR *jcr, bool is_extensible) } if ((attrfd = openat(attrdirfd, target_attrname, O_RDWR | O_CREAT | O_TRUNC, st.st_mode)) < 0) { - Mmsg3(jcr->errmsg, _("Unable to open xattr %s on file \"%s\": ERR=%s\n"), + Mmsg3(jcr->errmsg, + _("Unable to open xattr %s on file \"%s\": ERR=%s\n"), target_attrname, jcr->last_fname, be.bstrerror()); Dmsg3(100, "Unable to open xattr %s on file \"%s\": ERR=%s\n", target_attrname, jcr->last_fname, be.bstrerror()); @@ -3120,15 +3386,16 @@ static bxattr_exit_code solaris_restore_xattrs(JCR *jcr, bool is_extensible) * Restore the actual data. */ if (st.st_size > 0) { - used_bytes = (data - jcr->xattr_data->content); - cnt = total_bytes - used_bytes; + used_bytes = (data - content); + cnt = content_length - used_bytes; /* * Do a sanity check, the st.st_size should be the same as the number of bytes * we have available as data of the stream. */ if (cnt != st.st_size) { - Mmsg2(jcr->errmsg, _("Unable to restore data of xattr %s on file \"%s\": Not all data available in xattr stream\n"), + Mmsg2(jcr->errmsg, + _("Unable to restore data of xattr %s on file \"%s\": Not all data available in xattr stream\n"), target_attrname, jcr->last_fname); Dmsg2(100, "Unable to restore data of xattr %s on file \"%s\": Not all data available in xattr stream\n", target_attrname, jcr->last_fname); @@ -3138,7 +3405,8 @@ static bxattr_exit_code solaris_restore_xattrs(JCR *jcr, bool is_extensible) while (cnt > 0) { cnt = write(attrfd, data, cnt); if (cnt < 0) { - Mmsg3(jcr->errmsg, _("Unable to restore data of xattr %s on file \"%s\": ERR=%s\n"), + Mmsg3(jcr->errmsg, + _("Unable to restore data of xattr %s on file \"%s\": ERR=%s\n"), target_attrname, jcr->last_fname, be.bstrerror()); Dmsg3(100, "Unable to restore data of xattr %s on file \"%s\": ERR=%s\n", target_attrname, jcr->last_fname, be.bstrerror()); @@ -3147,7 +3415,7 @@ static bxattr_exit_code solaris_restore_xattrs(JCR *jcr, bool is_extensible) used_bytes += cnt; data += cnt; - cnt = total_bytes - used_bytes; + cnt = content_length - used_bytes; } } break; @@ -3158,7 +3426,8 @@ static bxattr_exit_code solaris_restore_xattrs(JCR *jcr, bool is_extensible) linked_target = bp; if (symlink(linked_target, target_attrname) < 0) { - Mmsg4(jcr->errmsg, _("Unable to symlink xattr %s to %s on file \"%s\": ERR=%s\n"), + Mmsg4(jcr->errmsg, + _("Unable to symlink xattr %s to %s on file \"%s\": ERR=%s\n"), target_attrname, linked_target, jcr->last_fname, be.bstrerror()); Dmsg4(100, "Unable to symlink xattr %s to %s on file \"%s\": ERR=%s\n", target_attrname, linked_target, jcr->last_fname, be.bstrerror()); @@ -3191,7 +3460,8 @@ static bxattr_exit_code solaris_restore_xattrs(JCR *jcr, bool is_extensible) retval = bxattr_exit_ok; break; default: - Mmsg3(jcr->errmsg, _("Unable to restore owner of xattr %s on file \"%s\": ERR=%s\n"), + Mmsg3(jcr->errmsg, + _("Unable to restore owner of xattr %s on file \"%s\": ERR=%s\n"), target_attrname, jcr->last_fname, be.bstrerror()); Dmsg3(100, "Unable to restore owner of xattr %s on file \"%s\": ERR=%s\n", target_attrname, jcr->last_fname, be.bstrerror()); @@ -3216,7 +3486,8 @@ static bxattr_exit_code solaris_restore_xattrs(JCR *jcr, bool is_extensible) times[1].tv_usec = 0; if (futimesat(attrdirfd, target_attrname, times) < 0) { - Mmsg3(jcr->errmsg, _("Unable to restore filetimes of xattr %s on file \"%s\": ERR=%s\n"), + Mmsg3(jcr->errmsg, + _("Unable to restore filetimes of xattr %s on file \"%s\": ERR=%s\n"), target_attrname, jcr->last_fname, be.bstrerror()); Dmsg3(100, "Unable to restore filetimes of xattr %s on file \"%s\": ERR=%s\n", target_attrname, jcr->last_fname, be.bstrerror()); @@ -3231,7 +3502,8 @@ static bxattr_exit_code solaris_restore_xattrs(JCR *jcr, bool is_extensible) goto bail_out; parse_error: - Mmsg1(jcr->errmsg, _("Illegal xattr stream, failed to parse xattr stream on file \"%s\"\n"), + Mmsg1(jcr->errmsg, + _("Illegal xattr stream, failed to parse xattr stream on file \"%s\"\n"), jcr->last_fname); Dmsg1(100, "Illegal xattr stream, failed to parse xattr stream on file \"%s\"\n", jcr->last_fname); @@ -3259,8 +3531,7 @@ static bxattr_exit_code solaris_build_xattr_streams(JCR *jcr, FF_PKT *ff_pkt) * If not just pretend things went ok. */ if (pathconf(jcr->last_fname, _PC_XATTR_EXISTS) > 0) { - jcr->xattr_data->nr_saved = 0; - jcr->xattr_data->link_cache = New(alist(10, not_owned_by_alist)); + jcr->xattr_data->u.build->nr_saved = 0; /* * As we change the cwd in the save function save the current cwd @@ -3269,13 +3540,18 @@ static bxattr_exit_code solaris_build_xattr_streams(JCR *jcr, FF_PKT *ff_pkt) getcwd(cwd, sizeof(cwd)); retval = solaris_save_xattrs(jcr, NULL, NULL); chdir(cwd); - delete jcr->xattr_data->link_cache; - jcr->xattr_data->link_cache = NULL; + if (jcr->xattr_data->u.build->link_cache) { + delete jcr->xattr_data->u.build->link_cache; + jcr->xattr_data->u.build->link_cache = NULL; + } } return retval; } -static bxattr_exit_code solaris_parse_xattr_streams(JCR *jcr, int stream) +static bxattr_exit_code solaris_parse_xattr_streams(JCR *jcr, + int stream, + char *content, + uint32_t content_length) { char cwd[PATH_MAX]; bool is_extensible = false; @@ -3288,7 +3564,9 @@ static bxattr_exit_code solaris_parse_xattr_streams(JCR *jcr, int stream) #if defined(HAVE_SYS_NVPAIR_H) && defined(_PC_SATTR_ENABLED) case STREAM_XATTR_SOLARIS_SYS: if (pathconf(jcr->last_fname, _PC_SATTR_ENABLED) <= 0) { - Mmsg1(jcr->errmsg, _("Failed to restore extensible attributes on file \"%s\"\n"), jcr->last_fname); + Mmsg1(jcr->errmsg, + _("Failed to restore extensible attributes on file \"%s\"\n"), + jcr->last_fname); Dmsg1(100, "Unable to restore extensible attributes on file \"%s\", filesystem doesn't support this\n", jcr->last_fname); return bxattr_exit_error; @@ -3299,7 +3577,9 @@ static bxattr_exit_code solaris_parse_xattr_streams(JCR *jcr, int stream) #endif case STREAM_XATTR_SOLARIS: if (pathconf(jcr->last_fname, _PC_XATTR_ENABLED) <= 0) { - Mmsg1(jcr->errmsg, _("Failed to restore extended attributes on file \"%s\"\n"), jcr->last_fname); + Mmsg1(jcr->errmsg, + _("Failed to restore extended attributes on file \"%s\"\n"), + jcr->last_fname); Dmsg1(100, "Unable to restore extended attributes on file \"%s\", filesystem doesn't support this\n", jcr->last_fname); return bxattr_exit_error; @@ -3314,7 +3594,7 @@ static bxattr_exit_code solaris_parse_xattr_streams(JCR *jcr, int stream) * for restore after return from the solaris_restore_xattrs function. */ getcwd(cwd, sizeof(cwd)); - retval = solaris_restore_xattrs(jcr, is_extensible); + retval = solaris_restore_xattrs(jcr, is_extensible, content, content_length); chdir(cwd); return retval; } @@ -3323,8 +3603,12 @@ static bxattr_exit_code solaris_parse_xattr_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) = solaris_build_xattr_streams; -static bxattr_exit_code (*os_parse_xattr_streams)(JCR *jcr, int stream) = solaris_parse_xattr_streams; +static bxattr_exit_code (*os_build_xattr_streams) + (JCR *jcr, FF_PKT *ff_pkt) = + solaris_build_xattr_streams; +static bxattr_exit_code (*os_parse_xattr_streams) + (JCR *jcr, int stream, char *content, uint32_t content_length) = + solaris_parse_xattr_streams; #endif /* defined(HAVE_SUN_OS) */ @@ -3359,7 +3643,10 @@ bxattr_exit_code build_xattr_streams(JCR *jcr, FF_PKT *ff_pkt) } } -bxattr_exit_code parse_xattr_streams(JCR *jcr, int stream) +bxattr_exit_code parse_xattr_streams(JCR *jcr, + int stream, + char *content, + uint32_t content_length) { int ret; berrno be; @@ -3379,7 +3666,8 @@ bxattr_exit_code parse_xattr_streams(JCR *jcr, int stream) case ENOENT: return bxattr_exit_ok; default: - Mmsg2(jcr->errmsg, _("Unable to stat file \"%s\": ERR=%s\n"), + Mmsg2(jcr->errmsg, + _("Unable to stat file \"%s\": ERR=%s\n"), jcr->last_fname, be.bstrerror()); Dmsg2(100, "Unable to stat file \"%s\": ERR=%s\n", jcr->last_fname, be.bstrerror()); @@ -3411,14 +3699,14 @@ bxattr_exit_code parse_xattr_streams(JCR *jcr, int stream) */ for (cnt = 0; cnt < sizeof(os_default_xattr_streams) / sizeof(int); cnt++) { if (os_default_xattr_streams[cnt] == stream) { - return os_parse_xattr_streams(jcr, stream); + return os_parse_xattr_streams(jcr, stream, content, content_length); } } } else { /* * Increment error count but don't log an error again for the same filesystem. */ - jcr->xattr_data->nr_errors++; + jcr->xattr_data->u.parse->nr_errors++; return bxattr_exit_ok; } diff --git a/bacula/src/filed/xattr.h b/bacula/src/filed/xattr.h index e84c87b994..d54b9124fe 100644 --- a/bacula/src/filed/xattr.h +++ b/bacula/src/filed/xattr.h @@ -63,17 +63,28 @@ struct xattr_link_cache_entry_t { #define BXATTR_FLAG_SAVE_NATIVE 0x01 #define BXATTR_FLAG_RESTORE_NATIVE 0x02 +struct xattr_build_data_t { + uint32_t nr_errors; + uint32_t nr_saved; + POOLMEM *content; + uint32_t content_length; + alist *link_cache; +}; + +struct xattr_parse_data_t { + uint32_t nr_errors; +}; + /* * Internal tracking data. */ struct xattr_data_t { - POOLMEM *content; - uint32_t content_length; - uint32_t nr_errors; - uint32_t nr_saved; - alist *link_cache; - uint32_t current_dev; uint32_t flags; /* See BXATTR_FLAG_* */ + uint32_t current_dev; + union { + struct xattr_build_data_t *build; + struct xattr_parse_data_t *parse; + } u; }; /* -- 2.39.5