]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/dird/bsr.c
Fix problem in BVFS with concurrent queries
[bacula/bacula] / bacula / src / dird / bsr.c
index fe38277f28a09dda07d11d9181ad6979730d711a..63d85b8745f56624b5c940be1545318eda9faebe 100644 (file)
@@ -1,12 +1,12 @@
 /*
    Bacula® - The Network Backup Solution
 
-   Copyright (C) 2002-2008 Free Software Foundation Europe e.V.
+   Copyright (C) 2002-2010 Free Software Foundation Europe e.V.
 
    The main author of Bacula is Kern Sibbald, with contributions from
    many others, a complete list can be found in the file AUTHORS.
    This program is Free Software; you can redistribute it and/or
-   modify it under the terms of version two of the GNU General Public
+   modify it under the terms of version three of the GNU Affero General Public
    License as published by the Free Software Foundation and included
    in the file LICENSE.
 
@@ -15,7 +15,7 @@
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
    General Public License for more details.
 
-   You should have received a copy of the GNU General Public License
+   You should have received a copy of the GNU Affero General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
@@ -34,7 +34,6 @@
  *
  *     Kern Sibbald, July MMII
  *
- *   Version $Id$
  */
 
 #include "bacula.h"
@@ -152,6 +151,9 @@ void free_bsr(RBSR *bsr)
       if (bsr->VolParams) {
          free(bsr->VolParams);
       }
+      if (bsr->fileregex) {
+         free(bsr->fileregex);
+      }
       next = bsr->next;
       free(bsr);
    }
@@ -173,6 +175,10 @@ bool complete_bsr(UAContext *ua, RBSR *bsr)
       }
       bsr->VolSessionId = jr.VolSessionId;
       bsr->VolSessionTime = jr.VolSessionTime;
+      if (jr.JobFiles == 0) {      /* zero files is OK, not an error, but */
+         bsr->VolCount = 0;        /*   there are no volumes */
+         continue;
+      }
       if ((bsr->VolCount=db_get_job_volume_parameters(ua->jcr, ua->db, bsr->JobId,
            &(bsr->VolParams))) == 0) {
          ua->error_msg(_("Unable to get Job Volume Parameters. ERR=%s\n"), db_strerror(ua->db));
@@ -251,14 +257,42 @@ bail_out:
    return count;
 }
 
