From: Eric Bollengier Date: Wed, 24 Jan 2024 11:04:40 +0000 (+0100) Subject: Fix org#2704 about old FD compatibility X-Git-Tag: Beta-15.0.1~65 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0624c8ab68c273900a57446e40a6b5735d05b1b9;p=thirdparty%2Fbacula.git Fix org#2704 about old FD compatibility 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. --- diff --git a/bacula/src/dird/fd_cmds.c b/bacula/src/dird/fd_cmds.c index 2609b3e5b..38fafeee8 100644 --- a/bacula/src/dird/fd_cmds.c +++ b/bacula/src/dird/fd_cmds.c @@ -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"), diff --git a/bacula/src/dird/getmsg.c b/bacula/src/dird/getmsg.c index 45f136ef5..5d82dd214 100644 --- a/bacula/src/dird/getmsg.c +++ b/bacula/src/dird/getmsg.c @@ -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; diff --git a/bacula/src/jcr.h b/bacula/src/jcr.h index 53d50569c..9c4798a5a 100644 --- a/bacula/src/jcr.h +++ b/bacula/src/jcr.h @@ -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 */