From 3894b58757467e494328617f097b47585f1b05a8 Mon Sep 17 00:00:00 2001 From: Marco van Wieringen Date: Fri, 16 Sep 2011 16:03:05 +0200 Subject: [PATCH] Add XATTR flags for backup and restore. When the OS reports it doesn't support xattr we clear either the SAVE or RESTORE native xattr flag. This way we only test once if a particular filesystem has xattr support and ignore it for any further file until we switch filesystems. --- bacula/src/filed/xattr.c | 113 +++++++++++++++++++++++++++++++++------ bacula/src/filed/xattr.h | 9 +++- 2 files changed, 105 insertions(+), 17 deletions(-) diff --git a/bacula/src/filed/xattr.c b/bacula/src/filed/xattr.c index 938f8c24c6..e59e519021 100644 --- a/bacula/src/filed/xattr.c +++ b/bacula/src/filed/xattr.c @@ -345,7 +345,15 @@ static bxattr_exit_code aix_xattr_build_streams(JCR *jcr, FF_PKT *ff_pkt) switch (errno) { case ENOENT: case EFORMAT: + return bxattr_exit_ok; case 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. + */ + jcr->xattr_data->flags &= ~BXATTR_FLAG_SAVE_NATIVE; return bxattr_exit_ok; default: Mmsg2(jcr->errmsg, _("llistea error on file \"%s\": ERR=%s\n"), @@ -376,7 +384,6 @@ static bxattr_exit_code aix_xattr_build_streams(JCR *jcr, FF_PKT *ff_pkt) switch (errno) { case ENOENT: case EFORMAT: - case ENOTSUP: retval = bxattr_exit_ok; goto bail_out; default: @@ -439,7 +446,6 @@ static bxattr_exit_code aix_xattr_build_streams(JCR *jcr, FF_PKT *ff_pkt) switch (errno) { case ENOENT: case EFORMAT: - case ENOTSUP: retval = bxattr_exit_ok; goto bail_out; default: @@ -467,7 +473,6 @@ static bxattr_exit_code aix_xattr_build_streams(JCR *jcr, FF_PKT *ff_pkt) switch (errno) { case ENOENT: case EFORMAT: - case ENOTSUP: retval = bxattr_exit_ok; goto bail_out; default: @@ -568,7 +573,15 @@ static bxattr_exit_code aix_xattr_parse_streams(JCR *jcr, int stream) 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. + */ + jcr->xattr_data->flags &= ~BXATTR_FLAG_RESTORE_NATIVE; goto bail_out; default: Mmsg2(jcr->errmsg, _("lsetea error on file \"%s\": ERR=%s\n"), @@ -966,7 +979,15 @@ static bxattr_exit_code generic_xattr_build_streams(JCR *jcr, FF_PKT *ff_pkt) case -1: switch (errno) { case ENOENT: + 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. + */ + jcr->xattr_data->flags &= ~BXATTR_FLAG_SAVE_NATIVE; return bxattr_exit_ok; default: Mmsg2(jcr->errmsg, _("llistxattr error on file \"%s\": ERR=%s\n"), @@ -996,7 +1017,6 @@ static bxattr_exit_code generic_xattr_build_streams(JCR *jcr, FF_PKT *ff_pkt) case -1: switch (errno) { case ENOENT: - case BXATTR_ENOTSUP: retval = bxattr_exit_ok; goto bail_out; default: @@ -1077,7 +1097,6 @@ static bxattr_exit_code generic_xattr_build_streams(JCR *jcr, FF_PKT *ff_pkt) case -1: switch (errno) { case ENOENT: - case BXATTR_ENOTSUP: retval = bxattr_exit_ok; goto bail_out; default: @@ -1104,7 +1123,6 @@ static bxattr_exit_code generic_xattr_build_streams(JCR *jcr, FF_PKT *ff_pkt) if (xattr_value_len < 0) { switch (errno) { case ENOENT: - case BXATTR_ENOTSUP: retval = bxattr_exit_ok; goto bail_out; default: @@ -1204,7 +1222,15 @@ static bxattr_exit_code generic_xattr_parse_streams(JCR *jcr, int stream) if (lsetxattr(jcr->last_fname, current_xattr->name, current_xattr->value, current_xattr->value_length, 0) != 0) { switch (errno) { case ENOENT: + 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. + */ + jcr->xattr_data->flags &= ~BXATTR_FLAG_RESTORE_NATIVE; goto bail_out; default: Mmsg2(jcr->errmsg, _("lsetxattr error on file \"%s\": ERR=%s\n"), @@ -1714,6 +1740,13 @@ static bxattr_exit_code tru64_build_xattr_streams(JCR *jcr, FF_PKT *ff_pkt) case -1: 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. + */ + jcr->xattr_data->flags &= ~BXATTR_FLAG_SAVE_NATIVE; retval = bxattr_exit_ok; goto bail_out; default: @@ -1737,9 +1770,6 @@ static bxattr_exit_code tru64_build_xattr_streams(JCR *jcr, FF_PKT *ff_pkt) switch (xattr_list_len) { case -1: switch (errno) { - case EOPNOTSUPP: - retval = bxattr_exit_ok; - goto bail_out; default: Mmsg2(jcr->errmsg, _("getproplist error on file \"%s\": ERR=%s\n"), jcr->last_fname, be.bstrerror()); @@ -1761,7 +1791,7 @@ static bxattr_exit_code tru64_build_xattr_streams(JCR *jcr, FF_PKT *ff_pkt) break; } } else { - /** + /* * No xattr on file. */ retval = bxattr_exit_ok; @@ -1945,6 +1975,13 @@ static bxattr_exit_code tru64_parse_xattr_streams(JCR *jcr, int stream) case -1: 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. + */ + jcr->xattr_data->flags &= ~BXATTR_FLAG_RESTORE_NATIVE; retval = bxattr_exit_ok; goto bail_out; default: @@ -3296,26 +3333,72 @@ static bxattr_exit_code (*os_parse_xattr_streams)(JCR *jcr, int stream) = solari */ bxattr_exit_code build_xattr_streams(JCR *jcr, FF_PKT *ff_pkt) { - if (os_build_xattr_streams) { - return (*os_build_xattr_streams)(jcr, ff_pkt); + /** + * See if we are changing from one device to an other. + * We save the current device we are scanning and compare + * it with the current st_dev in the last stat performed on + * the file we are currently storing. + */ + if (jcr->xattr_data->current_dev != ff_pkt->statp.st_dev) { + /* + * Reset the acl save flags. + */ + jcr->xattr_data->flags = 0; + jcr->xattr_data->flags |= BXATTR_FLAG_SAVE_NATIVE; + + /* + * Save that we started scanning a new filesystem. + */ + jcr->xattr_data->current_dev = ff_pkt->statp.st_dev; + } + + if ((jcr->xattr_data->flags & BXATTR_FLAG_SAVE_NATIVE) && os_parse_xattr_streams) { + return os_build_xattr_streams(jcr, ff_pkt); + } else { + return bxattr_exit_ok; } - return bxattr_exit_error; } bxattr_exit_code parse_xattr_streams(JCR *jcr, int stream) { unsigned int cnt; - if (os_parse_xattr_streams) { + /** + * See if we are changing from one device to an other. + * We save the current device we are restoring to and compare + * it with the current st_dev in the last stat performed on + * the file we are currently storing. + */ + if (jcr->xattr_data->current_dev != ff_pkt->statp.st_dev) { + /* + * Reset the acl save flags. + */ + jcr->xattr_data->flags = 0; + jcr->xattr_data->flags |= BXATTR_FLAG_RESTORE_NATIVE; + + /* + * Save that we started restoring to a new filesystem. + */ + jcr->xattr_data->current_dev = ff_pkt->statp.st_dev; + } + + if ((jcr->xattr_data->flags & BXATTR_FLAG_RESTORE_NATIVE) && os_parse_xattr_streams) { /* * See if we can parse this stream, and ifso give it a try. */ 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); } } + } else { + /* + * Increment error count but don't log an error again for the same filesystem. + */ + jcr->xattr_data->nr_errors++; + return bxattr_exit_ok; } + /* * Issue a warning and discard the message. But pretend the restore was ok. */ diff --git a/bacula/src/filed/xattr.h b/bacula/src/filed/xattr.h index 1fe551818b..e84c87b994 100644 --- a/bacula/src/filed/xattr.h +++ b/bacula/src/filed/xattr.h @@ -30,9 +30,9 @@ #define __XATTR_H #if defined(HAVE_LINUX_OS) -#define BXATTR_ENOTSUP EOPNOTSUPP +#define BXATTR_ENOTSUP EOPNOTSUPP #elif defined(HAVE_DARWIN_OS) -#define BXATTR_ENOTSUP ENOTSUP +#define BXATTR_ENOTSUP ENOTSUP #endif /* @@ -60,6 +60,9 @@ struct xattr_link_cache_entry_t { char target[PATH_MAX]; }; +#define BXATTR_FLAG_SAVE_NATIVE 0x01 +#define BXATTR_FLAG_RESTORE_NATIVE 0x02 + /* * Internal tracking data. */ @@ -69,6 +72,8 @@ struct xattr_data_t { uint32_t nr_errors; uint32_t nr_saved; alist *link_cache; + uint32_t current_dev; + uint32_t flags; /* See BXATTR_FLAG_* */ }; /* -- 2.39.5