From: Kern Sibbald Date: Mon, 8 Mar 2004 14:54:29 +0000 (+0000) Subject: Second cut data spooling + fix yesterday's patch X-Git-Tag: Release-1.34.0~66 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=66f79b648a1245426be2f1c2c36b0d0f08ea43ef;p=bacula%2Fbacula Second cut data spooling + fix yesterday's patch git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@1115 91ce42f0-d328-0410-95d8-f526ca767f89 --- diff --git a/bacula/autoconf/aclocal.m4 b/bacula/autoconf/aclocal.m4 index 929c66a23b..0ad0a8affb 100644 --- a/bacula/autoconf/aclocal.m4 +++ b/bacula/autoconf/aclocal.m4 @@ -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.], diff --git a/bacula/src/cats/sql_get.c b/bacula/src/cats/sql_get.c index d2d4624892..700b6ba636 100644 --- a/bacula/src/cats/sql_get.c +++ b/bacula/src/cats/sql_get.c @@ -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); } diff --git a/bacula/src/console/conio.c b/bacula/src/console/conio.c index 443ced7812..fee692718e 100755 --- a/bacula/src/console/conio.c +++ b/bacula/src/console/conio.c @@ -988,6 +988,9 @@ void clrbrk() static void sigintcatcher(int sig) { brkflg++; + if (brkflg > 1) { + exit(1); + } signal(SIGINT, sigintcatcher); } diff --git a/bacula/src/stored/Makefile.in b/bacula/src/stored/Makefile.in index 5cf75bbc4e..aa4105c50d 100644 --- a/bacula/src/stored/Makefile.in +++ b/bacula/src/stored/Makefile.in @@ -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 diff --git a/bacula/src/stored/append.c b/bacula/src/stored/append.c index 0f755ff493..b22d6cad9f 100644 --- a/bacula/src/stored/append.c +++ b/bacula/src/stored/append.c @@ -32,16 +32,6 @@ 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; -} diff --git a/bacula/src/stored/bcopy.c b/bacula/src/stored/bcopy.c index 73e79945a1..7d334c2ea8 100644 --- a/bacula/src/stored/bcopy.c +++ b/bacula/src/stored/bcopy.c @@ -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"), diff --git a/bacula/src/stored/block.c b/bacula/src/stored/block.c index 5a3edc52ee..5d2ba8b3bc 100644 --- a/bacula/src/stored/block.c +++ b/bacula/src/stored/block.c @@ -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); diff --git a/bacula/src/stored/btape.c b/bacula/src/stored/btape.c index 62f19c87de..ac7f24f2be 100644 --- a/bacula/src/stored/btape.c +++ b/bacula/src/stored/btape.c @@ -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) { diff --git a/bacula/src/stored/dev.h b/bacula/src/stored/dev.h index 941b5112ca..7c12595e41 100644 --- a/bacula/src/stored/dev.h +++ b/bacula/src/stored/dev.h @@ -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 */ diff --git a/bacula/src/stored/device.c b/bacula/src/stored/device.c index 3351c87ecb..b6a7c9518e 100644 --- a/bacula/src/stored/device.c +++ b/bacula/src/stored/device.c @@ -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); diff --git a/bacula/src/stored/label.c b/bacula/src/stored/label.c index e1d5aa609f..c13debe43a 100644 --- a/bacula/src/stored/label.c +++ b/bacula/src/stored/label.c @@ -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)); diff --git a/bacula/src/stored/mount.c b/bacula/src/stored/mount.c index ced3c8ea71..ad97db1dc1 100644 --- a/bacula/src/stored/mount.c +++ b/bacula/src/stored/mount.c @@ -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; diff --git a/bacula/src/stored/protos.h b/bacula/src/stored/protos.h index f4c3776047..8c25d83545 100644 --- a/bacula/src/stored/protos.h +++ b/bacula/src/stored/protos.h @@ -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 index 0000000000..d825963e1c --- /dev/null +++ b/bacula/src/stored/spool.c @@ -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; +} diff --git a/bacula/src/version.h b/bacula/src/version.h index 0ab3d658f2..16ccc164b1 100644 --- a/bacula/src/version.h +++ b/bacula/src/version.h @@ -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