]> git.ipfire.org Git - thirdparty/bacula.git/commitdiff
Fix #9127 About incorrect handling of the new Accurate 'o' option with multiple incre...
authorEric Bollengier <eric@baculasystems.com>
Tue, 17 May 2022 09:59:31 +0000 (11:59 +0200)
committerEric Bollengier <eric@baculasystems.com>
Fri, 27 May 2022 08:30:33 +0000 (10:30 +0200)
bacula/src/filed/accurate.c
bacula/src/filed/backup.c
bacula/src/filed/bacl_linux.c
bacula/src/filed/crypto.c
bacula/src/filed/restore.c
bacula/src/filed/restore.h
bacula/src/findlib/bfile.c
bacula/src/findlib/find.h
bacula/src/stored/record_util.c

index 09b437c8093f693534b0a3adf6a4303e2f958acd..8e0b7fdff23bb69762a3400fbbde3438bd585688 100644 (file)
@@ -360,7 +360,7 @@ bail_out:
  */
 static int check_checksum_diff(JCR *jcr, FF_PKT *ff_pkt, CurFile *elt)
 {
-   int ret = 0;
+   int ret = -1;
    int digest_stream = STREAM_NONE;
    DIGEST *digest = NULL;
    char *fname;
@@ -383,7 +383,6 @@ static int check_checksum_diff(JCR *jcr, FF_PKT *ff_pkt, CurFile *elt)
       if (!*elt->chksum && !jcr->rerunning) {
          Jmsg(jcr, M_WARNING, 0, _("Cannot verify checksum for %s\n"),
                ff_pkt->fname);
-         ret = -1;
          goto bail_out;
       }
 
@@ -432,7 +431,6 @@ static int check_checksum_diff(JCR *jcr, FF_PKT *ff_pkt, CurFile *elt)
             digest_name = crypto_digest_name(digest);
 
             bin_to_base64(digest_buf, BASE64_SIZE(size), md, size, true);
-
             if (strcmp(digest_buf, elt->chksum)) {
                Dmsg4(dbglvl,"%s      %s chksum  diff. Cat: %s File: %s\n",
                      fname,
@@ -440,6 +438,9 @@ static int check_checksum_diff(JCR *jcr, FF_PKT *ff_pkt, CurFile *elt)
                      elt->chksum,
                      digest_buf);
                ret = 1;
+
+            } else {
+               ret = 0;
             }
             free(digest_buf);
          }
@@ -656,12 +657,15 @@ bool accurate_check_file(JCR *jcr, FF_PKT *ff_pkt)
             if (ret == 1) {
                // checksum has changed, backup file normally
                stat = true;
-            } else if (ret == -1){
+
+            } else if (ret == -1) {
                stat = false;
                goto bail_out;
+
             } else {
                /* Checksum hasn't changed, we can backup only meta */
                ff_pkt->stat_update = true;
+               ff_pkt->accurate_chksum = elt.chksum; /* record the checksum to send it */
             }
          }
       } else if (!only_changed && !stat) {
index 9bb5435295aed2adb3401a279ba8020139257b96..1b21e688580ccf008077aa0b42b96faa20e9e625 100644 (file)
@@ -523,11 +523,17 @@ int save_file(JCR *jcr, FF_PKT *ff_pkt, bool top_level)
    }
 
    if (IS_FT_OBJECT(ff_pkt->type) || /* Meta data only for restore object */
-       ff_pkt->type == FT_DELETED || /* Meta data only for deleted files */
-       bctx.ff_pkt->stat_update) {   /* Only metadata changed for file */
+       ff_pkt->type == FT_DELETED){  /* Meta data only for deleted files */
       goto good_rtn;
    }
 
+   /* If we have only to update attributes, we need to send the checksum to fill
+    * the catalog correctly for the next job
+    */
+   if (ff_pkt->stat_update) {
+      has_file_data = false;
+   }
+
    /** Set up the encryption context and send the session data to the SD */
    if (has_file_data && jcr->crypto.pki_encrypt) {
       if (!crypto_session_send(jcr, sd)) {
@@ -553,6 +559,13 @@ int save_file(JCR *jcr, FF_PKT *ff_pkt, bool top_level)
       do_read = true;
    }
 
+   /* If we have only to update attributes, we need to send the checksum to fill
+    * the catalog correctly for the next job
+    */
+   if (ff_pkt->stat_update) {
+      do_read = false;
+   }
+
    if (ff_pkt->cmd_plugin && !ff_pkt->no_read) {
       do_read = true;
    }
@@ -1215,7 +1228,8 @@ bool encode_and_send_attributes(bctx_t &bctx)
       unstrip_path(ff_pkt);
    }
 
-   Dmsg2(300, ">stored: attr len=%d: %s\n", sd->msglen, sd->msg);
+   char b[1024];
+   Dmsg2(300, ">stored: attr len=%d: %s\n", sd->msglen, asciidump(sd->msg, sd->msglen, b, sizeof(b)));
    if (!stat && !jcr->is_job_canceled()) {
       Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
             sd->bstrerror());
