From 790838e6a19e1f94c201976e8dc4742059c60369 Mon Sep 17 00:00:00 2001 From: Kern Sibbald Date: Thu, 7 Aug 2003 15:10:11 +0000 Subject: [PATCH] Doc + read_record updates git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@663 91ce42f0-d328-0410-95d8-f526ca767f89 --- bacula/kernstodo | 5 + bacula/platforms/mandrake/bacula.spec.in | 31 ++- bacula/src/dird/inc_conf.c | 2 + bacula/src/lib/alist.c | 6 +- bacula/src/lib/alist.h | 14 +- bacula/src/stored/Makefile.in | 10 +- bacula/src/stored/bcopy.c | 152 +++++++------- bacula/src/stored/bextract.c | 17 +- bacula/src/stored/bls.c | 13 +- bacula/src/stored/bscan.c | 22 +- bacula/src/stored/btape.c | 9 +- bacula/src/stored/label.c | 1 - bacula/src/stored/protos.h | 166 ++++++++-------- bacula/src/stored/read.c | 243 +++++------------------ bacula/src/stored/read_record.c | 147 ++++++++------ bacula/src/stored/record.h | 110 +++++----- bacula/src/version.h | 6 +- 17 files changed, 433 insertions(+), 521 deletions(-) diff --git a/bacula/kernstodo b/bacula/kernstodo index 1728136f9d..b547f69481 100644 --- a/bacula/kernstodo +++ b/bacula/kernstodo @@ -31,6 +31,11 @@ For 1.31 release: For 1.32: +- Make bextract release the drive properly between tapes + so that an autochanger can be made to work. +- Fix "restore all" to bypass building the tree. +- Fix restore to list errors if Invalid block found, and if # files + restored does not match # expected. - User wants to NOT backup up certain big files (email files). - Maybe remove multiple simultaneous devices code in SD. - On Windows with very long path names, it may be impossible to create diff --git a/bacula/platforms/mandrake/bacula.spec.in b/bacula/platforms/mandrake/bacula.spec.in index ba5fdeb816..cd629282b2 100644 --- a/bacula/platforms/mandrake/bacula.spec.in +++ b/bacula/platforms/mandrake/bacula.spec.in @@ -10,10 +10,18 @@ # If you want the MySQL version, use: # rpmbuild -ba --define "build_mysql 1" bacula.spec # - +# If you want the MySQL version and static builds, use: +# rpmbuild -ba --define "build_mysql 1" --define "build_static 1" bacula.spec +# If you want the MySQL version and static builds + come console , use: +# rpmbuild -ba --define "build_mysql 1" --define "build_static 1" --define "build_gnome 1" bacula.spec %define mysql 0 +%define static 0 +%define gnome 0 %{?build_mysql:%define mysql 1} +%{?build_static:%define static 1} +%{?build_gnome:%define gnome 1} + Summary: Bacula - The Network Backup Solution @@ -30,8 +38,12 @@ Distribution: The Bacula Team Packager: D. Scott Barninger Requires: gnome-libs >= 1.4 Requires: readline -BuildRequires: gnome-libs-devel >= 1.4 BuildRequires: readline-devel +%if %{gnome} +Requires: gnome-libs >= 1.4 +BuildRequires: gnome-libs-devel >= 1.4 +%endif + %if %{mysql} Requires: mysql >= 3.23 Requires: mysql-server >= 3.23 @@ -121,7 +133,16 @@ patch src/cats/make_sqlite_tables.in src/cats/make_sqlite_tables.in.patch --sysconfdir=/etc/bacula \ --with-scriptdir=/etc/bacula \ --enable-smartalloc \ +%if %{gnome} --enable-gnome \ +%endif +%if %{static} + --enable-static-fd \ + --enable-static-sd \ + --enable-static-dir \ + --enable-static-tools \ + --enable-static-cons \ +%endif %if %{mysql} --with-mysql \ %else @@ -171,9 +192,9 @@ rm -f $RPM_BUILD_ROOT/etc/bacula/grant_mysql_privileges %endif # install the init scripts -cp platforms/redhat/bacula-dir $RPM_BUILD_ROOT/etc/rc.d/init.d/bacula-dir -cp platforms/redhat/bacula-fd $RPM_BUILD_ROOT/etc/rc.d/init.d/bacula-fd -cp platforms/redhat/bacula-sd $RPM_BUILD_ROOT/etc/rc.d/init.d/bacula-sd +cp platforms/mandrake/bacula-dir $RPM_BUILD_ROOT/etc/rc.d/init.d/bacula-dir +cp platforms/mandrake/bacula-fd $RPM_BUILD_ROOT/etc/rc.d/init.d/bacula-fd +cp platforms/mandrake/bacula-sd $RPM_BUILD_ROOT/etc/rc.d/init.d/bacula-sd # install the menu stuff cp scripts/bacula.png $RPM_BUILD_ROOT/usr/share/pixmaps/bacula.png diff --git a/bacula/src/dird/inc_conf.c b/bacula/src/dird/inc_conf.c index 2b2629090f..d9aac3bad1 100644 --- a/bacula/src/dird/inc_conf.c +++ b/bacula/src/dird/inc_conf.c @@ -510,6 +510,8 @@ static void setup_current_opts(void) if (res_incexe.current_opts == NULL) { res_incexe.current_opts = (FOPTS *)malloc(sizeof(FOPTS)); memset(res_incexe.current_opts, 0, sizeof(FOPTS)); + res_incexe.current_opts->match.init(1, true); + res_incexe.current_opts->base_list.init(1, true); res_incexe.num_opts = 1; res_incexe.opts_list = (FOPTS **)malloc(sizeof(FOPTS *)); res_incexe.opts_list[0] = res_incexe.current_opts; diff --git a/bacula/src/lib/alist.c b/bacula/src/lib/alist.c index e5eafaf933..72613242ac 100644 --- a/bacula/src/lib/alist.c +++ b/bacula/src/lib/alist.c @@ -62,8 +62,10 @@ void * alist::get(int index) void alist::destroy() { if (items) { - for (int i=0; iinit(num); +inline alist::alist(int num, bool own) { + this->init(num, own); } diff --git a/bacula/src/stored/Makefile.in b/bacula/src/stored/Makefile.in index df205d0487..4748ff5a99 100644 --- a/bacula/src/stored/Makefile.in +++ b/bacula/src/stored/Makefile.in @@ -20,16 +20,18 @@ dummy: # bacula-sd SVRSRCS = stored.c autochanger.c acquire.c append.c \ askdir.c authenticate.c \ - block.c dev.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 record.c status.c stored_conf.c mount.c + read.c read_record.c \ + record.c status.c stored_conf.c mount.c SVROBJS = stored.o autochanger.o acquire.o append.o \ askdir.o authenticate.o \ - block.o dev.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 record.o status.o stored_conf.o + read.o read_record.o \ + record.o status.o stored_conf.o # btape TAPESRCS = btape.c block.c butil.c dev.c device.c label.c \ diff --git a/bacula/src/stored/bcopy.c b/bacula/src/stored/bcopy.c index f0f985eaf7..36a4a45ce5 100644 --- a/bacula/src/stored/bcopy.c +++ b/bacula/src/stored/bcopy.c @@ -31,14 +31,14 @@ #include "stored.h" /* Forward referenced functions */ -static void record_cb(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec); +static int record_cb(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec); /* Global variables */ static DEVICE *in_dev = NULL; static DEVICE *out_dev = NULL; -static JCR *in_jcr; /* input jcr */ -static JCR *out_jcr; /* output jcr */ +static JCR *in_jcr; /* input jcr */ +static JCR *out_jcr; /* output jcr */ static BSR *bsr = NULL; static char *wd = "/tmp"; static int list_records = 0; @@ -78,42 +78,42 @@ int main (int argc, char *argv[]) while ((ch = getopt(argc, argv, "b:c:d:mn:p:rsu:vV:w:?")) != -1) { switch (ch) { case 'b': - bsr = parse_bsr(NULL, optarg); - break; + bsr = parse_bsr(NULL, optarg); + break; case 'c': /* specify config file */ - if (configfile != NULL) { - free(configfile); - } - configfile = bstrdup(optarg); - break; + if (configfile != NULL) { + free(configfile); + } + configfile = bstrdup(optarg); + break; case 'd': /* debug level */ - debug_level = atoi(optarg); - if (debug_level <= 0) - debug_level = 1; - break; + debug_level = atoi(optarg); + if (debug_level <= 0) + debug_level = 1; + break; case 'v': - verbose++; - break; + verbose++; + break; case 'i': /* input Volume name */ - iVolumeName = optarg; - break; + iVolumeName = optarg; + break; case 'o': /* output Volume name */ - oVolumeName = optarg; - break; + oVolumeName = optarg; + break; case 'w': - wd = optarg; - break; + wd = optarg; + break; case '?': - default: - usage(); + default: + usage(); } } @@ -135,7 +135,7 @@ int main (int argc, char *argv[]) /* Setup and acquire input device for reading */ in_jcr = setup_jcr("bcopy", argv[0], bsr, iVolumeName); - in_dev = setup_to_access_device(in_jcr, 1); /* read device */ + in_dev = setup_to_access_device(in_jcr, 1); /* read device */ if (!in_dev) { exit(1); } @@ -144,7 +144,7 @@ int main (int argc, char *argv[]) out_jcr = setup_jcr("bcopy", argv[1], bsr, oVolumeName); out_dev = setup_to_access_device(out_jcr, 0); /* no acquire */ if (!out_dev) { - exit(1); + exit(1); } /* For we must now acquire the device for writing */ out_block = new_block(out_dev); @@ -179,12 +179,12 @@ int main (int argc, char *argv[]) -static void record_cb(JCR *in_jcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec) +static int record_cb(JCR *in_jcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec) { if (list_records) { Pmsg5(000, _("Record: SessId=%u SessTim=%u FileIndex=%d Stream=%d len=%u\n"), - rec->VolSessionId, rec->VolSessionTime, rec->FileIndex, - rec->Stream, rec->data_len); + rec->VolSessionId, rec->VolSessionTime, rec->FileIndex, + rec->Stream, rec->data_len); } /* * Check for Start or End of Session Record @@ -193,44 +193,44 @@ static void record_cb(JCR *in_jcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *re if (rec->FileIndex < 0) { if (verbose > 1) { - dump_label_record(dev, rec, 1); + dump_label_record(dev, rec, 1); } switch (rec->FileIndex) { - case PRE_LABEL: - Pmsg0(000, "Volume is prelabeled. This volume cannot be copied.\n"); - return; - case VOL_LABEL: - 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)) { + case PRE_LABEL: + Pmsg0(000, "Volume is prelabeled. This volume cannot be copied.\n"); + return 1; + case VOL_LABEL: + Pmsg0(000, "Volume label not copied.\n"); + return 1; + 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)); + 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: - Pmsg0(000, "EOM label not copied.\n"); - return; - case EOT_LABEL: /* end of all tapes */ - Pmsg0(000, "EOT label not copied.\n"); - return; - default: - break; + 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: + Pmsg0(000, "EOM label not copied.\n"); + return 1; + case EOT_LABEL: /* end of all tapes */ + Pmsg0(000, "EOT label not copied.\n"); + return 1; + default: + break; } } @@ -238,33 +238,33 @@ static void record_cb(JCR *in_jcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *re 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); + 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)); + 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; + strerror_dev(out_dev)); + break; } } - return; + return 1; } /* Dummies to replace askdir.c */ -int dir_get_volume_info(JCR *jcr, enum get_vol_info_rw writing) { return 1;} -int dir_find_next_appendable_volume(JCR *jcr) { return 1;} -int dir_update_volume_info(JCR *jcr, VOLUME_CAT_INFO *vol, int relabel) { return 1; } -int dir_create_jobmedia_record(JCR *jcr) { return 1; } -int dir_ask_sysop_to_mount_next_volume(JCR *jcr, DEVICE *dev) { return 1; } -int dir_update_file_attributes(JCR *jcr, DEV_RECORD *rec) { return 1;} -int dir_send_job_status(JCR *jcr) {return 1;} +int dir_get_volume_info(JCR *jcr, enum get_vol_info_rw writing) { return 1;} +int dir_find_next_appendable_volume(JCR *jcr) { return 1;} +int dir_update_volume_info(JCR *jcr, VOLUME_CAT_INFO *vol, int relabel) { return 1; } +int dir_create_jobmedia_record(JCR *jcr) { return 1; } +int dir_ask_sysop_to_mount_next_volume(JCR *jcr, DEVICE *dev) { return 1; } +int dir_update_file_attributes(JCR *jcr, DEV_RECORD *rec) { return 1;} +int dir_send_job_status(JCR *jcr) {return 1;} int dir_ask_sysop_to_mount_volume(JCR *jcr, DEVICE *dev) { fprintf(stderr, "Mount Volume %s on device %s and press return when ready: ", in_jcr->VolumeName, dev_name(dev)); - getchar(); + getchar(); return 1; } diff --git a/bacula/src/stored/bextract.c b/bacula/src/stored/bextract.c index 45b1e73a21..ed517b08d2 100644 --- a/bacula/src/stored/bextract.c +++ b/bacula/src/stored/bextract.c @@ -39,7 +39,7 @@ int win32_client = 0; static void do_extract(char *fname); -static void record_cb(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec); +static int record_cb(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec); static DEVICE *dev = NULL; static BFILE bfd; @@ -235,12 +235,12 @@ static void do_extract(char *devname) /* * Called here for each record from read_records() */ -static void record_cb(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec) +static int record_cb(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec) { int stat; if (rec->FileIndex < 0) { - return; /* we don't want labels */ + return 1; /* we don't want labels */ } /* File Attributes stream */ @@ -278,7 +278,7 @@ static void record_cb(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec) stream_to_ascii(attr->data_stream)); } extract = FALSE; - return; + return 1; } @@ -363,7 +363,7 @@ static void record_cb(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec) Emsg3(M_ERROR, 0, _("Seek to %s error on %s: ERR=%s\n"), edit_uint64(fileAddr, ec1), attr->ofname, berror(&bfd)); extract = FALSE; - return; + return 1; } } } else { @@ -375,7 +375,7 @@ static void record_cb(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec) (const Bytef *)wbuf, (uLong)wsize) != Z_OK)) { Emsg1(M_ERROR, 0, _("Uncompression error. ERR=%d\n"), stat); extract = FALSE; - return; + return 1; } Dmsg2(100, "Write uncompressed %d bytes, total before write=%d\n", compress_len, total); @@ -384,7 +384,7 @@ static void record_cb(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec) Emsg2(M_ERROR, 0, _("Write error on %s: %s\n"), attr->ofname, strerror(errno)); extract = FALSE; - return; + return 1; } total += compress_len; fileAddr += compress_len; @@ -395,7 +395,7 @@ static void record_cb(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec) if (extract) { Emsg0(M_ERROR, 0, "GZIP data stream found, but GZIP not configured!\n"); extract = FALSE; - return; + return 1; } #endif break; @@ -426,6 +426,7 @@ static void record_cb(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec) break; } /* end switch */ + return 1; } diff --git a/bacula/src/stored/bls.c b/bacula/src/stored/bls.c index 17af6f3231..61798faf19 100644 --- a/bacula/src/stored/bls.c +++ b/bacula/src/stored/bls.c @@ -40,7 +40,7 @@ static void do_jobs(char *infname); static void do_ls(char *fname); static void do_close(JCR *jcr); static void get_session_record(DEVICE *dev, DEV_RECORD *rec, SESSION_LABEL *sessrec); -static void record_cb(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec); +static int record_cb(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec); static DEVICE *dev; static int dump_label = FALSE; @@ -305,12 +305,13 @@ static void do_blocks(char *infname) /* * We are only looking for labels or in particula Job Session records */ -static void jobs_cb(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec) +static int jobs_cb(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec) { if (rec->FileIndex < 0) { dump_label_record(dev, rec, verbose); } rec->remainder = 0; + return 1; } /* Do list job records */ @@ -333,11 +334,11 @@ static void do_ls(char *infname) /* * Called here for each record from read_records() */ -static void record_cb(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec) +static int record_cb(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec) { if (rec->FileIndex < 0) { get_session_record(dev, rec, &sessrec); - return; + return 1; } /* File Attributes stream */ if (rec->Stream == STREAM_UNIX_ATTRIBUTES || @@ -358,7 +359,7 @@ static void record_cb(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec) Jmsg(jcr, M_ERROR, 0, _("%s stream not supported on this Client.\n"), stream_to_ascii(attr->data_stream)); } - return; + return 1; } build_attr_output_fnames(jcr, attr); @@ -367,7 +368,7 @@ static void record_cb(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec) num_files++; } } - return; + return 1; } diff --git a/bacula/src/stored/bscan.c b/bacula/src/stored/bscan.c index 4467a280fb..53dc6b5c6f 100644 --- a/bacula/src/stored/bscan.c +++ b/bacula/src/stored/bscan.c @@ -36,7 +36,7 @@ /* Forward referenced functions */ static void do_scan(void); -static void record_cb(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec); +static int record_cb(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec); static int create_file_attributes_record(B_DB *db, JCR *mjcr, char *fname, char *lname, int type, char *ap, DEV_RECORD *rec); @@ -305,7 +305,7 @@ static void do_scan() term_dev(dev); } -static void record_cb(JCR *bjcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec) +static int record_cb(JCR *bjcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec) { JCR *mjcr; char ec1[30]; @@ -331,7 +331,7 @@ static void record_cb(JCR *bjcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec) switch (rec->FileIndex) { case PRE_LABEL: Pmsg0(000, _("Volume is prelabeled. This tape cannot be scanned.\n")); - return; + return 1; break; case VOL_LABEL: @@ -353,7 +353,7 @@ static void record_cb(JCR *bjcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec) if (strcmp(pr.PoolType, dev->VolHdr.PoolType) != 0) { Pmsg2(000, _("VOL_LABEL: PoolType mismatch. DB=%s Vol=%s\n"), pr.PoolType, dev->VolHdr.PoolType); - return; + return 1; } else if (verbose) { Pmsg1(000, _("Pool type \"%s\" is OK.\n"), pr.PoolType); } @@ -380,7 +380,7 @@ static void record_cb(JCR *bjcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec) if (strcmp(mr.MediaType, dev->VolHdr.MediaType) != 0) { Pmsg2(000, _("VOL_LABEL: MediaType mismatch. DB=%s Vol=%s\n"), mr.MediaType, dev->VolHdr.MediaType); - return; + return 1; } else if (verbose) { Pmsg1(000, _("Media type \"%s\" is OK.\n"), mr.MediaType); } @@ -451,19 +451,19 @@ static void record_cb(JCR *bjcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec) Pmsg3(000, _("SOS_LABEL: VolSessId mismatch for JobId=%u. DB=%d Vol=%d\n"), jr.JobId, jr.VolSessionId, rec->VolSessionId); - return; + return 1; } if (rec->VolSessionTime != jr.VolSessionTime) { Pmsg3(000, _("SOS_LABEL: VolSessTime mismatch for JobId=%u. DB=%d Vol=%d\n"), jr.JobId, jr.VolSessionTime, rec->VolSessionTime); - return; + return 1; } if (jr.PoolId != pr.PoolId) { Pmsg3(000, _("SOS_LABEL: PoolId mismatch for JobId=%u. DB=%d Vol=%d\n"), jr.JobId, jr.PoolId, pr.PoolId); - return; + return 1; } break; @@ -531,7 +531,7 @@ static void record_cb(JCR *bjcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec) default: break; } /* end switch */ - return; + return 1; } mjcr = get_jcr_by_session(rec->VolSessionId, rec->VolSessionTime); @@ -542,7 +542,7 @@ static void record_cb(JCR *bjcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec) } else { ignored_msgs++; } - return; + return 1; } if (mjcr->VolFirstIndex == 0) { mjcr->VolFirstIndex = block->FirstIndex; @@ -642,7 +642,7 @@ static void record_cb(JCR *bjcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec) Pmsg2(0, _("Unknown stream type!!! stream=%d data=%s\n"), rec->Stream, rec->data); break; } - return; + return 1; } /* diff --git a/bacula/src/stored/btape.c b/bacula/src/stored/btape.c index 44f1eabea4..eed019ac31 100644 --- a/bacula/src/stored/btape.c +++ b/bacula/src/stored/btape.c @@ -64,7 +64,7 @@ static void qfillcmd(); static void statcmd(); static void unfillcmd(); static int flush_block(DEV_BLOCK *block, int dump); -static void record_cb(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec); +static int record_cb(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec); static int my_mount_next_read_volume(JCR *jcr, DEVICE *dev, DEV_BLOCK *block); static void scan_blocks(); static void set_volume_name(char *VolName, int volnum); @@ -1349,7 +1349,7 @@ bail_out: /* * We are called here from "unfill" for each record on the tape. */ -static void record_cb(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec) +static int record_cb(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec) { SESSION_LABEL label; @@ -1370,7 +1370,7 @@ static void record_cb(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec) switch (rec->FileIndex) { case PRE_LABEL: Pmsg0(-1, "Volume is prelabeled. This tape cannot be scanned.\n"); - return; + return 1;; case VOL_LABEL: unser_volume_label(dev, rec); Pmsg3(-1, "VOL_LABEL: block=%u size=%d vol=%s\n", block->BlockNumber, @@ -1411,7 +1411,7 @@ static void record_cb(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec) default: break; } - return; + return 1; } if (++file_index != rec->FileIndex) { Pmsg3(000, "Incorrect FileIndex in Block %u. Got %d, expected %d.\n", @@ -1448,6 +1448,7 @@ static void record_cb(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec) if (end_of_tape) { Pmsg1(000, "End of all blocks. Block=%u\n", block->BlockNumber); } + return 1; } diff --git a/bacula/src/stored/label.c b/bacula/src/stored/label.c index 1912d1571e..59f8a1dd77 100644 --- a/bacula/src/stored/label.c +++ b/bacula/src/stored/label.c @@ -442,7 +442,6 @@ void create_session_label(JCR *jcr, DEV_RECORD *rec, int label) { ser_declare; - rec->sync = 1; /* wait for completion */ rec->VolSessionId = jcr->VolSessionId; rec->VolSessionTime = jcr->VolSessionTime; rec->Stream = jcr->JobId; diff --git a/bacula/src/stored/protos.h b/bacula/src/stored/protos.h index 107d2d2cc3..be1116b9aa 100644 --- a/bacula/src/stored/protos.h +++ b/bacula/src/stored/protos.h @@ -28,91 +28,91 @@ uint32_t new_VolSessionId(); /* From acquire.c */ -DEVICE *acquire_device_for_append(JCR *jcr, DEVICE *dev, DEV_BLOCK *block); -int acquire_device_for_read(JCR *jcr, DEVICE *dev, DEV_BLOCK *block); -int release_device(JCR *jcr, DEVICE *dev); +DEVICE *acquire_device_for_append(JCR *jcr, DEVICE *dev, DEV_BLOCK *block); +int acquire_device_for_read(JCR *jcr, DEVICE *dev, DEV_BLOCK *block); +int release_device(JCR *jcr, DEVICE *dev); /* From askdir.c */ enum get_vol_info_rw { GET_VOL_INFO_FOR_WRITE, GET_VOL_INFO_FOR_READ }; -int dir_get_volume_info(JCR *jcr, enum get_vol_info_rw); -int dir_find_next_appendable_volume(JCR *jcr); -int dir_update_volume_info(JCR *jcr, VOLUME_CAT_INFO *vol, int relabel); -int dir_ask_sysop_to_mount_next_volume(JCR *jcr, DEVICE *dev); -int dir_ask_sysop_to_mount_volume(JCR *jcr, DEVICE *dev); -int dir_update_file_attributes(JCR *jcr, DEV_RECORD *rec); -int dir_send_job_status(JCR *jcr); -int dir_create_jobmedia_record(JCR *jcr); +int dir_get_volume_info(JCR *jcr, enum get_vol_info_rw); +int dir_find_next_appendable_volume(JCR *jcr); +int dir_update_volume_info(JCR *jcr, VOLUME_CAT_INFO *vol, int relabel); +int dir_ask_sysop_to_mount_next_volume(JCR *jcr, DEVICE *dev); +int dir_ask_sysop_to_mount_volume(JCR *jcr, DEVICE *dev); +int dir_update_file_attributes(JCR *jcr, DEV_RECORD *rec); +int dir_send_job_status(JCR *jcr); +int dir_create_jobmedia_record(JCR *jcr); /* authenticate.c */ -int authenticate_director(JCR *jcr); -int authenticate_filed(JCR *jcr); +int authenticate_director(JCR *jcr); +int authenticate_filed(JCR *jcr); /* From block.c */ -void dump_block(DEV_BLOCK *b, char *msg); +void dump_block(DEV_BLOCK *b, char *msg); DEV_BLOCK *new_block(DEVICE *dev); -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); +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); #define CHECK_BLOCK_NUMBERS true #define NO_BLOCK_NUMBER_CHECK false -int read_block_from_device(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, bool check_block_numbers); -int read_block_from_dev(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, bool check_block_numbers); +int read_block_from_device(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, bool check_block_numbers); +int read_block_from_dev(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, bool check_block_numbers); /* From butil.c -- utilities for SD tool programs */ -void print_ls_output(char *fname, char *link, int type, struct stat *statp); +void print_ls_output(char *fname, char *link, int type, struct stat *statp); JCR *setup_jcr(char *name, char *device, BSR *bsr, char *VolumeName); DEVICE *setup_to_access_device(JCR *jcr, int read_access); -void display_tape_error_status(JCR *jcr, DEVICE *dev); +void display_tape_error_status(JCR *jcr, DEVICE *dev); DEVRES *find_device_res(char *device_name, int read_access); /* From dev.c */ -DEVICE *init_dev(DEVICE *dev, DEVRES *device); -int open_dev(DEVICE *dev, char *VolName, int mode); -void close_dev(DEVICE *dev); -void force_close_dev(DEVICE *dev); -int truncate_dev(DEVICE *dev); -void term_dev(DEVICE *dev); -char * strerror_dev(DEVICE *dev); -void clrerror_dev(DEVICE *dev, int func); -int update_pos_dev(DEVICE *dev); -int rewind_dev(DEVICE *dev); -int load_dev(DEVICE *dev); -int offline_dev(DEVICE *dev); -int flush_dev(DEVICE *dev); -int weof_dev(DEVICE *dev, int num); -int write_block(DEVICE *dev); -int write_dev(DEVICE *dev, char *buf, size_t len); -int read_dev(DEVICE *dev, char *buf, size_t len); -int status_dev(DEVICE *dev, uint32_t *status); -int eod_dev(DEVICE *dev); -int fsf_dev(DEVICE *dev, int num); -int fsr_dev(DEVICE *dev, int num); -int bsf_dev(DEVICE *dev, int num); -int bsr_dev(DEVICE *dev, int num); -void attach_jcr_to_device(DEVICE *dev, JCR *jcr); -void detach_jcr_from_device(DEVICE *dev, JCR *jcr); -JCR *next_attached_jcr(DEVICE *dev, JCR *jcr); -int dev_can_write(DEVICE *dev); -int offline_or_rewind_dev(DEVICE *dev); +DEVICE *init_dev(DEVICE *dev, DEVRES *device); +int open_dev(DEVICE *dev, char *VolName, int mode); +void close_dev(DEVICE *dev); +void force_close_dev(DEVICE *dev); +int truncate_dev(DEVICE *dev); +void term_dev(DEVICE *dev); +char * strerror_dev(DEVICE *dev); +void clrerror_dev(DEVICE *dev, int func); +int update_pos_dev(DEVICE *dev); +int rewind_dev(DEVICE *dev); +int load_dev(DEVICE *dev); +int offline_dev(DEVICE *dev); +int flush_dev(DEVICE *dev); +int weof_dev(DEVICE *dev, int num); +int write_block(DEVICE *dev); +int write_dev(DEVICE *dev, char *buf, size_t len); +int read_dev(DEVICE *dev, char *buf, size_t len); +int status_dev(DEVICE *dev, uint32_t *status); +int eod_dev(DEVICE *dev); +int fsf_dev(DEVICE *dev, int num); +int fsr_dev(DEVICE *dev, int num); +int bsf_dev(DEVICE *dev, int num); +int bsr_dev(DEVICE *dev, int num); +void attach_jcr_to_device(DEVICE *dev, JCR *jcr); +void detach_jcr_from_device(DEVICE *dev, JCR *jcr); +JCR *next_attached_jcr(DEVICE *dev, JCR *jcr); +int dev_can_write(DEVICE *dev); +int offline_or_rewind_dev(DEVICE *dev); /* Get info about device */ -char * dev_name(DEVICE *dev); -char * dev_vol_name(DEVICE *dev); +char * dev_name(DEVICE *dev); +char * dev_vol_name(DEVICE *dev); uint32_t dev_block(DEVICE *dev); uint32_t dev_file(DEVICE *dev); -int dev_is_tape(DEVICE *dev); +int dev_is_tape(DEVICE *dev); /* From device.c */ -int open_device(DEVICE *dev); -int fixup_device_block_write_error(JCR *jcr, DEVICE *dev, DEV_BLOCK *block); +int open_device(DEVICE *dev); +int fixup_device_block_write_error(JCR *jcr, DEVICE *dev, DEV_BLOCK *block); void _lock_device(char *file, int line, DEVICE *dev); void _unlock_device(char *file, int line, DEVICE *dev); void _block_device(char *file, int line, DEVICE *dev, int state); @@ -122,44 +122,44 @@ void _give_back_device_lock(char *file, int line, DEVICE *dev, bsteal_lock_t *ho void set_new_volume_parameters(JCR *jcr, DEVICE *dev); /* From dircmd.c */ -void *connection_request(void *arg); +void *connection_request(void *arg); /* From fd_cmds.c */ -void run_job(JCR *jcr); +void run_job(JCR *jcr); /* From job.c */ -void stored_free_jcr(JCR *jcr); -void connection_from_filed(void *arg); -void handle_filed_connection(BSOCK *fd, char *job_name); +void stored_free_jcr(JCR *jcr); +void connection_from_filed(void *arg); +void handle_filed_connection(BSOCK *fd, char *job_name); /* From label.c */ -int read_dev_volume_label(JCR *jcr, DEVICE *dev, DEV_BLOCK *block); -void create_session_label(JCR *jcr, DEV_RECORD *rec, int label); -void create_volume_label(DEVICE *dev, char *VolName); -int write_volume_label_to_dev(JCR *jcr, DEVRES *device, char *VolName, char *PoolName); -int write_session_label(JCR *jcr, DEV_BLOCK *block, int label); -int write_volume_label_to_block(JCR *jcr, DEVICE *dev, DEV_BLOCK *block); -void dump_volume_label(DEVICE *dev); -void dump_label_record(DEVICE *dev, DEV_RECORD *rec, int verbose); -int unser_volume_label(DEVICE *dev, DEV_RECORD *rec); -int unser_session_label(SESSION_LABEL *label, DEV_RECORD *rec); +int read_dev_volume_label(JCR *jcr, DEVICE *dev, DEV_BLOCK *block); +void create_session_label(JCR *jcr, DEV_RECORD *rec, int label); +void create_volume_label(DEVICE *dev, char *VolName); +int write_volume_label_to_dev(JCR *jcr, DEVRES *device, char *VolName, char *PoolName); +int write_session_label(JCR *jcr, DEV_BLOCK *block, int label); +int write_volume_label_to_block(JCR *jcr, DEVICE *dev, DEV_BLOCK *block); +void dump_volume_label(DEVICE *dev); +void dump_label_record(DEVICE *dev, DEV_RECORD *rec, int verbose); +int unser_volume_label(DEVICE *dev, DEV_RECORD *rec); +int unser_session_label(SESSION_LABEL *label, DEV_RECORD *rec); /* From match_bsr.c */ int match_bsr(BSR *bsr, DEV_RECORD *rec, VOLUME_LABEL *volrec, - SESSION_LABEL *sesrec); + SESSION_LABEL *sesrec); int match_bsr_block(BSR *bsr, DEV_BLOCK *block); void position_bsr_block(BSR *bsr, DEV_BLOCK *block); /* From mount.c */ -int mount_next_write_volume(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, int release); -int mount_next_read_volume(JCR *jcr, DEVICE *dev, DEV_BLOCK *block); -void release_volume(JCR *jcr, DEVICE *dev); +int mount_next_write_volume(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, int release); +int mount_next_read_volume(JCR *jcr, DEVICE *dev, DEV_BLOCK *block); +void release_volume(JCR *jcr, DEVICE *dev); /* From autochanger.c */ -int autoload_device(JCR *jcr, DEVICE *dev, int writing, BSOCK *dir); -int autochanger_list(JCR *jcr, DEVICE *dev, BSOCK *dir); -void invalidate_slot_in_catalog(JCR *jcr); +int autoload_device(JCR *jcr, DEVICE *dev, int writing, BSOCK *dir); +int autochanger_list(JCR *jcr, DEVICE *dev, BSOCK *dir); +void invalidate_slot_in_catalog(JCR *jcr); /* From parse_bsr.c */ @@ -174,13 +174,13 @@ extern void create_vol_list(JCR *jcr); /* From record.c */ char *FI_to_ascii(int fi); char *stream_to_ascii(int stream, int fi); -int write_record_to_block(DEV_BLOCK *block, DEV_RECORD *rec); -int can_write_record_to_block(DEV_BLOCK *block, DEV_RECORD *rec); -int read_record_from_block(DEV_BLOCK *block, DEV_RECORD *rec); +int write_record_to_block(DEV_BLOCK *block, DEV_RECORD *rec); +int can_write_record_to_block(DEV_BLOCK *block, DEV_RECORD *rec); +int read_record_from_block(DEV_BLOCK *block, DEV_RECORD *rec); DEV_RECORD *new_record(); -void free_record(DEV_RECORD *rec); +void free_record(DEV_RECORD *rec); /* From read_record.c */ int read_records(JCR *jcr, DEVICE *dev, - void record_cb(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec), + int record_cb(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec), int mount_cb(JCR *jcr, DEVICE *dev, DEV_BLOCK *block)); diff --git a/bacula/src/stored/read.c b/bacula/src/stored/read.c index 2777002b19..d2268133eb 100644 --- a/bacula/src/stored/read.c +++ b/bacula/src/stored/read.c @@ -29,7 +29,7 @@ #include "stored.h" /* Forward referenced subroutines */ -static void get_session_record(DEVICE *dev, DEV_RECORD *rec, SESSION_LABEL *sessrec); +static int record_cb(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec); /* Responses sent to the File daemon */ @@ -43,29 +43,20 @@ static char rec_header[] = "rechdr %ld %ld %ld %ld %ld"; */ int do_read_data(JCR *jcr) { - BSOCK *ds; - BSOCK *fd_sock = jcr->file_bsock; + BSOCK *fd = jcr->file_bsock; int ok = TRUE; - int done = FALSE; DEVICE *dev; - DEV_RECORD *rec; DEV_BLOCK *block; - POOLMEM *hdr; - SESSION_LABEL sessrec; /* session record */ - uint32_t BlockNumber = 0; Dmsg0(20, "Start read data.\n"); dev = jcr->device->dev; - memset(&sessrec, 0, sizeof(sessrec)); /* Tell File daemon we will send data */ - bnet_fsend(fd_sock, OK_data); - Dmsg1(10, "bstored>filed: %s\n", fd_sock->msg); + bnet_fsend(fd, OK_data); + Dmsg1(10, "bstored>filed: %s\n", fd->msg); - ds = fd_sock; - - if (!bnet_set_buffer_size(ds, MAX_NETWORK_BUFFER_SIZE, BNET_SETBUF_READ)) { + if (!bnet_set_buffer_size(fd, MAX_NETWORK_BUFFER_SIZE, BNET_SETBUF_READ)) { return 0; } @@ -96,199 +87,61 @@ int do_read_data(JCR *jcr) return 0; } - rec = new_record(); - free_pool_memory(rec->data); - rec->data = ds->msg; /* use socket message buffer */ - hdr = get_pool_memory(PM_MESSAGE); - - /* - * Read records, apply BSR filtering, and return any that are - * matched. - */ - for ( ; ok && !done; ) { - if (job_canceled(jcr)) { - ok = FALSE; - break; - } - /* Read Record */ - Dmsg1(500, "Main read_record. rem=%d\n", rec->remainder); - - if (block_is_empty(block) && !read_block_from_device(jcr, dev, block, CHECK_BLOCK_NUMBERS)) { - 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; - } - /* Read and discard Volume Label */ - record = new_record(); - read_block_from_device(jcr, dev, block, NO_BLOCK_NUMBER_CHECK); - read_record_from_block(block, record); - get_session_record(dev, record, &sessrec); - free_record(record); - /* Now, continue to read the records on this volume */ - - } else if (dev->state & ST_EOF) { - Dmsg0(90, "Got End of File. Trying again ...\n"); - continue; /* End of File */ - } else if (dev->state & ST_SHORT) { - continue; - } else { - /* I/O error -- or non-standard end of tape */ - Dmsg0(000, "I/O error, bailing out.\n"); - ok = FALSE; - break; - } - } - - if (!block_is_empty(block) && !match_bsr_block(jcr->bsr, block)) { - Dmsg5(150, "reject Blk=%u blen=%u bVer=%d SessId=%u SessTim=%u\n", - block->BlockNumber, block->block_len, block->BlockVer, - block->VolSessionId, block->VolSessionTime); - empty_block(block); /* force read next block */ - continue; - } - - for (rec->state=0; !is_block_empty(rec); ) { - - if (!read_record_from_block(block, rec)) { - break; - } - /* - * At this point, we have at least a record header. - * Now decide if we want this record or not, but remember - * before accessing the record, we may need to read again to - * 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) { - get_session_record(dev, rec, &sessrec); - continue; - } /* end if label record */ - - - /* Match BSR against current record */ - if (jcr->bsr) { - int stat = match_bsr(jcr->bsr, rec, &dev->VolHdr, &sessrec); - if (stat == -1) { /* no more possible matches */ - done = TRUE; - break; - } else if (stat == 0) { /* no match */ - Dmsg0(50, "BSR rejected record\n"); - rec->remainder = 0; - continue; - } - } else { - /* Old way, deprecated */ - if (rec->VolSessionId != jcr->read_VolSessionId || - rec->VolSessionTime != jcr->read_VolSessionTime) { - Dmsg0(50, "Ignore record ids not equal\n"); - rec->remainder = 0; - continue; /* ignore */ - } - } - - if (block->block_read) { - if (BlockNumber != block->BlockNumber) { - Jmsg(jcr, M_ERROR, 0, _("Invalid block number. Expected %u, got %u\n"), - BlockNumber, block->BlockNumber); - } - BlockNumber = block->BlockNumber + 1; - block->block_read = false; - } + ok = read_records(jcr, dev, record_cb, mount_next_read_volume); - if (is_partial_record(rec)) { - break; /* Go read full record */ - } - - /* - * We "finally" have a full record here. Now - * generate Header parameters and send to File daemon - * Note, we build header in hdr buffer to avoid wiping - * out the data record - */ - ds->msg = hdr; - Dmsg5(400, "Send to FD: SessId=%u SessTim=%u FI=%d Strm=%d, len=%d\n", - rec->VolSessionId, rec->VolSessionTime, rec->FileIndex, rec->Stream, - rec->data_len); - if (!bnet_fsend(ds, rec_header, rec->VolSessionId, rec->VolSessionTime, - rec->FileIndex, rec->Stream, rec->data_len)) { - Dmsg1(30, ">filed: Error Hdr=%s\n", ds->msg); - hdr = ds->msg; - ds->msg = rec->data; - Jmsg1(jcr, M_FATAL, 0, _("Error sending to File daemon. ERR=%s\n"), - bnet_strerror(ds)); - ok = FALSE; - break; - } else { - Dmsg1(30, ">filed: Hdr=%s\n", ds->msg); - } - - hdr = ds->msg; /* restore hdr buffer */ - ds->msg = rec->data; /* restore data record address */ - - /* Send data record to File daemon */ - ds->msglen = rec->data_len; - Dmsg1(40, ">filed: send %d bytes data.\n", ds->msglen); - if (!bnet_send(ds)) { - Pmsg1(000, "Error sending to FD. ERR=%s\n", bnet_strerror(ds)); - Dmsg1(100, "Hdr=%s\n", hdr); - Dmsg1(100, "data=%s\n", ds->msg); - Jmsg1(jcr, M_FATAL, 0, _("Error sending to File daemon. ERR=%s\n"), - bnet_strerror(ds)); - ok = FALSE; - break; - } - } /* end for loop reading records */ - } /* end for loop reading blocks */ /* Send end of data to FD */ - bnet_sig(ds, BNET_EOD); + bnet_sig(fd, BNET_EOD); if (!release_device(jcr, dev)) { ok = FALSE; } - free_pool_memory(hdr); + free_block(block); - rec->data = NULL; /* previously released */ - free_record(rec); free_vol_list(jcr); Dmsg0(30, "Done reading.\n"); return ok ? 1 : 0; } -static void get_session_record(DEVICE *dev, DEV_RECORD *rec, SESSION_LABEL *sessrec) +/* + * Called here for each record from read_records() + */ +static int record_cb(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec) { - 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; + BSOCK *fd = jcr->file_bsock; + int ok = TRUE; + POOLMEM *save_msg; + + if (rec->FileIndex < 0) { + return 1; + } + Dmsg5(100, "Send to FD: SessId=%u SessTim=%u FI=%d Strm=%d, len=%d\n", + rec->VolSessionId, rec->VolSessionTime, rec->FileIndex, rec->Stream, + rec->data_len); + + /* Send record header to File daemon */ + if (!bnet_fsend(fd, rec_header, rec->VolSessionId, rec->VolSessionTime, + rec->FileIndex, rec->Stream, rec->data_len)) { + Dmsg1(30, ">filed: Error Hdr=%s\n", fd->msg); + Jmsg1(jcr, M_FATAL, 0, _("Error sending to File daemon. ERR=%s\n"), + bnet_strerror(fd)); + return FALSE; + } else { + Dmsg1(30, ">filed: Hdr=%s\n", fd->msg); + } + + + /* Send data record to File daemon */ + save_msg = fd->msg; /* save fd message pointer */ + fd->msg = rec->data; /* pass data directly to bnet_send */ + fd->msglen = rec->data_len; + Dmsg1(30, ">filed: send %d bytes data.\n", fd->msglen); + if (!bnet_send(fd)) { + Pmsg1(000, "Error sending to FD. ERR=%s\n", bnet_strerror(fd)); + Jmsg1(jcr, M_FATAL, 0, _("Error sending to File daemon. ERR=%s\n"), + bnet_strerror(fd)); + + ok = FALSE; } - Dmsg5(10, "%s Record: VolSessionId=%d VolSessionTime=%d JobId=%d DataLen=%d\n", - rtype, rec->VolSessionId, rec->VolSessionTime, rec->Stream, rec->data_len); + fd->msg = save_msg; /* restore fd message pointer */ + return ok; } diff --git a/bacula/src/stored/read_record.c b/bacula/src/stored/read_record.c index 8fd93d5b33..0d10941c6a 100644 --- a/bacula/src/stored/read_record.c +++ b/bacula/src/stored/read_record.c @@ -39,18 +39,20 @@ static char *rec_state_to_str(DEV_RECORD *rec); #endif int read_records(JCR *jcr, DEVICE *dev, - void record_cb(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec), + int record_cb(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec), int mount_cb(JCR *jcr, DEVICE *dev, DEV_BLOCK *block)) { DEV_BLOCK *block; - DEV_RECORD *rec; - uint32_t record, num_files = 0; + DEV_RECORD *rec = NULL; + uint32_t record; int ok = TRUE; - int done = FALSE; + bool done = false; SESSION_LABEL sessrec; + dlist *recs; block = new_block(dev); - rec = new_record(); + recs = new dlist(rec, &rec->link); + for ( ; ok && !done; ) { if (job_canceled(jcr)) { ok = FALSE; @@ -63,7 +65,7 @@ int read_records(JCR *jcr, DEVICE *dev, Dmsg3(100, "EOT. stat=%s blk=%d rem=%d\n", rec_state_to_str(rec), block->BlockNumber, rec->remainder); - Jmsg(jcr, M_INFO, 0, "Got EOM at file %u on device %s, Volume \"%s\"\n", + Jmsg(jcr, M_INFO, 0, "End of Volume at file %u on device %s, Volume \"%s\"\n", dev->file, dev_name(dev), jcr->VolumeName); if (!mount_cb(jcr, dev, block)) { Jmsg(jcr, M_INFO, 0, "End of all volumes.\n"); @@ -78,7 +80,7 @@ int read_records(JCR *jcr, DEVICE *dev, trec->FileIndex = EOT_LABEL; trec->File = dev->file; trec->Block = rec->Block; /* return block last read */ - record_cb(jcr, dev, block, trec); + ok = record_cb(jcr, dev, block, trec); free_record(trec); break; } @@ -92,17 +94,15 @@ int read_records(JCR *jcr, DEVICE *dev, read_block_from_device(jcr, dev, block, NO_BLOCK_NUMBER_CHECK); read_record_from_block(block, trec); get_session_record(dev, trec, &sessrec); - record_cb(jcr, dev, block, trec); + ok = record_cb(jcr, dev, block, trec); free_record(trec); - goto next_record; /* go read new tape */ - } else if (dev->state & ST_EOF) { Jmsg(jcr, M_INFO, 0, "Got EOF at file %u on device %s, Volume \"%s\"\n", dev->file, dev_name(dev), jcr->VolumeName); Dmsg0(20, "read_record got eof. try again\n"); continue; } else if (dev->state & ST_SHORT) { - Jmsg(jcr, M_INFO, 0, "%s", dev->errmsg); + Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg); continue; } else { /* I/O error or strange end of tape */ @@ -117,12 +117,32 @@ int read_records(JCR *jcr, DEVICE *dev, block->VolSessionId, block->VolSessionTime); continue; } - if (verbose) { - Pmsg4(000, "Block: %d VI=%u VT=%u blen=%d\n", block->BlockNumber, - block->VolSessionId, block->VolSessionTime, block->block_len); - } + Dmsg4(100, "Block: %d VI=%u VT=%u blen=%d\n", block->BlockNumber, + block->VolSessionId, block->VolSessionTime, block->block_len); -next_record: + /* + * Get a new record for each Job as defined by + * VolSessionId and VolSessionTime + */ + bool found = false; + for (rec=(DEV_RECORD *)recs->first(); rec; rec=(DEV_RECORD *)recs->next(rec)) { + if (rec->VolSessionId == block->VolSessionId && + rec->VolSessionTime == block->VolSessionTime) { + found = true; + break; + } + } + if (!found) { + rec = new_record(); + recs->prepend(rec); + Dmsg2(100, "New record for SI=%d ST=%d\n", + block->VolSessionId, block->VolSessionTime); + } else { + if ((rec->Block+1) != block->BlockNumber) { + Jmsg(jcr, M_ERROR, 0, _("Invalid block number. Expected %u, got %u\n"), + rec->Block+1, block->BlockNumber); + } + } record = 0; for (rec->state=0; !is_block_empty(rec); ) { if (!read_record_from_block(block, rec)) { @@ -139,28 +159,29 @@ next_record: * get all the data. */ record++; - if (verbose) { - Dmsg6(30, "recno=%d state=%s blk=%d SI=%d ST=%d FI=%d\n", record, - rec_state_to_str(rec), block->BlockNumber, - rec->VolSessionId, rec->VolSessionTime, rec->FileIndex); - } - if (debug_level >= 30) { - Dmsg4(30, "VolSId=%ld FI=%s Strm=%s Size=%ld\n", rec->VolSessionId, - FI_to_ascii(rec->FileIndex), - stream_to_ascii(rec->Stream, rec->FileIndex), - rec->data_len); - } + Dmsg6(30, "recno=%d state=%s blk=%d SI=%d ST=%d FI=%d\n", record, + rec_state_to_str(rec), block->BlockNumber, + rec->VolSessionId, rec->VolSessionTime, rec->FileIndex); + Dmsg4(30, "VolSId=%ld FI=%s Strm=%s Size=%ld\n", rec->VolSessionId, + FI_to_ascii(rec->FileIndex), + stream_to_ascii(rec->Stream, rec->FileIndex), + rec->data_len); 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) { get_session_record(dev, rec, &sessrec); - record_cb(jcr, dev, block, rec); + ok = record_cb(jcr, dev, block, rec); + if (rec->FileIndex == EOS_LABEL) { + Dmsg2(100, "Remove rec. SI=%d ST=%d\n", rec->VolSessionId, + rec->VolSessionTime); + recs->remove(rec); + free_record(rec); + } continue; } /* end if label record */ @@ -170,15 +191,12 @@ next_record: if (jcr->bsr) { int stat = match_bsr(jcr->bsr, rec, &dev->VolHdr, &sessrec); if (stat == -1) { /* no more possible matches */ - done = TRUE; /* all items found, stop */ + done = true; /* all items found, stop */ break; } else if (stat == 0) { /* no match */ - if (verbose) { - Dmsg5(10, "BSR no match rec=%d block=%d SessId=%d SessTime=%d FI=%d\n", - record, block->BlockNumber, rec->VolSessionId, rec->VolSessionTime, - rec->FileIndex); - } - rec->remainder = 0; + Dmsg5(10, "BSR no match rec=%d block=%d SessId=%d SessTime=%d FI=%d\n", + record, block->BlockNumber, rec->VolSessionId, rec->VolSessionTime, + rec->FileIndex); continue; /* we don't want record, read next one */ } } @@ -188,13 +206,18 @@ next_record: rec->VolSessionId, rec->VolSessionTime, rec->FileIndex); break; /* read second part of record */ } - record_cb(jcr, dev, block, rec); - } - } - if (verbose) { - printf("%u files found.\n", num_files); + ok = record_cb(jcr, dev, block, rec); + } /* end for loop over records */ + } /* end for loop over blocks */ + + /* Walk down list and free all remaining allocated recs */ + for (rec=(DEV_RECORD *)recs->first(); rec; ) { + DEV_RECORD *nrec = (DEV_RECORD *)recs->next(rec); + recs->remove(rec); + free_record(rec); + rec = nrec; } - free_record(rec); + delete recs; free_block(block); return ok; } @@ -205,26 +228,26 @@ static void get_session_record(DEVICE *dev, DEV_RECORD *rec, SESSION_LABEL *sess 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; + 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); diff --git a/bacula/src/stored/record.h b/bacula/src/stored/record.h index f0c3684d0c..f00207547e 100644 --- a/bacula/src/stored/record.h +++ b/bacula/src/stored/record.h @@ -30,15 +30,15 @@ #define __RECORD_H 1 /* Return codes from read_device_volume_label() */ -#define VOL_NOT_READ 0 /* Volume label not read */ -#define VOL_OK 1 /* volume name OK */ -#define VOL_NO_LABEL 2 /* volume not labeled */ -#define VOL_IO_ERROR 3 /* volume I/O error */ -#define VOL_NAME_ERROR 4 /* Volume name mismatch */ -#define VOL_CREATE_ERROR 5 /* Error creating label */ -#define VOL_VERSION_ERROR 6 /* Bacula version error */ -#define VOL_LABEL_ERROR 7 /* Bad label type */ -#define VOL_NO_MEDIA 8 /* Hard error -- no media present */ +#define VOL_NOT_READ 0 /* Volume label not read */ +#define VOL_OK 1 /* volume name OK */ +#define VOL_NO_LABEL 2 /* volume not labeled */ +#define VOL_IO_ERROR 3 /* volume I/O error */ +#define VOL_NAME_ERROR 4 /* Volume name mismatch */ +#define VOL_CREATE_ERROR 5 /* Error creating label */ +#define VOL_VERSION_ERROR 6 /* Bacula version error */ +#define VOL_LABEL_ERROR 7 /* Bad label type */ +#define VOL_NO_MEDIA 8 /* Hard error -- no media present */ /* See block.h for RECHDR_LENGTH */ @@ -61,12 +61,12 @@ */ /* Record state bit definitions */ -#define REC_NO_HEADER (1<<0) /* No header read */ +#define REC_NO_HEADER (1<<0) /* No header read */ #define REC_PARTIAL_RECORD (1<<1) /* returning partial record */ #define REC_BLOCK_EMPTY (1<<2) /* not enough data in block */ -#define REC_NO_MATCH (1<<3) /* No match on continuation data */ +#define REC_NO_MATCH (1<<3) /* No match on continuation data */ #define REC_CONTINUATION (1<<4) /* Continuation record found */ -#define REC_ISTAPE (1<<5) /* Set if device is tape */ +#define REC_ISTAPE (1<<5) /* Set if device is tape */ #define is_partial_record(r) ((r)->state & REC_PARTIAL_RECORD) #define is_block_empty(r) ((r)->state & REC_BLOCK_EMPTY) @@ -78,22 +78,22 @@ * This is the memory structure for the record header. */ struct DEV_RECORD { - int sync; /* synchronous */ - /* File and Block are always returned on reading records, but - * only returned on writing if sync is set (obviously). + dlink link; /* link for chaining in read_record.c */ + /* File and Block are always returned during reading + * and writing records. */ - uint32_t File; /* File number */ - uint32_t Block; /* Block number */ - uint32_t VolSessionId; /* sequential id within this session */ - uint32_t VolSessionTime; /* session start time */ - int32_t FileIndex; /* sequential file number */ - int32_t Stream; /* stream number */ - uint32_t data_len; /* current record length */ - uint32_t remainder; /* remaining bytes to read/write */ - uint32_t state; /* state bits */ + uint32_t File; /* File number */ + uint32_t Block; /* Block number */ + uint32_t VolSessionId; /* sequential id within this session */ + uint32_t VolSessionTime; /* session start time */ + int32_t FileIndex; /* sequential file number */ + int32_t Stream; /* stream number */ + uint32_t data_len; /* current record length */ + uint32_t remainder; /* remaining bytes to read/write */ + uint32_t state; /* state bits */ uint8_t ser_buf[WRITE_RECHDR_LENGTH]; /* serialized record header goes here */ - POOLMEM *data; /* Record data. This MUST be a memory pool item */ -}; + POOLMEM *data; /* Record data. This MUST be a memory pool item */ +}; /* @@ -101,12 +101,12 @@ struct DEV_RECORD { * Note, these values are negative to distinguish them * from user records where the FileIndex is forced positive. */ -#define PRE_LABEL -1 /* Vol label on unwritten tape */ -#define VOL_LABEL -2 /* Volume label first file */ -#define EOM_LABEL -3 /* Writen at end of tape */ -#define SOS_LABEL -4 /* Start of Session */ -#define EOS_LABEL -5 /* End of Session */ -#define EOT_LABEL -6 /* End of physical tape (2 eofs) */ +#define PRE_LABEL -1 /* Vol label on unwritten tape */ +#define VOL_LABEL -2 /* Volume label first file */ +#define EOM_LABEL -3 /* Writen at end of tape */ +#define SOS_LABEL -4 /* Start of Session */ +#define EOS_LABEL -5 /* End of Session */ +#define EOT_LABEL -6 /* End of physical tape (2 eofs) */ /* * Volume Label Record. This is the in-memory definition. The @@ -121,27 +121,27 @@ struct Volume_Label { * in the DEVICE buffer, but are not actually written * to the tape. */ - int32_t LabelType; /* This is written in header only */ - uint32_t LabelSize; /* length of serialized label */ + int32_t LabelType; /* This is written in header only */ + uint32_t LabelSize; /* length of serialized label */ /* * The items below this line are stored on * the tape */ - char Id[32]; /* Bacula Immortal ... */ + char Id[32]; /* Bacula Immortal ... */ - uint32_t VerNum; /* Label version number */ + uint32_t VerNum; /* Label version number */ /* VerNum <= 10 */ - float64_t label_date; /* Date tape labeled */ - float64_t label_time; /* Time tape labeled */ + float64_t label_date; /* Date tape labeled */ + float64_t label_time; /* Time tape labeled */ /* VerNum >= 11 */ - btime_t label_btime; /* tdate tape labeled */ - btime_t write_btime; /* tdate tape written */ + btime_t label_btime; /* tdate tape labeled */ + btime_t write_btime; /* tdate tape written */ /* Unused with VerNum >= 11 */ - float64_t write_date; /* Date this label written */ - float64_t write_time; /* Time this label written */ + float64_t write_date; /* Date this label written */ + float64_t write_time; /* Time this label written */ char VolName[MAX_NAME_LENGTH]; /* Volume name */ char PrevVolName[MAX_NAME_LENGTH]; /* Previous Volume Name */ @@ -150,9 +150,9 @@ struct Volume_Label { char MediaType[MAX_NAME_LENGTH]; /* Type of this media */ char HostName[MAX_NAME_LENGTH]; /* Host name of writing computer */ - char LabelProg[50]; /* Label program name */ - char ProgVersion[50]; /* Program version */ - char ProgDate[50]; /* Program build date/time */ + char LabelProg[50]; /* Label program name */ + char ProgVersion[50]; /* Program version */ + char ProgDate[50]; /* Program build date/time */ }; #define SER_LENGTH_Volume_Label 1024 /* max serialised length of volume label */ @@ -165,27 +165,27 @@ typedef struct Volume_Label VOLUME_LABEL; * This record is at the beginning and end of each session */ struct Session_Label { - char Id[32]; /* Bacula Immortal ... */ + char Id[32]; /* Bacula Immortal ... */ - uint32_t VerNum; /* Label version number */ + uint32_t VerNum; /* Label version number */ - uint32_t JobId; /* Job id */ - uint32_t VolumeIndex; /* Sequence no of volume for this job */ + uint32_t JobId; /* Job id */ + uint32_t VolumeIndex; /* Sequence no of volume for this job */ /* VerNum >= 11 */ - btime_t write_btime; /* Tdate this label written */ + btime_t write_btime; /* Tdate this label written */ /* VerNum < 11 */ - float64_t write_date; /* Date this label written */ + float64_t write_date; /* Date this label written */ /* Unused VerNum >= 11 */ - float64_t write_time; /* Time this label written */ + float64_t write_time; /* Time this label written */ char PoolName[MAX_NAME_LENGTH]; /* Pool name */ char PoolType[MAX_NAME_LENGTH]; /* Pool type */ char JobName[MAX_NAME_LENGTH]; /* base Job name */ char ClientName[MAX_NAME_LENGTH]; - char Job[MAX_NAME_LENGTH]; /* Unique name of this Job */ + char Job[MAX_NAME_LENGTH]; /* Unique name of this Job */ char FileSetName[MAX_NAME_LENGTH]; char FileSetMD5[MAX_NAME_LENGTH]; uint32_t JobType; @@ -198,11 +198,11 @@ struct Session_Label { uint32_t StartFile; uint32_t EndFile; uint32_t JobErrors; - uint32_t JobStatus; /* Job status */ + uint32_t JobStatus; /* Job status */ }; typedef struct Session_Label SESSION_LABEL; -#define SERIAL_BUFSIZE 1024 /* volume serialisation buffer size */ +#define SERIAL_BUFSIZE 1024 /* volume serialisation buffer size */ #endif diff --git a/bacula/src/version.h b/bacula/src/version.h index 3e26c96c2d..e1efc7f45b 100644 --- a/bacula/src/version.h +++ b/bacula/src/version.h @@ -1,8 +1,8 @@ /* */ -#define VERSION "1.31a" +#define VERSION "1.31b" #define VSTRING "1" -#define BDATE "02 Aug 2003" -#define LSMDATE "02Aug03" +#define BDATE "03 Aug 2003" +#define LSMDATE "03Aug03" /* Debug flags */ #define DEBUG 1 -- 2.39.5