]> git.sur5r.net Git - bacula/bacula/commitdiff
Second cut data spooling + fix yesterday's patch
authorKern Sibbald <kern@sibbald.com>
Mon, 8 Mar 2004 14:54:29 +0000 (14:54 +0000)
committerKern Sibbald <kern@sibbald.com>
Mon, 8 Mar 2004 14:54:29 +0000 (14:54 +0000)
git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@1115 91ce42f0-d328-0410-95d8-f526ca767f89

15 files changed:
bacula/autoconf/aclocal.m4
bacula/src/cats/sql_get.c
bacula/src/console/conio.c
bacula/src/stored/Makefile.in
bacula/src/stored/append.c
bacula/src/stored/bcopy.c
bacula/src/stored/block.c
bacula/src/stored/btape.c
bacula/src/stored/dev.h
bacula/src/stored/device.c
bacula/src/stored/label.c
bacula/src/stored/mount.c
bacula/src/stored/protos.h
bacula/src/stored/spool.c [new file with mode: 0644]
bacula/src/version.h

index 929c66a23bd98cba7dff288d58f97070bb4d011d..0ad0a8affb674a528ea2d54930fa56c2a84258be 100644 (file)
@@ -344,7 +344,6 @@ db_found=no
 AC_MSG_CHECKING(for MySQL support)
 AC_ARG_WITH(mysql,
 [
-Which DBMS do you want to use (please select only one):
   --with-mysql[=DIR]      Include MySQL support.  DIR is the MySQL base
                           install directory, default is to search through
                           a number of common places for the MySQL files.],
@@ -414,7 +413,6 @@ Which DBMS do you want to use (please select only one):
 
 AC_ARG_WITH(embedded-mysql,
 [
-Which DBMS do you want to use (please select only one):
   --with-embedded-mysql[=DIR] Include MySQL support.  DIR is the MySQL base
                           install directory, default is to search through
                           a number of common places for the MySQL files.],
@@ -492,7 +490,6 @@ db_found=no
 AC_MSG_CHECKING(for SQLite support)
 AC_ARG_WITH(sqlite,
 [
-Which DBMS do you want to use (please select only one):
   --with-sqlite[=DIR]     Include SQLite support.  DIR is the SQLite base
                           install directory, default is to search through
                           a number of common places for the SQLite files.],
@@ -630,7 +627,6 @@ fi
 AC_MSG_CHECKING(for Berkeley DB support)
 AC_ARG_WITH(berkeleydb,
 [
-Which DBMS do you want to use (please select only one):
   --with-berkeleydb[=DIR] Include Berkeley DB support.  DIR is the Berkeley DB base
                           install directory, default is to search through
                           a number of common places for the DB files.],
index d2d462489268d6a6d3b2d993c7e82424213eca1a..700b6ba63644b865fbb986349e5f9f700a5eee71 100644 (file)
@@ -799,7 +799,7 @@ int db_get_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr)
       Mmsg(&mdb->cmd, "SELECT MediaId,VolumeName,VolJobs,VolFiles,VolBlocks,"
          "VolBytes,VolMounts,VolErrors,VolWrites,MaxVolBytes,VolCapacityBytes,"
          "MediaType,VolStatus,PoolId,VolRetention,VolUseDuration,MaxVolJobs,MaxVolFiles,"
-         "Recycle,Slot,FirstWritten,LastWritten "
+         "Recycle,Slot,FirstWritten,LastWritten,InChanger "
          "FROM Media WHERE VolumeName='%s'", mr->VolumeName);
    }  
 
index 443ced781234ab5bbf757b0452aea9f37694fa7b..fee692718ece3edeeb8c5a5f3ec41c464c34c79e 100755 (executable)
@@ -988,6 +988,9 @@ void clrbrk()
 static void sigintcatcher(int sig)
 {
    brkflg++;
+   if (brkflg > 1) {
+      exit(1);
+   }
    signal(SIGINT, sigintcatcher);
 }
 
index 5cf75bbc4e151cc2a2ddcfb910b3f6163b4eb245..aa4105c50d5233fe0abb79c3d92d27c3e74aab6d 100644 (file)
@@ -22,44 +22,44 @@ SVRSRCS = stored.c autochanger.c acquire.c append.c \
          askdir.c authenticate.c \
          block.c butil.c dev.c \
          device.c dircmd.c fd_cmds.c job.c \
-         label.c match_bsr.c parse_bsr.c \
-         read.c read_record.c \
-         record.c status.c stored_conf.c mount.c
+         label.c match_bsr.c mount.c parse_bsr.c \
+         read.c read_record.c record.c \
+         spool.c status.c stored_conf.c
 SVROBJS = stored.o autochanger.o acquire.o append.o \
          askdir.o authenticate.o \
          block.o butil.o dev.o \
          device.o dircmd.o fd_cmds.o job.o \
          label.o match_bsr.o mount.o parse_bsr.o \
-         read.o read_record.o \
-         record.o status.o stored_conf.o
+         read.o read_record.o record.o \
+         spool.o status.o stored_conf.o
 
 # btape
 TAPESRCS = btape.c block.c butil.c dev.c device.c label.c \
           acquire.c mount.c record.c read_record.c \
-          stored_conf.c match_bsr.c parse_bsr.o
+          stored_conf.c match_bsr.c parse_bsr.c spool.c
 TAPEOBJS = btape.o block.o butil.o dev.o device.o label.o \
           autochanger.o acquire.o mount.o record.o read_record.o \
-          stored_conf.o match_bsr.o parse_bsr.o
+          stored_conf.o match_bsr.o parse_bsr.o spool.o
 
 # bls
 BLSOBJS = bls.o block.o butil.o device.o dev.o label.o match_bsr.o \
          autochanger.o acquire.o mount.o parse_bsr.o record.o  \
-         read_record.o stored_conf.o
+         read_record.o stored_conf.o spool.o
 
 # bextract
 BEXTOBJS = bextract.o block.o device.o dev.o label.o record.o \
           autochanger.o acquire.o mount.o match_bsr.o parse_bsr.o butil.o \
-          read_record.o stored_conf.o
+          read_record.o stored_conf.o spool.o
 
 # bscan
 SCNOBJS = bscan.o block.o device.o dev.o label.o \
          autochanger.o acquire.o mount.o record.o match_bsr.o parse_bsr.o \
-         butil.o read_record.o stored_conf.o
+         butil.o read_record.o stored_conf.o spool.o
 
 # bcopy
 COPYOBJS = bcopy.o block.o device.o dev.o label.o \
           autochanger.o acquire.o mount.o record.o match_bsr.o parse_bsr.o \
-          butil.o read_record.o stored_conf.o
+          butil.o read_record.o stored_conf.o spool.o
 
 
 
index 0f755ff493fc8a64f2cf2be0031690d84cb84221..b22d6cad9fc4945aa3c91e4a8b9e4348ebcfd198 100644 (file)
 static char OK_data[]    = "3000 OK data\n";
 
 /* Forward referenced functions */
-static bool are_attributes_spooled(JCR *jcr);
-static int begin_attribute_spool(JCR *jcr);
-static int discard_attribute_spool(JCR *jcr);
-static int commit_attribute_spool(JCR *jcr);
-static int open_data_spool_file(JCR *jcr);
-static int close_data_spool_file(JCR *jcr);
-static int begin_data_spool(JCR *jcr);
-static int discard_data_spool(JCR *jcr);
-static int commit_data_spool(JCR *jcr);
-
 
 /* 
  *  Append Data sent from File daemon  
@@ -192,7 +182,7 @@ int do_append_data(JCR *jcr)
         while (!write_record_to_block(block, &rec)) {
             Dmsg2(150, "!write_record_to_block data_len=%d rem=%d\n", rec.data_len,
                       rec.remainder);
-           if (!write_block_to_device(jcr, dev, block)) {
+           if (!write_block_to_device(jcr->dcr, block)) {
                Dmsg2(90, "Got write_block_to_dev error on device %s. %s\n",
                  dev_name(dev), strerror_dev(dev));
                Jmsg(jcr, M_FATAL, 0, _("Cannot fixup device error. %s\n"),
@@ -255,7 +245,7 @@ int do_append_data(JCR *jcr)
       }
       Dmsg0(90, "back from write_end_session_label()\n");
       /* Flush out final partial block of this session */
-      if (!write_block_to_device(jcr, dev, block)) {
+      if (!write_block_to_device(jcr->dcr, block)) {
          Dmsg0(100, _("Set ok=FALSE after write_block_to_device.\n"));
         set_jcr_job_status(jcr, JS_ErrorTerminated);
         ok = false;
@@ -287,97 +277,3 @@ int do_append_data(JCR *jcr)
    Dmsg1(100, "return from do_append_data() stat=%d\n", ok);
    return ok ? 1 : 0;
 }
-
-
-static int begin_data_spool(JCR *jcr)
-{
-   if (jcr->dcr->spool_data) {
-      return open_data_spool_file(jcr);
-   }
-   return 1;
-}
-
-static int discard_data_spool(JCR *jcr)
-{
-   if (jcr->dcr->spool_data && jcr->dcr->spool_fd >= 0) {
-      return close_data_spool_file(jcr);
-   }
-   return 1;
-}
-
-static int commit_data_spool(JCR *jcr)
-{
-   if (jcr->dcr->spool_data && jcr->dcr->spool_fd >= 0) {
-//     despool_data(jcr);
-      return close_data_spool_file(jcr);
-   }
-   return 1;
-}
-
-static void make_unique_data_spool_filename(JCR *jcr, POOLMEM **name)
-{
-   Mmsg(name, "%s/%s.data.spool.%s.%s", working_directory, my_name,
-      jcr->Job, jcr->device->hdr.name);
-}
-
-
-static int open_data_spool_file(JCR *jcr)
-{
-   POOLMEM *name  = get_pool_memory(PM_MESSAGE);
-   int spool_fd;
-
-   make_unique_data_spool_filename(jcr, &name);
-   if ((spool_fd = open(name, O_CREAT|O_TRUNC|O_RDWR|O_BINARY, 0640)) >= 0) {
-      jcr->dcr->spool_fd = spool_fd;
-      jcr->spool_attributes = true;
-   } else {
-      Jmsg(jcr, M_ERROR, 0, "open data spool file %s failed: ERR=%s\n", name, strerror(errno));
-      free_pool_memory(name);
-      return 0;
-    }
-    free_pool_memory(name);
-    return 1;
-}
-
-static int close_data_spool_file(JCR *jcr)
-{
-    POOLMEM *name  = get_pool_memory(PM_MESSAGE);
-
-    make_unique_data_spool_filename(jcr, &name);
-    close(jcr->dcr->spool_fd);
-    jcr->dcr->spool_fd = -1;
-    unlink(name);
-    free_pool_memory(name);
-    return 1;
-}
-
-
-static bool are_attributes_spooled(JCR *jcr)
-{
-   return jcr->spool_attributes && jcr->dir_bsock->spool_fd;
-}
-
-static int begin_attribute_spool(JCR *jcr)
-{
-   if (!jcr->no_attributes && jcr->spool_attributes) {
-      return open_spool_file(jcr, jcr->dir_bsock);
-   }
-   return 1;
-}
-
-static int discard_attribute_spool(JCR *jcr)
-{
-   if (are_attributes_spooled(jcr)) {
-      return close_spool_file(jcr, jcr->dir_bsock);
-   }
-   return 1;
-}
-
-static int commit_attribute_spool(JCR *jcr)
-{
-   if (are_attributes_spooled(jcr)) {
-      bnet_despool_to_bsock(jcr->dir_bsock);
-      return close_spool_file(jcr, jcr->dir_bsock);
-   }
-   return 1;
-}
index 73e79945a15beceacfac0ab43d23e9eba3727dfd..7d334c2ea804a898b1f9a17911a0f9459a7a4962 100644 (file)
@@ -167,7 +167,7 @@ int main (int argc, char *argv[])
    out_block = out_jcr->dcr->block;
 
    read_records(in_jcr, in_dev, record_cb, mount_next_read_volume);
-   if (!write_block_to_device(out_jcr, out_dev, out_block)) {
+   if (!write_block_to_device(out_jcr->dcr, out_block)) {
       Pmsg0(000, _("Write of last block failed.\n"));
    }
 
@@ -214,14 +214,14 @@ static int record_cb(JCR *in_jcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec
         while (!write_record_to_block(out_block, rec)) {
             Dmsg2(150, "!write_record_to_block data_len=%d rem=%d\n", rec->data_len,
                       rec->remainder);
-           if (!write_block_to_device(out_jcr, out_dev, out_block)) {
+           if (!write_block_to_device(out_jcr->dcr, out_block)) {
                Dmsg2(90, "Got write_block_to_dev error on device %s. %s\n",
                  dev_name(out_dev), strerror_dev(out_dev));
                Jmsg(out_jcr, M_FATAL, 0, _("Cannot fixup device error. %s\n"),
                     strerror_dev(out_dev));
            }
         }
-        if (!write_block_to_device(out_jcr, out_dev, out_block)) {
+        if (!write_block_to_device(out_jcr->dcr, out_block)) {
             Dmsg2(90, "Got write_block_to_dev error on device %s. %s\n",
               dev_name(out_dev), strerror_dev(out_dev));
             Jmsg(out_jcr, M_FATAL, 0, _("Cannot fixup device error. %s\n"),
@@ -244,7 +244,7 @@ static int record_cb(JCR *in_jcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec
    while (!write_record_to_block(out_block, rec)) {
       Dmsg2(150, "!write_record_to_block data_len=%d rem=%d\n", rec->data_len,
                 rec->remainder);
-      if (!write_block_to_device(out_jcr, out_dev, out_block)) {
+      if (!write_block_to_device(out_jcr->dcr, out_block)) {
          Dmsg2(90, "Got write_block_to_dev error on device %s. %s\n",
            dev_name(out_dev), strerror_dev(out_dev));
          Jmsg(out_jcr, M_FATAL, 0, _("Cannot fixup device error. %s\n"),
index 5a3edc52eeeb46d913d28a0c9f4aaa5b397d7e4d..5d2ba8b3bcd7e78a32b74e0852521db2725fb983 100644 (file)
@@ -177,7 +177,7 @@ void empty_block(DEV_BLOCK *block)
  * in the buffer should have already been reserved by
  * init_block.
  */
-static void ser_block_header(DEV_BLOCK *block)
+void ser_block_header(DEV_BLOCK *block)
 {
    ser_declare;
    uint32_t CheckSum = 0;
@@ -310,13 +310,20 @@ static int unser_block_header(JCR *jcr, DEVICE *dev, DEV_BLOCK *block)
  *       : 0 on failure
  *
  */
-int write_block_to_device(JCR *jcr, DEVICE *dev, DEV_BLOCK *block)
+int write_block_to_device(DCR *dcr, DEV_BLOCK *block)
 {
    int stat = 1;
-   DCR *dcr = jcr->dcr;
+   DEVICE *dev = dcr->dev;
+   JCR *jcr = dcr->jcr;
 
    lock_device(dev);
 
+   if (dcr->spooling) {
+      stat = write_block_to_spool_file(dcr, block);
+      unlock_device(dev);
+      return stat;
+   }
+
    /*
     * If a new volume has been mounted since our last write
     *  Create a JobMedia record for the previous volume written,
@@ -341,7 +348,7 @@ int write_block_to_device(JCR *jcr, DEVICE *dev, DEV_BLOCK *block)
       }
    }
 
-   if (!write_block_to_dev(jcr, dev, block)) {
+   if (!write_block_to_dev(dcr, block)) {
        stat = fixup_device_block_write_error(jcr, dev, block);
    }
 
@@ -355,13 +362,14 @@ int write_block_to_device(JCR *jcr, DEVICE *dev, DEV_BLOCK *block)
  *  Returns: 1 on success or EOT
  *          0 on hard error
  */
-int write_block_to_dev(JCR *jcr, DEVICE *dev, DEV_BLOCK *block)
+int write_block_to_dev(DCR *dcr, DEV_BLOCK *block)
 {
    ssize_t stat = 0;
    uint32_t wlen;                    /* length to write */
    int hit_max1, hit_max2;
    bool ok;
-   DCR *dcr = jcr->dcr;
+   DEVICE *dev = dcr->dev;
+   JCR *jcr = dcr->jcr;
 
 #ifdef NO_TAPE_WRITE_TEST
    empty_block(block);
index 62f19c87de5124ec5275593054aea7b55d681aba..ac7f24f2bea67fef914884e288d0971733f2b181 100644 (file)
@@ -629,7 +629,7 @@ static int re_read_block_test()
       Pmsg0(0, _("Error writing record to block.\n")); 
       goto bail_out;
    }
-   if (!write_block_to_dev(jcr, dev, block)) {
+   if (!write_block_to_dev(jcr->dcr, block)) {
       Pmsg0(0, _("Error writing block to device.\n")); 
       goto bail_out;
    } else {
@@ -640,7 +640,7 @@ static int re_read_block_test()
       Pmsg0(0, _("Error writing record to block.\n")); 
       goto bail_out;
    }
-   if (!write_block_to_dev(jcr, dev, block)) {
+   if (!write_block_to_dev(jcr->dcr, block)) {
       Pmsg0(0, _("Error writing block to device.\n")); 
       goto bail_out;
    } else {
@@ -651,7 +651,7 @@ static int re_read_block_test()
       Pmsg0(0, _("Error writing record to block.\n")); 
       goto bail_out;
    }
-   if (!write_block_to_dev(jcr, dev, block)) {
+   if (!write_block_to_dev(jcr->dcr, block)) {
       Pmsg0(0, _("Error writing block to device.\n")); 
       goto bail_out;
    } else {
@@ -748,7 +748,7 @@ static int write_read_test()
          Pmsg0(0, _("Error writing record to block.\n")); 
         goto bail_out;
       }
-      if (!write_block_to_dev(jcr, dev, block)) {
+      if (!write_block_to_dev(jcr->dcr, block)) {
          Pmsg0(0, _("Error writing block to device.\n")); 
         goto bail_out;
       }
@@ -764,7 +764,7 @@ static int write_read_test()
          Pmsg0(0, _("Error writing record to block.\n")); 
         goto bail_out;
       }
-      if (!write_block_to_dev(jcr, dev, block)) {
+      if (!write_block_to_dev(jcr->dcr, block)) {
          Pmsg0(0, _("Error writing block to device.\n")); 
         goto bail_out;
       }
@@ -856,7 +856,7 @@ static int position_test()
          Pmsg0(0, _("Error writing record to block.\n")); 
         goto bail_out;
       }
-      if (!write_block_to_dev(jcr, dev, block)) {
+      if (!write_block_to_dev(jcr->dcr, block)) {
          Pmsg0(0, _("Error writing block to device.\n")); 
         goto bail_out;
       }
@@ -872,7 +872,7 @@ static int position_test()
          Pmsg0(0, _("Error writing record to block.\n")); 
         goto bail_out;
       }
-      if (!write_block_to_dev(jcr, dev, block)) {
+      if (!write_block_to_dev(jcr->dcr, block)) {
          Pmsg0(0, _("Error writing block to device.\n")); 
         goto bail_out;
       }
@@ -1421,7 +1421,7 @@ static void wrcmd()
       Pmsg0(0, _("Error writing record to block.\n")); 
       goto bail_out;
    }
-   if (!write_block_to_dev(jcr, dev, block)) {
+   if (!write_block_to_dev(jcr->dcr, block)) {
       Pmsg0(0, _("Error writing block to device.\n")); 
       goto bail_out;
    } else {
@@ -1831,7 +1831,7 @@ This may take a long time -- hours! ...\n\n");
         ok = FALSE;
       }
       /* Write out final block of this session */
-      if (!write_block_to_device(jcr, dev, block)) {
+      if (!write_block_to_device(jcr->dcr, block)) {
          Pmsg0(-1, _("Set ok=FALSE after write_block_to_device.\n"));
         ok = FALSE;
       }
@@ -2136,7 +2136,7 @@ static int flush_block(DEV_BLOCK *block, int dump)
    /* Copy block */
    this_file = dev->file;
    this_block_num = dev->block_num;
-   if (!write_block_to_dev(jcr, dev, block)) {
+   if (!write_block_to_dev(jcr->dcr, block)) {
       Pmsg3(000, "Last block at: %u:%u this_dev_block_num=%d\n", 
                  last_file, last_block_num, this_block_num);
       if (vol_num == 1) {
@@ -2247,7 +2247,7 @@ static void qfillcmd()
          Pmsg0(0, _("Error writing record to block.\n")); 
         goto bail_out;
       }
-      if (!write_block_to_dev(jcr, dev, block)) {
+      if (!write_block_to_dev(jcr->dcr, block)) {
          Pmsg0(0, _("Error writing block to device.\n")); 
         goto bail_out;
       }
@@ -2350,7 +2350,7 @@ static void bfill_cmd()
       *p = block_num;
       block->binbuf = block->buf_len;
       block->bufp = block->buf + block->binbuf;
-      if (!write_block_to_dev(jcr, dev, block)) {
+      if (!write_block_to_dev(jcr->dcr, block)) {
         break;
       }
       if ((block_num++ % 100) == 0) {
index 941b5112ca68ef01255c064b4f24c89d4ed2d83a..7c12595e41442b637b58c4ab3235f0df1caa4dae 100644 (file)
@@ -220,6 +220,7 @@ struct DCR {
    DEV_BLOCK *block;                 /* pointer to block */
    DEV_RECORD *record;               /* pointer to record */
    bool spool_data;                  /* set to spool data */
+   bool spooling;                    /* set when actually spooling */
    int spool_fd;                     /* fd if spooling */
    bool NewVol;                      /* set if new Volume mounted */
    bool WroteVol;                    /* set if Volume written */
index 3351c87ecbf718c12ba1ee00c72404749d126718..b6a7c9518e5533fee0e228433a327530952d9998 100644 (file)
@@ -147,7 +147,7 @@ int fixup_device_block_write_error(JCR *jcr, DEVICE *dev, DEV_BLOCK *block)
     *  empty label_blk, and nothing will be written.
     */
    Dmsg0(190, "write label block to dev\n");
-   if (!write_block_to_dev(jcr, dev, label_blk)) {
+   if (!write_block_to_dev(jcr->dcr, label_blk)) {
       Pmsg1(0, "write_block_to_device Volume label failed. ERR=%s",
        strerror_dev(dev));
       free_block(label_blk);
@@ -179,7 +179,7 @@ int fixup_device_block_write_error(JCR *jcr, DEVICE *dev, DEV_BLOCK *block)
 
    /* Write overflow block to device */
    Dmsg0(190, "Write overflow block to dev\n");
-   if (!write_block_to_dev(jcr, dev, block)) {
+   if (!write_block_to_dev(jcr->dcr, block)) {
       Pmsg1(0, "write_block_to_device overflow block failed. ERR=%s",
        strerror_dev(dev));
       unblock_device(dev);
index e1d5aa609f1b6c68638eb9d437a1a8eeb9b35695..c13debe43a9217f2daa0df68e5c0e5aaaf409778 100644 (file)
@@ -417,8 +417,8 @@ int write_volume_label_to_dev(JCR *jcr, DEVRES *device, char *VolName, char *Poo
    }
    free_pool_memory(rec.data);
       
-   Dmsg0(99, "Call write_block_to_device()\n");
-   if (!write_block_to_dev(jcr, dev, block)) {
+   Dmsg0(99, "Call write_block_to_dev()\n");
+   if (!write_block_to_dev(jcr->dcr, block)) {
       memset(&dev->VolHdr, 0, sizeof(dev->VolHdr));
       Dmsg2(30, "Bad Label write on %s. ERR=%s\n", dev_name(dev), strerror_dev(dev));
       stat = 9;
@@ -537,7 +537,7 @@ int write_session_label(JCR *jcr, DEV_BLOCK *block, int label)
     */
    if (!can_write_record_to_block(block, rec)) {
       Dmsg0(100, "Cannot write session label to block.\n");
-      if (!write_block_to_device(jcr, dev, block)) {
+      if (!write_block_to_device(jcr->dcr, block)) {
          Dmsg0(90, "Got session label write_block_to_dev error.\n");
          Jmsg(jcr, M_FATAL, 0, _("Error writing Session label to %s: %s\n"), 
                           dev_vol_name(dev), strerror(errno));
index ced3c8ea71424914ba40d7451246d08521380662..ad97db1dc1785cc7e523c9892e569b646d3d4931 100644 (file)
@@ -285,7 +285,7 @@ read_volume:
            }
         }
         /* Attempt write to check write permission */
-        if (!write_block_to_dev(jcr, dev, block)) {
+        if (!write_block_to_dev(jcr->dcr, block)) {
             Jmsg2(jcr, M_ERROR, 0, _("Unable to write device \"%s\". ERR=%s\n"),
               dev_name(dev), strerror_dev(dev));
            goto mount_next_vol;
index f4c377604701ba2c6aa17eb8967d160412a2a892..8c25d835455fb5bd8fc89f5eea9cf70ac4941d7f 100644 (file)
@@ -59,9 +59,10 @@ DEV_BLOCK *dup_block(DEV_BLOCK *eblock);
 void   init_block_write(DEV_BLOCK *block);
 void   empty_block(DEV_BLOCK *block);
 void   free_block(DEV_BLOCK *block);
-int    write_block_to_device(JCR *jcr, DEVICE *dev, DEV_BLOCK *block);
-int    write_block_to_dev(JCR *jcr, DEVICE *dev, DEV_BLOCK *block);
+int    write_block_to_device(DCR *dcr, DEV_BLOCK *block);
+int    write_block_to_dev(DCR *dcr, DEV_BLOCK *block);
 void   print_block_read_errors(JCR *jcr, DEV_BLOCK *block);
+void   ser_block_header(DEV_BLOCK *block);
 
 #define CHECK_BLOCK_NUMBERS    true
 #define NO_BLOCK_NUMBER_CHECK  false
@@ -197,3 +198,13 @@ void        free_record(DEV_RECORD *rec);
 int read_records(JCR *jcr,  DEVICE *dev, 
        int record_cb(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec),
        int mount_cb(JCR *jcr, DEVICE *dev, DEV_BLOCK *block));
+
+/* From spool.c */
+int begin_data_spool(JCR *jcr);
+int discard_data_spool(JCR *jcr);
+int commit_data_spool(JCR *jcr);
+bool are_attributes_spooled(JCR *jcr);
+int begin_attribute_spool(JCR *jcr);
+int discard_attribute_spool(JCR *jcr);
+int commit_attribute_spool(JCR *jcr);
+bool write_block_to_spool_file(DCR *dcr, DEV_BLOCK *block);
diff --git a/bacula/src/stored/spool.c b/bacula/src/stored/spool.c
new file mode 100644 (file)
index 0000000..d825963
--- /dev/null
@@ -0,0 +1,240 @@
+/*
+ *  Spooling code 
+ *
+ *     Kern Sibbald, March 2004
+ *
+ *  Version $Id$
+ */
+/*
+   Copyright (C) 2000-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
+   published by the Free Software Foundation; either version 2 of
+   the License, or (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   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 along with this program; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+   MA 02111-1307, USA.
+
+ */
+
+#include "bacula.h"
+#include "stored.h"
+
+/* Forward referenced subroutines */
+static void make_unique_data_spool_filename(JCR *jcr, POOLMEM **name);
+static int open_data_spool_file(JCR *jcr);
+static int close_data_spool_file(JCR *jcr);
+static bool despool_data(DCR *dcr);
+
+
+int begin_data_spool(JCR *jcr)
+{
+   if (jcr->dcr->spool_data) {
+      return open_data_spool_file(jcr);
+   }
+   return 1;
+}
+
+int discard_data_spool(JCR *jcr)
+{
+   if (jcr->dcr->spool_data && jcr->dcr->spool_fd >= 0) {
+      return close_data_spool_file(jcr);
+   }
+   return 1;
+}
+
+int commit_data_spool(JCR *jcr)
+{
+   bool stat;
+   if (jcr->dcr->spool_data && jcr->dcr->spool_fd >= 0) {
+      lock_device(jcr->dcr->dev);
+      stat = despool_data(jcr->dcr);
+      unlock_device(jcr->dcr->dev);
+      if (!stat) {
+        close_data_spool_file(jcr);
+        return 0;
+      }
+      return close_data_spool_file(jcr);
+   }
+   return 1;
+}
+
+static void make_unique_data_spool_filename(JCR *jcr, POOLMEM **name)
+{
+   Mmsg(name, "%s/%s.data.spool.%s.%s", working_directory, my_name,
+      jcr->Job, jcr->device->hdr.name);
+}
+
+
+static int open_data_spool_file(JCR *jcr)
+{
+   POOLMEM *name  = get_pool_memory(PM_MESSAGE);
+   int spool_fd;
+
+   make_unique_data_spool_filename(jcr, &name);
+   if ((spool_fd = open(name, O_CREAT|O_TRUNC|O_RDWR|O_BINARY, 0640)) >= 0) {
+      jcr->dcr->spool_fd = spool_fd;
+      jcr->spool_attributes = true;
+   } else {
+      Jmsg(jcr, M_ERROR, 0, "open data spool file %s failed: ERR=%s\n", name, strerror(errno));
+      free_pool_memory(name);
+      return 0;
+    }
+    free_pool_memory(name);
+    return 1;
+}
+
+static int close_data_spool_file(JCR *jcr)
+{
+    POOLMEM *name  = get_pool_memory(PM_MESSAGE);
+
+    make_unique_data_spool_filename(jcr, &name);
+    close(jcr->dcr->spool_fd);
+    jcr->dcr->spool_fd = -1;
+    unlink(name);
+    free_pool_memory(name);
+    return 1;
+}
+
+static bool despool_data(DCR *dcr)
+{
+   DEVICE *sdev;
+   DCR *sdcr;
+   dcr->spooling = false;
+   bool ok = true;
+   DEV_BLOCK *block = dcr->block;
+   JCR *jcr = dcr->jcr;
+
+   /* Set up a dev structure to read */
+   sdev = (DEVICE *)malloc(sizeof(DEVICE));
+   memset(sdev, 0, sizeof(DEVICE));
+   sdev->fd = dcr->spool_fd;
+   lseek(sdev->fd, 0, SEEK_SET); /* rewind */
+   sdcr = new_dcr(jcr, sdev);
+   for ( ; ok; ) {
+      if (job_canceled(jcr)) {
+        ok = false;
+        break;
+      }
+      if (!read_block_from_dev(jcr, sdev, block, CHECK_BLOCK_NUMBERS)) {
+        if (dev_state(sdev, ST_EOT)) {
+           break;
+        }
+        ok = false;
+        break;
+      }
+      if (!write_block_to_dev(dcr, block)) {
+        ok = false;
+        break;
+      }
+   }
+   lseek(sdev->fd, 0, SEEK_SET); /* rewind */
+   if (ftruncate(sdev->fd, 0) != 0) {
+      ok = false;
+   }
+   return ok;
+}
+
+/*
+ * Write a block to the spool file
+ *
+ *  Returns: true on success or EOT
+ *          false on hard error
+ */
+bool write_block_to_spool_file(DCR *dcr, DEV_BLOCK *block)
+{
+   ssize_t stat = 0;
+   uint32_t wlen;                    /* length to write */
+   DEVICE *dev = dcr->dev;
+   int retry = 0;
+
+   ASSERT(block->binbuf == ((uint32_t) (block->bufp - block->buf)));
+
+   wlen = block->binbuf;
+   if (wlen <= WRITE_BLKHDR_LENGTH) {  /* Does block have data in it? */
+      Dmsg0(100, "return write_block_to_dev no data to write\n");
+      return true;
+   }
+   /* 
+    * Clear to the end of the buffer if it is not full,
+    *  and on tape devices, apply min and fixed blocking.
+    */
+   if (wlen != block->buf_len) {
+      uint32_t blen;                 /* current buffer length */
+
+      Dmsg2(200, "binbuf=%d buf_len=%d\n", block->binbuf, block->buf_len);
+      blen = wlen;
+
+      /* Adjust write size to min/max for tapes only */
+      if (dev->state & ST_TAPE) {
+        if (wlen < dev->min_block_size) {
+           wlen =  ((dev->min_block_size + TAPE_BSIZE - 1) / TAPE_BSIZE) * TAPE_BSIZE;
+        }
+        /* check for fixed block size */
+        if (dev->min_block_size == dev->max_block_size) {
+           wlen = block->buf_len;    /* fixed block size already rounded */
+        }
+      }
+      if (wlen-blen > 0) {
+        memset(block->bufp, 0, wlen-blen); /* clear garbage */
+      }
+   }  
+
+   ser_block_header(block);
+
+   Dmsg1(300, "Write block of %u bytes\n", wlen);      
+write_again:
+   stat = write(dcr->spool_fd, block->buf, (size_t)wlen);
+   if (stat != (ssize_t)wlen) {
+      if (!despool_data(dcr)) {
+        return false;
+      }
+      if (retry++ > 1) {
+        return false;
+      }
+      goto write_again;
+   }
+
+   empty_block(block);
+   return true;
+}
+
+
+
+bool are_attributes_spooled(JCR *jcr)
+{
+   return jcr->spool_attributes && jcr->dir_bsock->spool_fd;
+}
+
+int begin_attribute_spool(JCR *jcr)
+{
+   if (!jcr->no_attributes && jcr->spool_attributes) {
+      return open_spool_file(jcr, jcr->dir_bsock);
+   }
+   return 1;
+}
+
+int discard_attribute_spool(JCR *jcr)
+{
+   if (are_attributes_spooled(jcr)) {
+      return close_spool_file(jcr, jcr->dir_bsock);
+   }
+   return 1;
+}
+
+int commit_attribute_spool(JCR *jcr)
+{
+   if (are_attributes_spooled(jcr)) {
+      bnet_despool_to_bsock(jcr->dir_bsock);
+      return close_spool_file(jcr, jcr->dir_bsock);
+   }
+   return 1;
+}
index 0ab3d658f278646d9b8f1755041e075ec58d7af5..16ccc164b13154a228e99e4c72812f86623d4fcc 100644 (file)
@@ -2,8 +2,8 @@
 #undef  VERSION
 #define VERSION "1.33.4"
 #define VSTRING "1"
-#define BDATE   "06 Mar 2004"
-#define LSMDATE "06Mar04"
+#define BDATE   "08 Mar 2004"
+#define LSMDATE "08Mar04"
 
 /* Debug flags */
 #undef  DEBUG