*
* Kern Sibbald, November MM
*
- * This routine is run as a separate thread.
- *
+ * This routine is run as a separate thread.
+ *
* Current implementation is Catalog verification only (i.e. no
* verification versus tape).
*
*/
/*
- Copyright (C) 2000-2003 Kern Sibbald and John Walker
+ Copyright (C) 2000-2004 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
/* Commands sent to File daemon */
static char restorecmd[] = "restore replace=%c prelinks=%d where=%s\n";
static char storaddr[] = "storage address=%s port=%d ssl=0\n";
-static char sessioncmd[] = "session %s %ld %ld %ld %ld %ld %ld\n";
+static char sessioncmd[] = "session %s %ld %ld %ld %ld %ld %ld\n";
/* Responses received from File daemon */
static char OKrestore[] = "2000 OK restore\n";
/* External functions */
-/*
+/*
* Do a restore of the specified files
- *
+ *
* Returns: 0 on failure
* 1 on success
*/
-int do_restore(JCR *jcr)
+int do_restore(JCR *jcr)
{
BSOCK *fd;
JOB_DBR rjr; /* restore job record */
}
memset(&rjr, 0, sizeof(rjr));
- jcr->jr.Level = 'F'; /* Full restore */
- jcr->jr.StartTime = jcr->start_time;
+ jcr->jr.JobLevel = L_FULL; /* Full restore */
if (!db_update_job_start_record(jcr, jcr->db, &jcr->jr)) {
- Jmsg(jcr, M_ERROR, 0, "%s", db_strerror(jcr->db));
+ Jmsg(jcr, M_FATAL, 0, "%s", db_strerror(jcr->db));
restore_cleanup(jcr, JS_ErrorTerminated);
return 0;
}
Dmsg1(20, "RestoreJobId=%d\n", jcr->job->RestoreJobId);
- /*
+ /*
* The following code is kept temporarily for compatibility.
* It is the predecessor to the Bootstrap file.
+ * DEPRECATED
*/
if (!jcr->RestoreBootstrap) {
/*
rjr.JobId = jcr->job->RestoreJobId; /* specified by Job Resource */
}
if (!db_get_job_record(jcr, jcr->db, &rjr)) {
- Jmsg2(jcr, M_FATAL, 0, _("Cannot get job record id=%d %s"), rjr.JobId,
+ Jmsg2(jcr, M_FATAL, 0, _("Cannot get job record id=%d %s"), rjr.JobId,
db_strerror(jcr->db));
restore_cleanup(jcr, JS_ErrorTerminated);
return 0;
jcr->VolumeName[0] = 0;
if (!db_get_job_volume_names(jcr, jcr->db, rjr.JobId, &jcr->VolumeName) ||
jcr->VolumeName[0] == 0) {
- Jmsg(jcr, M_FATAL, 0, _("Cannot find Volume Name for restore Job %d. %s"),
+ Jmsg(jcr, M_FATAL, 0, _("Cannot find Volume names for restore Job %d. %s"),
rjr.JobId, db_strerror(jcr->db));
restore_cleanup(jcr, JS_ErrorTerminated);
return 0;
}
Dmsg1(20, "Got job Volume Names: %s\n", jcr->VolumeName);
}
-
+
/* Print Job Start message */
Jmsg(jcr, M_INFO, 0, _("Start Restore Job %s\n"), jcr->Job);
Dmsg0(10, "Open connection with storage daemon\n");
set_jcr_job_status(jcr, JS_WaitSD);
/*
- * Start conversation with Storage daemon
+ * Start conversation with Storage daemon
*/
if (!connect_to_storage_daemon(jcr, 10, SDConnectTimeout, 1)) {
restore_cleanup(jcr, JS_ErrorTerminated);
}
Dmsg0(50, "Storage daemon connection OK\n");
- /*
- * Start conversation with File daemon
+ /*
+ * Start conversation with File daemon
*/
set_jcr_job_status(jcr, JS_WaitFD);
if (!connect_to_file_daemon(jcr, 10, FDConnectTimeout, 1)) {
return 0;
}
- /*
+ /*
* send Storage daemon address to the File daemon,
* then wait for File daemon to make connection
* with Storage daemon.
return 0;
}
- /*
+ /*
* Send the bootstrap file -- what Volumes/files to restore
*/
if (!send_bootstrap_file(jcr)) {
return 0;
}
- /*
- * The following code is deprecated
+ /*
+ * The following code is deprecated
*/
if (!jcr->RestoreBootstrap) {
/*
* Pass the VolSessionId, VolSessionTime, Start and
* end File and Blocks on the session command.
*/
- bnet_fsend(fd, sessioncmd,
+ bnet_fsend(fd, sessioncmd,
jcr->VolumeName,
- rjr.VolSessionId, rjr.VolSessionTime,
- rjr.StartFile, rjr.EndFile, rjr.StartBlock,
+ rjr.VolSessionId, rjr.VolSessionTime,
+ rjr.StartFile, rjr.EndFile, rjr.StartBlock,
rjr.EndBlock);
if (!response(jcr, fd, OKsession, "Session", DISPLAY_ERROR)) {
restore_cleanup(jcr, JS_ErrorTerminated);
/* Send restore command */
char replace, *where;
+ char empty = '\0';
if (jcr->replace != 0) {
replace = jcr->replace;
} else if (jcr->job->RestoreWhere) {
where = jcr->job->RestoreWhere; /* no override take from job */
} else {
- where = ""; /* None */
+ where = ∅ /* None */
}
jcr->prefix_links = jcr->job->PrefixLinks;
bash_spaces(where);
static void restore_cleanup(JCR *jcr, int TermCode)
{
char sdt[MAX_TIME_LENGTH], edt[MAX_TIME_LENGTH];
- char ec1[30], ec2[30];
+ char ec1[30], ec2[30], ec3[30];
char term_code[100], fd_term_msg[100], sd_term_msg[100];
- char *term_msg;
+ const char *term_msg;
int msg_type;
double kbps;
Dmsg0(20, "In restore_cleanup\n");
+ dequeue_messages(jcr); /* display any queued messages */
set_jcr_job_status(jcr, TermCode);
update_job_end_record(jcr);
msg_type = M_INFO; /* by default INFO message */
switch (TermCode) {
case JS_Terminated:
- term_msg = _("Restore OK");
+ if (jcr->ExpectedFiles > jcr->jr.JobFiles) {
+ term_msg = _("Restore OK -- warning file count mismatch");
+ } else {
+ term_msg = _("Restore OK");
+ }
break;
case JS_FatalError:
case JS_ErrorTerminated:
- term_msg = _("*** Restore Error ***");
+ term_msg = _("*** Restore Error ***");
msg_type = M_ERROR; /* Generate error message */
if (jcr->store_bsock) {
bnet_sig(jcr->store_bsock, BNET_TERMINATE);
- pthread_cancel(jcr->SD_msg_chan);
+ if (jcr->SD_msg_chan) {
+ pthread_cancel(jcr->SD_msg_chan);
+ }
}
break;
case JS_Canceled:
term_msg = _("Restore Canceled");
if (jcr->store_bsock) {
bnet_sig(jcr->store_bsock, BNET_TERMINATE);
- pthread_cancel(jcr->SD_msg_chan);
+ if (jcr->SD_msg_chan) {
+ pthread_cancel(jcr->SD_msg_chan);
+ }
}
break;
default:
sprintf(term_code, _("Inappropriate term code: %c\n"), TermCode);
break;
}
- bstrftime(sdt, sizeof(sdt), jcr->jr.StartTime);
- bstrftime(edt, sizeof(edt), jcr->jr.EndTime);
+ bstrftimes(sdt, sizeof(sdt), jcr->jr.StartTime);
+ bstrftimes(edt, sizeof(edt), jcr->jr.EndTime);
if (jcr->jr.EndTime - jcr->jr.StartTime > 0) {
kbps = (double)jcr->jr.JobBytes / (1000 * (jcr->jr.EndTime - jcr->jr.StartTime));
} else {
jobstatus_to_ascii(jcr->FDJobStatus, fd_term_msg, sizeof(fd_term_msg));
jobstatus_to_ascii(jcr->SDJobStatus, sd_term_msg, sizeof(sd_term_msg));
- Jmsg(jcr, msg_type, 0, _("Bacula " VERSION " (" LSMDATE "): %s\n\
-JobId: %d\n\
-Job: %s\n\
-Client: %s\n\
-Start time: %s\n\
-End time: %s\n\
-Files Restored: %s\n\
-Bytes Restored: %s\n\
-Rate: %.1f KB/s\n\
-Non-fatal FD Errors: %d\n\
-FD termination status: %s\n\
-SD termination status: %s\n\
-Termination: %s\n\n"),
+ Jmsg(jcr, msg_type, 0, _("Bacula " VERSION " (" LSMDATE "): %s\n"
+" JobId: %d\n"
+" Job: %s\n"
+" Client: %s\n"
+" Start time: %s\n"
+" End time: %s\n"
+" Files Expected: %s\n"
+" Files Restored: %s\n"
+" Bytes Restored: %s\n"
+" Rate: %.1f KB/s\n"
+" FD Errors: %d\n"
+" FD termination status: %s\n"
+" SD termination status: %s\n"
+" Termination: %s\n\n"),
edt,
jcr->jr.JobId,
jcr->jr.Job,
jcr->client->hdr.name,
sdt,
edt,
- edit_uint64_with_commas((uint64_t)jcr->jr.JobFiles, ec1),
- edit_uint64_with_commas(jcr->jr.JobBytes, ec2),
+ edit_uint64_with_commas((uint64_t)jcr->ExpectedFiles, ec1),
+ edit_uint64_with_commas((uint64_t)jcr->jr.JobFiles, ec2),
+ edit_uint64_with_commas(jcr->jr.JobBytes, ec3),
(float)kbps,
jcr->Errors,
fd_term_msg,