2 * Bacula Director -- restore.c -- responsible for restoring files
4 * Kern Sibbald, November MM
6 * This routine is run as a separate thread.
8 * Current implementation is Catalog verification only (i.e. no
9 * verification versus tape).
11 * Basic tasks done here:
13 * Open Message Channel with Storage daemon to tell him a job will be starting.
14 * Open connection with File daemon and pass him commands
16 * Update the DB according to what files where restored????
21 Bacula® - The Network Backup Solution
23 Copyright (C) 2000-2006 Free Software Foundation Europe e.V.
25 The main author of Bacula is Kern Sibbald, with contributions from
26 many others, a complete list can be found in the file AUTHORS.
27 This program is Free Software; you can redistribute it and/or
28 modify it under the terms of version two of the GNU General Public
29 License as published by the Free Software Foundation plus additions
30 that are listed in the file LICENSE.
32 This program is distributed in the hope that it will be useful, but
33 WITHOUT ANY WARRANTY; without even the implied warranty of
34 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
35 General Public License for more details.
37 You should have received a copy of the GNU General Public License
38 along with this program; if not, write to the Free Software
39 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
42 Bacula® is a registered trademark of John Walker.
43 The licensor of Bacula is the Free Software Foundation Europe
44 (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
45 Switzerland, email:ftf@fsfeurope.org.
52 /* Commands sent to File daemon */
53 static char restorecmd[] = "restore replace=%c prelinks=%d where=%s\n";
54 static char storaddr[] = "storage address=%s port=%d ssl=0\n";
56 /* Responses received from File daemon */
57 static char OKrestore[] = "2000 OK restore\n";
58 static char OKstore[] = "2000 OK storage\n";
59 static char OKbootstrap[] = "2000 OK bootstrap\n";
62 * Do a restore of the specified files
64 * Returns: 0 on failure
67 bool do_restore(JCR *jcr)
70 JOB_DBR rjr; /* restore job record */
72 free_wstorage(jcr); /* we don't write */
74 memset(&rjr, 0, sizeof(rjr));
75 jcr->jr.JobLevel = L_FULL; /* Full restore */
76 if (!db_update_job_start_record(jcr, jcr->db, &jcr->jr)) {
77 Jmsg(jcr, M_FATAL, 0, "%s", db_strerror(jcr->db));
78 restore_cleanup(jcr, JS_ErrorTerminated);
81 Dmsg0(20, "Updated job start record\n");
83 Dmsg1(20, "RestoreJobId=%d\n", jcr->job->RestoreJobId);
85 if (!jcr->RestoreBootstrap) {
86 Jmsg0(jcr, M_FATAL, 0, _("Cannot restore without a bootstrap file.\n"
87 "You probably ran a restore job directly. All restore jobs must\n"
88 "be run using the restore command.\n"));
89 restore_cleanup(jcr, JS_ErrorTerminated);
94 /* Print Job Start message */
95 Jmsg(jcr, M_INFO, 0, _("Start Restore Job %s\n"), jcr->Job);
98 * Open a message channel connection with the Storage
99 * daemon. This is to let him know that our client
100 * will be contacting him for a backup session.
103 Dmsg0(10, "Open connection with storage daemon\n");
104 set_jcr_job_status(jcr, JS_WaitSD);
106 * Start conversation with Storage daemon
108 if (!connect_to_storage_daemon(jcr, 10, SDConnectTimeout, 1)) {
109 restore_cleanup(jcr, JS_ErrorTerminated);
113 * Now start a job with the Storage daemon
115 if (!start_storage_daemon_job(jcr, jcr->rstorage, NULL)) {
116 restore_cleanup(jcr, JS_ErrorTerminated);
119 if (!bnet_fsend(jcr->store_bsock, "run")) {
123 * Now start a Storage daemon message thread
125 if (!start_storage_daemon_message_thread(jcr)) {
126 restore_cleanup(jcr, JS_ErrorTerminated);
129 Dmsg0(50, "Storage daemon connection OK\n");
133 * Start conversation with File daemon
135 set_jcr_job_status(jcr, JS_WaitFD);
136 if (!connect_to_file_daemon(jcr, 10, FDConnectTimeout, 1)) {
137 restore_cleanup(jcr, JS_ErrorTerminated);
141 fd = jcr->file_bsock;
142 set_jcr_job_status(jcr, JS_Running);
145 * send Storage daemon address to the File daemon,
146 * then wait for File daemon to make connection
147 * with Storage daemon.
149 if (jcr->rstore->SDDport == 0) {
150 jcr->rstore->SDDport = jcr->rstore->SDport;
152 bnet_fsend(fd, storaddr, jcr->rstore->address, jcr->rstore->SDDport);
153 Dmsg1(6, "dird>filed: %s\n", fd->msg);
154 if (!response(jcr, fd, OKstore, "Storage", DISPLAY_ERROR)) {
155 restore_cleanup(jcr, JS_ErrorTerminated);
160 * Send the bootstrap file -- what Volumes/files to restore
162 if (!send_bootstrap_file(jcr, fd) ||
163 !response(jcr, fd, OKbootstrap, "Bootstrap", DISPLAY_ERROR)) {
164 restore_cleanup(jcr, JS_ErrorTerminated);
169 if (!send_runscripts_commands(jcr)) {
170 restore_cleanup(jcr, JS_ErrorTerminated);
174 /* Send restore command */
175 char replace, *where;
178 if (jcr->replace != 0) {
179 replace = jcr->replace;
180 } else if (jcr->job->replace != 0) {
181 replace = jcr->job->replace;
183 replace = REPLACE_ALWAYS; /* always replace */
186 where = jcr->where; /* override */
187 } else if (jcr->job->RestoreWhere) {
188 where = jcr->job->RestoreWhere; /* no override take from job */
190 where = ∅ /* None */
192 jcr->prefix_links = jcr->job->PrefixLinks;
194 bnet_fsend(fd, restorecmd, replace, jcr->prefix_links, where);
195 unbash_spaces(where);
197 if (!response(jcr, fd, OKrestore, "Restore", DISPLAY_ERROR)) {
198 restore_cleanup(jcr, JS_ErrorTerminated);
202 /* Wait for Job Termination */
203 int stat = wait_for_job_termination(jcr);
204 restore_cleanup(jcr, stat);
209 bool do_restore_init(JCR *jcr)
216 * Release resources allocated during restore.
219 void restore_cleanup(JCR *jcr, int TermCode)
221 char sdt[MAX_TIME_LENGTH], edt[MAX_TIME_LENGTH];
222 char ec1[30], ec2[30], ec3[30];
223 char term_code[100], fd_term_msg[100], sd_term_msg[100];
224 const char *term_msg;
228 Dmsg0(20, "In restore_cleanup\n");
229 dequeue_messages(jcr); /* display any queued messages */
230 set_jcr_job_status(jcr, TermCode);
232 if (jcr->unlink_bsr && jcr->RestoreBootstrap) {
233 unlink(jcr->RestoreBootstrap);
234 jcr->unlink_bsr = false;
237 update_job_end_record(jcr);
239 msg_type = M_INFO; /* by default INFO message */
242 if (jcr->ExpectedFiles > jcr->jr.JobFiles) {
243 term_msg = _("Restore OK -- warning file count mismatch");
245 term_msg = _("Restore OK");
249 case JS_ErrorTerminated:
250 term_msg = _("*** Restore Error ***");
251 msg_type = M_ERROR; /* Generate error message */
252 if (jcr->store_bsock) {
253 bnet_sig(jcr->store_bsock, BNET_TERMINATE);
254 if (jcr->SD_msg_chan) {
255 pthread_cancel(jcr->SD_msg_chan);
260 term_msg = _("Restore Canceled");
261 if (jcr->store_bsock) {
262 bnet_sig(jcr->store_bsock, BNET_TERMINATE);
263 if (jcr->SD_msg_chan) {
264 pthread_cancel(jcr->SD_msg_chan);
269 term_msg = term_code;
270 sprintf(term_code, _("Inappropriate term code: %c\n"), TermCode);
273 bstrftimes(sdt, sizeof(sdt), jcr->jr.StartTime);
274 bstrftimes(edt, sizeof(edt), jcr->jr.EndTime);
275 if (jcr->jr.EndTime - jcr->jr.StartTime > 0) {
276 kbps = (double)jcr->jr.JobBytes / (1000 * (jcr->jr.EndTime - jcr->jr.StartTime));
284 jobstatus_to_ascii(jcr->FDJobStatus, fd_term_msg, sizeof(fd_term_msg));
285 jobstatus_to_ascii(jcr->SDJobStatus, sd_term_msg, sizeof(sd_term_msg));
287 Jmsg(jcr, msg_type, 0, _("Bacula %s (%s): %s\n"
293 " Files Expected: %s\n"
294 " Files Restored: %s\n"
295 " Bytes Restored: %s\n"
298 " FD termination status: %s\n"
299 " SD termination status: %s\n"
300 " Termination: %s\n\n"),
306 jcr->client->hdr.name,
309 edit_uint64_with_commas((uint64_t)jcr->ExpectedFiles, ec1),
310 edit_uint64_with_commas((uint64_t)jcr->jr.JobFiles, ec2),
311 edit_uint64_with_commas(jcr->jr.JobBytes, ec3),
318 Dmsg0(20, "Leaving restore_cleanup\n");