]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/filed/backup.c
Loose #ifdef and use const bool wrapper for some cleaner coding.
[bacula/bacula] / bacula / src / filed / backup.c
index 1d54c285bce8b61354952053fe60fdbaa97c41eb..820f03087b9dec94bb2203d0e66df7c4a2e2a33f 100644 (file)
@@ -1,7 +1,7 @@
 /*
    Bacula® - The Network Backup Solution
 
-   Copyright (C) 2000-2008 Free Software Foundation Europe e.V.
+   Copyright (C) 2000-2009 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.
 #include "bacula.h"
 #include "filed.h"
 
+#if defined(HAVE_ACL)
+const bool have_acl = true;
+#else
+const bool have_acl = false;
+#endif
+
+#if defined(HAVE_XATTR)
+const bool have_xattr = true;
+#else
+const bool have_xattr = false;
+#endif
+
 /* Forward referenced functions */
 int save_file(JCR *jcr, FF_PKT *ff_pkt, bool top_level);
 static int send_data(JCR *jcr, int stream, FF_PKT *ff_pkt, DIGEST *digest, DIGEST *signature_digest);
@@ -46,22 +58,6 @@ static bool crypto_session_start(JCR *jcr);
 static void crypto_session_end(JCR *jcr);
 static bool crypto_session_send(JCR *jcr, BSOCK *sd);
 
-/*
- * check for BSD nodump flag
- */
-static bool no_dump(JCR *jcr, FF_PKT *ff_pkt)
-{
-#if defined(HAVE_CHFLAGS) && defined(UF_NODUMP)
-   if ( (ff_pkt->flags & FO_HONOR_NODUMP) &&
-        (ff_pkt->statp.st_flags & UF_NODUMP) ) {
-      Jmsg(jcr, M_INFO, 1, _("     NODUMP flag set - will not process %s\n"),
-           ff_pkt->fname);
-      return true;                    /* do not backup this file */
-   }
-#endif
-   return false;                      /* do backup */
-}
-
 /*
  * Find all the requested files and send them
  * to the Storage daemon.
@@ -144,8 +140,17 @@ bool blast_data_to_storage_daemon(JCR *jcr, char *addr)
    
    start_heartbeat_monitor(jcr);
 
-   jcr->acl_data = get_pool_memory(PM_MESSAGE);
-   jcr->xattr_data = get_pool_memory(PM_MESSAGE);
+   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);
+   }
+
+   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);
+   }
 
    /* Subroutine save_file() is called for each file */
    if (!find_files(jcr, (FF_PKT *)jcr->ff, save_file, plugin_save)) {
@@ -153,15 +158,31 @@ bool blast_data_to_storage_daemon(JCR *jcr, char *addr)
       set_jcr_job_status(jcr, JS_ErrorTerminated);
    }
 
-   accurate_send_deleted_list(jcr);              /* send deleted list to SD  */
+   if (have_acl && jcr->acl_data->nr_errors > 0) {
+      Jmsg(jcr, M_ERROR, 0, _("Encountered %ld acl errors while doing backup\n"),
+           jcr->acl_data->nr_errors);
+   }
+   if (have_xattr && jcr->xattr_data->nr_errors > 0) {
+      Jmsg(jcr, M_ERROR, 0, _("Encountered %ld xattr errors while doing backup\n"),
+           jcr->xattr_data->nr_errors);
+   }
 
-   free_pool_memory(jcr->acl_data);
-   free_pool_memory(jcr->xattr_data);
+   accurate_send_deleted_list(jcr);              /* send deleted list to SD  */
 
    stop_heartbeat_monitor(jcr);
 
    sd->signal(BNET_EOD);            /* end of sending data */
 
