]> git.sur5r.net Git - bacula/bacula/commitdiff
Correct restore across volumes + document
authorKern Sibbald <kern@sibbald.com>
Wed, 28 Aug 2002 21:10:33 +0000 (21:10 +0000)
committerKern Sibbald <kern@sibbald.com>
Wed, 28 Aug 2002 21:10:33 +0000 (21:10 +0000)
git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@125 91ce42f0-d328-0410-95d8-f526ca767f89

bacula/src/dird/ua_server.c
bacula/src/lib/bnet.c
bacula/src/stored/bextract.c
bacula/src/stored/bls.c
bacula/src/stored/mount.c
bacula/src/stored/read.c
bacula/src/stored/stored_conf.c

index a5aa83324028a6151f13535719a201c99af4ce08..a2af20fc7a2d46e4dcb11a50a12eab92b150edd6 100644 (file)
@@ -80,6 +80,7 @@ static void *connect_thread(void *arg)
 
    pthread_detach(pthread_self());
 
+   /*  ****FIXME**** put # 5 on config parameter */
    bnet_thread_server(UA_port, 5, &ua_workq, handle_UA_client_request);
    return NULL;
 }
index 312edad2c7aa2ede2b143cd48242e3c52d7e973a..80b1a53cda0536d3585aceff7ebf6929254cb0f6 100644 (file)
@@ -281,7 +281,6 @@ bnet_send(BSOCK *bsock)
         bsock->b_errno = errno;
       }
       if (rc < 0) {
-        /************FIXME********* use Pmsg() **/
          Jmsg4(bsock->jcr, M_ERROR, 0, _("Write error sending to %s:%s:%d: ERR=%s\n"), 
               bsock->who, bsock->host, bsock->port,  bnet_strerror(bsock));
       } else {
@@ -348,11 +347,12 @@ static uint32_t *bget_host_ip(void *jcr, char *host)
    } else {
       /******FIXME***** use gethostbyname_r or mutex ****/
       if ((hp = gethostbyname(host)) == NULL) {
-         Pmsg2(0, "gethostbyname() for %s failed: ERR=%s\n", host, strerror(errno));
+         Jmsg2(jcr, M_ERROR, 0, "gethostbyname() for %s failed: ERR=%s\n", 
+              host, strerror(errno));
         return NULL;
       }
       if (hp->h_length != sizeof(inaddr.s_addr) || hp->h_addrtype != AF_INET) {
-          Jmsg2(jcr, M_WARNING, 0, _("gethostbyname() network address length error.\n\
+          Jmsg2(jcr, M_ERROR, 0, _("gethostbyname() network address length error.\n\
 Wanted %d got %d bytes for s_addr.\n"), sizeof(inaddr.s_addr), hp->h_length);
          return NULL;
       }
index f34ed129780cec9464aab8a33c6cb6ac1082ca2b..a0d24176869f0dbace87a52471237851cd1a9b03 100644 (file)
@@ -34,7 +34,7 @@
 
 static void do_extract(char *fname, char *prefix);
 static void print_ls_output(char *fname, char *link, int type, struct stat *statp);
-
+static void get_session_record(DEVICE *dev, DEV_RECORD *rec, SESSION_LABEL *sessrec);
 
 static DEVICE *dev = NULL;
 static int ofd = -1;
@@ -155,6 +155,30 @@ int main (int argc, char *argv[])
    }
    return 0;
 }
+
+/*
+ * Device got an error, attempt to analyse it
+ */
+static void display_error_status()
+{
+   uint32_t status;
+
+   Emsg0(M_ERROR, 0, dev->errmsg);
+   status_dev(dev, &status);
+   Dmsg1(20, "Device status: %x\n", status);
+   if (status & MT_EOD)
+      Emsg0(M_ERROR_TERM, 0, "Unexpected End of Data\n");
+   else if (status & MT_EOT)
+      Emsg0(M_ERROR_TERM, 0, "Unexpected End of Tape\n");
+   else if (status & MT_EOF)
+      Emsg0(M_ERROR_TERM, 0, "Unexpected End of File\n");
+   else if (status & MT_DR_OPEN)
+      Emsg0(M_ERROR_TERM, 0, "Tape Door is Open\n");
+   else if (!(status & MT_ONLINE))
+      Emsg0(M_ERROR_TERM, 0, "Unexpected Tape is Off-line\n");
+   else
+      Emsg2(M_ERROR_TERM, 0, "Read error on Record Header %s: %s\n", dev_name(dev), strerror(errno));
+}
   
 
 static void do_extract(char *devname, char *where)
@@ -228,13 +252,18 @@ static void do_extract(char *devname, char *where)
 
    for ( ;; ) {
       if (!read_block_from_device(dev, block)) {
-        uint32_t status;
          Dmsg1(500, "Main read record failed. rem=%d\n", rec->remainder);
         if (dev->state & ST_EOT) {
+           DEV_RECORD *record;
            if (!mount_next_read_volume(jcr, dev, block)) {
               break;
            }
-           continue;
+           record = new_record();
+           read_block_from_device(dev, block);
+           read_record_from_block(block, record);
+           get_session_record(dev, record, &sessrec);
+           free_record(record);
+           goto next_record;
         }
         if (dev->state & ST_EOF) {
            continue;                 /* try again */
@@ -242,75 +271,25 @@ static void do_extract(char *devname, char *where)
         if (dev->state & ST_SHORT) {
            continue;
         }
-         Pmsg0(0, "Read Record got a bad record\n");
-        status_dev(dev, &status);
-         Dmsg1(20, "Device status: %x\n", status);
-        if (status & MT_EOD)
-            Emsg0(M_ERROR_TERM, 0, "Unexpected End of Data\n");
-        else if (status & MT_EOT)
-            Emsg0(M_ERROR_TERM, 0, "Unexpected End of Tape\n");
-        else if (status & MT_EOF)
-            Emsg0(M_ERROR_TERM, 0, "Unexpected End of File\n");
-        else if (status & MT_DR_OPEN)
-            Emsg0(M_ERROR_TERM, 0, "Tape Door is Open\n");
-        else if (!(status & MT_ONLINE))
-            Emsg0(M_ERROR_TERM, 0, "Unexpected Tape is Off-line\n");
-        else
-            Emsg3(M_ERROR_TERM, 0, "Read error %d on Record Header %s: %s\n", 
-              status, dev_name(dev), strerror(errno));
+        display_error_status();
       }
 
+next_record:
       for (rec->state=0; !is_block_empty(rec); ) {
         if (!read_record_from_block(block, rec)) {
            break;
         }
 
-        /* This is no longer used */                
-        if (rec->VolSessionId == 0 && rec->VolSessionTime == 0) {
-            Emsg0(M_ERROR, 0, "Zero header record. This shouldn't happen.\n");
-           break;                       /* END OF FILE */
+        if (rec->FileIndex == EOM_LABEL) { /* end of tape? */
+            Dmsg0(40, "Get EOM LABEL\n");
+           rec->remainder = 0;
+           break;                         /* yes, get out */
         }
 
-        /* 
-         * Check for Start or End of Session Record 
-         *
-         */
+        /* Some sort of label? */ 
         if (rec->FileIndex < 0) {
-           char *rtype;
-           memset(&sessrec, 0, sizeof(sessrec));
-           switch (rec->FileIndex) {
-              case PRE_LABEL:
-                  rtype = "Fresh Volume Label";   
-                 break;
-              case VOL_LABEL:
-                  rtype = "Volume Label";
-                 unser_volume_label(dev, rec);
-                 break;
-              case SOS_LABEL:
-                  rtype = "Begin Session";
-                 unser_session_label(&sessrec, rec);
-                 break;
-              case EOS_LABEL:
-                  rtype = "End Session";
-                 break;
-              case EOM_LABEL:
-                  rtype = "End of Media";
-                 break;
-              default:
-                  rtype = "Unknown";
-                 break;
-           }
-           if (debug_level > 0) {
-               printf("%s Record: VolSessionId=%d VolSessionTime=%d JobId=%d DataLen=%d\n",
-                 rtype, rec->VolSessionId, rec->VolSessionTime, rec->Stream, rec->data_len);
-           }
-
-            Dmsg1(40, "Got label = %d\n", rec->FileIndex);
-           if (rec->FileIndex == EOM_LABEL) { /* end of tape? */
-               Dmsg0(40, "Get EOM LABEL\n");
-              break;                         /* yes, get out */
-           }
-           continue;                         /* ignore other labels */
+           get_session_record(dev, rec, &sessrec);
+           continue;
         } /* end if label record */
 
         /* Is this the file we want? */
@@ -529,6 +508,36 @@ static void print_ls_output(char *fname, char *link, int type, struct stat *stat
    fputs(buf, stdout);
 }
 
+static void get_session_record(DEVICE *dev, DEV_RECORD *rec, SESSION_LABEL *sessrec)
+{
+   char *rtype;
+   memset(sessrec, 0, sizeof(sessrec));
+   switch (rec->FileIndex) {
+      case PRE_LABEL:
+         rtype = "Fresh Volume Label";   
+        break;
+      case VOL_LABEL:
+         rtype = "Volume Label";
+        unser_volume_label(dev, rec);
+        break;
+      case SOS_LABEL:
+         rtype = "Begin Session";
+        unser_session_label(sessrec, rec);
+        break;
+      case EOS_LABEL:
+         rtype = "End Session";
+        break;
+      case EOM_LABEL:
+         rtype = "End of Media";
+        break;
+      default:
+         rtype = "Unknown";
+        break;
+   }
+   Dmsg5(10, "%s Record: VolSessionId=%d VolSessionTime=%d JobId=%d DataLen=%d\n",
+        rtype, rec->VolSessionId, rec->VolSessionTime, rec->Stream, rec->data_len);
+}
+
 /* Dummies to replace askdir.c */
 int    dir_get_volume_info(JCR *jcr) { return 1;}
 int    dir_find_next_appendable_volume(JCR *jcr) { return 1;}
index f8c40a3d003b89c26d594089225c3182309f6889..9c4c20f10605c3862f50fbdef82143a65e7d9bef 100644 (file)
@@ -34,6 +34,7 @@ static void do_ls(char *fname);
 static void print_ls_output(char *fname, char *link, int type, struct stat *statp);
 static void do_setup(char *infname);
 static void do_close();
+static void get_session_record(DEVICE *dev, DEV_RECORD *rec, SESSION_LABEL *sessrec);
 
 static DEVICE *dev;
 static int default_tape = FALSE;
@@ -244,7 +245,7 @@ static void do_setup(char *infname)
         *p = 0;
       }
    }
-   Dmsg2(10, "Device=%s, Vol=%s.\n", infname, VolName);
+   Dmsg2(000, "Device=%s, Vol=%s.\n", infname, VolName);
    dev = init_dev(NULL, infname);
    if (!dev) {
       Emsg1(M_FATAL, 0, "Cannot open %s\n", infname);
@@ -263,7 +264,7 @@ static void do_setup(char *infname)
    NumVolumes = 0;
    CurVolume = 1;
    for (p = VolName; p && *p; ) {
-      p = strchr(p, '^');
+      p = strchr(p, '|');
       if (p) {
         *p++ = 0;
       }
@@ -488,10 +489,22 @@ Warning, this Volume is a continuation of Volume %s\n",
       if (!read_block_from_device(dev, block)) {
          Dmsg0(20, "!read_record()\n");
         if (dev->state & ST_EOT) {
+           DEV_RECORD *record;
+            Dmsg3(000, "EOT. stat=%s blk=%d rem=%d\n", rec_state_to_str(rec), 
+                 block->BlockNumber, rec->remainder);
            if (!mount_next_volume(infname)) {
+               Dmsg3(000, "After mount next vol. stat=%s blk=%d rem=%d\n", rec_state_to_str(rec), 
+                 block->BlockNumber, rec->remainder);
               break;
            }
-           continue;
+            Dmsg3(000, "After mount next vol. stat=%s blk=%d rem=%d\n", rec_state_to_str(rec), 
+                 block->BlockNumber, rec->remainder);
+           record = new_record();
+           read_block_from_device(dev, block);
+           read_record_from_block(block, record);
+           get_session_record(dev, record, &sessrec);
+           free_record(record);
+           goto next_record;
         }
         if (dev->state & ST_EOF) {
             Emsg1(M_INFO, 0, "Got EOF on device %s\n", dev_name(dev));
@@ -509,12 +522,12 @@ Warning, this Volume is a continuation of Volume %s\n",
          Dmsg2(10, "Block: %d blen=%d\n", block->BlockNumber, block->block_len);
       }
 
+next_record:
       record = 0;
       for (rec->state=0; !is_block_empty(rec); ) {
         if (!read_record_from_block(block, rec)) {
             Dmsg3(10, "!read-break. stat=%s blk=%d rem=%d\n", rec_state_to_str(rec), 
                  block->BlockNumber, rec->remainder);
-//         rec->remainder = 0;
            break;
         }
          Dmsg3(10, "read-OK. stat=%s blk=%d rem=%d\n", rec_state_to_str(rec), 
@@ -537,56 +550,16 @@ Warning, this Volume is a continuation of Volume %s\n",
                  rec->data_len);
         }
 
-        /*  
-         * Check for End of File record (all zeros)
-         *    NOTE: this no longer exists
-         */
-        if (rec->VolSessionId == 0 && rec->VolSessionTime == 0) {
-            Emsg0(M_ERROR_TERM, 0, "Zero VolSessionId and VolSessionTime. This shouldn't happen\n");
+        if (rec->FileIndex == EOM_LABEL) { /* end of tape? */
+            Dmsg0(40, "Get EOM LABEL\n");
+           rec->remainder = 0;
+           break;                         /* yes, get out */
         }
 
-        /* 
-         * Check for Start or End of Session Record 
-         *
-         */
+        /* Some sort of label? */ 
         if (rec->FileIndex < 0) {
-           char *rtype;
-           memset(&sessrec, 0, sizeof(sessrec));
-           switch (rec->FileIndex) {
-              case PRE_LABEL:
-                  rtype = "Fresh Volume Label";   
-                 break;
-              case VOL_LABEL:
-                  rtype = "Volume Label";
-                 unser_volume_label(dev, rec);
-                 break;
-              case SOS_LABEL:
-                  rtype = "Begin Session";
-                 unser_session_label(&sessrec, rec);
-                 break;
-              case EOS_LABEL:
-                  rtype = "End Session";
-                 break;
-              case EOM_LABEL:
-                  rtype = "End of Media";
-                 break;
-              default:
-                  rtype = "Unknown";
-                 break;
-           }
-           if (debug_level > 0) {
-               printf("%s Record: VolSessionId=%d VolSessionTime=%d JobId=%d DataLen=%d\n",
-                 rtype, rec->VolSessionId, rec->VolSessionTime, rec->Stream, rec->data_len);
-           }
-
-            Dmsg1(40, "Got label = %d\n", rec->FileIndex);
-           if (rec->FileIndex == EOM_LABEL) { /* end of tape? */
-               Dmsg0(100, "EOM LABEL break\n");
-              rec->remainder = 0;
-              break;                         /* yes, get out */
-           }
-           rec->remainder = 0;
-            continue;              /* we don't want record, read next one */
+           get_session_record(dev, rec, &sessrec);
+           continue;
         } /* end if label record */
 
         /* 
@@ -684,6 +657,37 @@ static void print_ls_output(char *fname, char *link, int type, struct stat *stat
    fputs(buf, stdout);
 }
 
+static void get_session_record(DEVICE *dev, DEV_RECORD *rec, SESSION_LABEL *sessrec)
+{
+   char *rtype;
+   memset(sessrec, 0, sizeof(sessrec));
+   switch (rec->FileIndex) {
+      case PRE_LABEL:
+         rtype = "Fresh Volume Label";   
+        break;
+      case VOL_LABEL:
+         rtype = "Volume Label";
+        unser_volume_label(dev, rec);
+        break;
+      case SOS_LABEL:
+         rtype = "Begin Session";
+        unser_session_label(sessrec, rec);
+        break;
+      case EOS_LABEL:
+         rtype = "End Session";
+        break;
+      case EOM_LABEL:
+         rtype = "End of Media";
+        break;
+      default:
+         rtype = "Unknown";
+        break;
+   }
+   Dmsg5(10, "%s Record: VolSessionId=%d VolSessionTime=%d JobId=%d DataLen=%d\n",
+        rtype, rec->VolSessionId, rec->VolSessionTime, rec->Stream, rec->data_len);
+}
+
+
 /* Dummies to replace askdir.c */
 int    dir_get_volume_info(JCR *jcr) { return 1;}
 int    dir_find_next_appendable_volume(JCR *jcr) { return 1;}
index fea18a03c11c9eb209e207a00205437cf411fbfe..70879769f2070480bb886e7388492f935d34a555 100644 (file)
@@ -379,7 +379,7 @@ int mount_next_read_volume(JCR *jcr, DEVICE *dev, DEV_BLOCK *block)
       for (int i=1; i<jcr->CurVolume; i++) {
         vol = vol->next;
       }
-      strcpy(jcr->VolumeName, vol->VolumeName);
+      pm_strcpy(&jcr->VolumeName, vol->VolumeName);
       Dmsg1(400, "There is another volume %s.\n", jcr->VolumeName);
 
       close_dev(dev);
index 35e2abe6266ad201e3035fe6d27f97c88f070b22..b4037e813d3404b18897ebcd6a9daf31bfb5a09a 100644 (file)
@@ -29,6 +29,7 @@
 #include "stored.h"
 
 /* Forward referenced subroutines */
+static void get_session_record(DEVICE *dev, DEV_RECORD *rec, SESSION_LABEL *sessrec);
 
 /* Variables used by Child process */
 /* Global statistics */
@@ -113,10 +114,15 @@ int do_read_data(JCR *jcr)
       if (!read_block_from_device(dev, block)) {
          Dmsg1(500, "Main read record failed. rem=%d\n", rec->remainder);
         if (dev->state & ST_EOT) {
+           DEV_RECORD *record;
            if (!mount_next_read_volume(jcr, dev, block)) {
               break;
            }
-           continue;
+           record = new_record();
+           read_block_from_device(dev, block);
+           read_record_from_block(block, record);
+           get_session_record(dev, record, &sessrec);
+           free_record(record);
         }
         if (dev->state & ST_EOF) {
             Dmsg0(90, "Got End of File. Trying again ...\n");
@@ -139,45 +145,19 @@ int do_read_data(JCR *jcr)
          *  get all the data.
          */
 
+        if (rec->FileIndex == EOM_LABEL) { /* end of tape? */
+            Dmsg0(40, "Get EOM LABEL\n");
+           rec->remainder = 0;
+           break;                         /* yes, get out */
+        }
+
         /* Some sort of label? */ 
         if (rec->FileIndex < 0) {
-           char *rtype;
-           memset(&sessrec, 0, sizeof(sessrec));
-           switch (rec->FileIndex) {
-              case PRE_LABEL:
-                  rtype = "Fresh Volume Label";   
-                 break;
-              case VOL_LABEL:
-                  rtype = "Volume Label";
-                 unser_volume_label(dev, rec);
-                 break;
-              case SOS_LABEL:
-                  rtype = "Begin Session";
-                 unser_session_label(&sessrec, rec);
-                 break;
-              case EOS_LABEL:
-                  rtype = "End Session";
-                 break;
-              case EOM_LABEL:
-                  rtype = "End of Media";
-                 break;
-              default:
-                  rtype = "Unknown";
-                 break;
-           }
-            Dmsg5(10, "%s Record: VolSessionId=%d VolSessionTime=%d JobId=%d DataLen=%d\n",
-                 rtype, rec->VolSessionId, rec->VolSessionTime, rec->Stream, rec->data_len);
-
-            Dmsg1(40, "Got label = %d\n", rec->FileIndex);
-           if (rec->FileIndex == EOM_LABEL) { /* end of tape? */
-               Dmsg0(40, "Get EOM LABEL\n");
-              rec->remainder = 0;
-              break;                         /* yes, get out */
-           }
-           rec->remainder = 0;
-           continue;                         /* ignore other labels */
+           get_session_record(dev, rec, &sessrec);
+           continue;
         } /* end if label record */
 
+
         /* Match BSR against current record */
         if (jcr->bsr) {
            if (!match_bsr(jcr->bsr, rec, &dev->VolHdr, &sessrec)) {
@@ -246,3 +226,33 @@ int do_read_data(JCR *jcr)
    Dmsg0(30, "Done reading.\n");
    return ok ? 1 : 0;
 }
+
+static void get_session_record(DEVICE *dev, DEV_RECORD *rec, SESSION_LABEL *sessrec)
+{
+   char *rtype;
+   memset(sessrec, 0, sizeof(sessrec));
+   switch (rec->FileIndex) {
+      case PRE_LABEL:
+         rtype = "Fresh Volume Label";   
+        break;
+      case VOL_LABEL:
+         rtype = "Volume Label";
+        unser_volume_label(dev, rec);
+        break;
+      case SOS_LABEL:
+         rtype = "Begin Session";
+        unser_session_label(sessrec, rec);
+        break;
+      case EOS_LABEL:
+         rtype = "End Session";
+        break;
+      case EOM_LABEL:
+         rtype = "End of Media";
+        break;
+      default:
+         rtype = "Unknown";
+        break;
+   }
+   Dmsg5(10, "%s Record: VolSessionId=%d VolSessionTime=%d JobId=%d DataLen=%d\n",
+        rtype, rec->VolSessionId, rec->VolSessionTime, rec->Stream, rec->data_len);
+}
index c42bf4c392a47b52c5ba6ba32f98627fcf813bad..2ea9e4881b7a9ad4ba58caf976f49fc46475cd69 100644 (file)
@@ -61,7 +61,7 @@ static struct res_items store_items[] = {
    {"workingdirectory",      store_dir,  ITEM(res_store.working_directory), 0, ITEM_REQUIRED, 0},
    {"piddirectory",          store_dir,  ITEM(res_store.pid_directory), 0, ITEM_REQUIRED, 0},
    {"subsysdirectory",       store_dir,  ITEM(res_store.subsys_directory), 0, ITEM_REQUIRED, 0},
-   {"maximumconcurrentjobs", store_int,  ITEM(res_store.max_concurrent_jobs), 0, ITEM_DEFAULT, 1},
+   {"maximumconcurrentjobs", store_pint, ITEM(res_store.max_concurrent_jobs), 0, ITEM_DEFAULT, 2},
    {NULL, NULL, 0, 0, 0, 0} 
 };