2 Bacula® - The Network Backup Solution
4 Copyright (C) 2000-2009 Free Software Foundation Europe e.V.
6 The main author of Bacula is Kern Sibbald, with contributions from
7 many others, a complete list can be found in the file AUTHORS.
8 This program is Free Software; you can redistribute it and/or
9 modify it under the terms of version two of the GNU General Public
10 License as published by the Free Software Foundation and included
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23 Bacula® is a registered trademark of Kern Sibbald.
24 The licensor of Bacula is the Free Software Foundation Europe
25 (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
26 Switzerland, email:ftf@fsfeurope.org.
29 * Bacula Director -- restore.c -- responsible for restoring files
31 * Kern Sibbald, November MM
33 * This routine is run as a separate thread.
35 * Current implementation is Catalog verification only (i.e. no
36 * verification versus tape).
38 * Basic tasks done here:
40 * Open Message Channel with Storage daemon to tell him a job will be starting.
41 * Open connection with File daemon and pass him commands
43 * Update the DB according to what files where restored????
52 /* Commands sent to File daemon */
53 static char restorecmd[] = "restore replace=%c prelinks=%d where=%s\n";
54 static char restorecmdR[] = "restore replace=%c prelinks=%d regexwhere=%s\n";
55 static char storaddr[] = "storage address=%s port=%d ssl=0\n";
57 /* Responses received from File daemon */
58 static char OKrestore[] = "2000 OK restore\n";
59 static char OKstore[] = "2000 OK storage\n";
61 /* Responses received from the Storage daemon */
62 static char OKbootstrap[] = "3000 OK bootstrap\n";
65 * Do a restore of the specified files
67 * Returns: 0 on failure
70 bool do_restore(JCR *jcr)
73 JOB_DBR rjr; /* restore job record */
74 char replace, *where, *cmd;
78 free_wstorage(jcr); /* we don't write */
80 if (!allow_duplicate_job(jcr)) {
84 memset(&rjr, 0, sizeof(rjr));
85 jcr->jr.JobLevel = L_FULL; /* Full restore */
86 if (!db_update_job_start_record(jcr, jcr->db, &jcr->jr)) {
87 Jmsg(jcr, M_FATAL, 0, "%s", db_strerror(jcr->db));
90 Dmsg0(20, "Updated job start record\n");
92 Dmsg1(20, "RestoreJobId=%d\n", jcr->job->RestoreJobId);
94 if (!jcr->RestoreBootstrap) {
95 Jmsg0(jcr, M_FATAL, 0, _("Cannot restore without a bootstrap file.\n"
96 "You probably ran a restore job directly. All restore jobs must\n"
97 "be run using the restore command.\n"));
102 /* Print Job Start message */
103 Jmsg(jcr, M_INFO, 0, _("Start Restore Job %s\n"), jcr->Job);
106 * Open a message channel connection with the Storage
107 * daemon. This is to let him know that our client
108 * will be contacting him for a backup session.
111 Dmsg0(10, "Open connection with storage daemon\n");
112 set_jcr_job_status(jcr, JS_WaitSD);
114 * Start conversation with Storage daemon
116 if (!connect_to_storage_daemon(jcr, 10, SDConnectTimeout, 1)) {
119 sd = jcr->store_bsock;
121 * Now start a job with the Storage daemon
123 if (!start_storage_daemon_job(jcr, jcr->rstorage, NULL)) {
128 * Send the bootstrap file -- what Volumes/files to restore
130 if (!send_bootstrap_file(jcr, sd) ||
131 !response(jcr, sd, OKbootstrap, "Bootstrap", DISPLAY_ERROR)) {
135 if (!sd->fsend("run")) {
139 * Now start a Storage daemon message thread
141 if (!start_storage_daemon_message_thread(jcr)) {
144 Dmsg0(50, "Storage daemon connection OK\n");
148 * Start conversation with File daemon
150 set_jcr_job_status(jcr, JS_WaitFD);
151 if (!connect_to_file_daemon(jcr, 10, FDConnectTimeout, 1)) {
155 fd = jcr->file_bsock;
156 set_jcr_job_status(jcr, JS_Running);
159 * send Storage daemon address to the File daemon,
160 * then wait for File daemon to make connection
161 * with Storage daemon.
163 if (jcr->rstore->SDDport == 0) {
164 jcr->rstore->SDDport = jcr->rstore->SDport;
166 fd->fsend(storaddr, jcr->rstore->address, jcr->rstore->SDDport);
167 Dmsg1(6, "dird>filed: %s\n", fd->msg);
168 if (!response(jcr, fd, OKstore, "Storage", DISPLAY_ERROR)) {
172 if (!send_runscripts_commands(jcr)) {
176 /* Send restore command */
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 if (jcr->RegexWhere) {
187 where = jcr->RegexWhere; /* override */
189 } else if (jcr->job->RegexWhere) {
190 where = jcr->job->RegexWhere; /* no override take from job */
193 } else if (jcr->where) {
194 where = jcr->where; /* override */
196 } else if (jcr->job->RestoreWhere) {
197 where = jcr->job->RestoreWhere; /* no override take from job */
200 } else { /* nothing was specified */
201 where = ∅ /* use default */
205 jcr->prefix_links = jcr->job->PrefixLinks;
208 fd->fsend(cmd, replace, jcr->prefix_links, where);
209 unbash_spaces(where);
211 if (!response(jcr, fd, OKrestore, "Restore", DISPLAY_ERROR)) {
215 /* Wait for Job Termination */
216 stat = wait_for_job_termination(jcr);
217 restore_cleanup(jcr, stat);
221 restore_cleanup(jcr, JS_ErrorTerminated);
225 bool do_restore_init(JCR *jcr)
232 * Release resources allocated during restore.
235 void restore_cleanup(JCR *jcr, int TermCode)
237 char sdt[MAX_TIME_LENGTH], edt[MAX_TIME_LENGTH];
238 char ec1[30], ec2[30], ec3[30];
239 char term_code[100], fd_term_msg[100], sd_term_msg[100];
240 const char *term_msg;
241 int msg_type = M_INFO;
244 Dmsg0(20, "In restore_cleanup\n");
245 update_job_end(jcr, TermCode);
247 if (jcr->unlink_bsr && jcr->RestoreBootstrap) {
248 unlink(jcr->RestoreBootstrap);
249 jcr->unlink_bsr = false;
252 if (job_canceled(jcr)) {
253 cancel_storage_daemon_job(jcr);
258 if (jcr->ExpectedFiles > jcr->jr.JobFiles) {
259 term_msg = _("Restore OK -- warning file count mismatch");
261 term_msg = _("Restore OK");
265 term_msg = _("Restore OK -- with warnings");
268 case JS_ErrorTerminated:
269 term_msg = _("*** Restore Error ***");
270 msg_type = M_ERROR; /* Generate error message */
271 if (jcr->store_bsock) {
272 jcr->store_bsock->signal(BNET_TERMINATE);
273 if (jcr->SD_msg_chan) {
274 pthread_cancel(jcr->SD_msg_chan);
279 term_msg = _("Restore Canceled");
280 if (jcr->store_bsock) {
281 jcr->store_bsock->signal(BNET_TERMINATE);
282 if (jcr->SD_msg_chan) {
283 pthread_cancel(jcr->SD_msg_chan);
288 term_msg = term_code;
289 sprintf(term_code, _("Inappropriate term code: %c\n"), TermCode);
292 bstrftimes(sdt, sizeof(sdt), jcr->jr.StartTime);
293 bstrftimes(edt, sizeof(edt), jcr->jr.EndTime);
294 if (jcr->jr.EndTime - jcr->jr.StartTime > 0) {
295 kbps = (double)jcr->jr.JobBytes / (1000 * (jcr->jr.EndTime - jcr->jr.StartTime));
303 jobstatus_to_ascii(jcr->FDJobStatus, fd_term_msg, sizeof(fd_term_msg));
304 jobstatus_to_ascii(jcr->SDJobStatus, sd_term_msg, sizeof(sd_term_msg));
306 Jmsg(jcr, msg_type, 0, _("%s %s %s (%s): %s\n"
307 " Build OS: %s %s %s\n"
310 " Restore Client: %s\n"
313 " Files Expected: %s\n"
314 " Files Restored: %s\n"
315 " Bytes Restored: %s\n"
318 " FD termination status: %s\n"
319 " SD termination status: %s\n"
320 " Termination: %s\n\n"),
321 BACULA, my_name, VERSION, LSMDATE, edt,
322 HOST_OS, DISTNAME, DISTVER,
328 edit_uint64_with_commas((uint64_t)jcr->ExpectedFiles, ec1),
329 edit_uint64_with_commas((uint64_t)jcr->jr.JobFiles, ec2),
330 edit_uint64_with_commas(jcr->jr.JobBytes, ec3),
337 Dmsg0(20, "Leaving restore_cleanup\n");