+   if (have_acl && 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->content);
+      free(jcr->xattr_data);
+      jcr->xattr_data = NULL;
+   }
    if (jcr->big_buf) {
       free(jcr->big_buf);
       jcr->big_buf = NULL;
@@ -300,14 +321,10 @@ int save_file(JCR *jcr, FF_PKT *ff_pkt, bool top_level)
       break;
    case FT_REGE:
       Dmsg1(130, "FT_REGE saving: %s\n", ff_pkt->fname);
-      if (no_dump(jcr, ff_pkt))
-          return 1;
       has_file_data = true;
       break;
    case FT_REG:
       Dmsg1(130, "FT_REG saving: %s\n", ff_pkt->fname);
-      if (no_dump(jcr, ff_pkt))
-          return 1;
       has_file_data = true;
       break;
    case FT_LNK:
@@ -315,8 +332,6 @@ int save_file(JCR *jcr, FF_PKT *ff_pkt, bool top_level)
       break;
    case FT_DIRBEGIN:
       jcr->num_files_examined--;      /* correct file count */
-      if (no_dump(jcr, ff_pkt))       /* disable recursion on nodump directories */
-          ff_pkt->flags |= FO_NO_RECURSION;
       return 1;                       /* not used */
    case FT_NORECURSE:
       Jmsg(jcr, M_INFO, 1, _("     Recursion turned off. Will not descend from %s into %s\n"),
@@ -362,21 +377,21 @@ int save_file(JCR *jcr, FF_PKT *ff_pkt, bool top_level)
       berrno be;
       Jmsg(jcr, M_NOTSAVED, 0, _("     Could not access \"%s\": ERR=%s\n"), ff_pkt->fname,
          be.bstrerror(ff_pkt->ff_errno));
-      jcr->Errors++;
+      jcr->JobErrors++;
       return 1;
    }
    case FT_NOFOLLOW: {
       berrno be;
       Jmsg(jcr, M_NOTSAVED, 0, _("     Could not follow link \"%s\": ERR=%s\n"), 
            ff_pkt->fname, be.bstrerror(ff_pkt->ff_errno));
-      jcr->Errors++;
+      jcr->JobErrors++;
       return 1;
    }
    case FT_NOSTAT: {
       berrno be;
       Jmsg(jcr, M_NOTSAVED, 0, _("     Could not stat \"%s\": ERR=%s\n"), ff_pkt->fname,
          be.bstrerror(ff_pkt->ff_errno));
-      jcr->Errors++;
+      jcr->JobErrors++;
       return 1;
    }
    case FT_DIRNOCHG:
@@ -390,13 +405,13 @@ int save_file(JCR *jcr, FF_PKT *ff_pkt, bool top_level)
       berrno be;
       Jmsg(jcr, M_NOTSAVED, 0, _("     Could not open directory \"%s\": ERR=%s\n"), 
            ff_pkt->fname, be.bstrerror(ff_pkt->ff_errno));
-      jcr->Errors++;
+      jcr->JobErrors++;
       return 1;
    }
    default:
       Jmsg(jcr, M_NOTSAVED, 0,  _("     Unknown file type %d; not saved: %s\n"), 
            ff_pkt->type, ff_pkt->fname);
-      jcr->Errors++;
+      jcr->JobErrors++;
       return 1;
    }
 
@@ -450,7 +465,7 @@ int save_file(JCR *jcr, FF_PKT *ff_pkt, bool top_level)
          if (signing_digest == NULL) {
             Jmsg(jcr, M_NOTSAVED, 0, _("%s signature digest initialization failed\n"),
                stream_to_ascii(signing_algorithm));
-            jcr->Errors++;
+            jcr->JobErrors++;
             goto good_rtn;
          }
       }
@@ -522,7 +537,7 @@ int save_file(JCR *jcr, FF_PKT *ff_pkt, bool top_level)
          berrno be;
          Jmsg(jcr, M_NOTSAVED, 0, _("     Cannot open \"%s\": ERR=%s.\n"), ff_pkt->fname,
               be.bstrerror());
