]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/dird/bsr.c
Add heap stats to Dir and SD -- eliminate #ifdefs
[bacula/bacula] / bacula / src / dird / bsr.c
index e8e3508be5060263693fdee7098b7665c9c84916..88f89d162728e96ed2ccddab79b92e6000c4622d 100644 (file)
@@ -11,7 +11,7 @@
  */
 
 /*
-   Copyright (C) 2002-2003 Kern Sibbald and John Walker
+   Copyright (C) 2002-2004 Kern Sibbald and John Walker
 
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License as
@@ -34,8 +34,8 @@
 #include "dird.h"
 
 /* Forward referenced functions */
-static RBSR *sort_bsr(RBSR *bsr);
 static void write_bsr(UAContext *ua, RBSR *bsr, FILE *fd);
+void print_bsr(UAContext *ua, RBSR *bsr);
 
 
 /*
@@ -57,28 +57,70 @@ static void free_findex(RBSR_FINDEX *fi)
    }
 }
 
-static void write_findex(UAContext *ua, RBSR_FINDEX *fi, FILE *fd) 
+/*
+ * Our data structures were not designed completely
+ *  correctly, so the file indexes cover the full
+ *  range regardless of volume. The FirstIndex and LastIndex
+ *  passed in here are for the current volume, so when 
+ *  writing out the fi, constrain them to those values.
+ *
+ * We are called here once for each JobMedia record
+ *  for each Volume.
+ */
+static uint32_t write_findex(UAContext *ua, RBSR_FINDEX *fi, 
+             int32_t FirstIndex, int32_t LastIndex, FILE *fd) 
+{
+   uint32_t count = 0;
+   for ( ; fi; fi=fi->next) {
+      int32_t findex, findex2;
+      if ((fi->findex >= FirstIndex && fi->findex <= LastIndex) ||
+         (fi->findex2 >= FirstIndex && fi->findex2 <= LastIndex) ||
+         (fi->findex < FirstIndex && fi->findex2 > LastIndex)) {
+        findex = fi->findex < FirstIndex ? FirstIndex : fi->findex;
+        findex2 = fi->findex2 > LastIndex ? LastIndex : fi->findex2;
+        if (findex == findex2) {
+            fprintf(fd, "FileIndex=%d\n", findex);
+           count++;
+        } else {
+            fprintf(fd, "FileIndex=%d-%d\n", findex, findex2);
+           count += findex2 - findex + 1;
+        }
+      }
+   }
+   return count;
+}
+
+/*
+ * Find out if Volume defined with FirstIndex and LastIndex
+ *   falls within the range of selected files in the bsr.
+ */
+static bool is_volume_selected(RBSR_FINDEX *fi, 
+             int32_t FirstIndex, int32_t LastIndex) 
 {
    if (fi) {
-      if (fi->findex == fi->findex2) {
-         fprintf(fd, "FileIndex=%d\n", fi->findex);
-      } else {
-         fprintf(fd, "FileIndex=%d-%d\n", fi->findex, fi->findex2);
+      if ((fi->findex >= FirstIndex && fi->findex <= LastIndex) ||
+         (fi->findex2 >= FirstIndex && fi->findex2 <= LastIndex) ||
+         (fi->findex < FirstIndex && fi->findex2 > LastIndex)) {
+        return true;
       }
-      write_findex(ua, fi->next, fd);
+      return is_volume_selected(fi->next, FirstIndex, LastIndex);
    }
+   return false;
 }
 
 
+
 static void print_findex(UAContext *ua, RBSR_FINDEX *fi)
 {
-   if (fi) {
+   bsendmsg(ua, "fi=0x%lx\n", fi);
+   for ( ; fi; fi=fi->next) {
       if (fi->findex == fi->findex2) {
          bsendmsg(ua, "FileIndex=%d\n", fi->findex);
+//       Dmsg1(100, "FileIndex=%d\n", fi->findex);
       } else {
          bsendmsg(ua, "FileIndex=%d-%d\n", fi->findex, fi->findex2);
+//       Dmsg2(100, "FileIndex=%d-%d\n", fi->findex, fi->findex2);
       }
-      print_findex(ua, fi->next);
    }
 }
 
@@ -95,10 +137,10 @@ void free_bsr(RBSR *bsr)
 {
    if (bsr) {
       free_findex(bsr->fi);
-      free_bsr(bsr->next);
       if (bsr->VolParams) {
         free(bsr->VolParams);
       }
+      free_bsr(bsr->next);
       free(bsr);
    }
 }
@@ -109,9 +151,8 @@ void free_bsr(RBSR *bsr)
  */
 int complete_bsr(UAContext *ua, RBSR *bsr)
 {
-   JOB_DBR jr;
-
    if (bsr) {
+      JOB_DBR jr;
       memset(&jr, 0, sizeof(jr));
       jr.JobId = bsr->JobId;
       if (!db_get_job_record(ua->jcr, ua->db, &jr)) {
@@ -151,8 +192,6 @@ int write_bsr_file(UAContext *ua, RBSR *bsr)
       free_pool_memory(fname);
       return 0;
    }
-   /* Sort the bsr chain */
-   bsr = sort_bsr(bsr);
    /* Write them to file */
    write_bsr(ua, bsr, fd);
    stat = !ferror(fd);
@@ -166,51 +205,68 @@ int write_bsr_file(UAContext *ua, RBSR *bsr)
    start_prompt(ua, "");
    for (RBSR *nbsr=bsr; nbsr; nbsr=nbsr->next) {
       for (int i=0; i < nbsr->VolCount; i++) {
-        add_prompt(ua, nbsr->VolParams[i].VolumeName);
+        if (nbsr->VolParams[i].VolumeName[0]) {
+           add_prompt(ua, nbsr->VolParams[i].VolumeName);
+        }
       }
    }
    for (int i=0; i < ua->num_prompts; i++) {
       bsendmsg(ua, "   %s\n", ua->prompt[i]);
       free(ua->prompt[i]);
    }
+   if (ua->num_prompts == 0) {
+      bsendmsg(ua, _("No Volumes found to restore.\n"));
+      stat = 0;
+   }
    ua->num_prompts = 0;
    bsendmsg(ua, "\n");
    free_pool_memory(fname);
    return stat;
 }
 
-/*
- * First sort the bsr chain, then sort the VolParams   
- */
-static RBSR *sort_bsr(RBSR *bsr)
-{
-   if (!bsr) {
-      return bsr;
-   }
-   /* ****FIXME**** sort the bsr chain */
-   for (RBSR *nbsr=bsr; nbsr; nbsr=nbsr->next) {
-   }
-   return bsr;
-}
-
 static void write_bsr(UAContext *ua, RBSR *bsr, FILE *fd)
 {
    if (bsr) {
+      uint32_t count;
+      /*
+       * 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;
+        }
          fprintf(fd, "Volume=\"%s\"\n", bsr->VolParams[i].VolumeName);
          fprintf(fd, "VolSessionId=%u\n", bsr->VolSessionId);
          fprintf(fd, "VolSessionTime=%u\n", bsr->VolSessionTime);
-         fprintf(fd, "VolFile=%u-%u\n", bsr->VolParams[i].StartFile, 
-                bsr->VolParams[i].EndFile);
-         fprintf(fd, "VolBlock=%u-%u\n", bsr->VolParams[i].StartBlock,
-                bsr->VolParams[i].EndBlock);
-        write_findex(ua, bsr->fi, fd);
+        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, "VolFile=%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(ua, bsr->fi, bsr->VolParams[i].FirstIndex,
+                             bsr->VolParams[i].LastIndex, fd);
+        if (count) {
+            fprintf(fd, "Count=%u\n", count);
+        }
       }
       write_bsr(ua, bsr->next, fd);
    }
 }
 
-static void print_bsr(UAContext *ua, RBSR *bsr)
+void print_bsr(UAContext *ua, RBSR *bsr)
 {
    if (bsr) {
       for (int i=0; i < bsr->VolCount; i++) {
@@ -242,7 +298,7 @@ void add_findex(RBSR *bsr, uint32_t JobId, int32_t findex)
       return;                        /* probably a dummy directory */
    }
    
-   if (!bsr->fi) {                   /* if no FI add one */
+   if (bsr->fi == NULL) {            /* if no FI add one */
       /* This is the first FileIndex item in the chain */
       bsr->fi = new_findex();
       bsr->JobId = JobId;
@@ -273,7 +329,7 @@ void add_findex(RBSR *bsr, uint32_t JobId, int32_t findex)
    }
 
    /* 
-    * At this point, bsr points to bsr containing JobId,
+    * At this point, bsr points to bsr containing this JobId,
     *  and we are sure that there is at least one fi record.
     */
    lfi = fi = bsr->fi;
@@ -295,6 +351,10 @@ void add_findex(RBSR *bsr, uint32_t JobId, int32_t findex)
       if (findex == (fi->findex2 + 1)) {  /* extend up */
         RBSR_FINDEX *nfi;     
         fi->findex2 = findex;
+        /*
+         * If the following record contains one higher, merge its
+         *   file index by extending it up.
+         */
         if (fi->next && ((findex+1) == fi->next->findex)) { 
            nfi = fi->next;
            fi->findex2 = nfi->findex2;