]> 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:20:19 +0000 (09:20 +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 a42b1723214835ee63bc178d08cf2190106ca1b7..185c1c33be4c975b05dd60c65ee3c0eb25c3677e 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
@@ -195,6 +223,8 @@ int connect_to_file_daemon(JCR *jcr, int retry_interval, int max_retry_time,
           cr.FileRetention = jcr->client->FileRetention;
           cr.JobRetention = jcr->client->JobRetention;
           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, _("Error updating Client record. ERR=%s\n"),
                 db_strerror(jcr->db));
index 89e6b97785c883fe5b220579685653c201b1c4e3..c441fcf65e5102667db5cf13a7295e7b4eeb9013 100644 (file)
@@ -251,6 +251,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 53038cf5871a72e66aa0dab40b9dab9ab12802ba..a0c5c121060a26827f24d19d3cda3769df0a483c 100644 (file)
@@ -399,6 +399,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 */