From: Eric Bollengier Date: Wed, 24 Jan 2024 11:04:40 +0000 (+0100) Subject: Fix org#2704 about old FD compatibility X-Git-Tag: Release-13.0.4~8 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=32a1c1c59b43b01bed97aab2cc18315fe0a39a41;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 a42b17232..185c1c33b 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 @@ -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)); diff --git a/bacula/src/dird/getmsg.c b/bacula/src/dird/getmsg.c index 89e6b9778..c441fcf65 100644 --- a/bacula/src/dird/getmsg.c +++ b/bacula/src/dird/getmsg.c @@ -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; diff --git a/bacula/src/jcr.h b/bacula/src/jcr.h index 53038cf58..a0c5c1210 100644 --- a/bacula/src/jcr.h +++ b/bacula/src/jcr.h @@ -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 */