]> git.ipfire.org Git - thirdparty/bacula.git/commitdiff
Fix org#2704 about old FD compatibility
authorEric Bollengier <eric@baculasystems.com>
Wed, 24 Jan 2024 11:04:40 +0000 (12:04 +0100)
committerEric Bollengier <eric@baculasystems.com>
Tue, 30 Jan 2024 08:22:43 +0000 (09:22 +0100)
Old client (prior to 11.0.0) job messages are silently dropped from
the director logs. The Job status is correct, but the messages are
not displayed in the catalog or the bacula-dir.log.

The workaround is to enable the local log on each impacted FD,
or upgrade them to 13.0.x.

This fix will detect the client version and apply a fix dynamically
when getting a message.

bacula/src/dird/fd_cmds.c
bacula/src/dird/getmsg.c
bacula/src/jcr.h

index 2609b3e5b2e62805f68a64b4b019e57124cea89c..38fafeee8398705b94af59af45cb7a3bc2ba6140 100644 (file)
@@ -72,6 +72,34 @@ static void delete_bsock_end_cb(JCR *jcr, void *ctx)
    free_bsock(socket);
 }
 
+/* 16.0.10 (12Jan24) x86_64-pc-linux-gnu,ubuntu,20.04 -> 160010 */
+static uint64_t scan_version(char *str)
+{
+   Enter(0);
+   uint64_t version = 0;
+
+   regex_t r1;
+   regmatch_t pmatch[16];
+   regcomp(&r1, "^([0-9]+)\\.([0-9]+)\\.([0-9]+)", REG_EXTENDED);
+   if (regexec(&r1, str, 4, pmatch, 0) == 0 &&
+       pmatch[1].rm_so == 0 && pmatch[1].rm_eo > 0 && pmatch[1].rm_eo < 50 &&
+       pmatch[2].rm_so > 0 && pmatch[2].rm_eo > 0 && (pmatch[2].rm_eo - pmatch[2].rm_so) < 50 &&
+       pmatch[3].rm_so > 0 && pmatch[3].rm_eo > 0 && (pmatch[3].rm_eo - pmatch[3].rm_so) < 50)
+   {
+      char buf[50];
+      bstrncpy(buf, str + pmatch[1].rm_so, pmatch[1].rm_eo - pmatch[1].rm_so + 1);
+      version = str_to_uint64(buf) * 10000;
+
+      bstrncpy(buf, str + pmatch[2].rm_so, pmatch[2].rm_eo - pmatch[2].rm_so + 1);
+      version += str_to_uint64(buf) * 100;
+
+      bstrncpy(buf, str + pmatch[3].rm_so, pmatch[3].rm_eo - pmatch[3].rm_so + 1);
+      version += str_to_uint64(buf);
+   }
+   regfree(&r1);
+   return version;
+}
+
 /*
  * Open connection with File daemon.
  * Try connecting every retry_interval (default 10 sec), and
@@ -188,6 +216,7 @@ int connect_to_file_daemon(JCR *jcr, int retry_interval, int max_retry_time,
              bstrncpy(cr.Plugins, pos+1, sizeof(cr.Plugins));
           }
           bstrncpy(cr.Uname, fd->msg+strlen(OKjob)+1, sizeof(cr.Uname));
+          jcr->client_version = scan_version(cr.Uname);
 
           if (!db_update_client_record(jcr, jcr->db, &cr)) {
              Jmsg(jcr, M_WARNING, 0, _("[DE0028] Error updating Client record. ERR=%s\n"),
index 45f136ef59a83f614992c0d548252313b3103970..5d82dd214fe0fd0fac0491df22112e0d33b08aea 100644 (file)
@@ -250,6 +250,14 @@ int bget_dirmsg(JCR *jcr, BSOCK *bs, BSOCK_CLIENT_TYPE role)
          if (*msg == ' ') {
             msg++;                    /* skip leading space */
          }
+         /* Fix to support old FDs */
+         if (role == BSOCK_TYPE_FD && jcr->client_version > 0 && jcr->client_version < 130000) {
+            type = type + 1; /* Adding M_EVENTS pushed all old events by 1, we fix it automatically here */
+         }
+         if (type == M_ABORT) { // not allowed here
+            Jmsg1(jcr, M_ERROR, 0, _("Malformed message: %s\n"), bs->msg);
+            continue;
+         }
          Dmsg1(900, "Dispatch msg: %s", msg);
          dispatch_message(jcr, type, mtime, msg);
          continue;
index 53d50569ca518eb59268f19434ba1014053188a1..9c4798a5afe0dac7e189549182f15ce0900e0d06 100644 (file)
@@ -433,6 +433,7 @@ public:
    int32_t FDVersion;                 /* File daemon version number */
    int32_t SDVersion;                 /* Storage daemon version number */
    int64_t spool_size;                /* Spool size for this job */
+   uint64_t client_version;           /* Client version as a number */
    utime_t snapshot_retention;        /* Snapshot retention (from Client/Job resource) */
    volatile bool sd_msg_thread_done;  /* Set when Storage message thread done */
    bool wasVirtualFull;               /* set if job was VirtualFull */