From: Kern Sibbald Date: Thu, 17 Mar 2005 18:24:54 +0000 (+0000) Subject: - Detect if fseeko exists with autoconf. If so, use it X-Git-Tag: Release-1.38.0~592 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=d5472a00f3258b5777f44de47d2d9b1db0e807f2;p=bacula%2Fbacula - Detect if fseeko exists with autoconf. If so, use it and ftello. - Remove old bacula-*.conf from examples directory (out of date). - Remove latex-fr index files from CVS. - Rewrite code that stops reading the tape so that the tape is marked at EOT, then once the work is done, the EOT flag is removed. - Flush output to file after every send in console. - Make setting VolFiles to smaller number fatal. - Disable Multiple Connections code. - Add patch from user for NetBSD statvsfs() fix to fstype.c - Take more care with errors in acquire.c - Don't run through dvd code in append.c if bad status returned. - Modify code so that an autochanger fault is fatal. - Use dev->print_name() in more places. - Implement dev->can_steal_lock() to simplify code. - Make btape re-read first 10000 records on fill command. - Check error return and fail job from fseeko and ftello in spool.c. Don't let a -1 slip in as size. git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@1890 91ce42f0-d328-0410-95d8-f526ca767f89 --- diff --git a/bacula/autoconf/config.h.in b/bacula/autoconf/config.h.in index ee8c0df5c1..154fe9376e 100644 --- a/bacula/autoconf/config.h.in +++ b/bacula/autoconf/config.h.in @@ -270,6 +270,9 @@ /* Define to 1 if you have the `fork' function. */ #undef HAVE_FORK +/* Define to 1 if you have the `fseeko' function. */ +#undef HAVE_FSEEKO + /* Define to 1 if you have the `getcwd' function. */ #undef HAVE_GETCWD diff --git a/bacula/autoconf/configure.in b/bacula/autoconf/configure.in index 3cabbaec34..cb4804cf8c 100644 --- a/bacula/autoconf/configure.in +++ b/bacula/autoconf/configure.in @@ -1452,7 +1452,7 @@ AC_CHECK_FUNCS(strtoll, [AC_DEFINE(HAVE_STRTOLL)]) AC_CHECK_FUNCS(chflags) -AC_CHECK_FUNCS(snprintf vsnprintf gethostid) +AC_CHECK_FUNCS(snprintf vsnprintf gethostid fseeko) dnl# -------------------------------------------------------------------------- dnl# CHECKING FOR THREAD SAFE FUNCTIONS diff --git a/bacula/configure b/bacula/configure index b04bb191b4..6b8730a0a5 100755 --- a/bacula/configure +++ b/bacula/configure @@ -18169,7 +18169,8 @@ done -for ac_func in snprintf vsnprintf gethostid + +for ac_func in snprintf vsnprintf gethostid fseeko do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` echo "$as_me:$LINENO: checking for $ac_func" >&5 diff --git a/bacula/examples/conf/bacula-dir.conf b/bacula/examples/conf/bacula-dir.conf deleted file mode 100644 index c3188e6a24..0000000000 --- a/bacula/examples/conf/bacula-dir.conf +++ /dev/null @@ -1,449 +0,0 @@ -# -# Kerns Production Bacula Director Daemon Configuration file -# - -Director { - Name = HeadMan - DIRport = 9101 # where we listen for UA connections - QueryFile = "/home/bacula/bin/query.sql" - WorkingDirectory = "/home/bacula/bin/working" - PidDirectory = "/home/bacula/bin/working" - SubSysDirectory = "/home/bacula/bin/working" - Maximum Concurrent Jobs = 1 - Password = -} - -Schedule { - Name = "PolyMatouWeeklyCycle" - Run = Level=Full sun at 1:05 - Run = Level=Incremental mon-sat at 1:05 -} - -Schedule { - Name = "MatouWeeklyCycle" - Run = Level=Full 1st sat at 1:05 - Run = Level=Differential 2nd-5th sat at 1:05 - Run = Level=Incremental sun-fri at 1:05 -} - -Schedule { - Name = "VerifyCycle" - Run = Level=Catalog sun-sat at 5:05 -} - - -Schedule { - Name = "MinimatouWeeklyCycle" - Run = Level=Full fri at 1:05 - Run = Level=Incremental sat-thu at 1:05 -} - -Schedule { - Name = "MinouWeeklyCycle" - Run = Level=Full thu at 1:05 - Run = Level=Incremental fri-wed at 1:05 -} - -Schedule { - Name = "RufusWeeklyCycle" - Run = Level=Full 1st mon at 1:05 - Run = Level=Differential 2nd-5th mon at 1:05 - Run = Level=Incremental tue-sun at 1:05 -} - -Schedule { - Name = "CatalogSched" - Run = Level=Full sun-sat at 1:10 -} - -Schedule { - Name = "Watchdog" - Run = Level=Full sun-sat at 6:05 -} - - -Job { - Name = "Matou" - Type = Backup - Level = Incremental - Client=Matou - FileSet="Matou Set" - Messages = Standard - Storage = DLTDrive - Pool = Default - Schedule = "MatouWeeklyCycle" - Write Bootstrap = "/mnt/deuter/files/backup/matou.bsr" - Priority = 10 -} - -Job { - Name = "Polymatou" - Type = Backup - Level = Incremental - Client=Polymatou - FileSet="Full Set" - Messages = Standard - Storage = DLTDrive - Pool = Default - Schedule = "PolyMatouWeeklyCycle" - Write Bootstrap = "/mnt/deuter/files/backup/pmatou.bsr" - Priority = 10 -} - -Job { - Name = "Rufus" - Type = Backup - Level = Incremental - Client=Rufus - FileSet="RufusAll" - Messages = Standard - Storage = DLTDrive - Pool = Default - Schedule = "RufusWeeklyCycle" - Write Bootstrap = "/mnt/deuter/files/backup/rufus.bsr" - Priority = 10 -} - -Job { - Name = "Minimatou" - Type = Backup - Level = Incremental - Client=Minimatou - FileSet="Win32 Full Set" - Messages = Standard - Storage = DLTDrive - Pool = Default - Schedule = "MinimatouWeeklyCycle" - Write Bootstrap = "/mnt/deuter/files/backup/mmatou.bsr" - Priority = 11 -} - -Job { - Name = "Minou" - Type = Backup - Level = Incremental - Client=Minou - FileSet="Minou Full Set" - Messages = Standard - Storage = DLTDrive - Pool = Default - Schedule = "MinouWeeklyCycle" - Write Bootstrap = "/mnt/deuter/files/backup/minou.bsr" - Priority = 11 -} - -Job { - Name = "PmatouVerify" - Type = Verify - Level = Catalog - Client=PmatouVerify - FileSet="Verify Set" - Messages = Standard - Storage = DLTDrive - Pool = Default - Schedule = "VerifyCycle" - Priority = 20 # run after backups -} - -Job { - Name = "MatouVerify" - Type = Verify - Level = Catalog - Client=MatouVerify - FileSet="Verify Set" - Messages = Standard - Storage = DLTDrive - Pool = Default - Schedule = "VerifyCycle" - Priority = 20 -} - -Job { - Name = "RufusVerify" - Type = Verify - Level = Catalog - Client=RufusVerify - FileSet="Verify Set" - Messages = Standard - Storage = DLTDrive - Pool = Default - Schedule = "VerifyCycle" - Priority = 20 -} - -Job { - Name = "CatalogBackup" - Type = Backup - Level = Full - Client = Polymatou - FileSet = "CatalogFile" - Messages = Standard - Storage = DLTDrive - Pool = Default - Schedule = "CatalogSched" - RunBeforeJob = "/home/bacula/bin/make_catalog_backup" - RunAfterJob = "/home/bacula/bin/delete_catalog_backup" - Write Bootstrap = "/mnt/deuter/files/backup/catalog.bsr" - Priority = 15 # run after backups, but before Verifies -} - -Job { - Name = "Watchdog" - Type = Admin - Client=Watchdog - FileSet="Verify Set" - Messages = Standard - Storage = DLTDrive - Pool = Default - Schedule = "Watchdog" - RunAfterJob = "/home/bacula/bin/watchdog" - Priority = 99 # last job to run -} - -# Standard Restore template, to be changed by Console program -Job { - Name = "RestoreFiles" - Type = Restore - Client=Rufus - FileSet="Full Set" - Storage = DLTDrive - Messages = Standard - Pool = Default - Where = /tmp/bacula-restores -} - - -FileSet { - Name = "Matou Set" - Include = signature=MD5 { - / - /home - /usr - /files - } - Exclude = { /tmp/* } -} - - -FileSet { - Name = "Full Set" - Include = signature=MD5 { - @/etc/backup.list - } - Exclude = { } -} - -FileSet { - Name = "RufusAll" - Include = signature=MD5 { - / - /boot - /home - /usr - } - Exclude = { } -} - -# Backup the copy of the catalog -FileSet { - Name = "CatalogFile" - Include = signature=MD5 { - /home/bacula/bin/working/bacula.sql - } -} - - -FileSet { - Name = "Verify Set" - Include = verify=pins5 signature=MD5 { - /boot - /bin - /sbin - /usr/bin - /lib - /root/.ssh - /home/kern/.ssh - /var/named - /etc/sysconfig - /etc/ssh - /etc/security - /etc/exports - /etc/rc.d/init.d - /etc/sendmail.cf - /etc/sysctl.conf - /etc/services - /etc/xinetd.d - /etc/hosts.allow - /etc/hosts.deny - /etc/hosts - /etc/modules.conf - /etc/named.conf - /etc/pam.d - /etc/resolv.conf - } - Exclude = { } -} - - -FileSet { - Name = "Win32 Full Set" - Include = signature=MD5 { - "c:/My Documents" - } - Exclude = { } -} - -FileSet { - Name = "Minou Full Set" - Include = signature=MD5 { - "d:/My Documents" - } - Exclude = { } -} - -# Definition of tape storage device -Storage { - Name = DLTDrive - Address = lpmatou - SDPort = 9103 - Password = - Device = "HP DLT 80" # must be same as Device in Storage daemon - Media Type = DLT8000 # must be same as MediaType in Storage daemon -} - -#Storage { -# Name = "8mmDrive" -# Address = lpmatou -# SDPort = 9103 -# Password = -# Device = "Exabyte 8mm" -# MediaType = "8mm" -#} - -Client { - Name = Matou - Address = lmatou - FDPort = 9102 - Catalog = BackupDB - Password = - File Retention = 30d # 80 days - Job Retention = 1y # one year - AutoPrune = yes # Prune expired Jobs/Files -} - -Client { - Name = Polymatou - Address = lpmatou - FDPort = 9102 - Catalog = BackupDB - Password = - File Retention = 30d # 80 days - Job Retention = 1y # one year - AutoPrune = yes # Prune expired Jobs/Files -} - -Client { - Name = Rufus - Address = rufus - FDPort = 9102 - Catalog = BackupDB - Password = - File Retention = 30d # 80 days - Job Retention = 1y # one year - AutoPrune = yes # Prune expired Jobs/Files -} - -Client { - Name = Minimatou - Address = minimatou - FDPort = 9102 - Catalog = BackupDB - Password = - File Retention = 30d # 80 days - Job Retention = 1y # one year - AutoPrune = yes # Prune expired Jobs/Files -} - -Client { - Name = Minou - Address = minou - FDPort = 9102 - Catalog = BackupDB - Password = - File Retention = 30d # 80 days - Job Retention = 1y # one year - AutoPrune = yes # Prune expired Jobs/Files -} - -Client { - Name = MatouVerify - Address = lmatou - FDPort = 9102 - Catalog = Verify - Password = - File Retention = 30d # 30 days - Job Retention = 30d # 30 days - AutoPrune = yes # Prune expired Jobs/Files -} - -Client { - Name = PmatouVerify - Address = lpmatou - FDPort = 9102 - Catalog = Verify - Password = - File Retention = 30d # 30 days - Job Retention = 30d # 30 days - AutoPrune = yes # Prune expired Jobs/Files -} - -Client { - Name = RufusVerify - Address = rufus - FDPort = 9102 - Catalog = Verify - Password = - File Retention = 30d # 30 days - Job Retention = 30d # 30 days - AutoPrune = yes # Prune expired Jobs/Files -} - -Client { - Name = Watchdog - Address = rufus - FDPort = 9102 - Catalog = Verify - Password = - File Retention = 1d # 1 days - Job Retention = 1m # 1 month - AutoPrune = yes # Prune expired Jobs/Files -} - -Catalog { - Name = BackupDB - dbname = bacula; user = bacula; password = "" -} - -Catalog { - Name = Verify - dbname = verify; user = bacula; password = "" -} - -Messages { - Name = Standard - mailcommand = "/home/bacula/bin/smtp -h mail.sibbald.com -f \"\(Bacula\) %r\" -s \"Bacula: %t %e of %c %l\" %r" - operatorcommand = "/home/bacula/bin/smtp -h YOUR-SMTP_SERVER.com -f \"\(Bacula\) %r\" -s \"Bacula: Intervention needed for %j\" %r" - MailOnError = YOUR-EMAIL@YOU.com = all - append = "/home/bacula/bin/log" = all - operator = YOUR-EMAIL@YOU.com = mount - console = all -} - - -Pool { - Name = Default - Pool Type = Backup - Recycle = yes # Bacula can automatically recycle Volumes - AutoPrune = yes # Prune expired volumes - Volume Retention = 1y # one year -} diff --git a/bacula/examples/conf/bacula-fd.conf b/bacula/examples/conf/bacula-fd.conf deleted file mode 100644 index 2e5fd48354..0000000000 --- a/bacula/examples/conf/bacula-fd.conf +++ /dev/null @@ -1,31 +0,0 @@ -# -# Kern's Production Bacula File Daemon Configuration file -# -# -# "Global" File daemon configuration specifications -# -Client { # this is me - Name = "PolymatouFD" - FDport = 9102 # where we listen for the director - WorkingDirectory = "/home/bacula/bin/working" - PidDirectory = "/home/bacula/bin/working" - SubSysDirectory = "/home/bacula/bin/working" -} - -# -# List Directors who are permitted to contact the File daemon -# -Director { - Name = HeadMan - Password = "" -} - -Director { - Name = RightHandMan - Password = xxxxx -} - -Messages { - Name = Standard - director = HeadMan = all, !skipped -} diff --git a/bacula/examples/conf/bacula-sd.conf b/bacula/examples/conf/bacula-sd.conf deleted file mode 100644 index 35521378b4..0000000000 --- a/bacula/examples/conf/bacula-sd.conf +++ /dev/null @@ -1,53 +0,0 @@ -# -# Kern's Production Bacula Storage Daemon Configuration file -# - -# -# "Global" Storage daemon configuration specifications -# -Storage { - Name = "MainSD" - SDPort = 9103 # Directors port - WorkingDirectory = "/home/bacula/bin/working" - PidDirectory = "/home/bacula/bin/working" - SubSysDirectory = "/home/bacula/bin/working" -} - -# -# List Directors who are permitted to contact Storage daemon -# -Director { - Name = HeadMan - Password = "" -} - -# -# Devices supported by this Storage daemon -# To connect, the Director must have the same Name and MediaType, -# which are sent to the File daemon -# -Device { - Name = "HP DLT 80" - Media Type = DLT8000 - Archive Device = /dev/nst0 - AutomaticMount = yes; # when device opened, read it - AlwaysOpen = yes; - RemovableMedia = yes; -} - -#Device { -# Name = "Exabyte 8mm" -# Media Type = "8mm" -# Archive Device = /dev/nst1 -# Hardware end of medium = No; -## LabelMedia = yes; # lets Bacula label unlabelled media -# AutomaticMount = yes; # when device opened, read it -# AlwaysOpen = Yes; -# RemovableMedia = yes; -#} - -Messages { - Name = Standard - director = HeadMan = all - operator = root = mount -} diff --git a/bacula/kernstodo b/bacula/kernstodo index 4585e5ad2d..d28c724b5b 100644 --- a/bacula/kernstodo +++ b/bacula/kernstodo @@ -29,6 +29,8 @@ Autochangers: For 1.37: - Add disk seeking on restore. +- Make "update slots" when pointing to Autochanger, remove + all Volumes from other drives. - Don't start a second file job if one is already running. - Add Python writable variable for changing the Priority, Client, Storage, JobStatus (error), ... @@ -135,6 +137,9 @@ Regression tests (Scott): 1.37 Possibilities: +- A HOLD command to stop all jobs from starting. +- A PAUSE command to pause all running jobs ==> release the + drive. === From Carsten Menke Following is a list of what I think in the situations where I'm faced with, diff --git a/bacula/src/baconfig.h b/bacula/src/baconfig.h index 06baea30ff..2cf0480635 100644 --- a/bacula/src/baconfig.h +++ b/bacula/src/baconfig.h @@ -470,6 +470,32 @@ int m_msg(const char *file, int line, POOLMEM *&pool_buf, const char *fmt, ...) #define bmalloc(size) b_malloc(__FILE__, __LINE__, (size)) #endif +/* + * Replace codes needed in both file routines and non-file routines + * Job replace codes -- in "replace" + */ +#define REPLACE_ALWAYS 'a' +#define REPLACE_IFNEWER 'w' +#define REPLACE_NEVER 'n' +#define REPLACE_IFOLDER 'o' + +/* This probably should be done on a machine by machine basic, but it works */ +/* This is critical for the smartalloc routines to properly align memory */ +#define ALIGN_SIZE (sizeof(double)) +#define BALIGN(x) (((x) + ALIGN_SIZE - 1) & ~(ALIGN_SIZE -1)) + + +/* ============================================================= + * OS Dependent defines + * ============================================================= + */ + +#ifndef HAVE_FSEEKO +/* Bad news. This OS cannot handle 64 bit fseeks and ftells */ +#define fseeko fseek +#define ftello ftell +#endif + #ifdef __alpha__ #define OSF 1 #endif @@ -533,24 +559,12 @@ extern "C" int fchdir(int filedes); extern "C" long gethostid(void); #endif -/* This probably should be done on a machine by machine basic, but it works */ -#define ALIGN_SIZE (sizeof(double)) -#define BALIGN(x) (((x) + ALIGN_SIZE - 1) & ~(ALIGN_SIZE -1)) - /* Added by KES to deal with Win32 systems */ #ifndef S_ISWIN32 #define S_ISWIN32 020000 #endif -/* - * Replace codes needed in both file routines and non-file routines - * Job replace codes -- in "replace" - */ -#define REPLACE_ALWAYS 'a' -#define REPLACE_IFNEWER 'w' -#define REPLACE_NEVER 'n' -#define REPLACE_IFOLDER 'o' #undef HAVE_SETLOCALE #ifdef HAVE_SETLOCALE diff --git a/bacula/src/console/console.c b/bacula/src/console/console.c index 5db974b480..8bf17863fd 100644 --- a/bacula/src/console/console.c +++ b/bacula/src/console/console.c @@ -208,9 +208,9 @@ static void read_and_process_input(FILE *input, BSOCK *UA_sock) for ( ;; ) { if (at_prompt) { /* don't prompt multiple times */ - prompt = ""; + prompt = ""; } else { - prompt = "*"; + prompt = "*"; at_prompt = true; } if (tty_input) { @@ -239,15 +239,15 @@ static void read_and_process_input(FILE *input, BSOCK *UA_sock) if (stat < 0) { break; /* error or interrupt */ } else if (stat == 0) { /* timeout */ - if (strcmp(prompt, "*") == 0) { - bnet_fsend(UA_sock, ".messages"); + if (strcmp(prompt, "*") == 0) { + bnet_fsend(UA_sock, ".messages"); } else { continue; } } else { at_prompt = FALSE; /* @ => internal command for us */ - if (UA_sock->msg[0] == '@') { + if (UA_sock->msg[0] == '@') { parse_args(UA_sock->msg, &args, &argc, argk, argv, MAX_CMD_ARGS); if (!do_a_command(input, UA_sock)) { break; @@ -264,7 +264,7 @@ static void read_and_process_input(FILE *input, BSOCK *UA_sock) while ((stat = bnet_recv(UA_sock)) >= 0) { if (at_prompt) { if (!stop) { - sendit("\n"); + sendit("\n"); } at_prompt = false; } @@ -287,7 +287,7 @@ static void read_and_process_input(FILE *input, BSOCK *UA_sock) if (UA_sock->msglen == BNET_PROMPT) { at_prompt = true; } - Dmsg1(100, "Got poll %s\n", bnet_sig_to_ascii(UA_sock)); + Dmsg1(100, "Got poll %s\n", bnet_sig_to_ascii(UA_sock)); } } } @@ -404,7 +404,7 @@ try_again: LockRes(); ndir = 0; foreach_res(dir, R_DIRECTOR) { - senditf( _("%d %s at %s:%d\n"), 1+ndir++, dir->hdr.name, dir->address, + senditf( _("%d %s at %s:%d\n"), 1+ndir++, dir->hdr.name, dir->address, dir->DIRport); } UnlockRes(); @@ -414,7 +414,7 @@ try_again: } item = atoi(UA_sock->msg); if (item < 0 || item > ndir) { - senditf(_("You must enter a number between 1 and %d\n"), ndir); + senditf(_("You must enter a number between 1 and %d\n"), ndir); goto try_again; } LockRes(); @@ -728,7 +728,7 @@ void sendit(const char *buf) if (output == stdout || tee) { char *p, *q; /* - * Here, we convert every \n into \r\n because the + * Here, we convert every \n into \r\n because the * terminal is in raw mode when we are using * conio. */ @@ -736,8 +736,8 @@ void sendit(const char *buf) if (p-q > 0) { t_sendl(q, p-q); } - t_sendl("\r\n", 2); - q = ++p; /* point after \n */ + t_sendl("\r\n", 2); + q = ++p; /* point after \n */ } if (*q) { t_send(q); @@ -748,10 +748,11 @@ void sendit(const char *buf) } #else fputs(buf, output); + fflush(output); if (tee) { fputs(buf, stdout); } - if (output == stdout || tee) { + if (output != stdout || tee) { fflush(stdout); } #endif diff --git a/bacula/src/dird/backup.c b/bacula/src/dird/backup.c index d8dad976b6..b6db59e2b3 100644 --- a/bacula/src/dird/backup.c +++ b/bacula/src/dird/backup.c @@ -228,8 +228,11 @@ bool do_backup(JCR *jcr) /* Pickup Job termination data */ stat = wait_for_job_termination(jcr); - backup_cleanup(jcr, stat); - return stat == JS_Terminated; + if (stat == JS_Terminated) { + backup_cleanup(jcr, stat); + return true; + } + return false; } diff --git a/bacula/src/dird/catreq.c b/bacula/src/dird/catreq.c index 6baf7d7f50..c1e499cd2d 100644 --- a/bacula/src/dird/catreq.c +++ b/bacula/src/dird/catreq.c @@ -235,8 +235,12 @@ void catalog_request(JCR *jcr, BSOCK *bs, char *msg) * Insanity check for VolFiles get set to a smaller value */ if (sdmr.VolFiles < mr.VolFiles) { - Jmsg(jcr, M_ERROR, 0, _("ERROR!! Volume Files at %u being set to %u. This is probably wrong.\n"), - mr.VolFiles, sdmr.VolFiles); + Jmsg(jcr, M_FATAL, 0, _("Volume Files at %u being set to %u" + " for Volume \"%s\". This is incorrect.\n"), + mr.VolFiles, sdmr.VolFiles, mr.VolumeName); + bnet_fsend(bs, "1992 Update Media error\n"); + db_unlock(jcr->db); + return; } } Dmsg2(400, "Update media: BefVolJobs=%u After=%u\n", mr.VolJobs, sdmr.VolJobs); diff --git a/bacula/src/dird/dird_conf.c b/bacula/src/dird/dird_conf.c index 27175cda70..fe4a02374a 100644 --- a/bacula/src/dird/dird_conf.c +++ b/bacula/src/dird/dird_conf.c @@ -191,7 +191,8 @@ static RES_ITEM cat_items[] = { {"user", store_str, ITEM(res_cat.db_user), 0, 0, 0}, {"dbname", store_str, ITEM(res_cat.db_name), 0, ITEM_REQUIRED, 0}, {"dbsocket", store_str, ITEM(res_cat.db_socket), 0, 0, 0}, - {"multipleconnections", store_yesno, ITEM(res_cat.mult_db_connections), 1, 0, 0}, + /* Turned off for the moment */ + {"multipleconnections", store_yesno, ITEM(res_cat.mult_db_connections), 0, 0, 0}, {NULL, NULL, NULL, 0, 0, 0} }; diff --git a/bacula/src/dird/mac.c b/bacula/src/dird/mac.c index 7946828696..9cf64be42c 100644 --- a/bacula/src/dird/mac.c +++ b/bacula/src/dird/mac.c @@ -187,8 +187,11 @@ bool do_mac(JCR *jcr) } else { stat = jcr->SDJobStatus; } - mac_cleanup(jcr, stat); - return jcr->JobStatus == JS_Terminated; + if (stat == JS_Terminated) { + mac_cleanup(jcr, stat); + return true; + } + return false; } diff --git a/bacula/src/dird/newvol.c b/bacula/src/dird/newvol.c index 2475f00502..831cd93ad3 100644 --- a/bacula/src/dird/newvol.c +++ b/bacula/src/dird/newvol.c @@ -13,7 +13,7 @@ * Version $Id$ */ /* - Copyright (C) 2001-2004 Kern Sibbald and John Walker + Copyright (C) 2001-2005 Kern Sibbald This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -59,7 +59,7 @@ bool newVolume(JCR *jcr, MEDIA_DBR *mr) set_pool_dbr_defaults_in_media_dbr(mr, &pr); jcr->VolumeName[0] = 0; bstrncpy(mr->MediaType, jcr->store->media_type, sizeof(mr->MediaType)); - if (generate_event(jcr, "NewVolume") == 1 && jcr->VolumeName[0]) { + if (generate_event(jcr, "NewVolume") == 1 && jcr->VolumeName[0]) { bstrncpy(mr->VolumeName, jcr->VolumeName, sizeof(mr->VolumeName)); /* Check for special characters */ } else if (is_volume_name_legal(NULL, pr.LabelFormat)) { @@ -73,7 +73,7 @@ bool newVolume(JCR *jcr, MEDIA_DBR *mr) goto bail_out; } if (!is_volume_name_legal(NULL, mr->VolumeName)) { - Jmsg(jcr, M_ERROR, 0, _("Illegal character in Volume name \"%s\"\n"), + Jmsg(jcr, M_ERROR, 0, _("Illegal character in Volume name \"%s\"\n"), mr->VolumeName); goto bail_out; } @@ -82,11 +82,11 @@ bool newVolume(JCR *jcr, MEDIA_DBR *mr) if (db_create_media_record(jcr, jcr->db, mr) && db_update_pool_record(jcr, jcr->db, &pr)) { db_unlock(jcr->db); - Jmsg(jcr, M_INFO, 0, _("Created new Volume \"%s\" in catalog.\n"), mr->VolumeName); - Dmsg1(90, "Created new Volume=%s\n", mr->VolumeName); + Jmsg(jcr, M_INFO, 0, _("Created new Volume \"%s\" in catalog.\n"), mr->VolumeName); + Dmsg1(90, "Created new Volume=%s\n", mr->VolumeName); return true; } else { - Jmsg(jcr, M_ERROR, 0, "%s", db_strerror(jcr->db)); + Jmsg(jcr, M_ERROR, 0, "%s", db_strerror(jcr->db)); } } } @@ -111,7 +111,7 @@ static int create_simple_name(JCR *jcr, MEDIA_DBR *mr, POOL_DBR *pr) bstrncat(tmr.VolumeName, num, sizeof(tmr.VolumeName)); if (db_get_media_record(jcr, jcr->db, &tmr)) { Jmsg(jcr, M_WARNING, 0, - _("Wanted to create Volume \"%s\", but it already exists. Trying again.\n"), + _("Wanted to create Volume \"%s\", but it already exists. Trying again.\n"), tmr.VolumeName); continue; } diff --git a/bacula/src/dird/restore.c b/bacula/src/dird/restore.c index 0b7fb49a64..e9c4047400 100644 --- a/bacula/src/dird/restore.c +++ b/bacula/src/dird/restore.c @@ -125,7 +125,7 @@ bool do_restore(JCR *jcr) */ if (!connect_to_storage_daemon(jcr, 10, SDConnectTimeout, 1)) { restore_cleanup(jcr, JS_ErrorTerminated); - return 0; + return false; } /* * Now start a job with the Storage daemon diff --git a/bacula/src/dird/verify.c b/bacula/src/dird/verify.c index 00970952f8..7fa3084aa6 100644 --- a/bacula/src/dird/verify.c +++ b/bacula/src/dird/verify.c @@ -334,8 +334,11 @@ bool do_verify(JCR *jcr) } stat = wait_for_job_termination(jcr); - verify_cleanup(jcr, stat); - return true; + if (stat == JS_Terminated) { + verify_cleanup(jcr, stat); + return true; + } + return false; } diff --git a/bacula/src/findlib/fstype.c b/bacula/src/findlib/fstype.c index b455d4a079..deb02b7b18 100644 --- a/bacula/src/findlib/fstype.c +++ b/bacula/src/findlib/fstype.c @@ -61,7 +61,6 @@ */ #if defined(HAVE_DARWIN_OS) \ || defined(HAVE_FREEBSD_OS ) \ - || defined(HAVE_NETBSD_OS) \ || defined(HAVE_OPENBSD_OS) #include @@ -77,7 +76,20 @@ bool fstype(const char *fname, char *fs, int fslen) Dmsg1(50, "statfs() failed for \"%s\"\n", fname); return false; } +#elif defined(HAVE_NETBSD_OS) +#include +#include +bool fstype(const char *fname, char *fs, int fslen) +{ + struct statvfs st; + if (statvfs(fname, &st) == 0) { + bstrncpy(fs, st.f_fstypename, fslen); + return true; + } + Dmsg1(50, "statfs() failed for \"%s\"\n", fname); + return false; +} #elif defined(HAVE_HPUX_OS) \ || defined(HAVE_IRIX_OS) diff --git a/bacula/src/jcr.h b/bacula/src/jcr.h index 85e8e98923..d5d569902f 100644 --- a/bacula/src/jcr.h +++ b/bacula/src/jcr.h @@ -252,6 +252,7 @@ struct JCR { /* Parmaters for Open Read Session */ BSR *bsr; /* Bootstrap record -- has everything */ + bool mount_next_volume; /* set to cause next volume mount */ uint32_t read_VolSessionId; uint32_t read_VolSessionTime; uint32_t read_StartFile; diff --git a/bacula/src/stored/acquire.c b/bacula/src/stored/acquire.c index c751aa887a..20855cf479 100644 --- a/bacula/src/stored/acquire.c +++ b/bacula/src/stored/acquire.c @@ -251,7 +251,7 @@ DCR *acquire_device_for_read(JCR *jcr, DEVICE *dev) break; } - Jmsg(jcr, M_FATAL, 0, _("Open device %s volume %s failed, ERR=%s\n"), + Jmsg(jcr, M_FATAL, 0, _("Open device %s Volume \"%s\" failed: ERR=%s\n"), dev->print_name(), dcr->VolumeName, strerror_dev(dev)); goto get_out; } @@ -562,6 +562,7 @@ ok_out: */ bool release_device(DCR *dcr) { + bool ok = true; JCR *jcr = dcr->jcr; DEVICE *dev = dcr->dev; @@ -591,6 +592,7 @@ bool release_device(DCR *dcr) if (!dir_create_jobmedia_record(dcr)) { Jmsg(jcr, M_FATAL, 0, _("Could not create JobMedia record for Volume=\"%s\" Job=%s\n"), dcr->VolCatInfo.VolCatName, jcr->Job); + ok = false; } /* If no more writers, write an EOF */ if (!dev->num_writers && dev_can_write(dev)) { @@ -614,6 +616,7 @@ bool release_device(DCR *dcr) Jmsg2(jcr, M_FATAL, 0, _("BAD ERROR: release_device %s, Volume \"%s\" not in use.\n"), dev->print_name(), NPRT(dcr->VolumeName)); Jmsg2(jcr, M_ERROR, 0, _("num_writers=%d state=%x\n"), dev->num_writers, dev->state); + ok = false; } /* Fire off Alert command and include any output */ @@ -645,5 +648,5 @@ bool release_device(DCR *dcr) unlock_device(dev); free_dcr(dcr); jcr->dcr = NULL; - return true; + return ok; } diff --git a/bacula/src/stored/append.c b/bacula/src/stored/append.c index 0596e07407..877c0a671c 100644 --- a/bacula/src/stored/append.c +++ b/bacula/src/stored/append.c @@ -285,7 +285,7 @@ bool do_append_data(JCR *jcr) * is set to yes, open the next part, so, in case of a device * that requires mount, it will be written to the device. */ - if (dev->is_dvd() && jcr->write_part_after_job && (dev->part_size > 0)) { + if (ok && dev->is_dvd() && jcr->write_part_after_job && (dev->part_size > 0)) { Dmsg0(100, "Writing last part because write_part_after_job is set.\n"); if (dev->part < dev->num_parts) { Jmsg3(jcr, M_FATAL, 0, _("Error while writing, current part number is less than the total number of parts (%d/%d, device=%s)\n"), diff --git a/bacula/src/stored/autochanger.c b/bacula/src/stored/autochanger.c index f127e96fe2..a1f36eeaf6 100644 --- a/bacula/src/stored/autochanger.c +++ b/bacula/src/stored/autochanger.c @@ -56,6 +56,7 @@ int autoload_device(DCR *dcr, int writing, BSOCK *dir) int slot; int drive = dev->device->drive_index; int rtn_stat = -1; /* error status */ + POOLMEM *changer; slot = dcr->VolCatInfo.InChanger ? dcr->VolCatInfo.Slot : 0; /* @@ -74,13 +75,11 @@ int autoload_device(DCR *dcr, int writing, BSOCK *dir) } Dmsg1(400, "Want changer slot=%d\n", slot); + changer = get_pool_memory(PM_FNAME); if (slot > 0 && dcr->device->changer_name && dcr->device->changer_command) { uint32_t timeout = dcr->device->max_changer_wait; - POOLMEM *changer; int loaded, status; - changer = get_pool_memory(PM_FNAME); - loaded = get_autochanger_loaded_slot(dcr); /* If tape we want is not loaded, load it. */ @@ -100,8 +99,9 @@ int autoload_device(DCR *dcr, int writing, BSOCK *dir) if (status != 0) { berrno be; be.set_errno(status); - Jmsg(jcr, M_INFO, 0, _("3992 Bad autochanger \"unload slot %d, drive %d\": ERR=%s.\n"), + Jmsg(jcr, M_FATAL, 0, _("3992 Bad autochanger \"unload slot %d, drive %d\": ERR=%s.\n"), slot, drive, be.strerror()); + goto bail_out; } Dmsg1(400, "unload status=%d\n", status); @@ -122,15 +122,15 @@ int autoload_device(DCR *dcr, int writing, BSOCK *dir) } else { berrno be; be.set_errno(status); - Jmsg(jcr, M_INFO, 0, _("3992 Bad autochanger \"load slot %d, drive %d\": ERR=%s.\n"), + Jmsg(jcr, M_FATAL, 0, _("3992 Bad autochanger \"load slot %d, drive %d\": ERR=%s.\n"), slot, drive, be.strerror()); + goto bail_out; } unlock_changer(dcr); Dmsg2(400, "load slot %d status=%d\n", slot, status); } else { status = 0; /* we got what we want */ } - free_pool_memory(changer); Dmsg1(400, "After changer, status=%d\n", status); if (status == 0) { /* did we succeed? */ rtn_stat = 1; /* tape loaded by changer */ @@ -138,7 +138,14 @@ int autoload_device(DCR *dcr, int writing, BSOCK *dir) } else { rtn_stat = 0; /* no changer found */ } + free_pool_memory(changer); return rtn_stat; + +bail_out: + free_pool_memory(changer); + unlock_changer(dcr); + return -1; + } static int get_autochanger_loaded_slot(DCR *dcr) diff --git a/bacula/src/stored/block.c b/bacula/src/stored/block.c index a5e96da7b9..97844bd103 100644 --- a/bacula/src/stored/block.c +++ b/bacula/src/stored/block.c @@ -542,7 +542,7 @@ bool write_block_to_dev(DCR *dcr) if (dev->dev_errno == ENOSPC) { Jmsg(jcr, M_INFO, 0, _("End of Volume \"%s\" at %u:%u on device %s. Write of %u bytes got %d.\n"), dev->VolCatInfo.VolCatName, - dev->file, dev->block_num, dev->dev_name, wlen, stat); + dev->file, dev->block_num, dev->print_name(), wlen, stat); } Dmsg6(100, "=== Write error. size=%u rtn=%d dev_blk=%d blk_blk=%d errno=%d: ERR=%s\n", wlen, stat, dev->block_num, block->BlockNumber, dev->dev_errno, strerror(dev->dev_errno)); @@ -789,7 +789,7 @@ static bool do_dvd_size_checks(DCR *dcr) Dmsg1(10, "Cannot get free space on the device ERR=%s.\n", dev->errmsg); Jmsg(jcr, M_FATAL, 0, _("End of Volume \"%s\" at %u:%u on device %s (part_size=%s, free_space=%s, free_space_errno=%d, errmsg=%s).\n"), dev->VolCatInfo.VolCatName, - dev->file, dev->block_num, dev->dev_name, + dev->file, dev->block_num, dev->print_name(), edit_uint64_with_commas(dev->part_size, ed1), edit_uint64_with_commas(dev->free_space, ed2), dev->free_space_errno, dev->errmsg); dev->dev_errno = -dev->free_space_errno; @@ -801,7 +801,7 @@ static bool do_dvd_size_checks(DCR *dcr) Dmsg0(10, "==== Just enough free space on the device to write the current part...\n"); Jmsg(jcr, M_INFO, 0, _("End of Volume \"%s\" at %u:%u on device %s (part_size=%s, free_space=%s, free_space_errno=%d).\n"), dev->VolCatInfo.VolCatName, - dev->file, dev->block_num, dev->dev_name, + dev->file, dev->block_num, dev->print_name(), edit_uint64_with_commas(dev->part_size, ed1), edit_uint64_with_commas(dev->free_space, ed2), dev->free_space_errno); terminate_writing_volume(dcr); @@ -818,14 +818,14 @@ static bool do_dvd_size_checks(DCR *dcr) */ bool read_block_from_device(DCR *dcr, bool check_block_numbers) { - bool stat; + bool ok; DEVICE *dev = dcr->dev; Dmsg0(200, "Enter read_block_from_device\n"); lock_device(dev); - stat = read_block_from_dev(dcr, check_block_numbers); + ok = read_block_from_dev(dcr, check_block_numbers); unlock_device(dev); Dmsg0(200, "Leave read_block_from_device\n"); - return stat; + return ok; } /* @@ -843,7 +843,7 @@ bool read_block_from_dev(DCR *dcr, bool check_block_numbers) DEVICE *dev = dcr->dev; DEV_BLOCK *block = dcr->block; - if (dev_state(dev, ST_EOT)) { + if (dev->at_eot()) { return false; } looping = 0; diff --git a/bacula/src/stored/btape.c b/bacula/src/stored/btape.c index 9a821b1b45..921fd55ac8 100644 --- a/bacula/src/stored/btape.c +++ b/bacula/src/stored/btape.c @@ -1776,10 +1776,14 @@ static void fillcmd() dev->min_block_size = dev->max_block_size; set_volume_name("TestVolume1", 1); - rewind_dev(dev); - weof_dev(dev, 1); + if (!dev->rewind()) { + Pmsg0(000, "Rewind failed.\n"); + } + if (!dev->weof()) { + Pmsg0(000, "Write EOF failed.\n"); + } labelcmd(); - dev->state &= ~ST_APPEND; /* force volume to be relabeled */ + dev->set_append(); /* force volume to be relabeled */ /* * Acquire output device for writing. Note, after acquiring a @@ -1959,12 +1963,6 @@ static void fillcmd() simple?"":"s", jcr->dcr->dev->file, jcr->dcr->dev->block_num, simple?"":"first "); jcr->dcr->block = block; - /* Release the device if multiple tapes being used */ -// if (!simple && !release_device(dcr)) { -// Pmsg0(-1, _("Error in release_device\n")); -// ok = false; -// } - do_unfill(); dev->min_block_size = min_block_size; @@ -2070,8 +2068,8 @@ static void do_unfill() if (!rewind_dev(dev)) { /* get to a known place on tape */ goto bail_out; } - /* Read the first 1000 records */ - Pmsg0(-1, _("Reading the first 1000 records.\n")); + /* Read the first 10000 records */ + Pmsg0(-1, _("Reading the first 10000 records.\n")); quickie_count = 0; read_records(dcr, quickie_cb, my_mount_next_read_volume); Pmsg4(-1, _("Reposition from %u:%u to %u:%u\n"), dev->file, dev->block_num, @@ -2162,7 +2160,7 @@ bail_out: free_block(first_block); } -/* Read 1000 records then stop */ +/* Read 10000 records then stop */ static bool quickie_cb(DCR *dcr, DEV_RECORD *rec) { DEVICE *dev = dcr->dev; @@ -2172,10 +2170,10 @@ static bool quickie_cb(DCR *dcr, DEV_RECORD *rec) return false; } quickie_count++; - if (quickie_count == 1000) { + if (quickie_count == 10000) { Pmsg2(-1, "1000 records read now at %d:%d\n", dev->file, dev->block_num); } - return quickie_count < 1000; + return quickie_count < 10000; } static bool compare_blocks(DEV_BLOCK *last_block, DEV_BLOCK *block) @@ -2418,7 +2416,7 @@ static void rawfill_cmd() /* - * Fill a tape using raw write() command + * Fill a tape using Bacula block writes */ static void bfill_cmd() { diff --git a/bacula/src/stored/dev.c b/bacula/src/stored/dev.c index 9261bb1f9b..bd7a09a829 100644 --- a/bacula/src/stored/dev.c +++ b/bacula/src/stored/dev.c @@ -329,8 +329,8 @@ open_dev(DEVICE *dev, char *VolName, int mode) continue; } dev->dev_errno = errno; - Mmsg2(&dev->errmsg, _("stored: unable to open device %s: ERR=%s\n"), - dev->dev_name, be.strerror()); + Mmsg2(&dev->errmsg, _("Unable to open device %s: ERR=%s\n"), + dev->print_name(), be.strerror(dev->dev_errno)); /* Stop any open timer we set */ if (dev->tid) { stop_thread_timer(dev->tid); diff --git a/bacula/src/stored/dev.h b/bacula/src/stored/dev.h index 62e7648605..f5c486b045 100644 --- a/bacula/src/stored/dev.h +++ b/bacula/src/stored/dev.h @@ -164,6 +164,8 @@ typedef struct s_steal_lock { } bsteal_lock_t; struct DEVRES; /* Device resource defined in stored_conf.h */ +int weof_dev(DEVICE *dev, int num); +bool rewind_dev(DEVICE *dev); /* * Device structure definition. There is one of these for @@ -262,19 +264,27 @@ public: int at_eot() const; int can_append() const; int can_read() const; + bool can_steal_lock() const { return dev_blocked && + (dev_blocked == BST_UNMOUNTED || + dev_blocked == BST_WAITING_FOR_SYSOP || + dev_blocked == BST_UNMOUNTED_WAITING_FOR_SYSOP); }; + + bool weof() { return !weof_dev(this, 1); }; + bool rewind() { return rewind_dev(this); }; const char *strerror() const; const char *archive_name() const; const char *name() const; const char *print_name() const; /* Name for display purposes */ - void set_eof(); - void set_eot(); - void set_append(); - void set_read(); - void set_offline(); + void set_eof(); /* in dev.c */ + void set_eot(); /* in dev.c */ + void set_append() { state |= ST_APPEND; }; + void set_read() { state |= ST_READ; }; + void set_offline() { state |= ST_OFFLINE; }; void clear_append(); void clear_read(); void clear_label(); void clear_offline(); + void clear_eot() { state &= ~ST_EOT; }; }; /* Note, these return int not bool! */ @@ -290,9 +300,6 @@ inline int DEVICE::at_eof() const { return state & ST_EOF; } inline int DEVICE::at_eot() const { return state & ST_EOT; } inline int DEVICE::can_append() const { return state & ST_APPEND; } inline int DEVICE::can_read() const { return state & ST_READ; } -inline void DEVICE::set_append() { state |= ST_APPEND; } -inline void DEVICE::set_read() { state |= ST_READ; } -inline void DEVICE::set_offline() { state |= ST_OFFLINE; } inline void DEVICE::clear_append() { state &= ~ST_APPEND; } inline void DEVICE::clear_read() { state &= ~ST_READ; } inline void DEVICE::clear_label() { state &= ~ST_LABEL; } diff --git a/bacula/src/stored/device.c b/bacula/src/stored/device.c index d6bdf470cf..436c1bd926 100644 --- a/bacula/src/stored/device.c +++ b/bacula/src/stored/device.c @@ -313,7 +313,7 @@ bool open_device(DCR *dcr) if (open_dev(dev, dcr->VolCatInfo.VolCatName, mode) < 0) { /* If polling, ignore the error */ if (!dev->poll) { - Jmsg2(dcr->jcr, M_FATAL, 0, _("Unable to open archive %s: ERR=%s\n"), + Jmsg2(dcr->jcr, M_FATAL, 0, _("Unable to open device %s: ERR=%s\n"), dev->print_name(), strerror_dev(dev)); Pmsg2(000, "Unable to open archive %s: ERR=%s\n", dev->print_name(), strerror_dev(dev)); diff --git a/bacula/src/stored/dircmd.c b/bacula/src/stored/dircmd.c index 29ed6249b3..dfee1ffe41 100644 --- a/bacula/src/stored/dircmd.c +++ b/bacula/src/stored/dircmd.c @@ -335,10 +335,7 @@ static bool do_label(JCR *jcr, int relabel) label_volume_if_ok(jcr, dev, oldname, newname, poolname, slot, relabel); force_close_dev(dev); /* Under certain "safe" conditions, we can steal the lock */ - } else if (dev->dev_blocked && - (dev->dev_blocked == BST_UNMOUNTED || - dev->dev_blocked == BST_WAITING_FOR_SYSOP || - dev->dev_blocked == BST_UNMOUNTED_WAITING_FOR_SYSOP)) { + } else if (dev->can_steal_lock()) { label_volume_if_ok(jcr, dev, oldname, newname, poolname, slot, relabel); } else if (dev->is_busy()) { send_dir_busy_message(dir, dev); @@ -803,10 +800,7 @@ static bool autochanger_cmd(JCR *jcr) } else if (!dev->is_open()) { autochanger_cmd(dcr, dir, cmd); /* Under certain "safe" conditions, we can steal the lock */ - } else if (dev->dev_blocked && - (dev->dev_blocked == BST_UNMOUNTED || - dev->dev_blocked == BST_WAITING_FOR_SYSOP || - dev->dev_blocked == BST_UNMOUNTED_WAITING_FOR_SYSOP)) { + } else if (dev->can_steal_lock()) { autochanger_cmd(dcr, dir, cmd); } else if (dev->is_busy()) { send_dir_busy_message(dir, dev); @@ -844,10 +838,7 @@ static bool readlabel_cmd(JCR *jcr) read_volume_label(jcr, dev, Slot); force_close_dev(dev); /* Under certain "safe" conditions, we can steal the lock */ - } else if (dev->dev_blocked && - (dev->dev_blocked == BST_UNMOUNTED || - dev->dev_blocked == BST_WAITING_FOR_SYSOP || - dev->dev_blocked == BST_UNMOUNTED_WAITING_FOR_SYSOP)) { + } else if (dev->can_steal_lock()) { read_volume_label(jcr, dev, Slot); } else if (dev->is_busy()) { send_dir_busy_message(dir, dev); diff --git a/bacula/src/stored/mount.c b/bacula/src/stored/mount.c index a7485b0448..a424b5e888 100644 --- a/bacula/src/stored/mount.c +++ b/bacula/src/stored/mount.c @@ -372,7 +372,7 @@ read_volume: /* Return an empty block */ empty_block(block); /* we used it for reading so set for write */ } - dev->state |= ST_APPEND; + dev->set_append(); Dmsg0(100, "set APPEND, normal return from read_dev_for_append\n"); return true; } @@ -406,7 +406,7 @@ bool mount_next_read_volume(DCR *dcr) */ if (jcr->NumVolumes > 1 && jcr->CurVolume < jcr->NumVolumes) { close_dev(dev); - dev->state &= ~ST_READ; + dev->clear_read(); if (!acquire_device_for_read(jcr, dev)) { Jmsg2(jcr, M_FATAL, 0, "Cannot open Dev=%s, Vol=%s\n", dev->print_name(), dcr->VolumeName); diff --git a/bacula/src/stored/read_record.c b/bacula/src/stored/read_record.c index bfecbc4e7e..893e0ddf3f 100644 --- a/bacula/src/stored/read_record.c +++ b/bacula/src/stored/read_record.c @@ -5,6 +5,9 @@ * archive. It uses a callback to pass you each record in turn, * as well as a callback for mounting the next tape. It takes * care of reading blocks, applying the bsr, ... + * Note, this routine is really the heart of the restore routines, + * and we are *really* bit pushing here so be careful about making + * any modifications. * * Kern E. Sibbald, August MMII * @@ -57,6 +60,7 @@ bool read_records(DCR *dcr, recs = New(dlist(rec, &rec->link)); position_to_first_file(jcr, dev); + jcr->mount_next_volume = false; for ( ; ok && !done; ) { if (job_canceled(jcr)) { @@ -66,12 +70,11 @@ bool read_records(DCR *dcr, if (!read_block_from_device(dcr, CHECK_BLOCK_NUMBERS)) { if (dev->at_eot()) { DEV_RECORD *trec = new_record(); - Jmsg(jcr, M_INFO, 0, "End of Volume at file %u on device %s, Volume \"%s\"\n", dev->file, dev->print_name(), dcr->VolumeName); if (!mount_cb(dcr)) { Jmsg(jcr, M_INFO, 0, "End of all volumes.\n"); - ok = false; + ok = false; /* Stop everything */ /* * Create EOT Label so that Media record may * be properly updated because this is the last @@ -81,8 +84,13 @@ bool read_records(DCR *dcr, trec->File = dev->file; ok = record_cb(dcr, trec); free_record(trec); + if (jcr->mount_next_volume) { + jcr->mount_next_volume = false; + dev->clear_eot(); + } break; } + jcr->mount_next_volume = false; /* * We just have a new tape up, now read the label (first record) * and pass it off to the callback routine, then continue @@ -116,7 +124,7 @@ bool read_records(DCR *dcr, Pmsg0(000, "Did fsr\n"); continue; /* try to continue */ } - ok = false; + ok = false; /* stop everything */ break; } } @@ -259,7 +267,11 @@ static int try_repositioning(JCR *jcr, DEV_RECORD *rec, DEVICE *dev) Dmsg2(300, "Current postion (file:block) %d:%d\n", dev->file, dev->block_num); jcr->bsr->mount_next_volume = false; -// dev->state |= ST_EOT; + if (!dev->at_eot()) { + /* Set EOT flag to force mount of next Volume */ + jcr->mount_next_volume = true; + dev->state |= ST_EOT; + } rec->Block = 0; return 1; } diff --git a/bacula/src/stored/spool.c b/bacula/src/stored/spool.c index 5e0b1651c1..e3e4cf3fa7 100644 --- a/bacula/src/stored/spool.c +++ b/bacula/src/stored/spool.c @@ -531,17 +531,22 @@ bool commit_attribute_spool(JCR *jcr) char ec1[30]; if (are_attributes_spooled(jcr)) { - if (fseek(jcr->dir_bsock->spool_fd, 0, SEEK_END) != 0) { + if (fseeko(jcr->dir_bsock->spool_fd, 0, SEEK_END) != 0) { berrno be; Jmsg(jcr, M_FATAL, 0, _("Fseek on attributes file failed: ERR=%s\n"), be.strerror()); + goto bail_out; + } + size = ftello(jcr->dir_bsock->spool_fd); + if (size < 0) { + berrno be; + Jmsg(jcr, M_FATAL, 0, _("Fseek on attributes file failed: ERR=%s\n"), + be.strerror()); + goto bail_out; } - size = ftell(jcr->dir_bsock->spool_fd); P(mutex); - if (size > 0) { - if (spool_stats.attr_size + size > spool_stats.max_attr_size) { - spool_stats.max_attr_size = spool_stats.attr_size + size; - } + if (spool_stats.attr_size + size > spool_stats.max_attr_size) { + spool_stats.max_attr_size = spool_stats.attr_size + size; } spool_stats.attr_size += size; V(mutex); @@ -551,6 +556,10 @@ bool commit_attribute_spool(JCR *jcr) return close_attr_spool_file(jcr, jcr->dir_bsock); } return true; + +bail_out: + close_attr_spool_file(jcr, jcr->dir_bsock); + return false; } static void make_unique_spool_filename(JCR *jcr, POOLMEM **name, int fd) diff --git a/bacula/src/version.h b/bacula/src/version.h index 04cff472ce..20c0b4d9c7 100644 --- a/bacula/src/version.h +++ b/bacula/src/version.h @@ -1,8 +1,8 @@ /* */ #undef VERSION -#define VERSION "1.37.7" -#define BDATE "14 March 2005" -#define LSMDATE "14Mar05" +#define VERSION "1.37.8" +#define BDATE "17 March 2005" +#define LSMDATE "17Mar05" /* Debug flags */ #undef DEBUG