index 0a3d936326abd45a764130d4b85f5d78fd9fa0e7..199822b76eece58eadcb35e783cbd4bff22f4fd9 100644 (file)
@@ -170,8 +170,8 @@ bRC_BACL BACL_Linux::os_restore_acl (JCR *jcr, int stream, char *content, uint32
  *
  * in/out - check API at bacl.h
  */
-bRC_BACL BACL_Linux::os_get_acl(JCR *jcr, BACL_type bacltype){
-
+bRC_BACL BACL_Linux::os_get_acl(JCR *jcr, BACL_type bacltype)
+{
    acl_t acl;
    acl_type_t acltype;
    char *acltext;
index e9ec5f9ae19b9dfd555dbf52a58639fcb106ae43..0f626192aec62095ecfda563d261f9a054165ce8 100644 (file)
@@ -258,10 +258,11 @@ bool crypto_terminate_digests(bctx_t &bctx)
       sd->msglen = size;
       sd->send();
       sd->signal(BNET_EOD);              /* end of checksum */
+
    }
 
    /** Terminate any digest and send it to Storage daemon */
-   if (bctx.digest) {
+   if (bctx.digest || ff_pkt->stat_update) {
       uint32_t size;
 
       sd->fsend("%ld %d 0", jcr->JobFiles, bctx.digest_stream);
@@ -274,9 +275,15 @@ bool crypto_terminate_digests(bctx_t &bctx)
          sd->msg = realloc_pool_memory(sd->msg, size);
       }
 
-      if (!crypto_digest_finalize(bctx.digest, (uint8_t *)sd->msg, &size)) {
-         Jmsg(jcr, M_FATAL, 0, _("An error occurred finalizing signing the stream.\n"));
-         return false;
+      if (ff_pkt->stat_update) {
+         /* The checksum comes from the accurate table and the format is in base64 */
+         size = base64_to_bin(sd->msg, sizeof_pool_memory(sd->msg), ff_pkt->accurate_chksum, strlen(ff_pkt->accurate_chksum));
+
+      } else {
+         if (!crypto_digest_finalize(bctx.digest, (uint8_t *)sd->msg, &size)) {
+            Jmsg(jcr, M_FATAL, 0, _("An error occurred finalizing signing the stream.\n"));
+            return false;
+         }
       }
 
       /* Keep the checksum if this file is a hardlink */
@@ -287,6 +294,7 @@ bool crypto_terminate_digests(bctx_t &bctx)
       sd->msglen = size;
       sd->send();
       sd->signal(BNET_EOD);              /* end of checksum */
+
    }
 
    /* Check if original file has a digest, and send it */
index 5cfb4e701d4ef9b678c36d7885b6c99183a28ca3..57181bfc2219230c3f8bf4f8bc62637420ec2611 100644 (file)
@@ -578,8 +578,13 @@ void do_restore(JCR *jcr)
           */
          jcr->num_files_examined++;
          rctx.extract = false;
+         rctx.update_attr = false;
          stat = CF_CORE;        /* By default, let Bacula's core handle it */
 
+         if (rctx.stream == STREAM_UNIX_ATTRIBUTE_UPDATE) {
+            rctx.update_attr = true; /* Some operations are possible, like ACL update */
+         }
+
          if (jcr->plugin) {
             stat = plugin_create_file(jcr, attr, &rctx.bfd, jcr->replace);
          }
@@ -922,11 +927,13 @@ void do_restore(JCR *jcr)
          /*
           * Do not restore ACLs when
           * a) The current file is not extracted
-          * b)     and it is not a directory (they are never "extracted")
-          * c)     and it is not a symlink (they are never "extracted")
-          * d) or the file name is empty
+          * b)     and it is not updated (only attributes)
+          * c)     and it is not a directory (they are never "extracted")
+          * d)     and it is not a symlink (they are never "extracted")
+          * e) or the file name is empty
           */
          if ((!rctx.extract &&
+              !rctx.update_attr &&
               jcr->last_type != FT_DIREND &&
               jcr->last_type != FT_LNK) ||
              (*jcr->last_fname == 0)) {
index 9de6795c885d8355aff7cd5fef00c93ef9e2494d..0634396a5b4c7a97fb2f8515c46b6142b88c4050 100644 (file)
@@ -58,6 +58,7 @@ struct r_ctx {
    int32_t type;                       /* file type FT_ */
    ATTR *attr;                         /* Pointer to attributes */
    bool extract;                       /* set when extracting */
+   bool update_attr;                   /* set when we update attributes, but no data */
    alist *delayed_streams;             /* streams that should be restored as last */
    worker *efs;                        /* Windows EFS worker thread */
    int32_t count;                      /* Debug count */
index 7915e6e0668681253cf69f23a839aeec02accb55..7e67984f5fe379c47e9be21ab54aea7d013822db 100644 (file)
@@ -86,6 +86,8 @@ const char *stream_to_ascii(int stream)
    switch (stream & STREAMMASK_TYPE) {
       case STREAM_UNIX_ATTRIBUTES:
          return _("Unix attributes");
+      case STREAM_UNIX_ATTRIBUTE_UPDATE:
+         return _("Unix attributes update");
       case STREAM_FILE_DATA:
          return _("File data");
       case STREAM_MD5_DIGEST:
index d2edcef3f962dbf5912c228c85798df01c1fe586..79ca579abe050221cf151731330d2a56ddb4e818 100644 (file)
@@ -155,6 +155,8 @@ struct FF_PKT {
    char *link;                        /* link if file linked */
    char *plugin;                      /* Current Options{Plugin=} name */
 
+   char *accurate_chksum;             /* keep the checksum from the accurate database */
+   
    /* Specific snapshot part */
    char *volume_path;                 /* volume path */
    char *snapshot_path;               /* snapshot path */
index c791e2b2d1ece9a054766ff1e1998c0eeaf46fbc..1c91f4daeb4168f3ab2bdf3437e6774e3cffea4a 100644 (file)
@@ -89,6 +89,8 @@ const char *stream_to_ascii(char *buf, int stream, int fi)
       stream &= STREAMMASK_TYPE;
       /* Stream was negative => all are continuation items */
       switch (stream) {
+      case STREAM_UNIX_ATTRIBUTE_UPDATE:
+         return _("contUATTRU");
       case STREAM_UNIX_ATTRIBUTES:
          return "contUATTR";
       case STREAM_FILE_DATA: