]> git.sur5r.net Git - bacula/bacula/commitdiff
Add XATTR flags for backup and restore.
authorMarco van Wieringen <mvw@planets.elm.net>
Fri, 16 Sep 2011 14:03:05 +0000 (16:03 +0200)
committerKern Sibbald <kern@sibbald.com>
Sat, 20 Apr 2013 12:50:01 +0000 (14:50 +0200)
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
bacula/src/filed/xattr.h

index 938f8c24c6ca86ac5f0be1f230012b27a328b7f7..e59e5190219f5b6059a36110d974fd074841eaa6 100644 (file)
@@ -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.
     */
index 1fe551818bac4507f06a81a38af0ccabacfb8945..e84c87b994f2aded89d5b7b0150a59b5f21027e7 100644 (file)
@@ -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_* */
 };
 
 /*