From 2643cdaa7a761d6d9ff906f26794d781c01c017d Mon Sep 17 00:00:00 2001 From: Kern Sibbald Date: Tue, 13 May 2003 14:17:25 +0000 Subject: [PATCH] Misc see kes-1.31 13May03 git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@506 91ce42f0-d328-0410-95d8-f526ca767f89 --- bacula/kernstodo | 32 ++--- bacula/platforms/redhat/bacula.spec.in | 21 +-- bacula/scripts/btraceback.gdb | 2 + bacula/src/cats/bdb.c | 2 + bacula/src/cats/sql.c | 6 + bacula/src/console/console.c | 24 ++-- bacula/src/dird/bacula-dir.conf.in | 1 - bacula/src/dird/dird_conf.c | 2 +- bacula/src/dird/ua_cmds.c | 84 ++++-------- bacula/src/dird/ua_label.c | 29 ++-- bacula/src/dird/ua_run.c | 5 +- bacula/src/dird/ua_select.c | 17 ++- bacula/src/filed/bacula-fd.conf.in | 1 - bacula/src/filed/filed_conf.c | 158 +++++++++++----------- bacula/src/filed/win32/bin/btraceback.gdb | 2 + bacula/src/findlib/create_file.c | 5 +- bacula/src/lib/jcr.c | 1 + bacula/src/lib/message.c | 62 +++++---- bacula/src/stored/askdir.c | 32 +++-- bacula/src/stored/autochanger.c | 49 ++----- bacula/src/stored/bacula-sd.conf.in | 1 - bacula/src/stored/block.c | 10 ++ bacula/src/stored/device.c | 2 - bacula/src/stored/dircmd.c | 4 - bacula/src/stored/mount.c | 137 ++++++++++--------- bacula/src/stored/stored_conf.c | 2 +- 26 files changed, 338 insertions(+), 353 deletions(-) diff --git a/bacula/kernstodo b/bacula/kernstodo index 2393a73720..dbae9222ec 100644 --- a/bacula/kernstodo +++ b/bacula/kernstodo @@ -1,5 +1,5 @@ Kern's ToDo List - 11 May 2003 + 13 May 2003 Documentation to do: (any release a little bit at a time) - Document running a test version. @@ -14,45 +14,38 @@ Testing to do: (painful) - that ALL console command line options work and are always implemented - blocksize recognition code. - multiple simultaneous Volumes +- Test if rewind at end of tape waits for tape to rewind. - Figure out how to use ssh or stunnel to protect Bacula communications. - For 1.31 release: +- Check if Job/File retentions apply to multivolume jobs. +- Add Progress command that periodically reports the progress of + a job or all jobs. - Implement "Reschedule OnError=yes interval=nnn times=xxx" -- Fix config of "console" - Shell character expansion is failing occassionally. - One block was orphaned in the SD probably after cancel. -- Test if rewind at end of tape waits for tape to rewind. -- Check if cancel works with FD. -- Error labeling tape from console gets Jmsg error because of no Job. + - Fix the following: rufus-dir: Max configured use duration exceeded. Marking Volume "MatouBackup" as Used. rufus-sd: Volume "" previously written, moving to end of data. rufus-sd: Matou.2003-05-10_10.39.18 Error: I canot write on this volume because: The number of files mismatch! Volume=1 Catalog=0 rufus-sd: Matou.2003-05-10_10.39.18 Error: askdir.c:155 NULL Volume name. This shouldn't happen!!! -- Properly configure console and gconsole (currently for source not - configured for installation). + - Fix "access not allowed" for backup of files on WinXP. - Check for existence of all new Win32 API's. See LoadLibrary in winservice.cpp -- Add Progress command that periodically reports the progress of - a job or all jobs. - Fix problem reported by Christopher McCurdy xeon-fd: Could not stat c:/Documents and Settings/All Users/Application Data/Humc:\Documents and Settings\All User98_AIX.kbf: ERR=No such file or directory - Implement argv/argk in place of sscanf in the daemon protocol. -- Examine Bare Metal restore problem. +- Examine Bare Metal restore problem (a FD crash exists somewhere ...). - Test multiple simultaneous Volumes - Document FInclude ... -- Test and implement get_pint and get_yesno. - Implement timeout in response() when it should come quickly. -- Check if Job/File retentions apply to multivolume jobs. -- Remove subsysdir from conf files (used only in autostart scripts). - Implement console @echo command. -- Implement global with DB name and add to btraceback.gdb - Bug: fix access problems on files restored on WinXP. - Implement a Slot priority (loaded/not loaded). - Implement "vacation" Incremental only saves. @@ -776,4 +769,11 @@ Done: (see kernsdone for more) - Change M_INFO to M_RESTORED for all restored files. - Fix command prompt in gnome-console by checking on Ready. - Merge SQLite, MySQL, and Rel spec into a single file. - +- Fix config of "console" +- Check if cancel works with FD (fixed). +- Properly configure console and gconsole (currently for source not + configured for installation). +- Error labeling tape from console gets Jmsg error because of no Job. +- Test and implement get_pint and get_yesno. +- Implement global with DB name and add to btraceback.gdb +- Remove subsysdir from conf files (used only in autostart scripts). diff --git a/bacula/platforms/redhat/bacula.spec.in b/bacula/platforms/redhat/bacula.spec.in index 26d47d56d4..f69b37527f 100644 --- a/bacula/platforms/redhat/bacula.spec.in +++ b/bacula/platforms/redhat/bacula.spec.in @@ -152,8 +152,8 @@ make cwd=${PWD} mkdir -p $RPM_BUILD_ROOT/etc/rc.d/init.d +mkdir -p $RPM_BUILD_ROOT/etc/logrotate.d mkdir -p $RPM_BUILD_ROOT/usr/share/pixmaps - mkdir -p $RPM_BUILD_ROOT/usr/share/gnome/apps/System mkdir -p $RPM_BUILD_ROOT/usr/share/applications @@ -180,15 +180,12 @@ make \ cd ${cwd} %if ! %{mysql} -# fixme - make installs the mysql start/stop scripts for sqlite build +# fixme - make installs the mysql scripts for sqlite build rm -f $RPM_BUILD_ROOT/etc/bacula/startmysql rm -f $RPM_BUILD_ROOT/etc/bacula/stopmysql rm -f $RPM_BUILD_ROOT/etc/bacula/grant_mysql_privileges %endif -# fixme - make installs test script /etc/bacula/gconsole -rm -f $RPM_BUILD_ROOT/etc/bacula/gconsole - # 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 @@ -206,6 +203,9 @@ cp ../depkgs/sqlite/sqlite.h $RPM_BUILD_ROOT/usr/lib/sqlite/sqlite.h cp ../depkgs/sqlite/libsqlite.a $RPM_BUILD_ROOT/usr/lib/sqlite/libsqlite.a %endif +# install the logrotate file +cp scripts/logrotate $RPM_BUILD_ROOT/etc/logrotate.d/bacula + %clean [ "$RPM_BUILD_ROOT" != "/" ] && rm -rf "$RPM_BUILD_ROOT" @@ -217,6 +217,7 @@ cp ../depkgs/sqlite/libsqlite.a $RPM_BUILD_ROOT/usr/lib/sqlite/libsqlite.a %attr(0754,root,root) /etc/bacula/bacula %attr(0754,root,root) /etc/bacula/console %attr(0754,root,root) /etc/bacula/fd +%attr(0754,root,root) /etc/bacula/gconsole %attr(0754,root,root) /etc/bacula/create_mysql_database %attr(0754,root,root) /etc/bacula/delete_catalog_backup %attr(0754,root,root) /etc/bacula/drop_bacula_tables @@ -235,11 +236,10 @@ cp ../depkgs/sqlite/libsqlite.a $RPM_BUILD_ROOT/usr/lib/sqlite/libsqlite.a %attr(0644,root,root) %doc COPYING ChangeLog INSTALL README ReleaseNotes doc/* %attr(0644,root,root) /usr/man/man1/* %attr(0644,root,root) /usr/share/pixmaps/bacula.png - %attr(0644,root,root) /usr/share/gnome/apps/System/bacula.desktop %attr(0644,root,root) /usr/share/applications/bacula.desktop - %attr(0644,root,root) %config(noreplace) /etc/bacula/gnome-console.conf +%attr(0644,root,root) /etc/logrotate.d/bacula %attr(0640,root,root) %config(noreplace) /etc/bacula/bacula-dir.conf %attr(0640,root,root) %config(noreplace) /etc/bacula/bacula-fd.conf @@ -285,6 +285,7 @@ echo "Creating bacula tables..." %attr(0754,root,root) /etc/bacula/bacula %attr(0754,root,root) /etc/bacula/console %attr(0754,root,root) /etc/bacula/fd +%attr(0754,root,root) /etc/bacula/gconsole %attr(0754,root,root) /etc/bacula/create_sqlite_database %attr(0754,root,root) /etc/bacula/delete_catalog_backup %attr(0754,root,root) /etc/bacula/drop_bacula_tables @@ -300,11 +301,10 @@ echo "Creating bacula tables..." %attr(0644,root,root) %doc COPYING ChangeLog INSTALL README ReleaseNotes doc/* %attr(0644,root,root) /usr/man/man1/* %attr(0644,root,root) /usr/share/pixmaps/bacula.png - %attr(0644,root,root) /usr/share/gnome/apps/System/bacula.desktop %attr(0644,root,root) /usr/share/applications/bacula.desktop - %attr(0644,root,root) %config(noreplace) /etc/bacula/gnome-console.conf +%attr(0644,root,root) /etc/logrotate.d/bacula %attr(0640,root,root) %config(noreplace) /etc/bacula/bacula-dir.conf %attr(0640,root,root) %config(noreplace) /etc/bacula/bacula-fd.conf @@ -348,6 +348,7 @@ chmod 0755 /usr/sbin/gnome-console %attr(0754,root,root) /etc/rc.d/init.d/bacula-fd %attr(0644,root,root) %doc COPYING ChangeLog INSTALL README ReleaseNotes doc/* +%attr(0644,root,root) /etc/logrotate.d/bacula %attr(0640,root,root) %config(noreplace) /etc/bacula/bacula-fd.conf %attr(0640,root,root) %dir /var/bacula @@ -371,6 +372,8 @@ chmod 0755 /usr/sbin/gnome-console * Mon May 11 2003 D. Scott Barninger - Misc changes to mysql/sqlite build and rh7/8 menu differences - Added rh_version to sub-package names +- Added installed but missing file /etc/bacula/gconsole +- rm'd /etc/bacula/grant_mysql_privileges on sqlite builds * Thu May 08 2003 Kern Sibbald - Update spec for version 1.31 and combine client * Sun Mar 30 2003 D. Scott Barninger diff --git a/bacula/scripts/btraceback.gdb b/bacula/scripts/btraceback.gdb index 74e1f23cfa..387430a57c 100644 --- a/bacula/scripts/btraceback.gdb +++ b/bacula/scripts/btraceback.gdb @@ -1,6 +1,8 @@ print my_name print exename print exepath +print catalog_db +print version bt thread apply all bt f 0 diff --git a/bacula/src/cats/bdb.c b/bacula/src/cats/bdb.c index 659b18fd8f..39da83fb00 100644 --- a/bacula/src/cats/bdb.c +++ b/bacula/src/cats/bdb.c @@ -44,6 +44,8 @@ #ifdef HAVE_BACULA_DB +char catalog_db[] = "Interal"; + /* Forward referenced functions */ extern char *working_directory; diff --git a/bacula/src/cats/sql.c b/bacula/src/cats/sql.c index 0af5969f20..cd9e10b101 100644 --- a/bacula/src/cats/sql.c +++ b/bacula/src/cats/sql.c @@ -39,6 +39,12 @@ #if HAVE_MYSQL | HAVE_SQLITE +#ifdef HAVE_MYSQL +char catalog_db[] = "MySQL"; +#else +char catalog_db[] = "SQLite"; +#endif + /* Forward referenced subroutines */ void print_dashes(B_DB *mdb); void print_result(B_DB *mdb); diff --git a/bacula/src/console/console.c b/bacula/src/console/console.c index 6a2bae7ab5..3823180cc8 100644 --- a/bacula/src/console/console.c +++ b/bacula/src/console/console.c @@ -8,21 +8,23 @@ */ /* - Copyright (C) 2000, 2001 Kern Sibbald and John Walker + Copyright (C) 2000-2003 Kern Sibbald and John Walker - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, + MA 02111-1307, USA. - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "bacula.h" diff --git a/bacula/src/dird/bacula-dir.conf.in b/bacula/src/dird/bacula-dir.conf.in index 1b1e7d2801..fc07bc837d 100644 --- a/bacula/src/dird/bacula-dir.conf.in +++ b/bacula/src/dird/bacula-dir.conf.in @@ -18,7 +18,6 @@ Director { # define myself QueryFile = "@scriptdir@/query.sql" WorkingDirectory = "@working_dir@" PidDirectory = "@piddir@" - SubSysDirectory = "@subsysdir@" Maximum Concurrent Jobs = 1 Password = "@dir_password@" # Console password Messages = Standard diff --git a/bacula/src/dird/dird_conf.c b/bacula/src/dird/dird_conf.c index f9684021d7..05e7e218c7 100644 --- a/bacula/src/dird/dird_conf.c +++ b/bacula/src/dird/dird_conf.c @@ -94,7 +94,7 @@ static struct res_items dir_items[] = { {"queryfile", store_dir, ITEM(res_dir.query_file), 0, ITEM_REQUIRED, 0}, {"workingdirectory", store_dir, ITEM(res_dir.working_directory), 0, ITEM_REQUIRED, 0}, {"piddirectory",store_dir, ITEM(res_dir.pid_directory), 0, ITEM_REQUIRED, 0}, - {"subsysdirectory", store_dir, ITEM(res_dir.subsys_directory), 0, ITEM_REQUIRED, 0}, + {"subsysdirectory", store_dir, ITEM(res_dir.subsys_directory), 0, 0, 0}, {"requiressl", store_yesno, ITEM(res_dir.require_ssl), 1, ITEM_DEFAULT, 0}, {"enablessl", store_yesno, ITEM(res_dir.enable_ssl), 1, ITEM_DEFAULT, 0}, {"maximumconcurrentjobs", store_pint, ITEM(res_dir.MaxConcurrentJobs), 0, ITEM_DEFAULT, 1}, diff --git a/bacula/src/dird/ua_cmds.c b/bacula/src/dird/ua_cmds.c index 11dc32e92b..30d2476c79 100644 --- a/bacula/src/dird/ua_cmds.c +++ b/bacula/src/dird/ua_cmds.c @@ -202,15 +202,10 @@ static int addcmd(UAContext *ua, char *cmd) while (pr.MaxVols > 0 && pr.NumVols >= pr.MaxVols) { bsendmsg(ua, _("Pool already has maximum volumes = %d\n"), pr.MaxVols); for (;;) { - if (!get_cmd(ua, _("Enter new maximum (zero for unlimited): "))) { + if (!get_pint(ua, _("Enter new maximum (zero for unlimited): "))) { return 1; } - pr.MaxVols = atoi(ua->cmd); - if (pr.MaxVols < 0) { - bsendmsg(ua, _("Max vols must be zero or greater.\n")); - continue; - } - break; + pr.MaxVols = ua->pint32_val; } } @@ -229,10 +224,10 @@ static int addcmd(UAContext *ua, char *cmd) for (;;) { char buf[100]; sprintf(buf, _("Enter number of Volumes to create. 0=>fixed name. Max=%d: "), max); - if (!get_cmd(ua, buf)) { + if (!get_pint(ua, buf)) { return 1; } - num = atoi(ua->cmd); + num = ua->pint32_val; if (num < 0 || num > max) { bsendmsg(ua, _("The number must be between 0 and %d\n"), max); continue; @@ -268,10 +263,10 @@ getVolName: strcat(name, "%04d"); for (;;) { - if (!get_cmd(ua, _("Enter the starting number: "))) { + if (!get_pint(ua, _("Enter the starting number: "))) { return 1; } - startnum = atoi(ua->cmd); + startnum = ua->pint32_val; if (startnum < 1) { bsendmsg(ua, _("Start number must be greater than zero.\n")); continue; @@ -284,10 +279,10 @@ getVolName: } if (store && store->autochanger) { - if (!get_cmd(ua, _("Enter slot (0 for none): "))) { + if (!get_pint(ua, _("Enter slot (0 for none): "))) { return 1; } - slot = atoi(ua->cmd); + slot = ua->pint32_val; } set_pool_dbr_defaults_in_media_dbr(&mr, &pr); @@ -755,14 +750,10 @@ static int update_volume(UAContext *ua) case 3: /* Max Jobs */ int32_t maxjobs; bsendmsg(ua, _("Current max jobs is: %u\n"), mr.MaxVolJobs); - if (!get_cmd(ua, _("Enter new Maximum Jobs: "))) { + if (!get_pint(ua, _("Enter new Maximum Jobs: "))) { return 0; } - maxjobs = atoi(ua->cmd); - if (maxjobs < 0) { - bsendmsg(ua, _("Invalid number, it must be 0 or greater\n")); - break; - } + maxjobs = ua->pint32_val; query = get_pool_memory(PM_MESSAGE); Mmsg(&query, "UPDATE Media SET MaxVolJobs=%u WHERE MediaId=%u", maxjobs, mr.MediaId); @@ -777,14 +768,10 @@ static int update_volume(UAContext *ua) case 4: /* Max Files */ int32_t maxfiles; bsendmsg(ua, _("Current max files is: %u\n"), mr.MaxVolFiles); - if (!get_cmd(ua, _("Enter new Maximum Files: "))) { + if (!get_pint(ua, _("Enter new Maximum Files: "))) { return 0; } - maxfiles = atoi(ua->cmd); - if (maxfiles < 0) { - bsendmsg(ua, _("Invalid number, it must be 0 or greater\n")); - break; - } + maxfiles = ua->pint32_val; query = get_pool_memory(PM_MESSAGE); Mmsg(&query, "UPDATE Media SET MaxVolFiles=%u WHERE MediaId=%u", maxfiles, mr.MediaId); @@ -822,17 +809,10 @@ static int update_volume(UAContext *ua) int recycle; bsendmsg(ua, _("Current recycle flag is: %s\n"), mr.Recycle==1?_("yes"):_("no")); - if (!get_cmd(ua, _("Enter new Recycle status: "))) { + if (!get_yesno(ua, _("Enter new Recycle status: "))) { return 0; } - if (strcasecmp(ua->cmd, _("yes")) == 0) { - recycle = 1; - } else if (strcasecmp(ua->cmd, _("no")) == 0) { - recycle = 0; - } else { - bsendmsg(ua, _("Invalid recycle status specified.\n")); - break; - } + recycle = ua->pint32_val; query = get_pool_memory(PM_MESSAGE); Mmsg(&query, "UPDATE Media SET Recycle=%d WHERE MediaId=%u", recycle, mr.MediaId); @@ -856,14 +836,11 @@ static int update_volume(UAContext *ua) return 0; } bsendmsg(ua, _("Current Slot is: %d\n"), mr.Slot); - if (!get_cmd(ua, _("Enter new Slot: "))) { + if (!get_pint(ua, _("Enter new Slot: "))) { return 0; } - slot = atoi(ua->cmd); - if (slot < 0) { - bsendmsg(ua, _("Invalid slot, it must be 0 or greater\n")); - break; - } else if (pr.MaxVols > 0 && slot >(int)pr.MaxVols) { + slot = ua->pint32_val; + if (pr.MaxVols > 0 && slot > (int)pr.MaxVols) { bsendmsg(ua, _("Invalid slot, it must be between 0 and %d\n"), pr.MaxVols); break; @@ -884,18 +861,13 @@ static int update_volume(UAContext *ua) bsendmsg(ua, _("Warning changing Volume Files can result\n" "in loss of data on your Volume\n\n")); bsendmsg(ua, _("Current Volume Files is: %u\n"), mr.VolFiles); - if (!get_cmd(ua, _("Enter new number of Files for Volume: "))) { + if (!get_pint(ua, _("Enter new number of Files for Volume: "))) { return 0; } - VolFiles = atoi(ua->cmd); - if (VolFiles < 0) { - bsendmsg(ua, _("Invalid number, it must be 0 or greater\n")); - break; - } + VolFiles = ua->pint32_val; if (VolFiles != (int)(mr.VolFiles + 1)) { bsendmsg(ua, _("Normally, you should only increase Volume Files by one!\n")); - if (!get_cmd(ua, _("Continue? (yes/no): ")) || - strcasecmp(ua->cmd, "yes") != 0) { + if (!get_yesno(ua, _("Continue? (yes/no): ")) || ua->pint32_val == 0) { break; } } @@ -1103,14 +1075,10 @@ static int setdebugcmd(UAContext *ua, char *cmd) level = atoi(ua->argv[i]); } if (level < 0) { - if (!get_cmd(ua, _("Enter new debug level: "))) { + if (!get_pint(ua, _("Enter new debug level: "))) { return 1; } - level = atoi(ua->cmd); - } - if (level < 0) { - bsendmsg(ua, _("level cannot be negative.\n")); - return 1; + level = ua->pint32_val; } /* General debug? */ @@ -1266,10 +1234,10 @@ static int delete_volume(UAContext *ua) "and all Jobs saved on that volume from the Catalog\n"), mr.VolumeName); - if (!get_cmd(ua, _("Are you sure you want to delete this Volume? (yes/no): "))) { + if (!get_yesno(ua, _("Are you sure you want to delete this Volume? (yes/no): "))) { return 1; } - if (strcasecmp(ua->cmd, _("yes")) == 0) { + if (ua->pint32_val) { db_delete_media_record(ua->jcr, ua->db, &mr); } return 1; @@ -1287,10 +1255,10 @@ static int delete_pool(UAContext *ua) if (!get_pool_dbr(ua, &pr)) { return 1; } - if (!get_cmd(ua, _("Are you sure you want to delete this Pool? (yes/no): "))) { + if (!get_yesno(ua, _("Are you sure you want to delete this Pool? (yes/no): "))) { return 1; } - if (strcasecmp(ua->cmd, _("yes")) == 0) { + if (ua->pint32_val) { db_delete_pool_record(ua->jcr, ua->db, &pr); } return 1; diff --git a/bacula/src/dird/ua_label.c b/bacula/src/dird/ua_label.c index bd6481a91f..f2a90c8c13 100644 --- a/bacula/src/dird/ua_label.c +++ b/bacula/src/dird/ua_label.c @@ -225,24 +225,13 @@ checkName: /* If autochanger, request slot */ if (store->autochanger) { - int first = 1; - for ( ;; ) { - if (first) { - i = find_arg(ua, "slot"); - if (i >= 0 && ua->argv[i]) { - mr.Slot = atoi(ua->argv[i]); - } - first = 0; - } else { - if (!get_cmd(ua, _("Enter slot (0 for none): "))) { - return 1; - } - mr.Slot = atoi(ua->cmd); - } - if (mr.Slot >= 0) { /* OK */ - break; - } - bsendmsg(ua, _("Slot numbers must be positive.\n")); + i = find_arg(ua, "slot"); + if (i >= 0 && ua->argv[i]) { + mr.Slot = atoi(ua->argv[i]); + } else if (!get_pint(ua, _("Enter slot (0 for none): "))) { + return 1; + } else { + mr.Slot = ua->pint32_val; } } @@ -443,7 +432,7 @@ static int send_label_request(UAContext *ua, MEDIA_DBR *mr, MEDIA_DBR *omr, dev_name, mr->VolumeName, pr->Name, mr->MediaType, mr->Slot); } - while (bget_dirmsg(sd) >= 0) { + while (bnet_recv(sd) >= 0) { bsendmsg(ua, "%s", sd->msg); if (strncmp(sd->msg, "3000 OK label.", 14) == 0) { ok = TRUE; @@ -491,7 +480,7 @@ static vol_list_t *get_slot_list_from_SD(UAContext *ua) bnet_fsend(sd, _("autochanger list %s \n"), dev_name); /* Read and organize list of Volumes */ - while (bget_dirmsg(sd) >= 0) { + while (bnet_recv(sd) >= 0) { char *p; int Slot; strip_trailing_junk(sd->msg); diff --git a/bacula/src/dird/ua_run.c b/bacula/src/dird/ua_run.c index 0439326642..0c32983004 100644 --- a/bacula/src/dird/ua_run.c +++ b/bacula/src/dird/ua_run.c @@ -393,11 +393,11 @@ When: %s\n"), if (jid) { jcr->RestoreJobId = atoi(jid); } else { - if (!get_cmd(ua, _("Please enter a JobId for restore: "))) { + if (!get_pint(ua, _("Please enter a JobId for restore: "))) { free_jcr(jcr); return 1; } - jcr->RestoreJobId = atoi(ua->cmd); + jcr->RestoreJobId = ua->pint32_val; } } jcr->JobLevel = L_FULL; /* default level */ @@ -634,6 +634,7 @@ When: %s\n"), if (strncasecmp(ua->cmd, _("yes"), strlen(ua->cmd)) == 0) { Dmsg1(200, "Calling run_job job=%x\n", jcr->job); run_job(jcr); + bsendmsg(ua, _("Run Job command submitted.\n")); return 1; } diff --git a/bacula/src/dird/ua_select.c b/bacula/src/dird/ua_select.c index bc3eb0038d..5948cfc10b 100644 --- a/bacula/src/dird/ua_select.c +++ b/bacula/src/dird/ua_select.c @@ -552,10 +552,10 @@ POOL *get_pool_resource(UAContext *ua) int select_job_dbr(UAContext *ua, JOB_DBR *jr) { db_list_job_records(ua->jcr, ua->db, jr, prtit, ua, 0); - if (!get_cmd(ua, _("Enter the JobId to select: "))) { + if (!get_pint(ua, _("Enter the JobId to select: "))) { return 0; } - jr->JobId = atoi(ua->cmd); + jr->JobId = ua->pint32_val; if (!db_get_job_record(ua->jcr, ua->db, jr)) { bsendmsg(ua, "%s", db_strerror(ua->db)); return 0; @@ -647,6 +647,14 @@ int do_prompt(UAContext *ua, char *msg, char *prompt, int max_prompt) int i, item; char pmsg[MAXSTRING]; + if (ua->num_prompts == 2) { + item = 1; + if (prompt) { + bstrncpy(prompt, ua->prompt[1], max_prompt); + } + bsendmsg(ua, _("Automatically selected: %s\n"), ua->prompt[1]); + goto done; + } bsendmsg(ua, ua->prompt[0]); for (i=1; i < ua->num_prompts; i++) { bsendmsg(ua, "%6d: %s\n", i, ua->prompt[i]); @@ -674,12 +682,12 @@ int do_prompt(UAContext *ua, char *msg, char *prompt, int max_prompt) sprintf(pmsg, "%s (1-%d): ", msg, ua->num_prompts-1); } /* Either a . or an @ will get you out of the loop */ - if (!get_cmd(ua, pmsg) || *ua->cmd == '@') { + if (!get_pint(ua, pmsg)) { item = -1; /* error */ bsendmsg(ua, _("Selection aborted, nothing done.\n")); break; } - item = atoi(ua->cmd); + item = ua->pint32_val; if (item < 1 || item >= ua->num_prompts) { bsendmsg(ua, _("Please enter a number between 1 and %d\n"), ua->num_prompts-1); continue; @@ -690,6 +698,7 @@ int do_prompt(UAContext *ua, char *msg, char *prompt, int max_prompt) break; } +done: for (i=0; i < ua->num_prompts; i++) { free(ua->prompt[i]); } diff --git a/bacula/src/filed/bacula-fd.conf.in b/bacula/src/filed/bacula-fd.conf.in index 549f20c5e6..a73011ae7f 100644 --- a/bacula/src/filed/bacula-fd.conf.in +++ b/bacula/src/filed/bacula-fd.conf.in @@ -23,7 +23,6 @@ FileDaemon { # this is me FDport = @fd_port@ # where we listen for the director WorkingDirectory = @working_dir@ Pid Directory = @piddir@ - SubSys Directory = @subsysdir@ } # Send all messages except skipped files back to Director diff --git a/bacula/src/filed/filed_conf.c b/bacula/src/filed/filed_conf.c index 20114298b2..05781eb7cb 100644 --- a/bacula/src/filed/filed_conf.c +++ b/bacula/src/filed/filed_conf.c @@ -8,14 +8,14 @@ * 1. The generic lexical scanner in lib/lex.c and lib/lex.h * * 2. The generic config scanner in lib/parse_config.c and - * lib/parse_config.h. - * These files contain the parser code, some utility - * routines, and the common store routines (name, int, - * string). + * lib/parse_config.h. + * These files contain the parser code, some utility + * routines, and the common store routines (name, int, + * string). * * 3. The daemon specific file, which contains the Resource - * definitions as well as any specific store routines - * for the resource records. + * definitions as well as any specific store routines + * for the resource records. * * Kern Sibbald, September MM * @@ -77,7 +77,7 @@ static struct res_items cli_items[] = { {"fdaddress", store_str, ITEM(res_client.FDaddr), 0, 0, 0}, {"workingdirectory", store_dir, ITEM(res_client.working_directory), 0, ITEM_REQUIRED, 0}, {"piddirectory", store_dir, ITEM(res_client.pid_directory), 0, ITEM_REQUIRED, 0}, - {"subsysdirectory", store_dir, ITEM(res_client.subsys_directory), 0, ITEM_REQUIRED, 0}, + {"subsysdirectory", store_dir, ITEM(res_client.subsys_directory), 0, 0, 0}, {"requiressl", store_yesno, ITEM(res_client.require_ssl), 1, ITEM_DEFAULT, 0}, {"maximumconcurrentjobs", store_pint, ITEM(res_client.MaxConcurrentJobs), 0, ITEM_DEFAULT, 5}, {"messages", store_res, ITEM(res_client.messages), R_MSGS, 0, 0}, @@ -107,7 +107,7 @@ struct s_res resources[] = { {"filedaemon", cli_items, R_CLIENT, NULL}, {"client", cli_items, R_CLIENT, NULL}, /* alias for filedaemon */ {"messages", msgs_items, R_MSGS, NULL}, - {NULL, NULL, 0, NULL} + {NULL, NULL, 0, NULL} }; @@ -121,26 +121,26 @@ void dump_resource(int type, RES *reshdr, void sendit(void *sock, char *fmt, ... sendit(sock, "No record for %d %s\n", type, res_to_str(type)); return; } - if (type < 0) { /* no recursion */ + if (type < 0) { /* no recursion */ type = - type; recurse = 0; } switch (type) { case R_DIRECTOR: sendit(sock, "Director: name=%s password=%s\n", reshdr->name, - res->res_dir.password); - break; + res->res_dir.password); + break; case R_CLIENT: sendit(sock, "Client: name=%s FDport=%d\n", reshdr->name, - res->res_client.FDport); - break; + res->res_client.FDport); + break; case R_MSGS: sendit(sock, "Messages: name=%s\n", res->res_msgs.hdr.name); - if (res->res_msgs.mail_cmd) + if (res->res_msgs.mail_cmd) sendit(sock, " mailcmd=%s\n", res->res_msgs.mail_cmd); - if (res->res_msgs.operator_cmd) + if (res->res_msgs.operator_cmd) sendit(sock, " opcmd=%s\n", res->res_msgs.operator_cmd); - break; + break; default: sendit(sock, "Unknown resource type %d\n", type); } @@ -178,35 +178,35 @@ void free_resource(int type) switch (type) { case R_DIRECTOR: - if (res->res_dir.password) { - free(res->res_dir.password); - } - if (res->res_dir.address) { - free(res->res_dir.address); - } - break; + if (res->res_dir.password) { + free(res->res_dir.password); + } + if (res->res_dir.address) { + free(res->res_dir.address); + } + break; case R_CLIENT: - if (res->res_client.working_directory) { - free(res->res_client.working_directory); - } - if (res->res_client.pid_directory) { - free(res->res_client.pid_directory); - } - if (res->res_client.subsys_directory) { - free(res->res_client.subsys_directory); - } - if (res->res_client.FDaddr) { - free(res->res_client.FDaddr); - } - break; + if (res->res_client.working_directory) { + free(res->res_client.working_directory); + } + if (res->res_client.pid_directory) { + free(res->res_client.pid_directory); + } + if (res->res_client.subsys_directory) { + free(res->res_client.subsys_directory); + } + if (res->res_client.FDaddr) { + free(res->res_client.FDaddr); + } + break; case R_MSGS: - if (res->res_msgs.mail_cmd) - free(res->res_msgs.mail_cmd); - if (res->res_msgs.operator_cmd) - free(res->res_msgs.operator_cmd); - free_msgs_res((MSGS *)res); /* free message resource */ - res = NULL; - break; + if (res->res_msgs.mail_cmd) + free(res->res_msgs.mail_cmd); + if (res->res_msgs.operator_cmd) + free(res->res_msgs.operator_cmd); + free_msgs_res((MSGS *)res); /* free message resource */ + res = NULL; + break; default: printf("Unknown resource type %d\n", type); } @@ -236,10 +236,10 @@ void save_resource(int type, struct res_items *items, int pass) */ for (i=0; items[i].name; i++) { if (items[i].flags & ITEM_REQUIRED) { - if (!bit_is_set(i, res_all.res_dir.hdr.item_present)) { + if (!bit_is_set(i, res_all.res_dir.hdr.item_present)) { Emsg2(M_ABORT, 0, _("%s item is required in %s resource, but not found.\n"), - items[i].name, resources[rindex]); - } + items[i].name, resources[rindex]); + } } } @@ -250,33 +250,33 @@ void save_resource(int type, struct res_items *items, int pass) */ if (pass == 2) { switch (type) { - /* Resources not containing a resource */ - case R_MSGS: - case R_DIRECTOR: - break; + /* Resources not containing a resource */ + case R_MSGS: + case R_DIRECTOR: + break; - /* Resources containing another resource */ - case R_CLIENT: - if ((res = (URES *)GetResWithName(R_CLIENT, res_all.res_dir.hdr.name)) == NULL) { + /* Resources containing another resource */ + case R_CLIENT: + if ((res = (URES *)GetResWithName(R_CLIENT, res_all.res_dir.hdr.name)) == NULL) { Emsg1(M_ABORT, 0, "Cannot find Client resource %s\n", res_all.res_dir.hdr.name); - } - res->res_client.messages = res_all.res_client.messages; - break; - default: + } + res->res_client.messages = res_all.res_client.messages; + break; + default: Emsg1(M_ERROR, 0, _("Unknown resource type %d\n"), type); - error = 1; - break; + error = 1; + break; } /* Note, the resoure name was already saved during pass 1, * so here, we can just release it. */ if (res_all.res_dir.hdr.name) { - free(res_all.res_dir.hdr.name); - res_all.res_dir.hdr.name = NULL; + free(res_all.res_dir.hdr.name); + res_all.res_dir.hdr.name = NULL; } if (res_all.res_dir.hdr.desc) { - free(res_all.res_dir.hdr.desc); - res_all.res_dir.hdr.desc = NULL; + free(res_all.res_dir.hdr.desc); + res_all.res_dir.hdr.desc = NULL; } return; } @@ -284,34 +284,34 @@ void save_resource(int type, struct res_items *items, int pass) /* The following code is only executed on pass 1 */ switch (type) { case R_DIRECTOR: - size = sizeof(DIRRES); - break; + size = sizeof(DIRRES); + break; case R_CLIENT: - size = sizeof(CLIENT); - break; + size = sizeof(CLIENT); + break; case R_MSGS: - size = sizeof(MSGS); - break; + size = sizeof(MSGS); + break; default: printf(_("Unknown resource type %d\n"), type); - error = 1; - size = 1; - break; + error = 1; + size = 1; + break; } /* Common */ if (!error) { res = (URES *)malloc(size); memcpy(res, &res_all, size); if (!resources[rindex].res_head) { - resources[rindex].res_head = (RES *)res; /* store first entry */ + resources[rindex].res_head = (RES *)res; /* store first entry */ } else { - RES *next; - /* Add new res to end of chain */ - for (next=resources[rindex].res_head; next->next; next=next->next) - { } - next->next = (RES *)res; + RES *next; + /* Add new res to end of chain */ + for (next=resources[rindex].res_head; next->next; next=next->next) + { } + next->next = (RES *)res; Dmsg2(90, "Inserting %s res: %s\n", res_to_str(type), - res->res_dir.hdr.name); + res->res_dir.hdr.name); } } } diff --git a/bacula/src/filed/win32/bin/btraceback.gdb b/bacula/src/filed/win32/bin/btraceback.gdb index 74e1f23cfa..387430a57c 100755 --- a/bacula/src/filed/win32/bin/btraceback.gdb +++ b/bacula/src/filed/win32/bin/btraceback.gdb @@ -1,6 +1,8 @@ print my_name print exename print exepath +print catalog_db +print version bt thread apply all bt f 0 diff --git a/bacula/src/findlib/create_file.c b/bacula/src/findlib/create_file.c index a6d54d6e87..56ab9da7b9 100644 --- a/bacula/src/findlib/create_file.c +++ b/bacula/src/findlib/create_file.c @@ -68,7 +68,6 @@ int create_file(void *jcr, char *fname, char *ofile, char *lname, int new_mode, parent_mode, mode; uid_t uid; gid_t gid; - int stat = 0; int pnl; binit(ofd, win_io); @@ -137,7 +136,7 @@ int create_file(void *jcr, char *fname, char *ofile, char *lname, * execute bit set (i.e. parent_mode), and preserve what already * exists. Normally, this should do nothing. */ - if (!make_path(jcr, ofile, parent_mode, parent_mode, uid, gid, 1, NULL)) { + if (make_path(jcr, ofile, parent_mode, parent_mode, uid, gid, 1, NULL) != 0) { Dmsg1(0, "Could not make path. %s\n", ofile); return CF_ERROR; } @@ -224,7 +223,7 @@ int create_file(void *jcr, char *fname, char *ofile, char *lname, case FT_DIR: Dmsg2(300, "Make dir mode=%o dir=%s\n", new_mode, ofile); - if (!make_path(jcr, ofile, new_mode, parent_mode, uid, gid, 0, NULL)) { + if (make_path(jcr, ofile, new_mode, parent_mode, uid, gid, 0, NULL) != 0) { return CF_ERROR; } return CF_CREATED; diff --git a/bacula/src/lib/jcr.c b/bacula/src/lib/jcr.c index 5c77afbd74..fa716293ba 100755 --- a/bacula/src/lib/jcr.c +++ b/bacula/src/lib/jcr.c @@ -62,6 +62,7 @@ JCR *new_jcr(int size, JCR_free_HANDLER *daemon_free_jcr) jcr->VolumeName[0] = 0; jcr->errmsg = get_pool_memory(PM_MESSAGE); jcr->errmsg[0] = 0; + strcpy(jcr->Job, "*Console*"); /* default */ sigtimer.sa_flags = 0; sigtimer.sa_handler = timeout_handler; diff --git a/bacula/src/lib/message.c b/bacula/src/lib/message.c index 94eb942558..83283a52ce 100755 --- a/bacula/src/lib/message.c +++ b/bacula/src/lib/message.c @@ -37,6 +37,7 @@ char *working_directory = NULL; /* working directory path stored here */ int verbose = 0; /* increase User messages */ int debug_level = 0; /* debug level */ time_t daemon_start_time = 0; /* Daemon start time */ +char *version = VERSION " (" BDATE ")"; char my_name[20]; /* daemon name is stored here */ char *exepath = (char *)NULL; @@ -874,6 +875,19 @@ Jmsg(void *vjcr, int type, int level, char *fmt,...) Dmsg1(800, "Enter Jmsg type=%d\n", type); + /* Special case for the console, which has a dir_bsock and JobId==0, + * in that case, we send the message directly back to the + * dir_bsock. + */ + if (jcr && jcr->JobId == 0 && jcr->dir_bsock) { + BSOCK *dir = jcr->dir_bsock; + va_start(arg_ptr, fmt); + dir->msglen = bvsnprintf(dir->msg, sizeof_pool_memory(dir->msg), fmt, arg_ptr); + va_end(arg_ptr); + bnet_send(jcr->dir_bsock); + return; + } + msgs = NULL; job = NULL; if (jcr) { @@ -896,30 +910,30 @@ Jmsg(void *vjcr, int type, int level, char *fmt,...) return; /* no destination */ } switch (type) { - case M_ABORT: - len = sprintf(rbuf, "%s ABORTING due to ERROR\n", my_name); - break; - case M_ERROR_TERM: - len = sprintf(rbuf, "%s ERROR TERMINATION\n", my_name); - break; - case M_FATAL: - len = sprintf(rbuf, "%s: %s Fatal error: ", my_name, job); - if (jcr) { - set_jcr_job_status(jcr, JS_FatalError); - } - break; - case M_ERROR: - len = sprintf(rbuf, "%s: %s Error: ", my_name, job); - if (jcr) { - jcr->Errors++; - } - break; - case M_WARNING: - len = sprintf(rbuf, "%s: %s Warning: ", my_name, job); - break; - default: - len = sprintf(rbuf, "%s: ", my_name); - break; + case M_ABORT: + len = sprintf(rbuf, "%s ABORTING due to ERROR\n", my_name); + break; + case M_ERROR_TERM: + len = sprintf(rbuf, "%s ERROR TERMINATION\n", my_name); + break; + case M_FATAL: + len = sprintf(rbuf, "%s: %s Fatal error: ", my_name, job); + if (jcr) { + set_jcr_job_status(jcr, JS_FatalError); + } + break; + case M_ERROR: + len = sprintf(rbuf, "%s: %s Error: ", my_name, job); + if (jcr) { + jcr->Errors++; + } + break; + case M_WARNING: + len = sprintf(rbuf, "%s: %s Warning: ", my_name, job); + break; + default: + len = sprintf(rbuf, "%s: ", my_name); + break; } va_start(arg_ptr, fmt); diff --git a/bacula/src/stored/askdir.c b/bacula/src/stored/askdir.c index f3a7a3d14a..c73dc580c5 100644 --- a/bacula/src/stored/askdir.c +++ b/bacula/src/stored/askdir.c @@ -71,7 +71,7 @@ int dir_send_job_status(JCR *jcr) static int do_request_volume_info(JCR *jcr) { BSOCK *dir = jcr->dir_bsock; - VOLUME_CAT_INFO *vol = &jcr->VolCatInfo; + VOLUME_CAT_INFO vol; jcr->VolumeName[0] = 0; /* No volume */ if (bnet_recv(dir) <= 0) { @@ -79,23 +79,24 @@ static int do_request_volume_info(JCR *jcr) Mmsg(&jcr->errmsg, _("Network error on bnet_recv in req_vol_info.\n")); return 0; } - if (sscanf(dir->msg, OK_media, vol->VolCatName, - &vol->VolCatJobs, &vol->VolCatFiles, - &vol->VolCatBlocks, &vol->VolCatBytes, - &vol->VolCatMounts, &vol->VolCatErrors, - &vol->VolCatWrites, &vol->VolCatMaxBytes, - &vol->VolCatCapacityBytes, vol->VolCatStatus, - &vol->Slot, &vol->VolCatMaxJobs, &vol->VolCatMaxFiles) != 14) { + if (sscanf(dir->msg, OK_media, vol.VolCatName, + &vol.VolCatJobs, &vol.VolCatFiles, + &vol.VolCatBlocks, &vol.VolCatBytes, + &vol.VolCatMounts, &vol.VolCatErrors, + &vol.VolCatWrites, &vol.VolCatMaxBytes, + &vol.VolCatCapacityBytes, vol.VolCatStatus, + &vol.Slot, &vol.VolCatMaxJobs, &vol.VolCatMaxFiles) != 14) { Dmsg1(200, "Bad response from Dir: %s\n", dir->msg); Mmsg(&jcr->errmsg, _("Error scanning Dir response: %s\n"), dir->msg); return 0; } - unbash_spaces(vol->VolCatName); - pm_strcpy(&jcr->VolumeName, vol->VolCatName); /* set desired VolumeName */ + unbash_spaces(vol.VolCatName); + pm_strcpy(&jcr->VolumeName, vol.VolCatName); /* set desired VolumeName */ + memcpy(&jcr->VolCatInfo, &vol, sizeof(jcr->VolCatInfo)); Dmsg2(200, "do_reqest_vol_info got slot=%d Volume=%s\n", - vol->Slot, vol->VolCatName); + vol.Slot, vol.VolCatName); return 1; } @@ -166,14 +167,15 @@ int dir_update_volume_info(JCR *jcr, VOLUME_CAT_INFO *vol, int relabel) unbash_spaces(vol->VolCatName); if (bnet_recv(dir) <= 0) { Dmsg0(190, "updateVolCatInfo error bnet_recv\n"); - Jmsg(jcr, M_ERROR, 0, _("Error updating Volume Info: %s\n"), - bnet_strerror(dir)); + Jmsg(jcr, M_ERROR, 0, _("Error updating Volume info Vol=\"%s\": ERR=%s\n"), + vol->VolCatName, bnet_strerror(dir)); return 0; } Dmsg1(120, "Updatevol: %s", dir->msg); if (strcmp(dir->msg, OK_update) != 0) { Dmsg1(130, "Bad response from Dir: %s\n", dir->msg); - Jmsg(jcr, M_ERROR, 0, _("Error updating Volume Info: %s\n"), dir->msg); + Jmsg(jcr, M_ERROR, 0, _("Error updating Volume info Vol=\"%s\": %s\n"), + vol->VolCatName, dir->msg); return 0; } return 1; @@ -193,7 +195,7 @@ int dir_create_jobmedia_record(JCR *jcr) Dmsg1(100, "create_jobmedia(): %s", dir->msg); if (bnet_recv(dir) <= 0) { Dmsg0(190, "create_jobmedia error bnet_recv\n"); - Jmsg(jcr, M_ERROR, 0, _("Error creating JobMedia record: %s\n"), + Jmsg(jcr, M_ERROR, 0, _("Error creating JobMedia record: ERR=%s\n"), bnet_strerror(dir)); return 0; } diff --git a/bacula/src/stored/autochanger.c b/bacula/src/stored/autochanger.c index 4f9682766f..fbfa32a75c 100644 --- a/bacula/src/stored/autochanger.c +++ b/bacula/src/stored/autochanger.c @@ -74,11 +74,7 @@ int autoload_device(JCR *jcr, DEVICE *dev, int writing, BSOCK *dir) changer = get_pool_memory(PM_FNAME); /* Find out what is loaded, zero means device is unloaded */ - if (dir) { - bnet_fsend(dir, _("3301 Issuing autochanger \"loaded\" command.\n")); - } else { - Jmsg(jcr, M_INFO, 0, _("Issuing autochanger \"loaded\" command.\n")); - } + Jmsg(jcr, M_INFO, 0, _("3301 Issuing autochanger \"loaded\" command.\n")); changer = edit_device_codes(jcr, changer, jcr->device->changer_command, "loaded"); status = run_program(changer, timeout, results); @@ -86,13 +82,7 @@ int autoload_device(JCR *jcr, DEVICE *dev, int writing, BSOCK *dir) if (status == 0) { loaded = atoi(results); } else { - if (dir) { - bnet_fsend(dir, _("3991 Bad autochanger \"loaded\" status=%d.\n"), - status); - } else { - Jmsg(jcr, M_INFO, 0, _("Bad autochanger \"load slot\" status=%d.\n"), - status); - } + Jmsg(jcr, M_INFO, 0, _("3991 Bad autochanger \"load slot\" status=%d.\n"), status); loaded = -1; /* force unload */ } Dmsg1(100, "loaded=%s\n", results); @@ -106,11 +96,7 @@ int autoload_device(JCR *jcr, DEVICE *dev, int writing, BSOCK *dir) force_close_dev(dev); if (loaded != 0) { /* must unload drive */ Dmsg0(100, "Doing changer unload.\n"); - if (dir) { - bnet_fsend(dir, _("3302 Issuing autochanger \"unload\" command.\n")); - } else { - Jmsg(jcr, M_INFO, 0, _("Issuing autochanger \"unload\" command.\n")); - } + Jmsg(jcr, M_INFO, 0, _("3302 Issuing autochanger \"unload\" command.\n")); changer = edit_device_codes(jcr, changer, jcr->device->changer_command, "unload"); status = run_program(changer, timeout, NULL); @@ -120,32 +106,17 @@ int autoload_device(JCR *jcr, DEVICE *dev, int writing, BSOCK *dir) * Load the desired cassette */ Dmsg1(100, "Doing changer load slot %d\n", slot); - if (dir) { - bnet_fsend(dir, _("3303 Issuing autochanger \"load slot %d\" command.\n"), - slot); - } else { - Jmsg(jcr, M_INFO, 0, _("Issuing autochanger \"load slot %d\" command.\n"), - slot); - } + Jmsg(jcr, M_INFO, 0, _("3303 Issuing autochanger \"load slot %d\" command.\n"), + slot); changer = edit_device_codes(jcr, changer, jcr->device->changer_command, "load"); status = run_program(changer, timeout, NULL); if (status == 0) { - if (dir) { - bnet_fsend(dir, _("3304 Autochanger \"load slot %d\" status is OK.\n"), + Jmsg(jcr, M_INFO, 0, _("3304 Autochanger \"load slot %d\" status is OK.\n"), slot); - } else { - Jmsg(jcr, M_INFO, 0, _("Autochanger \"load slot %d\" status is OK.\n"), - slot); - } } else { - if (dir) { - bnet_fsend(dir, _("3992 Bad autochanger \"load slot\" status=%d.\n"), - status); - } else { - Jmsg(jcr, M_INFO, 0, _("Bad autochanger \"load slot\" status=%d.\n"), + Jmsg(jcr, M_INFO, 0, _("3992 Bad autochanger \"load slot\" status=%d.\n"), status); - } } Dmsg2(100, "load slot %d status=%d\n", slot, status); } @@ -185,16 +156,16 @@ int autochanger_list(JCR *jcr, DEVICE *dev, BSOCK *dir) force_close_dev(dev); /* First unload any tape */ - bnet_fsend(dir, _("3902 Issuing autochanger \"unload\" command.\n")); + bnet_fsend(dir, _("3305 Issuing autochanger \"unload\" command.\n")); changer = edit_device_codes(jcr, changer, jcr->device->changer_command, "unload"); run_program(changer, timeout, NULL); /* Now list slots occupied */ changer = edit_device_codes(jcr, changer, jcr->device->changer_command, "list"); - bnet_fsend(dir, _("3305 Issuing autochanger \"list\" command.\n")); + bnet_fsend(dir, _("3306 Issuing autochanger \"list\" command.\n")); bpipe = open_bpipe(changer, timeout, "r"); if (!bpipe) { - bnet_fsend(dir, _("3994 Open bpipe failed.\n")); + bnet_fsend(dir, _("3993 Open bpipe failed.\n")); goto bail_out; } /* Get output from changer */ diff --git a/bacula/src/stored/bacula-sd.conf.in b/bacula/src/stored/bacula-sd.conf.in index 37f415e4a2..6db6582f7b 100644 --- a/bacula/src/stored/bacula-sd.conf.in +++ b/bacula/src/stored/bacula-sd.conf.in @@ -15,7 +15,6 @@ Storage { # definition of myself SDPort = @sd_port@ # Director's port WorkingDirectory = "@working_dir@" Pid Directory = "@piddir@" - Subsys Directory = "@subsysdir@" } # diff --git a/bacula/src/stored/block.c b/bacula/src/stored/block.c index b438b38d51..762583b13a 100644 --- a/bacula/src/stored/block.c +++ b/bacula/src/stored/block.c @@ -428,6 +428,16 @@ int write_block_to_dev(JCR *jcr, DEVICE *dev, DEV_BLOCK *block) if (ok && bsr_dev(dev, 1) != 0) { ok = FALSE; Jmsg(jcr, M_ERROR, 0, _("Back space record at EOT failed. ERR=%s\n"), strerror(dev->dev_errno)); + /* ****FIXME***** + * On FreeBSD systems, if the user got here, it is likely that his/her + * tape drive is "frozen". The correct thing to do is a + * rewind(), but if we do that, higher levels in cleaning up, will + * most likely write the EOS record over the beginning of the + * tape. The rewind *is* done later in mount.c when another + * tape is requested. However, it should be done here. In that + * case, we need to send back some fatal error status to avoid + * future writes. + */ } if (ok) { DEV_BLOCK *lblock = new_block(dev); diff --git a/bacula/src/stored/device.c b/bacula/src/stored/device.c index e91d8ddf4a..b07756a617 100644 --- a/bacula/src/stored/device.c +++ b/bacula/src/stored/device.c @@ -113,8 +113,6 @@ int fixup_device_block_write_error(JCR *jcr, DEVICE *dev, DEV_BLOCK *block) Dmsg2(200, "Call update_vol_info Stat=%s Vol=%s\n", dev->VolCatInfo.VolCatStatus, dev->VolCatInfo.VolCatName); if (!dir_update_volume_info(jcr, &dev->VolCatInfo, 0)) { /* send Volume info to Director */ - Jmsg(jcr, M_ERROR, 0, _("Could not update Volume info Volume=%s Job=%s\n"), - dev->VolCatInfo.VolCatName, jcr->Job); P(dev->mutex); unblock_device(dev); return 0; /* device locked */ diff --git a/bacula/src/stored/dircmd.c b/bacula/src/stored/dircmd.c index 08d653d770..4b0be5edcb 100644 --- a/bacula/src/stored/dircmd.c +++ b/bacula/src/stored/dircmd.c @@ -431,11 +431,9 @@ static int read_label(JCR *jcr, DEVICE *dev) int stat; BSOCK *dir = jcr->dir_bsock; DEV_BLOCK *block; -#ifndef NEW_LOCK bsteal_lock_t hold; steal_device_lock(dev, &hold, BST_DOING_ACQUIRE); -#endif jcr->VolumeName[0] = 0; block = new_block(dev); @@ -452,9 +450,7 @@ static int read_label(JCR *jcr, DEVICE *dev) break; } free_block(block); -#ifndef NEW_LOCK return_device_lock(dev, &hold); -#endif return stat; } diff --git a/bacula/src/stored/mount.c b/bacula/src/stored/mount.c index 61c31b35ff..e06e3cb1f6 100644 --- a/bacula/src/stored/mount.c +++ b/bacula/src/stored/mount.c @@ -77,6 +77,13 @@ mount_next_vol: if (!dev_is_tape(dev) || !dev_cap(dev, CAP_ALWAYSOPEN)) { if (dev_cap(dev, CAP_OFFLINEUNMOUNT)) { offline_dev(dev); + /* + * Note, this rewind probably should not be here (it wasn't + * in prior versions of Bacula), but on FreeBSD, this is + * needed in the case the tape was "frozen" due to an error + * such as backspacing after writing and EOF. If it is not + * done, all future references to the drive get and I/O error. + */ } else if (!rewind_dev(dev)) { Jmsg2(jcr, M_WARNING, 0, _("Rewind error on device %s. ERR=%s\n"), dev_name(dev), strerror_dev(dev)); @@ -99,9 +106,9 @@ mount_next_vol: /* * Get Director's idea of what tape we should have mounted. */ - if (!dir_find_next_appendable_volume(jcr)) { - ask = 1; /* we must ask */ - Dmsg0(100, "did not find next volume. Must ask.\n"); + if (!dir_find_next_appendable_volume(jcr) && + !dir_ask_sysop_to_mount_next_volume(jcr, dev)) { + return 0; } Dmsg2(100, "After find_next_append. Vol=%s Slot=%d\n", jcr->VolCatInfo.VolCatName, jcr->VolCatInfo.Slot); @@ -177,69 +184,75 @@ read_volume: } else { vol_label_status = read_dev_volume_label(jcr, dev, block); } + /* + * At this point, dev->VolCatInfo has what is in the drive, if anything, + * and jcr->VolCatInfo has what the Director wants. + */ switch (vol_label_status) { - case VOL_OK: - Dmsg1(100, "Vol OK name=%s\n", jcr->VolumeName); - memcpy(&dev->VolCatInfo, &jcr->VolCatInfo, sizeof(jcr->VolCatInfo)); - if (strcmp(dev->VolCatInfo.VolCatStatus, "Recycle") == 0) { - recycle = 1; - } - break; /* got it */ - case VOL_NAME_ERROR: - Dmsg1(100, "Vol NAME Error Name=%s\n", jcr->VolumeName); - /* - * OK, we got a different volume mounted. First save the - * requested Volume info in the dev structure, then query if - * this volume is really OK. If not, put back the desired - * volume name and continue. - */ - memcpy(&dev->VolCatInfo, &jcr->VolCatInfo, sizeof(jcr->VolCatInfo)); - /* Check if this is a valid Volume in the pool */ - pm_strcpy(&jcr->VolumeName, dev->VolHdr.VolName); - if (!dir_get_volume_info(jcr, 1)) { - Mmsg(&jcr->errmsg, _("Wanted Volume \"%s\".\n" - " Current Volume \"%s\" not acceptable because:\n" - " %s"), - dev->VolCatInfo.VolCatName, dev->VolHdr.VolName, - jcr->dir_bsock->msg); - /* Restore desired volume name, note device info out of sync */ - memcpy(&jcr->VolCatInfo, &dev->VolCatInfo, sizeof(jcr->VolCatInfo)); - goto mount_error; - } - Dmsg1(100, "want new name=%s\n", jcr->VolumeName); - memcpy(&dev->VolCatInfo, &jcr->VolCatInfo, sizeof(jcr->VolCatInfo)); - break; + case VOL_OK: + Dmsg1(100, "Vol OK name=%s\n", jcr->VolumeName); + memcpy(&dev->VolCatInfo, &jcr->VolCatInfo, sizeof(jcr->VolCatInfo)); + if (strcmp(dev->VolCatInfo.VolCatStatus, "Recycle") == 0) { + recycle = 1; + } + break; /* got a Volume */ + case VOL_NAME_ERROR: + VOLUME_CAT_INFO VolCatInfo; - case VOL_NO_LABEL: - case VOL_IO_ERROR: - Dmsg1(500, "Vol NO_LABEL or IO_ERROR name=%s\n", jcr->VolumeName); - /* If permitted, create a label */ - if (dev_cap(dev, CAP_LABEL)) { - Dmsg0(100, "Create volume label\n"); - if (!write_volume_label_to_dev(jcr, (DEVRES *)dev->device, jcr->VolumeName, - jcr->pool_name)) { - Dmsg0(100, "!write_vol_label\n"); - goto mount_next_vol; - } - Jmsg(jcr, M_INFO, 0, _("Labeled new Volume \"%s\" on device %s.\n"), - jcr->VolumeName, dev_name(dev)); - goto read_volume; /* read label we just wrote */ - } - /* NOTE! Fall-through wanted. */ - default: + Dmsg1(100, "Vol NAME Error Name=%s\n", jcr->VolumeName); + /* + * OK, we got a different volume mounted. First save the + * requested Volume info (jcr) structure, then query if + * this volume is really OK. If not, put back the desired + * volume name and continue. + */ + memcpy(&VolCatInfo, &jcr->VolCatInfo, sizeof(jcr->VolCatInfo)); + /* Check if this is a valid Volume in the pool */ + pm_strcpy(&jcr->VolumeName, dev->VolHdr.VolName); + if (!dir_get_volume_info(jcr, 1)) { + Mmsg(&jcr->errmsg, _("Director wanted Volume \"%s\".\n" + " Current Volume \"%s\" not acceptable because:\n" + " %s"), + VolCatInfo.VolCatName, dev->VolHdr.VolName, + jcr->dir_bsock->msg); + /* Restore desired volume name, note device info out of sync */ + memcpy(&jcr->VolCatInfo, &VolCatInfo, sizeof(jcr->VolCatInfo)); + goto mount_error; + } + Dmsg1(100, "want new name=%s\n", jcr->VolumeName); + memcpy(&dev->VolCatInfo, &jcr->VolCatInfo, sizeof(jcr->VolCatInfo)); + break; /* got a Volume */ + + case VOL_NO_LABEL: + case VOL_IO_ERROR: + Dmsg1(500, "Vol NO_LABEL or IO_ERROR name=%s\n", jcr->VolumeName); + /* If permitted, create a label */ + if (dev_cap(dev, CAP_LABEL)) { + Dmsg0(100, "Create volume label\n"); + if (!write_volume_label_to_dev(jcr, (DEVRES *)dev->device, jcr->VolumeName, + jcr->pool_name)) { + Dmsg0(100, "!write_vol_label\n"); + goto mount_next_vol; + } + Jmsg(jcr, M_INFO, 0, _("Labeled new Volume \"%s\" on device %s.\n"), + jcr->VolumeName, dev_name(dev)); + goto read_volume; /* read label we just wrote */ + } + /* NOTE! Fall-through wanted. */ + default: mount_error: - /* Send error message */ - Jmsg1(jcr, M_WARNING, 0, "%s", jcr->errmsg); - if (autochanger) { - Jmsg(jcr, M_ERROR, 0, _("Autochanger Volume \"%s\" not found in slot %d.\n\ + /* Send error message */ + Jmsg1(jcr, M_WARNING, 0, "%s", jcr->errmsg); + if (autochanger) { + Jmsg(jcr, M_ERROR, 0, _("Autochanger Volume \"%s\" not found in slot %d.\n\ Setting slot to zero in catalog.\n"), - jcr->VolCatInfo.VolCatName, jcr->VolCatInfo.Slot); - jcr->VolCatInfo.Slot = 0; /* invalidate slot */ - Dmsg0(200, "update vol info in mount\n"); - dir_update_volume_info(jcr, &jcr->VolCatInfo, 1); /* set slot */ - } - Dmsg0(100, "Default\n"); - goto mount_next_vol; + jcr->VolCatInfo.VolCatName, jcr->VolCatInfo.Slot); + jcr->VolCatInfo.Slot = 0; /* invalidate slot */ + Dmsg0(200, "update vol info in mount\n"); + dir_update_volume_info(jcr, &jcr->VolCatInfo, 1); /* set slot */ + } + Dmsg0(100, "Default\n"); + goto mount_next_vol; } break; } diff --git a/bacula/src/stored/stored_conf.c b/bacula/src/stored/stored_conf.c index c3c8240d61..4704eca681 100644 --- a/bacula/src/stored/stored_conf.c +++ b/bacula/src/stored/stored_conf.c @@ -61,7 +61,7 @@ static struct res_items store_items[] = { {"sddport", store_int, ITEM(res_store.SDDport), 0, 0, 0}, /* deprecated */ {"workingdirectory", store_dir, ITEM(res_store.working_directory), 0, ITEM_REQUIRED, 0}, {"piddirectory", store_dir, ITEM(res_store.pid_directory), 0, ITEM_REQUIRED, 0}, - {"subsysdirectory", store_dir, ITEM(res_store.subsys_directory), 0, ITEM_REQUIRED, 0}, + {"subsysdirectory", store_dir, ITEM(res_store.subsys_directory), 0, 0, 0}, {"requiressl", store_yesno,ITEM(res_store.require_ssl), 1, ITEM_DEFAULT, 0}, {"maximumconcurrentjobs", store_pint, ITEM(res_store.max_concurrent_jobs), 0, ITEM_DEFAULT, 5}, {"heartbeatinterval", store_time, ITEM(res_store.heartbeat_interval), 0, ITEM_DEFAULT, 20*60}, -- 2.39.5