From 1a3d6d0b6c4282ff9e06c25af2d57d331a5ccba1 Mon Sep 17 00:00:00 2001 From: Kern Sibbald Date: Sat, 2 Nov 2002 22:38:36 +0000 Subject: [PATCH] First cut bcopy git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@184 91ce42f0-d328-0410-95d8-f526ca767f89 --- bacula/src/stored/Makefile.in | 3 +- bacula/src/stored/acquire.c | 3 +- bacula/src/stored/bcopy.c | 184 ++++++++++++++------------------ bacula/src/stored/bscan.c | 2 +- bacula/src/stored/btape.c | 16 +++ bacula/src/stored/butil.c | 44 +++----- bacula/src/stored/protos.h | 2 +- bacula/src/stored/read_record.c | 3 +- 8 files changed, 120 insertions(+), 137 deletions(-) diff --git a/bacula/src/stored/Makefile.in b/bacula/src/stored/Makefile.in index b93cd045fa..d828fb65ce 100644 --- a/bacula/src/stored/Makefile.in +++ b/bacula/src/stored/Makefile.in @@ -73,7 +73,8 @@ FDLIBS=@FDLIBS@ .c.o: $(CXX) $(DEFS) $(DEBUG) -c $(CPPFLAGS) -I$(srcdir) -I$(basedir) $(DINCLUDE) $(CFLAGS) $< #------------------------------------------------------------------------- -all: Makefile bacula-sd bls bextract bscan btape + +all: Makefile bacula-sd bls bextract bscan btape bcopy @echo "===== Make of stored is good ====" @echo " " diff --git a/bacula/src/stored/acquire.c b/bacula/src/stored/acquire.c index 95938dae0d..6cf7940624 100644 --- a/bacula/src/stored/acquire.c +++ b/bacula/src/stored/acquire.c @@ -241,7 +241,8 @@ int release_device(JCR *jcr, DEVICE *dev) dir_update_volume_info(jcr, &dev->VolCatInfo, 0); /* send Volume info to Director */ } } else { - Jmsg1(jcr, M_ERROR, 0, _("BAD ERROR: release_device %s not in use.\n"), dev_name(dev)); + Jmsg2(jcr, M_ERROR, 0, _("BAD ERROR: release_device %s, Volume %s not in use.\n"), + dev_name(dev), NPRT(jcr->VolumeName)); } detach_jcr_from_device(dev, jcr); unlock_device(dev); diff --git a/bacula/src/stored/bcopy.c b/bacula/src/stored/bcopy.c index e8265ded20..58cec0eb69 100644 --- a/bacula/src/stored/bcopy.c +++ b/bacula/src/stored/bcopy.c @@ -31,17 +31,21 @@ #include "stored.h" /* Forward referenced functions */ -static void do_scan(void); static void record_cb(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec); /* Global variables */ -static DEVICE *dev = NULL; -static B_DB *db; -static JCR *bjcr; /* jcr for bscan */ +static DEVICE *in_dev = NULL; +static DEVICE *out_dev = NULL; +static JCR *in_jcr; /* input jcr */ +static JCR *out_jcr; /* output jcr */ static BSR *bsr = NULL; static char *wd = "/tmp"; static int verbose = 0; +static int list_records = 0; +static uint32_t records = 0; +static uint32_t jobs = 0; +static DEV_BLOCK *out_block; #define CONFIG_FILE "bacula-sd.conf" char *configfile; @@ -120,34 +124,54 @@ It is currently under development and does not work.\n\n"); parse_config(configfile); - bjcr = setup_jcr("bcopy", argv[0], bsr); - dev = setup_to_access_device(bjcr, 0); /* read device */ - if (!dev) { + /* Setup and acquire input device for reading */ + in_jcr = setup_jcr("bcopy", argv[0], bsr); + in_dev = setup_to_access_device(in_jcr, 1); /* read device */ + if (!in_dev) { exit(1); } - do_copy(); + /* Setup output device for writing */ + out_jcr = setup_jcr("bcopy", argv[1], bsr); + out_dev = setup_to_access_device(out_jcr, 0); /* no acquire */ + if (!out_dev) { + exit(1); + } + /* For we must now acquire the device for writing */ + out_block = new_block(out_dev); + lock_device(out_dev); + if (open_dev(out_dev, out_jcr->VolumeName, READ_WRITE) < 0) { + Emsg1(M_FATAL, 0, _("dev open failed: %s\n"), out_dev->errmsg); + unlock_device(out_dev); + free_block(out_block); + exit(1); + } + unlock_device(out_dev); + if (!acquire_device_for_append(out_jcr, out_dev, out_block)) { + free_block(out_block); + free_jcr(in_jcr); + exit(1); + } + + read_records(in_jcr, in_dev, record_cb, mount_next_read_volume); + if (!write_block_to_device(out_jcr, out_dev, out_block)) { + Pmsg0(000, _("Write of last block failed.\n")); + } + + Pmsg2(000, _("%u Jobs copied. %u records copied.\n"), jobs, records); - free_jcr(bjcr); + free_block(out_block); + term_dev(in_dev); + term_dev(out_dev); + free_jcr(in_jcr); + free_jcr(out_jcr); return 0; } -static void do_copy() -{ - detach_jcr_from_device(dev, bjcr); - - read_records(bjcr, dev, record_cb, mount_next_read_volume); - release_device(bjcr, dev); - - term_dev(dev); -} -static void record_cb(JCR *bjcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec) +static void record_cb(JCR *in_jcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec) { - JCR *mjcr; - char ec1[30]; - if (list_records) { Pmsg5(000, _("Record: SessId=%u SessTim=%u FileIndex=%d Stream=%d len=%u\n"), rec->VolSessionId, rec->VolSessionTime, rec->FileIndex, @@ -166,79 +190,58 @@ static void record_cb(JCR *bjcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec) case PRE_LABEL: Pmsg0(000, "Volume is prelabeled. This volume cannot be copied.\n"); return; - break; case VOL_LABEL: - Pmsg1(000, "VOL_LABEL: OK for Volume: %s\n", mr.VolumeName); - break; + Pmsg0(000, "Volume label not copied.\n"); + return; case SOS_LABEL: + jobs++; break; case EOS_LABEL: + 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)) { + 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)) { + 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)); + } break; case EOM_LABEL: - break; + Pmsg0(000, "EOM label not copied.\n"); + return; case EOT_LABEL: /* end of all tapes */ - break; + Pmsg0(000, "EOT label not copied.\n"); + return; default: break; } - return; } /* Write record */ - - return; -} - -/* - * Free the Job Control Record if no one is still using it. - * Called from main free_jcr() routine in src/lib/jcr.c so - * that we can do our Director specific cleanup of the jcr. - */ -static void dird_free_jcr(JCR *jcr) -{ - Dmsg0(200, "Start dird free_jcr\n"); - - if (jcr->file_bsock) { - Dmsg0(200, "Close File bsock\n"); - bnet_close(jcr->file_bsock); - } - if (jcr->store_bsock) { - Dmsg0(200, "Close Store bsock\n"); - bnet_close(jcr->store_bsock); - } - if (jcr->RestoreBootstrap) { - free(jcr->RestoreBootstrap); + records++; + 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)) { + 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)); + break; + } } - Dmsg0(200, "End dird free_jcr\n"); + return; } - -/* - * Create a JCR as if we are really starting the job - */ -static JCR *create_jcr(JOB_DBR *jr, DEV_RECORD *rec, uint32_t JobId) -{ - JCR *jobjcr; - /* - * Transfer as much as possible to the Job JCR. Most important is - * the JobId and the ClientId. - */ - jobjcr = new_jcr(sizeof(JCR), dird_free_jcr); - jobjcr->JobType = jr->Type; - jobjcr->JobLevel = jr->Level; - jobjcr->JobStatus = jr->JobStatus; - strcpy(jobjcr->Job, jr->Job); - jobjcr->JobId = JobId; /* this is JobId on tape */ - jobjcr->sched_time = jr->SchedTime; - jobjcr->start_time = jr->StartTime; - jobjcr->VolSessionId = rec->VolSessionId; - jobjcr->VolSessionTime = rec->VolSessionTime; - jobjcr->ClientId = jr->ClientId; - attach_jcr_to_device(dev, jobjcr); - return jobjcr; -} - /* Dummies to replace askdir.c */ int dir_get_volume_info(JCR *jcr, int writing) { return 1;} int dir_find_next_appendable_volume(JCR *jcr) { return 1;} @@ -251,31 +254,8 @@ int dir_send_job_status(JCR *jcr) {return 1;} int dir_ask_sysop_to_mount_volume(JCR *jcr, DEVICE *dev) { - /* - * We are at the end of reading a tape. Now, we simulate handling - * the end of writing a tape by wiffling through the attached - * jcrs creating jobmedia records. - */ - Dmsg1(100, "Walk attached jcrs. Volume=%s\n", dev->VolCatInfo.VolCatName); - for (JCR *mjcr=NULL; (mjcr=next_attached_jcr(dev, mjcr)); ) { - if (verbose) { - Pmsg1(000, "create JobMedia for Job %s\n", mjcr->Job); - } - if (dev->state & ST_TAPE) { - mjcr->EndBlock = dev->block_num; - mjcr->EndFile = dev->file; - } else { - mjcr->EndBlock = (uint32_t)dev->file_addr; - mjcr->StartBlock = (uint32_t)(dev->file_addr >> 32); - } - if (!create_jobmedia_record(db, mjcr)) { - Pmsg2(000, _("Could not create JobMedia record for Volume=%s Job=%s\n"), - dev->VolCatInfo.VolCatName, mjcr->Job); - } - } - fprintf(stderr, "Mount Volume %s on device %s and press return when ready: ", - jcr->VolumeName, dev_name(dev)); + in_jcr->VolumeName, dev_name(dev)); getchar(); return 1; } diff --git a/bacula/src/stored/bscan.c b/bacula/src/stored/bscan.c index 2034ca2fce..18b01a7b54 100644 --- a/bacula/src/stored/bscan.c +++ b/bacula/src/stored/bscan.c @@ -191,7 +191,7 @@ int main (int argc, char *argv[]) parse_config(configfile); bjcr = setup_jcr("bscan", argv[0], bsr); - dev = setup_to_access_device(bjcr, 0); /* read device */ + dev = setup_to_access_device(bjcr, 1); /* read device */ if (!dev) { exit(1); } diff --git a/bacula/src/stored/btape.c b/bacula/src/stored/btape.c index 3238f3852e..0a38b1b38a 100644 --- a/bacula/src/stored/btape.c +++ b/bacula/src/stored/btape.c @@ -118,6 +118,7 @@ int read_dev(DEVICE *dev, char *buf, size_t len) int main(int argc, char *argv[]) { int ch; + DEV_BLOCK *block; /* Sanity checks */ if (TAPE_BSIZE % DEV_BSIZE != 0 || TAPE_BSIZE / DEV_BSIZE == 0) { @@ -204,10 +205,25 @@ int main(int argc, char *argv[]) if (!dev) { exit(1); } + block = new_block(dev); + lock_device(dev); + if (!(dev->state & ST_OPENED)) { + Dmsg0(129, "Opening device.\n"); + if (open_dev(dev, jcr->VolumeName, READ_WRITE) < 0) { + Emsg1(M_FATAL, 0, _("dev open failed: %s\n"), dev->errmsg); + unlock_device(dev); + free_block(block); + goto terminate; + } + } + Dmsg1(129, "open_dev %s OK\n", dev_name(dev)); + unlock_device(dev); + free_block(block); Dmsg0(200, "Do tape commands\n"); do_tape_cmds(); +terminate: terminate_btape(0); return 0; } diff --git a/bacula/src/stored/butil.c b/bacula/src/stored/butil.c index 4b372fca6e..e27f52c973 100644 --- a/bacula/src/stored/butil.c +++ b/bacula/src/stored/butil.c @@ -87,19 +87,15 @@ DEVICE *setup_to_access_device(JCR *jcr, int read_access) } } - if ((device=find_device_res(jcr->dev_name)) == NULL) { - Emsg2(M_FATAL, 0, "Cannot find device %s in config file %s.\n", + if ((device=find_device_res(jcr->dev_name, read_access)) == NULL) { + Emsg2(M_FATAL, 0, _("Cannot find device %s in config file %s.\n"), jcr->dev_name, configfile); return NULL; } dev = init_dev(NULL, device); - if (!dev) { - Emsg1(M_FATAL, 0, "Cannot open %s\n", jcr->dev_name); - return NULL; - } - if (!open_device(dev)) { - Emsg1(M_FATAL, 0, "Cannot open %s\n", jcr->dev_name); + if (!dev || !open_device(dev)) { + Emsg1(M_FATAL, 0, _("Cannot open %s\n"), jcr->dev_name); return NULL; } Dmsg0(90, "Device opened for read.\n"); @@ -115,19 +111,6 @@ DEVICE *setup_to_access_device(JCR *jcr, int read_access) free_block(block); return NULL; } - } else { - lock_device(dev); - if (!(dev->state & ST_OPENED)) { - Dmsg0(129, "Opening device.\n"); - if (open_dev(dev, jcr->VolumeName, READ_WRITE) < 0) { - Emsg1(M_FATAL, 0, _("dev open failed: %s\n"), dev->errmsg); - unlock_device(dev); - free_block(block); - return NULL; - } - } - Dmsg1(129, "open_dev %s OK\n", dev_name(dev)); - unlock_device(dev); } free_block(block); return dev; @@ -141,7 +124,7 @@ DEVICE *setup_to_access_device(JCR *jcr, int read_access) * Returns: NULL on failure * Device resource pointer on success */ -DEVRES *find_device_res(char *device_name) +DEVRES *find_device_res(char *device_name, int read_access) { int found = 0; DEVRES *device; @@ -155,11 +138,12 @@ DEVRES *find_device_res(char *device_name) } UnlockRes(); if (!found) { - Pmsg2(0, "Could not find device %s in config file %s.\n", device_name, + Pmsg2(0, _("Could not find device %s in config file %s.\n"), device_name, configfile); return NULL; } - Pmsg1(0, "Using device: %s\n", device_name); + Pmsg2(0, _("Using device: %s for %s.\n"), device_name, + read_access?"reading":"writing"); return device; } @@ -245,17 +229,17 @@ void display_error_status(DEVICE *dev) 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"); + 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"); + 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"); + 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"); + 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"); + 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)); + Emsg2(M_ERROR_TERM, 0, _("Read error on Record Header %s: %s\n"), dev_name(dev), strerror(errno)); } diff --git a/bacula/src/stored/protos.h b/bacula/src/stored/protos.h index d8cc8fd3d8..2cd5c18202 100644 --- a/bacula/src/stored/protos.h +++ b/bacula/src/stored/protos.h @@ -62,7 +62,7 @@ void print_ls_output(char *fname, char *link, int type, struct stat *statp); JCR *setup_jcr(char *name, char *device, BSR *bsr); DEVICE *setup_to_access_device(JCR *jcr, int read_access); void display_error_status(DEVICE *dev); -DEVRES *find_device_res(char *device_name); +DEVRES *find_device_res(char *device_name, int read_access); /* From dev.c */ diff --git a/bacula/src/stored/read_record.c b/bacula/src/stored/read_record.c index b324bf01f8..d8d281e816 100644 --- a/bacula/src/stored/read_record.c +++ b/bacula/src/stored/read_record.c @@ -92,7 +92,8 @@ int read_records(JCR *jcr, DEVICE *dev, goto next_record; } if (dev->state & ST_EOF) { - Emsg1(M_INFO, 0, "Got EOF on device %s\n", dev_name(dev)); + Emsg2(M_INFO, 0, "Got EOF on device %s, Volume \"%s\"\n", + dev_name(dev), jcr->VolumeName); Dmsg0(20, "read_record got eof. try again\n"); continue; } -- 2.39.5