-void display_bsr_info(UAContext *ua, RESTORE_CTX &rx)
+static void display_vol_info(UAContext *ua, RESTORE_CTX &rx, JobId_t JobId)
 {
-   char *p;
    POOL_MEM volmsg(PM_MESSAGE);
-   JobId_t JobId;
    char Device[MAX_NAME_LENGTH];
+   char online;
    RBSR *bsr;
 
+   for (bsr=rx.bsr; bsr; bsr=bsr->next) {
+      if (JobId && JobId != bsr->JobId) {
+         continue;
+      }
+
+      for (int i=0; i < bsr->VolCount; i++) {
+         if (bsr->VolParams[i].VolumeName[0]) {
+            if (!get_storage_device(Device, bsr->VolParams[i].Storage)) {
+               Device[0] = 0;
+            }
+            if (bsr->VolParams[i].InChanger && bsr->VolParams[i].Slot) {
+               online = '*';
+            } else {
+               online = ' ';
+            }
+            Mmsg(volmsg, "%c%-25s %-25s %-25s", 
+                 online, bsr->VolParams[i].VolumeName,
+                 bsr->VolParams[i].Storage, Device);
+            add_prompt(ua, volmsg.c_str());
+         }
+      }
+   }
+}
+
+void display_bsr_info(UAContext *ua, RESTORE_CTX &rx)
+{
+   char *p;
+   JobId_t JobId;
+
    /* Tell the user what he will need to mount */
    ua->send_msg("\n");
    ua->send_msg(_("The job will require the following\n"
@@ -268,38 +302,11 @@ void display_bsr_info(UAContext *ua, RESTORE_CTX &rx)
    start_prompt(ua, "");
    if (*rx.JobIds == 0) {
       /* Print Volumes in any order */
-      for (bsr=rx.bsr; bsr; bsr=bsr->next) {
-         for (int i=0; i < bsr->VolCount; i++) {
-            if (bsr->VolParams[i].VolumeName[0]) {
-               if (!get_storage_device(Device, bsr->VolParams[i].Storage)) {
-                  Device[0] = 0;
-               }
-               Mmsg(volmsg, "%-25.25s %-25.25s %-25.25s", 
-                    bsr->VolParams[i].VolumeName, 
-                    bsr->VolParams[i].Storage, Device);
-               add_prompt(ua, volmsg.c_str());
-            }
-         }
-      }
+      display_vol_info(ua, rx, 0);
    } else {
       /* Ensure that the volumes are printed in JobId order */
       for (p=rx.JobIds; get_next_jobid_from_list(&p, &JobId) > 0; ) {
-         for (bsr=rx.bsr; bsr; bsr=bsr->next) {
-            if (JobId != bsr->JobId) {
-               continue;
-            }
-            for (int i=0; i < bsr->VolCount; i++) {
-               if (bsr->VolParams[i].VolumeName[0]) {
-                  if (!get_storage_device(Device, bsr->VolParams[i].Storage)) {
-                     Device[0] = 0;
-                  }
-                  Mmsg(volmsg, "%-25.25s %-25.25s %-25.25s", 
-                       bsr->VolParams[i].VolumeName, 
-                       bsr->VolParams[i].Storage, Device);
-                  add_prompt(ua, volmsg.c_str());
-               }
-            }
-         }
+         display_vol_info(ua, rx, JobId);
       }
    }
    for (int i=0; i < ua->num_prompts; i++) {
@@ -308,6 +315,8 @@ void display_bsr_info(UAContext *ua, RESTORE_CTX &rx)
    }
    if (ua->num_prompts == 0) {
       ua->send_msg(_("No Volumes found to restore.\n"));
+   } else {
+      ua->send_msg(_("\nVolumes marked with \"*\" are online.\n"));
    }
    ua->num_prompts = 0;
    ua->send_msg("\n");
@@ -315,6 +324,70 @@ void display_bsr_info(UAContext *ua, RESTORE_CTX &rx)
    return;
 }
 
+/*
+ * Write bsr data for a single bsr record
+ */
+static uint32_t write_bsr_item(RBSR *bsr, UAContext *ua, 
+                   RESTORE_CTX &rx, FILE *fd, bool &first, uint32_t &LastIndex)
+{
+   char ed1[50], ed2[50];
+   uint32_t count = 0;
+   uint32_t total_count = 0;
+   char device[MAX_NAME_LENGTH];
+
+   /*
+    * For a given volume, loop over all the JobMedia records.
+    *   VolCount is the number of JobMedia records.
+    */
+   for (int i=0; i < bsr->VolCount; i++) {
+      if (!is_volume_selected(bsr->fi, bsr->VolParams[i].FirstIndex,
+           bsr->VolParams[i].LastIndex)) {
+         bsr->VolParams[i].VolumeName[0] = 0;  /* zap VolumeName */
+         continue;
+      }
+      if (!rx.store) {
+         find_storage_resource(ua, rx, bsr->VolParams[i].Storage,
+                                       bsr->VolParams[i].MediaType);
+      }
+      fprintf(fd, "Storage=\"%s\"\n", bsr->VolParams[i].Storage);
+      fprintf(fd, "Volume=\"%s\"\n", bsr->VolParams[i].VolumeName);
+      fprintf(fd, "MediaType=\"%s\"\n", bsr->VolParams[i].MediaType);
+      if (bsr->fileregex) {
+         fprintf(fd, "FileRegex=%s\n", bsr->fileregex);
+      }
+      if (get_storage_device(device, bsr->VolParams[i].Storage)) {
+         fprintf(fd, "Device=\"%s\"\n", device);
+      }
+      if (bsr->VolParams[i].Slot > 0) {
+         fprintf(fd, "Slot=%d\n", bsr->VolParams[i].Slot);
+      }
+      fprintf(fd, "VolSessionId=%u\n", bsr->VolSessionId);
+      fprintf(fd, "VolSessionTime=%u\n", bsr->VolSessionTime);
+      fprintf(fd, "VolAddr=%s-%s\n", edit_uint64(bsr->VolParams[i].StartAddr, ed1),
+              edit_uint64(bsr->VolParams[i].EndAddr, ed2));
+//    Dmsg2(100, "bsr VolParam FI=%u LI=%u\n",
+//      bsr->VolParams[i].FirstIndex, bsr->VolParams[i].LastIndex);
+
+      count = write_findex(bsr->fi, bsr->VolParams[i].FirstIndex,
+                           bsr->VolParams[i].LastIndex, fd);
+      if (count) {
+         fprintf(fd, "Count=%u\n", count);
+      }
+      total_count += count;
+      /* If the same file is present on two tapes or in two files
+       *   on a tape, it is a continuation, and should not be treated
+       *   twice in the totals.
+       */
+      if (!first && LastIndex == bsr->VolParams[i].FirstIndex) {
+         total_count--;
+      }
+      first = false;
+      LastIndex = bsr->VolParams[i].LastIndex;
+   }
+   return total_count;
+}
+
+
 /*
  * Here we actually write out the details of the bsr file.
  *  Note, there is one bsr for each JobId, but the bsr may
@@ -325,139 +398,22 @@ void display_bsr_info(UAContext *ua, RESTORE_CTX &rx)
  */
 static uint32_t write_bsr(UAContext *ua, RESTORE_CTX &rx, FILE *fd)
 {
-   uint32_t count = 0;
-   uint32_t total_count = 0;
-   uint32_t LastIndex = 0;
    bool first = true;
+   uint32_t LastIndex = 0;
+   uint32_t total_count = 0;
    char *p;
    JobId_t JobId;
-   char device[MAX_NAME_LENGTH];
    RBSR *bsr;
    if (*rx.JobIds == 0) {
       for (bsr=rx.bsr; bsr; bsr=bsr->next) {
-         /*
-          * For a given volume, loop over all the JobMedia records.
-          *   VolCount is the number of JobMedia records.
-          */
-         for (int i=0; i < bsr->VolCount; i++) {
-            if (!is_volume_selected(bsr->fi, bsr->VolParams[i].FirstIndex,
-                 bsr->VolParams[i].LastIndex)) {
-               bsr->VolParams[i].VolumeName[0] = 0;  /* zap VolumeName */
-               continue;
-            }
-            if (!rx.store) {
-               find_storage_resource(ua, rx, bsr->VolParams[i].Storage,
-                                             bsr->VolParams[i].MediaType);
-            }
-            fprintf(fd, "Volume=\"%s\"\n", bsr->VolParams[i].VolumeName);
-            fprintf(fd, "MediaType=\"%s\"\n", bsr->VolParams[i].MediaType);
-            if (bsr->fileregex) {
-               fprintf(fd, "FileRegex=%s\n", bsr->fileregex);
-            }
-            if (get_storage_device(device, bsr->VolParams[i].Storage)) {
-               fprintf(fd, "Device=\"%s\"\n", device);
-            }
-            if (bsr->VolParams[i].Slot > 0) {
-               fprintf(fd, "Slot=%d\n", bsr->VolParams[i].Slot);
-            }
-            fprintf(fd, "VolSessionId=%u\n", bsr->VolSessionId);
-            fprintf(fd, "VolSessionTime=%u\n", bsr->VolSessionTime);
-            if (bsr->VolParams[i].StartFile == bsr->VolParams[i].EndFile) {
-               fprintf(fd, "VolFile=%u\n", bsr->VolParams[i].StartFile);
-            } else {
-               fprintf(fd, "VolFile=%u-%u\n", bsr->VolParams[i].StartFile,
-                       bsr->VolParams[i].EndFile);
-            }
-            if (bsr->VolParams[i].StartBlock == bsr->VolParams[i].EndBlock) {
-               fprintf(fd, "VolBlock=%u\n", bsr->VolParams[i].StartBlock);
-            } else {
-               fprintf(fd, "VolBlock=%u-%u\n", bsr->VolParams[i].StartBlock,
-                       bsr->VolParams[i].EndBlock);
-            }
-   //       Dmsg2(100, "bsr VolParam FI=%u LI=%u\n",
-   //          bsr->VolParams[i].FirstIndex, bsr->VolParams[i].LastIndex);
-
-            count = write_findex(bsr->fi, bsr->VolParams[i].FirstIndex,
-                                 bsr->VolParams[i].LastIndex, fd);
-            if (count) {
-               fprintf(fd, "Count=%u\n", count);
-            }
-            total_count += count;
-            /* If the same file is present on two tapes or in two files
-             *   on a tape, it is a continuation, and should not be treated
-             *   twice in the totals.
-             */
-            if (!first && LastIndex == bsr->VolParams[i].FirstIndex) {
-               total_count--;
-            }
-            first = false;
-            LastIndex = bsr->VolParams[i].LastIndex;
-         }
+         total_count += write_bsr_item(bsr, ua, rx, fd, first, LastIndex);
       }
       return total_count;
    }
    for (p=rx.JobIds; get_next_jobid_from_list(&p, &JobId) > 0; ) {
       for (bsr=rx.bsr; bsr; bsr=bsr->next) {
-         if (JobId != bsr->JobId) {
-            continue;
-         }
-         /*
-          * For a given volume, loop over all the JobMedia records.
-          *   VolCount is the number of JobMedia records.
-          */
-         for (int i=0; i < bsr->VolCount; i++) {
-            if (!is_volume_selected(bsr->fi, bsr->VolParams[i].FirstIndex,
-                 bsr->VolParams[i].LastIndex)) {
-               bsr->VolParams[i].VolumeName[0] = 0;  /* zap VolumeName */
-               continue;
-            }
-            if (!rx.store) {
-               find_storage_resource(ua, rx, bsr->VolParams[i].Storage,
-                                             bsr->VolParams[i].MediaType);
-            }
-            fprintf(fd, "Volume=\"%s\"\n", bsr->VolParams[i].VolumeName);
-            fprintf(fd, "MediaType=\"%s\"\n", bsr->VolParams[i].MediaType);
-            if (bsr->fileregex) {
-               fprintf(fd, "FileRegex=%s\n", bsr->fileregex);
-            }
-            if (get_storage_device(device, bsr->VolParams[i].Storage)) {
-               fprintf(fd, "Device=\"%s\"\n", device);
-            }
-            if (bsr->VolParams[i].Slot > 0) {
-               fprintf(fd, "Slot=%d\n", bsr->VolParams[i].Slot);
-            }
-            fprintf(fd, "VolSessionId=%u\n", bsr->VolSessionId);
-            fprintf(fd, "VolSessionTime=%u\n", bsr->VolSessionTime);
-            if (bsr->VolParams[i].StartFile == bsr->VolParams[i].EndFile) {
-               fprintf(fd, "VolFile=%u\n", bsr->VolParams[i].StartFile);
-            } else {
-               fprintf(fd, "VolFile=%u-%u\n", bsr->VolParams[i].StartFile,
-                       bsr->VolParams[i].EndFile);
-            }
-            if (bsr->VolParams[i].StartBlock == bsr->VolParams[i].EndBlock) {
-               fprintf(fd, "VolBlock=%u\n", bsr->VolParams[i].StartBlock);
-            } else {
-               fprintf(fd, "VolBlock=%u-%u\n", bsr->VolParams[i].StartBlock,
-                       bsr->VolParams[i].EndBlock);
-            }
-   //       Dmsg2(100, "bsr VolParam FI=%u LI=%u\n",
-   //          bsr->VolParams[i].FirstIndex, bsr->VolParams[i].LastIndex);
-
-            count = write_findex(bsr->fi, bsr->VolParams[i].FirstIndex,
-                                 bsr->VolParams[i].LastIndex, fd);
-            if (count) {
-               fprintf(fd, "Count=%u\n", count);
-            }
-            total_count += count;
-            /* If the same file is present on two tapes or in two files
-             *   on a tape, it is a continuation, and should not be treated
-             *   twice in the totals.
-             */
-            if (!first && LastIndex == bsr->VolParams[i].FirstIndex) {
-               total_count--;
-            }
-            first = false;
-            LastIndex = bsr->VolParams[i].LastIndex;
+         if (JobId == bsr->JobId) {
+            total_count += write_bsr_item(bsr, ua, rx, fd, first, LastIndex);
          }
       }
    }
@@ -601,8 +557,15 @@ void add_findex_all(RBSR *bsr, uint32_t JobId)
          /* Add new JobId at end of chain */
          for (nbsr=bsr; nbsr->next; nbsr=nbsr->next)
             {  }
+
          nbsr->next = new_bsr();
          nbsr->next->JobId = JobId;
+
+         /* If we use regexp to restore, set it for each jobid */
+         if (bsr->fileregex) { 
+            nbsr->next->fileregex = bstrdup(bsr->fileregex);
+         }
+
          nbsr->next->fi = new_findex();
          nbsr->next->fi->findex = 1;
          nbsr->next->fi->findex2 = INT32_MAX;