From ef3609cb50edab26c5f2570cd76104966bb4948e Mon Sep 17 00:00:00 2001 From: Marco van Wieringen Date: Fri, 14 Aug 2009 14:43:38 +0200 Subject: [PATCH] Add all acl and xattr related variables which are either global or already part of the JCR into a simple structure and reference that from the JCR structure. --- bacula/src/filed/acl.c | 134 ++++++++++++++++++------------------- bacula/src/filed/acl.h | 9 +++ bacula/src/filed/backup.c | 33 +++++---- bacula/src/filed/filed.h | 2 + bacula/src/filed/restore.c | 40 ++++++----- bacula/src/filed/xattr.c | 111 ++++++++++++++++-------------- bacula/src/filed/xattr.h | 20 ++---- bacula/src/jcr.h | 11 ++- 8 files changed, 192 insertions(+), 168 deletions(-) diff --git a/bacula/src/filed/acl.c b/bacula/src/filed/acl.c index ca8313a2e3..b6f83f5b72 100644 --- a/bacula/src/filed/acl.c +++ b/bacula/src/filed/acl.c @@ -53,7 +53,6 @@ #include "bacula.h" #include "filed.h" -#include "acl.h" #if !defined(HAVE_ACL) /* @@ -83,8 +82,9 @@ static bacl_exit_code send_acl_stream(JCR *jcr, int stream) /* * Sanity check */ - if (jcr->acl_data_len <= 0) + if (jcr->acl_data->content_length <= 0) { return bacl_exit_ok; + } /* * Send header @@ -98,10 +98,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); + Dmsg1(400, "Backing up ACL <%s>\n", jcr->acl_data->content); msgsave = sd->msg; - sd->msg = jcr->acl_data; - sd->msglen = jcr->acl_data_len + 1; + sd->msg = jcr->acl_data->content; + sd->msglen = jcr->acl_data->content_length + 1; if (!sd->send()) { sd->msg = msgsave; sd->msglen = 0; @@ -137,7 +137,7 @@ 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_len = pm_strcpy(jcr->acl_data, acl_text); + jcr->acl_data->content_length = pm_strcpy(jcr->acl_data->content, acl_text); actuallyfree(acl_text); return send_acl_stream(jcr, STREAM_ACL_AIX_TEXT); } @@ -146,7 +146,7 @@ static bacl_exit_code aix_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt) static bacl_exit_code aix_parse_acl_streams(JCR *jcr, int stream) { - if (acl_put(jcr->last_fname, jcr->acl_data, 0) != 0) { + if (acl_put(jcr->last_fname, jcr->acl_data->content, 0) != 0) { return bacl_exit_error; } return bacl_exit_ok; @@ -343,8 +343,8 @@ static bacl_exit_code generic_get_acl_from_os(JCR *jcr, bacl_type acltype) * to acl_to_text() besides. */ if (acl->acl_cnt <= 0) { - pm_strcpy(jcr->acl_data, ""); - jcr->acl_data_len = 0; + pm_strcpy(jcr->acl_data->content, ""); + jcr->acl_data->content_length = 0; acl_free(acl); return bacl_exit_ok; } @@ -359,15 +359,15 @@ static bacl_exit_code generic_get_acl_from_os(JCR *jcr, bacl_type acltype) * 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, ""); - jcr->acl_data_len = 0; + pm_strcpy(jcr->acl_data->content, ""); + jcr->acl_data->content_length = 0; acl_free(acl); return bacl_exit_ok; } #endif if ((acl_text = acl_to_text(acl, NULL)) != NULL) { - jcr->acl_data_len = pm_strcpy(jcr->acl_data, acl_text); + jcr->acl_data->content_length = pm_strcpy(jcr->acl_data->content, acl_text); acl_free(acl); acl_free(acl_text); return bacl_exit_ok; @@ -378,8 +378,8 @@ static bacl_exit_code generic_get_acl_from_os(JCR *jcr, bacl_type acltype) Dmsg2(100, "acl_to_text error file=%s ERR=%s\n", jcr->last_fname, be.bstrerror()); - pm_strcpy(jcr->acl_data, ""); - jcr->acl_data_len = 0; + pm_strcpy(jcr->acl_data->content, ""); + jcr->acl_data->content_length = 0; acl_free(acl); return bacl_exit_error; } @@ -394,8 +394,8 @@ static bacl_exit_code generic_get_acl_from_os(JCR *jcr, bacl_type acltype) break; /* not supported */ #endif case ENOENT: - pm_strcpy(jcr->acl_data, ""); - jcr->acl_data_len = 0; + pm_strcpy(jcr->acl_data->content, ""); + jcr->acl_data->content_length = 0; return bacl_exit_ok; default: /* Some real error */ @@ -404,16 +404,16 @@ static bacl_exit_code generic_get_acl_from_os(JCR *jcr, bacl_type acltype) Dmsg2(100, "acl_get_file error file=%s ERR=%s\n", jcr->last_fname, be.bstrerror()); - pm_strcpy(jcr->acl_data, ""); - jcr->acl_data_len = 0; + pm_strcpy(jcr->acl_data->content, ""); + jcr->acl_data->content_length = 0; return bacl_exit_error; } } /* * Not supported, just pretend there is nothing to see */ - pm_strcpy(jcr->acl_data, ""); - jcr->acl_data_len = 0; + pm_strcpy(jcr->acl_data->content, ""); + jcr->acl_data->content_length = 0; return bacl_exit_ok; } @@ -430,7 +430,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) == 0) { + if (ostype == ACL_TYPE_DEFAULT && strlen(jcr->acl_data->content) == 0) { if (acl_delete_def_file(jcr->last_fname) == 0) { return bacl_exit_ok; } @@ -444,12 +444,12 @@ static bacl_exit_code generic_set_acl_on_os(JCR *jcr, bacl_type acltype) } } - acl = acl_from_text(jcr->acl_data); + acl = acl_from_text(jcr->acl_data->content); if (acl == NULL) { 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, jcr->last_fname, be.bstrerror()); + jcr->acl_data->content, jcr->last_fname, be.bstrerror()); return bacl_exit_error; } @@ -462,7 +462,7 @@ static bacl_exit_code generic_set_acl_on_os(JCR *jcr, bacl_type acltype) 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, jcr->last_fname, be.bstrerror()); + jcr->acl_data->content, jcr->last_fname, be.bstrerror()); acl_free(acl); return bacl_exit_error; } @@ -483,7 +483,7 @@ static bacl_exit_code generic_set_acl_on_os(JCR *jcr, bacl_type acltype) 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, jcr->last_fname, be.bstrerror()); + jcr->acl_data->content, jcr->last_fname, be.bstrerror()); acl_free(acl); return bacl_exit_error; } @@ -524,7 +524,7 @@ static bacl_exit_code darwin_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt) return bacl_exit_fatal; #endif - if (jcr->acl_data_len > 0) { + if (jcr->acl_data->content_length > 0) { return send_acl_stream(jcr, STREAM_ACL_DARWIN_ACCESS_ACL); } return bacl_exit_ok; @@ -571,7 +571,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_len > 0) { + if (jcr->acl_data->content_length > 0) { if (send_acl_stream(jcr, os_access_acl_streams[0]) == bacl_exit_fatal) return bacl_exit_fatal; } @@ -582,7 +582,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_len > 0) { + if (jcr->acl_data->content_length > 0) { if (send_acl_stream(jcr, os_default_acl_streams[0]) == bacl_exit_fatal) return bacl_exit_fatal; } @@ -637,9 +637,9 @@ 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_len = generic_get_acl_from_os(jcr, BACL_TYPE_ACCESS)) < 0) + if ((jcr->acl_data->content_length = generic_get_acl_from_os(jcr, BACL_TYPE_ACCESS)) < 0) return bacl_exit_error; - if (jcr->acl_data_len > 0) { + if (jcr->acl_data->content_length > 0) { if (!send_acl_stream(jcr, STREAM_ACL_TRU64_ACCESS_ACL)) return bacl_exit_error; } @@ -647,9 +647,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_len = generic_get_acl_from_os(jcr, BACL_TYPE_DEFAULT)) < 0) + if ((jcr->acl_data->content_length = generic_get_acl_from_os(jcr, BACL_TYPE_DEFAULT)) < 0) return bacl_exit_error; - if (jcr->acl_data_len > 0) { + if (jcr->acl_data->content_length > 0) { if (!send_acl_stream(jcr, STREAM_ACL_TRU64_DEFAULT_ACL)) return bacl_exit_error; } @@ -659,9 +659,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_len = generic_get_acl_from_os(jcr, BACL_TYPE_DEFAULT_DIR)) < 0) + if ((jcr->acl_data->content_length = generic_get_acl_from_os(jcr, BACL_TYPE_DEFAULT_DIR)) < 0) return bacl_exit_error; - if (jcr->acl_data_len > 0) { + if (jcr->acl_data->content_length > 0) { if (!send_acl_stream(jcr, STREAM_ACL_TRU64_DEFAULT_DIR_ACL)) return bacl_exit_error; } @@ -744,13 +744,13 @@ static bacl_exit_code hpux_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt) /* * Not supported, just pretend there is nothing to see */ - pm_strcpy(jcr->acl_data, ""); - jcr->acl_data_len = 0; + pm_strcpy(jcr->acl_data->content, ""); + jcr->acl_data->content_length = 0; return bacl_exit_ok; #endif case ENOENT: - pm_strcpy(jcr->acl_data, ""); - jcr->acl_data_len = 0; + pm_strcpy(jcr->acl_data->content, ""); + jcr->acl_data->content_length = 0; return bacl_exit_ok; default: Mmsg2(jcr->errmsg, _("getacl error on file \"%s\": ERR=%s\n"), @@ -758,14 +758,14 @@ static bacl_exit_code hpux_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt) Dmsg2(100, "getacl error file=%s ERR=%s\n", jcr->last_fname, be.bstrerror()); - pm_strcpy(jcr->acl_data, ""); - jcr->acl_data_len = 0; + pm_strcpy(jcr->acl_data->content, ""); + jcr->acl_data->content_length = 0; return bacl_exit_error; } } if (n == 0) { - pm_strcpy(jcr->acl_data, ""); - jcr->acl_data_len = 0; + pm_strcpy(jcr->acl_data->content, ""); + jcr->acl_data->content_length = 0; return bacl_exit_ok; } if ((n = getacl(jcr->last_fname, n, acls)) > 0) { @@ -774,12 +774,12 @@ 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, ""); - jcr->acl_data_len = 0; + pm_strcpy(jcr->acl_data->content, ""); + jcr->acl_data->content_length = 0; return bacl_exit_ok; } if ((acl_text = acltostr(n, acls, FORM_SHORT)) != NULL) { - jcr->acl_data_len = pm_strcpy(jcr->acl_data, acl_text); + jcr->acl_data->content_length = pm_strcpy(jcr->acl_data->content, acl_text); actuallyfree(acl_text); return send_acl_stream(jcr, STREAM_ACL_HPUX_ACL_ENTRY); @@ -787,7 +787,7 @@ static bacl_exit_code hpux_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt) 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, jcr->last_fname, be.bstrerror()); + jcr->acl_data->content, jcr->last_fname, be.bstrerror()); return bacl_exit_error; } return bacl_exit_error; @@ -799,19 +799,19 @@ static bacl_exit_code hpux_parse_acl_streams(JCR *jcr, int stream) struct acl_entry acls[NACLENTRIES]; berrno be; - n = strtoacl(jcr->acl_data, 0, NACLENTRIES, acls, ACL_FILEOWNER, ACL_FILEGROUP); + n = strtoacl(jcr->acl_data->content, 0, NACLENTRIES, acls, ACL_FILEOWNER, ACL_FILEGROUP); if (n <= 0) { 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, jcr->last_fname, be.bstrerror()); + jcr->acl_data->content, jcr->last_fname, be.bstrerror()); return bacl_exit_error; } - if (strtoacl(jcr->acl_data, n, NACLENTRIES, acls, ACL_FILEOWNER, ACL_FILEGROUP) != n) { + 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"), jcr->last_fname, be.bstrerror()); Dmsg3(100, "strtoacl error acl=%s file=%s ERR=%s\n", - jcr->acl_data, jcr->last_fname, be.bstrerror()); + jcr->acl_data->content, jcr->last_fname, be.bstrerror()); return bacl_exit_error; } @@ -829,7 +829,7 @@ static bacl_exit_code hpux_parse_acl_streams(JCR *jcr, int stream) 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, jcr->last_fname, be.bstrerror()); + jcr->acl_data->content, jcr->last_fname, be.bstrerror()); return bacl_exit_error; } } @@ -903,8 +903,8 @@ static bacl_exit_code solaris_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt) acl_enabled = pathconf(jcr->last_fname, _PC_ACL_ENABLED); switch (acl_enabled) { case 0: - pm_strcpy(jcr->acl_data, ""); - jcr->acl_data_len = 0; + pm_strcpy(jcr->acl_data->content, ""); + jcr->acl_data->content_length = 0; return bacl_exit_ok; case -1: switch (errno) { @@ -942,8 +942,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, ""); - jcr->acl_data_len = 0; + pm_strcpy(jcr->acl_data->content, ""); + jcr->acl_data->content_length = 0; return bacl_exit_ok; } @@ -957,7 +957,7 @@ 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_len = pm_strcpy(jcr->acl_data, acl_text); + jcr->acl_data->content_length = pm_strcpy(jcr->acl_data->content, acl_text); actuallyfree(acl_text); switch (acl_type(aclp)) { @@ -1003,7 +1003,7 @@ static bacl_exit_code solaris_parse_acl_streams(JCR *jcr, int stream) 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, jcr->last_fname, be.bstrerror()); + jcr->acl_data->content, jcr->last_fname, be.bstrerror()); return bacl_exit_error; } default: @@ -1040,11 +1040,11 @@ static bacl_exit_code solaris_parse_acl_streams(JCR *jcr, int stream) break; } - if ((error = acl_fromtext(jcr->acl_data, &aclp)) != 0) { + if ((error = acl_fromtext(jcr->acl_data->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, jcr->last_fname, acl_strerror(error)); + jcr->acl_data->content, jcr->last_fname, acl_strerror(error)); return bacl_exit_error; } @@ -1088,7 +1088,7 @@ static bacl_exit_code solaris_parse_acl_streams(JCR *jcr, int stream) 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, jcr->last_fname, acl_strerror(error)); + jcr->acl_data->content, jcr->last_fname, acl_strerror(error)); acl_free(aclp); return bacl_exit_error; } @@ -1152,13 +1152,13 @@ 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, ""); - jcr->acl_data_len = 0; + pm_strcpy(jcr->acl_data->content, ""); + jcr->acl_data->content_length = 0; return bacl_exit_ok; } if ((acl_text = acltotext(acls, n)) != NULL) { - jcr->acl_data_len = pm_strcpy(jcr->acl_data, acl_text); + jcr->acl_data->content_length = pm_strcpy(jcr->acl_data->content, acl_text); actuallyfree(acl_text); free(acls); return send_acl_stream(jcr, STREAM_ACL_SOLARIS_ACLENT); @@ -1167,7 +1167,7 @@ static bacl_exit_code solaris_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt) 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, jcr->last_fname, be.bstrerror()); + jcr->acl_data->content, jcr->last_fname, be.bstrerror()); } free(acls); @@ -1180,12 +1180,12 @@ static bacl_exit_code solaris_parse_acl_streams(JCR *jcr, int stream) aclent_t *acls; berrno be; - acls = aclfromtext(jcr->acl_data, &n); + acls = aclfromtext(jcr->acl_data->content, &n); if (!acls) { 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, jcr->last_fname, be.bstrerror()); + jcr->acl_data->content, jcr->last_fname, be.bstrerror()); return bacl_exit_error; } @@ -1202,7 +1202,7 @@ static bacl_exit_code solaris_parse_acl_streams(JCR *jcr, int stream) 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, jcr->last_fname, be.bstrerror()); + jcr->acl_data->content, jcr->last_fname, be.bstrerror()); actuallyfree(acls); return bacl_exit_error; } diff --git a/bacula/src/filed/acl.h b/bacula/src/filed/acl.h index 06d4194248..dc60ce41ec 100644 --- a/bacula/src/filed/acl.h +++ b/bacula/src/filed/acl.h @@ -69,4 +69,13 @@ typedef enum { #define BACL_ENOTSUP ENOTSUP #endif +/* + * Internal tracking data. + */ +struct acl_data_t { + POOLMEM *content; + uint32_t content_length; + uint32_t nr_errors; +}; + #endif diff --git a/bacula/src/filed/backup.c b/bacula/src/filed/backup.c index 54f42f9613..87f6556409 100644 --- a/bacula/src/filed/backup.c +++ b/bacula/src/filed/backup.c @@ -141,12 +141,15 @@ bool blast_data_to_storage_daemon(JCR *jcr, char *addr) start_heartbeat_monitor(jcr); if (have_acl) { - jcr->acl_data = get_pool_memory(PM_MESSAGE); - jcr->total_acl_errors = 0; + 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); } + if (have_xattr) { - jcr->xattr_data = get_pool_memory(PM_MESSAGE); - jcr->total_xattr_errors = 0; + 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); } /* Subroutine save_file() is called for each file */ @@ -155,13 +158,13 @@ bool blast_data_to_storage_daemon(JCR *jcr, char *addr) set_jcr_job_status(jcr, JS_ErrorTerminated); } - if (jcr->total_acl_errors > 0) { + if (jcr->acl_data->nr_errors > 0) { Jmsg(jcr, M_ERROR, 0, _("Encountered %ld acl errors while doing backup\n"), - jcr->total_acl_errors); + jcr->acl_data->nr_errors); } - if (jcr->total_xattr_errors > 0) { + if (jcr->xattr_data->nr_errors > 0) { Jmsg(jcr, M_ERROR, 0, _("Encountered %ld xattr errors while doing backup\n"), - jcr->total_xattr_errors); + jcr->xattr_data->nr_errors); } accurate_send_deleted_list(jcr); /* send deleted list to SD */ @@ -171,11 +174,13 @@ 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); + free_pool_memory(jcr->acl_data->content); + free(jcr->acl_data); jcr->acl_data = NULL; } if (have_xattr && jcr->xattr_data) { - free_pool_memory(jcr->xattr_data); + free_pool_memory(jcr->xattr_data->content); + free(jcr->xattr_data); jcr->xattr_data = NULL; } if (jcr->big_buf) { @@ -619,10 +624,10 @@ int save_file(JCR *jcr, FF_PKT *ff_pkt, bool top_level) * 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->total_acl_errors < ACL_REPORT_ERR_MAX_PER_JOB) { + if (jcr->acl_data->nr_errors < ACL_REPORT_ERR_MAX_PER_JOB) { Jmsg(jcr, M_ERROR, 0, "%s", jcr->errmsg); } - jcr->total_acl_errors++; + jcr->acl_data->nr_errors++; break; case bacl_exit_ok: break; @@ -643,10 +648,10 @@ int save_file(JCR *jcr, FF_PKT *ff_pkt, bool top_level) * 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->total_xattr_errors < XATTR_REPORT_ERR_MAX_PER_JOB) { + if (jcr->xattr_data->nr_errors < XATTR_REPORT_ERR_MAX_PER_JOB) { Jmsg(jcr, M_ERROR, 0, "%s", jcr->errmsg); } - jcr->total_xattr_errors++; + jcr->xattr_data->nr_errors++; break; case bxattr_exit_ok: break; diff --git a/bacula/src/filed/filed.h b/bacula/src/filed/filed.h index b82aef0860..54905cbf44 100644 --- a/bacula/src/filed/filed.h +++ b/bacula/src/filed/filed.h @@ -66,6 +66,8 @@ typedef enum { #include "filed_conf.h" #include "fd_plugins.h" #include "findlib/find.h" +#include "acl.h" +#include "xattr.h" #include "jcr.h" #include "protos.h" /* file daemon prototypes */ #include "lib/runscript.h" diff --git a/bacula/src/filed/restore.c b/bacula/src/filed/restore.c index c1dc3b7352..7c45f51346 100644 --- a/bacula/src/filed/restore.c +++ b/bacula/src/filed/restore.c @@ -251,12 +251,14 @@ void do_restore(JCR *jcr) binit(&rctx.forkbfd); attr = rctx.attr = new_attr(jcr); if (have_acl) { - jcr->acl_data = get_pool_memory(PM_MESSAGE); - jcr->total_acl_errors = 0; + 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); } if (have_xattr) { - jcr->xattr_data = get_pool_memory(PM_MESSAGE); - jcr->total_xattr_errors = 0; + 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); } while (bget_msg(sd) >= 0 && !job_canceled(jcr)) { @@ -610,8 +612,8 @@ void do_restore(JCR *jcr) break; } if (have_acl) { - pm_memcpy(jcr->acl_data, sd->msg, sd->msglen); - jcr->acl_data_len = sd->msglen; + pm_memcpy(jcr->acl_data->content, sd->msg, sd->msglen); + jcr->acl_data->content_length = sd->msglen; switch (parse_acl_streams(jcr, rctx.stream)) { case bacl_exit_fatal: goto bail_out; @@ -620,10 +622,10 @@ void do_restore(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->total_acl_errors < ACL_REPORT_ERR_MAX_PER_JOB) { + if (jcr->acl_data->nr_errors < ACL_REPORT_ERR_MAX_PER_JOB) { Qmsg(jcr, M_WARNING, 0, "%s", jcr->errmsg); } - jcr->total_acl_errors++; + jcr->acl_data->nr_errors++; break; case bacl_exit_ok: break; @@ -649,8 +651,8 @@ void do_restore(JCR *jcr) break; } if (have_xattr) { - pm_memcpy(jcr->xattr_data, sd->msg, sd->msglen); - jcr->xattr_data_len = sd->msglen; + pm_memcpy(jcr->xattr_data->content, sd->msg, sd->msglen); + jcr->xattr_data->content_length = sd->msglen; switch (parse_xattr_streams(jcr, rctx.stream)) { case bxattr_exit_fatal: goto bail_out; @@ -659,10 +661,10 @@ void do_restore(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->total_xattr_errors < XATTR_REPORT_ERR_MAX_PER_JOB) { + if (jcr->xattr_data->nr_errors < XATTR_REPORT_ERR_MAX_PER_JOB) { Qmsg(jcr, M_WARNING, 0, "%s", jcr->errmsg); } - jcr->total_xattr_errors++; + jcr->xattr_data->nr_errors++; break; case bxattr_exit_ok: break; @@ -766,11 +768,13 @@ ok_out: } if (have_xattr && jcr->xattr_data) { - free_pool_memory(jcr->xattr_data); + free_pool_memory(jcr->xattr_data->content); + free(jcr->xattr_data); jcr->xattr_data = NULL; } if (have_acl && jcr->acl_data) { - free_pool_memory(jcr->acl_data); + free_pool_memory(jcr->acl_data->content); + free(jcr->acl_data); jcr->acl_data = NULL; } @@ -779,13 +783,13 @@ ok_out: free_attr(rctx.attr); Dmsg2(10, "End Do Restore. Files=%d Bytes=%s\n", jcr->JobFiles, edit_uint64(jcr->JobBytes, ec1)); - if (jcr->total_acl_errors > 0) { + if (jcr->acl_data->nr_errors > 0) { Jmsg(jcr, M_ERROR, 0, _("Encountered %ld acl errors while doing restore\n"), - jcr->total_acl_errors); + jcr->acl_data->nr_errors); } - if (jcr->total_xattr_errors > 0) { + if (jcr->xattr_data->nr_errors > 0) { Jmsg(jcr, M_ERROR, 0, _("Encountered %ld xattr errors while doing restore\n"), - jcr->total_xattr_errors); + jcr->xattr_data->nr_errors); } if (non_support_data > 1 || non_support_attr > 1) { Jmsg(jcr, M_ERROR, 0, _("%d non-supported data streams and %d non-supported attrib streams ignored.\n"), diff --git a/bacula/src/filed/xattr.c b/bacula/src/filed/xattr.c index 5790f423d7..30ea749e1b 100644 --- a/bacula/src/filed/xattr.c +++ b/bacula/src/filed/xattr.c @@ -45,7 +45,6 @@ #include "bacula.h" #include "filed.h" -#include "xattr.h" #if !defined(HAVE_XATTR) /* @@ -75,8 +74,9 @@ static bxattr_exit_code send_xattr_stream(JCR *jcr, int stream) /* * Sanity check */ - if (jcr->xattr_data_len <= 0) + if (jcr->xattr_data->content_length <= 0) { return bxattr_exit_ok; + } /* * Send header @@ -90,10 +90,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); + Dmsg1(400, "Backing up XATTR <%s>\n", jcr->xattr_data->content); msgsave = sd->msg; - sd->msg = jcr->xattr_data; - sd->msglen = jcr->xattr_data_len; + sd->msg = jcr->xattr_data->content; + sd->msglen = jcr->xattr_data->content_length; if (!sd->send()) { sd->msg = msgsave; sd->msglen = 0; @@ -215,8 +215,8 @@ 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 = check_pool_memory_size(jcr->xattr_data, expected_serialize_len + 10); - ser_begin(jcr->xattr_data, expected_serialize_len + 10); + 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); /* * Walk the list of xattrs and serialize the data. @@ -236,9 +236,9 @@ static uint32_t serialize_xattr_stream(JCR *jcr, uint32_t expected_serialize_len ser_bytes(current_xattr->value, current_xattr->value_length); } - ser_end(jcr->xattr_data, expected_serialize_len + 10); - jcr->xattr_data_len = ser_length(jcr->xattr_data); - return jcr->xattr_data_len; + ser_end(jcr->xattr_data->content, expected_serialize_len + 10); + jcr->xattr_data->content_length = ser_length(jcr->xattr_data->content); + return jcr->xattr_data->content_length; } static bxattr_exit_code generic_xattr_build_streams(JCR *jcr, FF_PKT *ff_pkt) @@ -463,8 +463,8 @@ static bxattr_exit_code generic_xattr_parse_streams(JCR *jcr, int stream) * Start unserializing the data. We keep on looping while we have not * unserialized all bytes in the stream. */ - unser_begin(jcr->xattr_data, jcr->xattr_data_len); - while (unser_length(jcr->xattr_data) < jcr->xattr_data_len) { + unser_begin(jcr->xattr_data->content, jcr->xattr_data->content_length); + while (unser_length(jcr->xattr_data->content) < jcr->xattr_data->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. @@ -532,7 +532,7 @@ static bxattr_exit_code generic_xattr_parse_streams(JCR *jcr, int stream) free(current_xattr.value); } - unser_end(jcr->xattr_data, jcr->xattr_data_len); + unser_end(jcr->xattr_data->content, jcr->xattr_data->content_length); return retval; } @@ -655,7 +655,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->xpd->xattr_link_cache) { + foreach_alist(ptr, jcr->xattr_data->link_cache) { if (ptr && ptr->inum == inum) { return ptr; } @@ -671,7 +671,19 @@ static void add_xattr_link_cache_entry(JCR *jcr, ino_t inum, char *target) memset((caddr_t)ptr, 0, sizeof(xattr_link_cache_entry_t)); ptr->inum = inum; bstrncpy(ptr->target, target, sizeof(ptr->target)); - jcr->xpd->xattr_link_cache->append(ptr); + jcr->xattr_data->link_cache->append(ptr); +} + +static void flush_xattr_link_cache(JCR *jcr) +{ + xattr_link_cache_entry_t *ptr; + + foreach_alist(ptr, jcr->xattr_data->link_cache) { + if (ptr && ptr->target) { + free(ptr->target); + } + } +>>>>>>> Add all acl and xattr related variables which are either global or already part of the JCR:bacula/src/filed/xattr.c } #if defined(HAVE_SYS_NVPAIR_H) && defined(_PC_SATTR_ENABLED) @@ -968,15 +980,17 @@ 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. - * Encode the stat struct into an ASCII representation and jump out of the function. + * 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 + * out of the function. */ encode_stat(attribs, &st, 0, stream); - jcr->xpd->toplevel_hidden_dir_xattr_data_len = bsnprintf(jcr->xpd->toplevel_hidden_dir_xattr_data, - sizeof(jcr->xpd->toplevel_hidden_dir_xattr_data), - "%s%c%s%c%s%c", - target_attrname, 0, attribs, 0, - (acl_text) ? acl_text : "", 0); + 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; goto bail_out; } else { /* @@ -1005,8 +1019,8 @@ 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, buffer, cnt); - jcr->xattr_data_len = cnt; + pm_memcpy(jcr->xattr_data->content, buffer, cnt); + jcr->xattr_data->content_length = cnt; retval = send_xattr_stream(jcr, stream); /* @@ -1081,8 +1095,8 @@ 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, buffer, cnt); - jcr->xattr_data_len = cnt; + pm_memcpy(jcr->xattr_data->content, buffer, cnt); + jcr->xattr_data->content_length = cnt; retval = send_xattr_stream(jcr, stream); /* @@ -1097,16 +1111,17 @@ 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. */ - if (jcr->xpd->nr_xattr_saved == 0) { - pm_memcpy(jcr->xattr_data, jcr->xpd->toplevel_hidden_dir_xattr_data, - jcr->xpd->toplevel_hidden_dir_xattr_data_len); - jcr->xattr_data_len = jcr->xpd->toplevel_hidden_dir_xattr_data_len; + if (jcr->xattr_data->nr_saved == 0) { retval = send_xattr_stream(jcr, STREAM_XATTR_SOLARIS); + if (retval != bxattr_exit_ok) { + goto bail_out; + } } - pm_memcpy(jcr->xattr_data, buffer, cnt); - jcr->xattr_data_len = cnt; + pm_memcpy(jcr->xattr_data->content, buffer, cnt); + jcr->xattr_data->content_length = cnt; /* * Only dump the content of regular files. @@ -1124,9 +1139,9 @@ static bxattr_exit_code solaris_save_xattr(JCR *jcr, int fd, const char *xattr_n } while ((cnt = read(attrfd, buffer, sizeof(buffer))) > 0) { - jcr->xattr_data = check_pool_memory_size(jcr->xattr_data, jcr->xattr_data_len + cnt); - memcpy(jcr->xattr_data + jcr->xattr_data_len, buffer, cnt); - jcr->xattr_data_len += cnt; + 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; } if (cnt < 0) { @@ -1145,7 +1160,7 @@ static bxattr_exit_code solaris_save_xattr(JCR *jcr, int fd, const char *xattr_n if (retval) { retval = send_xattr_stream(jcr, stream); - jcr->xpd->nr_xattr_saved++; + jcr->xattr_data->nr_saved++; } /* @@ -1429,16 +1444,16 @@ 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_len; + 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 + 1; + target_attrname = jcr->xattr_data->content + 1; if ((bp = strchr(target_attrname, '\0')) == (char *)NULL || - (used_bytes = (bp - jcr->xattr_data)) >= (total_bytes - 1)) { + (used_bytes = (bp - jcr->xattr_data->content)) >= (total_bytes - 1)) { goto parse_error; } attribs = ++bp; @@ -1529,7 +1544,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)) >= (total_bytes - 1)) { + (used_bytes = (bp - jcr->xattr_data->content)) >= (total_bytes - 1)) { goto parse_error; } acl_text = ++bp; @@ -1606,7 +1621,7 @@ 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)) >= total_bytes) { + (used_bytes = (bp - jcr->xattr_data->content)) >= total_bytes) { goto parse_error; } @@ -1633,7 +1648,7 @@ 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); + used_bytes = (data - jcr->xattr_data->content); cnt = total_bytes - used_bytes; /* @@ -1772,21 +1787,19 @@ 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->xpd = (xattr_private_data_t *)malloc(sizeof(xattr_private_data_t)); - memset((caddr_t)jcr->xpd, 0, sizeof(xattr_private_data_t)); - jcr->xpd->xattr_link_cache = New(alist(10, not_owned_by_alist)); + jcr->xattr_data->nr_saved = 0; /* * As we change the cwd in the save function save the current cwd * for restore after return from the solaris_save_xattrs function. */ + jcr->xattr_data->link_cache = New(alist(10, not_owned_by_alist)); getcwd(cwd, sizeof(cwd)); retval = solaris_save_xattrs(jcr, NULL, NULL); chdir(cwd); - delete jcr->xpd->xattr_link_cache; - jcr->xpd->xattr_link_cache = NULL; - free(jcr->xpd); - jcr->xpd = NULL; + flush_xattr_link_cache(jcr); + delete jcr->xattr_data->link_cache; + jcr->xattr_data->link_cache = NULL; } return retval; } diff --git a/bacula/src/filed/xattr.h b/bacula/src/filed/xattr.h index 891c6fb275..90800a0385 100644 --- a/bacula/src/filed/xattr.h +++ b/bacula/src/filed/xattr.h @@ -55,20 +55,14 @@ struct xattr_link_cache_entry_t { }; /* - * Private data structure for threadsafe save of xattrs. - * For now its mostly for storing the solaris specific private data. + * Internal tracking data. */ -struct xattr_private_data_t { - /* - * This is the count of xattrs saved on a certain file, it gets reset - * on each new file processed and is used to see if we need to send - * the hidden xattr dir data. We only send that data when we encounter - * an other xattr on the file. - */ - int nr_xattr_saved; - char toplevel_hidden_dir_xattr_data[MAXSTRING]; - int toplevel_hidden_dir_xattr_data_len; - alist *xattr_link_cache; +struct xattr_data_t { + POOLMEM *content; + uint32_t content_length; + uint32_t nr_errors; + uint32_t nr_saved; + alist *link_cache; }; /* diff --git a/bacula/src/jcr.h b/bacula/src/jcr.h index fb6e1bd8c2..8513fe6d44 100644 --- a/bacula/src/jcr.h +++ b/bacula/src/jcr.h @@ -152,6 +152,8 @@ struct xattr_private_data_t; #ifdef FILE_DAEMON class htable; +struct acl_data_t; +struct xattr_data_t; struct CRYPTO_CTX { bool pki_sign; /* Enable PKI Signatures? */ @@ -348,13 +350,8 @@ public: /* File Daemon specific part of JCR */ uint32_t num_files_examined; /* files examined this job */ POOLMEM *last_fname; /* last file saved/verified */ - POOLMEM *acl_data; /* data with ACLs for backup/restore */ - uint32_t acl_data_len; /* length of acl data buffer */ - uint32_t total_acl_errors; /* numbers of errors encountered for acl backup/restore */ - xattr_private_data_t *xpd; /* private data for xattr saving */ - POOLMEM *xattr_data; /* data with Extended Attributes for backup/restore */ - uint32_t xattr_data_len; /* length of xattr_data buffer */ - uint32_t total_xattr_errors; /* numbers of errors encountered for xattr backup/restore */ + acl_data_t *acl_data; /* ACLs for backup/restore */ + xattr_data_t *xattr_data; /* Extended Attributes for backup/restore */ int32_t last_type; /* type of last file saved/verified */ int incremental; /* set if incremental for SINCE */ utime_t mtime; /* begin time for SINCE */ -- 2.39.5