]> git.ipfire.org Git - thirdparty/bacula.git/commitdiff
fix wrong "Last Volume Bytes" in VirtualFull
authorAlain Spineux <alain@baculasystems.com>
Tue, 6 Dec 2022 10:35:08 +0000 (11:35 +0100)
committerEric Bollengier <eric@baculasystems.com>
Thu, 14 Sep 2023 11:57:00 +0000 (13:57 +0200)
- the data was coming from the last volume that was READ instead
  of the last WTRITTEN one
- the problem don't show up in copy/migrate
- unify the code to retrieve this information for VF & MAC
  - extent get_job_volume_names() to also return the last written volume

bacula/src/cats/bdb.h
bacula/src/cats/protos.h
bacula/src/cats/sql_get.c
bacula/src/dird/backup.c
bacula/src/dird/mac.c
bacula/src/dird/ua_output.c
bacula/src/dird/vbackup.c

index 4de12cdd0b968ae037c97f65e92ac0cf2e9bc824..3e572f72c6e21cf3238f8b24ace1b5ae2bb63a58 100644 (file)
@@ -235,7 +235,8 @@ public:
    int bdb_get_client_record(JCR *jcr, CLIENT_DBR *cr);
    bool bdb_get_jobmedia_record(JCR *jcr, JOBMEDIA_DBR *jmr);
    bool bdb_get_job_record(JCR *jcr, JOB_DBR *jr);
-   int bdb_get_job_volume_names(JCR *jcr, JobId_t JobId, POOLMEM **VolumeNames);
+   int bdb_get_job_volume_names(JCR *jcr, JobId_t JobId, POOLMEM **VolumeNames,
+            char *LastVolumeName, int maxlen);
    bool bdb_get_file_attributes_record(JCR *jcr, char *fname, JOB_DBR *jr, FILE_DBR *fdbr);
    int bdb_get_fileset_record(JCR *jcr, FILESET_DBR *fsr);
    bool bdb_get_media_record(JCR *jcr, MEDIA_DBR *mr);
index 68675d7a7fd2f09bec88cb9a959d40f6580d9849..b8b33ce73dae5ca9e12fa7b465f4fdd594c52888 100644 (file)
@@ -217,8 +217,8 @@ void bdb_free_restoreobject_record(JCR *jcr, ROBJECT_DBR *rr);
            mdb->bdb_get_jobmedia_record(jcr, jmr)
 #define db_get_job_record(jcr, mdb, jr) \
            mdb->bdb_get_job_record(jcr, jr)
-#define db_get_job_volume_names(jcr, mdb, JobId, VolumeNames) \
-           mdb->bdb_get_job_volume_names(jcr, JobId, VolumeNames)
+#define db_get_job_volume_names(jcr, mdb, JobId, VolumeNames, LastVolumeName, maxlen) \
+           mdb->bdb_get_job_volume_names(jcr, JobId, VolumeNames, LastVolumeName, maxlen)
 #define db_get_file_attributes_record(jcr, mdb, fname, jr, fdbr) \
            mdb->bdb_get_file_attributes_record(jcr, fname, jr, fdbr)
 #define db_get_fileset_record(jcr, mdb, fsr) \
index 95a99ecbc236eed0f9a0acbc15fabb716b769568..c7632431f48e2fa108a7d7811deaa7de2c1660c8 100644 (file)
@@ -363,7 +363,8 @@ bool BDB::bdb_get_job_record(JCR *jcr, JOB_DBR *jr)
  *
  *  Returns: number of volumes on success
  */
