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.
- 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 <cmccurdy@eecis.udel.edu>
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.
- 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).
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
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
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"
%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
%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
%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
%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
%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
* Mon May 11 2003 D. Scott Barninger <barninger at fairfieldcomputers.com>
- 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 <kern at sibbald.com>
- Update spec for version 1.31 and combine client
* Sun Mar 30 2003 D. Scott Barninger <barninger at fairfieldcomputers.com>
print my_name
print exename
print exepath
+print catalog_db
+print version
bt
thread apply all bt
f 0
#ifdef HAVE_BACULA_DB
+char catalog_db[] = "Interal";
+
/* Forward referenced functions */
extern char *working_directory;
#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);
*/
/*
- 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"
QueryFile = "@scriptdir@/query.sql"
WorkingDirectory = "@working_dir@"
PidDirectory = "@piddir@"
- SubSysDirectory = "@subsysdir@"
Maximum Concurrent Jobs = 1
Password = "@dir_password@" # Console password
Messages = Standard
{"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},
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;
}
}
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;
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;
}
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);
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);
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);
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);
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;
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;
}
}
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? */
"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;
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;
/* 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;
}
}
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;
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);
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 */
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;
}
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;
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]);
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;
break;
}
+done:
for (i=0; i < ua->num_prompts; i++) {
free(ua->prompt[i]);
}
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
* 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
*
{"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},
{"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}
};
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);
}
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);
}
*/
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]);
+ }
}
}
*/
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;
}
/* 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);
}
}
}
print my_name
print exename
print exepath
+print catalog_db
+print version
bt
thread apply all bt
f 0
int new_mode, parent_mode, mode;
uid_t uid;
gid_t gid;
- int stat = 0;
int pnl;
binit(ofd, win_io);
* 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;
}
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;
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;
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;
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) {
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);
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) {
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;
}
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;
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;
}
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);
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);
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);
* 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);
}
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 */
SDPort = @sd_port@ # Director's port
WorkingDirectory = "@working_dir@"
Pid Directory = "@piddir@"
- Subsys Directory = "@subsysdir@"
}
#
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);
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 */
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);
break;
}
free_block(block);
-#ifndef NEW_LOCK
return_device_lock(dev, &hold);
-#endif
return stat;
}
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));
/*
* 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);
} 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;
}
{"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},