-         jcr->Errors++;
+         jcr->JobErrors++;
          if (tid) {
             stop_thread_timer(tid);
             tid = NULL;
@@ -559,7 +574,7 @@ int save_file(JCR *jcr, FF_PKT *ff_pkt, bool top_level)
             berrno be;
             Jmsg(jcr, M_NOTSAVED, -1, _("     Cannot open resource fork for \"%s\": ERR=%s.\n"), 
                  ff_pkt->fname, be.bstrerror());
-            jcr->Errors++;
+            jcr->JobErrors++;
             if (is_bopen(&ff_pkt->bfd)) {
                bclose(&ff_pkt->bfd);
             }
@@ -597,19 +612,51 @@ int save_file(JCR *jcr, FF_PKT *ff_pkt, bool top_level)
 #endif
 
    /*
-    * Save ACLs for anything not being a symlink.
+    * Save ACLs when requested and available for anything not being a symlink and not being a plugin.
     */
-   if (ff_pkt->flags & FO_ACL && ff_pkt->type != FT_LNK) {
-      if (!build_acl_streams(jcr, ff_pkt))
-         goto bail_out;
+   if (have_acl) {
+      if (ff_pkt->flags & FO_ACL && ff_pkt->type != FT_LNK && !ff_pkt->cmd_plugin) {
+         switch (build_acl_streams(jcr, ff_pkt)) {
+         case bacl_exit_fatal:
+            goto bail_out;
+         case bacl_exit_error:
+            /*
+             * 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) {
+               Jmsg(jcr, M_ERROR, 0, "%s", jcr->errmsg);
+            }
+            jcr->acl_data->nr_errors++;
+            break;
+         case bacl_exit_ok:
+            break;
+         }
+      }
    }
 
    /*
-    * Save Extended Attributes for all files.
+    * Save Extended Attributes when requested and available for all files not being a plugin.
     */
-   if (ff_pkt->flags & FO_XATTR) {
-      if (!build_xattr_streams(jcr, ff_pkt))
-         goto bail_out;
+   if (have_xattr) {
+      if (ff_pkt->flags & FO_XATTR && !ff_pkt->cmd_plugin) {
+         switch (build_xattr_streams(jcr, ff_pkt)) {
+         case bxattr_exit_fatal:
+            goto bail_out;
+         case bxattr_exit_error:
+            /*
+             * 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) {
+               Jmsg(jcr, M_ERROR, 0, "%s", jcr->errmsg);
+            }
+            jcr->xattr_data->nr_errors++;
+            break;
+         case bxattr_exit_ok:
+            break;
+         }
+      }
    }
 
    /* Terminate the signing digest and send it to the Storage daemon */
@@ -706,8 +753,8 @@ bail_out:
  * Currently this is not a problem as the only other stream, resource forks,
  * are not handled as sparse files.
  */
-int send_data(JCR *jcr, int stream, FF_PKT *ff_pkt, DIGEST *digest, 
-              DIGEST *signing_digest)
+static int send_data(JCR *jcr, int stream, FF_PKT *ff_pkt, DIGEST *digest, 
+                     DIGEST *signing_digest)
 {
    BSOCK *sd = jcr->store_bsock;
    uint64_t fileAddr = 0;             /* file address */
@@ -799,8 +846,10 @@ int send_data(JCR *jcr, int stream, FF_PKT *ff_pkt, DIGEST *digest,
     *    <file-index> <stream> <info>
     */
    if (!sd->fsend("%ld %d 0", jcr->JobFiles, stream)) {
-      Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
-            sd->bstrerror());
+      if (!job_canceled(jcr)) {
+         Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
+               sd->bstrerror());
+      }
       goto err;
    }
    Dmsg1(300, ">stored: datahdr %s\n", sd->msg);
@@ -957,8 +1006,10 @@ int send_data(JCR *jcr, int stream, FF_PKT *ff_pkt, DIGEST *digest,
       }
       sd->msg = wbuf;              /* set correct write buffer */
       if (!sd->send()) {
-         Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
-               sd->bstrerror());
+         if (!job_canceled(jcr)) {
+            Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
+                  sd->bstrerror());
+         }
          goto err;
       }
       Dmsg1(130, "Send data to SD len=%d\n", sd->msglen);
@@ -972,7 +1023,7 @@ int send_data(JCR *jcr, int stream, FF_PKT *ff_pkt, DIGEST *digest,
       berrno be;
       Jmsg(jcr, M_ERROR, 0, _("Read error on file %s. ERR=%s\n"),
          ff_pkt->fname, be.bstrerror(ff_pkt->bfd.berrno));
-      if (jcr->Errors++ > 1000) {       /* insanity check */
+      if (jcr->JobErrors++ > 1000) {       /* insanity check */
          Jmsg(jcr, M_FATAL, 0, _("Too many errors.\n"));
       }
    } else if (ff_pkt->flags & FO_ENCRYPT) {
@@ -992,8 +1043,10 @@ int send_data(JCR *jcr, int stream, FF_PKT *ff_pkt, DIGEST *digest,
          sd->msglen = encrypted_len;      /* set encrypted length */
          sd->msg = jcr->crypto.crypto_buf;       /* set correct write buffer */
          if (!sd->send()) {
-            Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
-                  sd->bstrerror());
+            if (!job_canceled(jcr)) {
+               Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
+                     sd->bstrerror());
+            }
             goto err;
          }
          Dmsg1(130, "Send data to SD len=%d\n", sd->msglen);
@@ -1003,8 +1056,10 @@ int send_data(JCR *jcr, int stream, FF_PKT *ff_pkt, DIGEST *digest,
    }
 
    if (!sd->signal(BNET_EOD)) {        /* indicate end of file data */
-      Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
-            sd->bstrerror());
+      if (!job_canceled(jcr)) {
+         Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
+               sd->bstrerror());
+      }
       goto err;
    }
 
@@ -1043,7 +1098,7 @@ bool encode_and_send_attributes(JCR *jcr, FF_PKT *ff_pkt, int &data_stream)
       Jmsg0(jcr, M_FATAL, 0, _("Invalid file flags, no supported data stream type.\n"));
       return false;
    }
-   encode_stat(attribs, ff_pkt, data_stream);
+   encode_stat(attribs, &ff_pkt->statp, ff_pkt->LinkFI, data_stream);
 
    /* Now possibly extend the attributes */
    attr_stream = encode_attribsEx(jcr, attribsEx, ff_pkt);
@@ -1061,8 +1116,10 @@ bool encode_and_send_attributes(JCR *jcr, FF_PKT *ff_pkt, int &data_stream)
     *    <file-index> <stream> <info>
     */
    if (!sd->fsend("%ld %d 0", jcr->JobFiles, attr_stream)) {
-      Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
-            sd->bstrerror());
+      if (!job_canceled(jcr)) {
+         Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
+               sd->bstrerror());
+      }
       return false;
    }
    Dmsg1(300, ">stored: attrhdr %s\n", sd->msg);
@@ -1101,8 +1158,10 @@ bool encode_and_send_attributes(JCR *jcr, FF_PKT *ff_pkt, int &data_stream)
 
    Dmsg2(300, ">stored: attr len=%d: %s\n", sd->msglen, sd->msg);
    if (!stat) {
-      Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
-            sd->bstrerror());
+      if (!job_canceled(jcr)) {
+         Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
+               sd->bstrerror());
+      }
       return false;
    }
    sd->signal(BNET_EOD);            /* indicate end of attributes data */