-int BDB::bdb_get_job_volume_names(JCR *jcr, JobId_t JobId, POOLMEM **VolumeNames)
+int BDB::bdb_get_job_volume_names(JCR *jcr, JobId_t JobId, POOLMEM **VolumeNames,
+      char *LastVolumeName, int maxlen)
 {
    SQL_ROW row;
    char ed1[50];
@@ -379,7 +380,10 @@ int BDB::bdb_get_job_volume_names(JCR *jcr, JobId_t JobId, POOLMEM **VolumeNames
         "ORDER BY 2 ASC", edit_int64(JobId,ed1));
 
    Dmsg1(130, "VolNam=%s\n", cmd);
-   *VolumeNames[0] = 0;
+   *VolumeNames[0] = '\0';
+   if (LastVolumeName != NULL && maxlen>0) {
+      LastVolumeName[0] = '\0';
+   }
    if (QueryDB(jcr, cmd)) {
       Dmsg1(130, "Num rows=%d\n", sql_num_rows());
       if (sql_num_rows() <= 0) {
@@ -400,6 +404,9 @@ int BDB::bdb_get_job_volume_names(JCR *jcr, JobId_t JobId, POOLMEM **VolumeNames
                pm_strcat(VolumeNames, row[0]);
             }
          }
+         if (LastVolumeName != NULL && stat > 0) {
+            bstrncat(LastVolumeName, row[0], maxlen); /* remember the last written volume */
+         }
       }
       sql_free_result();
    } else {
index 33f5e66eb15a654f6e72420dfc2f9feb8b9f6fa9..2cc4c6a992b1b0e4d203a93cd768f7d854218a2f 100644 (file)
@@ -1117,7 +1117,7 @@ void backup_cleanup(JCR *jcr, int TermCode)
    bstrftimes_na(schedt, sizeof(schedt), jcr->jr.SchedTime);
    bstrftimes_na(sdt, sizeof(sdt), jcr->jr.StartTime);
    bstrftimes_na(edt, sizeof(edt), jcr->jr.EndTime);
-   if (!db_get_job_volume_names(jcr, jcr->db, jcr->jr.JobId, &jcr->VolumeName)) {
+   if (!db_get_job_volume_names(jcr, jcr->db, jcr->jr.JobId, &jcr->VolumeName, NULL, 0)) {
       /*
        * Note, if the job has erred, most likely it did not write any
        *  tape, so suppress this "error" message since in that case
index dcbaf7a471adefbb585bba475ef4dd0efc15f5e7..66b387bdebb6731c196d0013dd3ace75ed474fb0 100644 (file)
@@ -887,7 +887,8 @@ void mac_cleanup(JCR *jcr, int TermCode, int writeTermCode)
 
       update_bootstrap_file(wjcr);
 
-      if (!db_get_job_volume_names(wjcr, wjcr->db, wjcr->jr.JobId, &wjcr->VolumeName)) {
+      if (!db_get_job_volume_names(wjcr, wjcr->db, wjcr->jr.JobId, &wjcr->VolumeName,
+            mr.VolumeName, sizeof(mr.VolumeName))) {
          /*
           * Note, if the job has failed, most likely it did not write any
           *  tape, so suppress this "error" message since in that case
@@ -898,17 +899,8 @@ void mac_cleanup(JCR *jcr, int TermCode, int writeTermCode)
             Jmsg(jcr, M_ERROR, 0, "%s", db_strerror(wjcr->db));
          }
          wjcr->VolumeName[0] = 0;         /* none */
-      }
-
-      if (wjcr->VolumeName[0]) {
-         /* Find last volume name. Multiple vols are separated by | */
-         char *p = strrchr(wjcr->VolumeName, '|');
-         if (p) {
-            p++;                         /* skip | */
-         } else {
-            p = wjcr->VolumeName;     /* no |, take full name */
-         }
-         bstrncpy(mr.VolumeName, p, sizeof(mr.VolumeName));
+      } else {
+         /* retrieve the last volume record for the "Last Volume Bytes" */
          if (!db_get_media_record(jcr, jcr->db, &mr)) {
             Jmsg(jcr, M_WARNING, 0, _("Error getting Media record for Volume \"%s\": ERR=%s"),
                mr.VolumeName, db_strerror(jcr->db));
index 9af03dfee7e911f8f6046a76ef6198baddc9e850..f925a950a781205f31f2cf34e501561b74df317a 100644 (file)
@@ -858,7 +858,7 @@ static int do_list_cmd(UAContext *ua, const char *cmd, e_list_type llist)
                continue;
             }
             VolumeName = get_pool_memory(PM_FNAME);
-            n = db_get_job_volume_names(ua->jcr, ua->db, jobid, &VolumeName);
+            n = db_get_job_volume_names(ua->jcr, ua->db, jobid, &VolumeName, NULL, 0);
             ua->send_msg(_("Jobid %d used %d Volume(s): %s\n"), jobid, n, VolumeName);
             free_pool_memory(VolumeName);
             done = true;
index cf2fb769c7f801520df1bf423f55d58ba41bc522..c5efe17a7e9192d46eb8bd7e36247b60d7fdcba9 100644 (file)
@@ -497,13 +497,6 @@ void vbackup_cleanup(JCR *jcr, int TermCode)
          db_strerror(jcr->db));
    }
 
-   bstrncpy(mr.VolumeName, jcr->VolumeName, sizeof(mr.VolumeName));
-   if (!db_get_media_record(jcr, jcr->db, &mr)) {
-      Jmsg(jcr, M_WARNING, 0, _("Error getting Media record for Volume \"%s\": ERR=%s"),
-         mr.VolumeName, db_strerror(jcr->db));
-      jcr->setJobStatus(JS_ErrorTerminated);
-   }
-
    update_bootstrap_file(jcr);
 
    switch (jcr->JobStatus) {
@@ -535,7 +528,8 @@ void vbackup_cleanup(JCR *jcr, int TermCode)
    bstrftimes(schedt, sizeof(schedt), jcr->jr.SchedTime);
    bstrftimes(sdt, sizeof(sdt), jcr->jr.StartTime);
    bstrftimes(edt, sizeof(edt), jcr->jr.EndTime);
-   if (!db_get_job_volume_names(jcr, jcr->db, jcr->jr.JobId, &jcr->VolumeName)) {
+   if (!db_get_job_volume_names(jcr, jcr->db, jcr->jr.JobId, &jcr->VolumeName,
+         mr.VolumeName, sizeof(mr.VolumeName))) {
       /*
        * Note, if the job has erred, most likely it did not write any
        *  tape, so suppress this "error" message since in that case
@@ -546,6 +540,12 @@ void vbackup_cleanup(JCR *jcr, int TermCode)
          Jmsg(jcr, M_ERROR, 0, "%s", db_strerror(jcr->db));
       }
       jcr->VolumeName[0] = 0;         /* none */
+   } else {
+      if (!db_get_media_record(jcr, jcr->db, &mr)) {
+         Jmsg(jcr, M_WARNING, 0, _("Error getting Media record for Volume \"%s\": ERR=%s"),
+            mr.VolumeName, db_strerror(jcr->db));
+         jcr->setJobStatus(JS_ErrorTerminated);
+      }
    }
 
    jobstatus_to_ascii(jcr->SDJobStatus, sd_term_msg, sizeof(sd_term_msg));