2 Bacula® - The Network Backup Solution
4 Copyright (C) 2000-2010 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 three of the GNU Affero 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 Affero 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????
51 /* Commands sent to File daemon */
52 static char restorecmd[] = "restore replace=%c prelinks=%d where=%s\n";
53 static char restorecmdR[] = "restore replace=%c prelinks=%d regexwhere=%s\n";
54 static char storaddr[] = "storage address=%s port=%d ssl=0 Authorization=%s\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 OKstoreend[] = "2000 OK storage end\n";
61 /* Responses received from the Storage daemon */
62 static char OKbootstrap[] = "3000 OK bootstrap\n";
64 static void build_restore_command(JCR *jcr, POOL_MEM &ret)
66 char replace, *where, *cmd;
69 /* Build the restore command */
71 if (jcr->replace != 0) {
72 replace = jcr->replace;
73 } else if (jcr->job->replace != 0) {
74 replace = jcr->job->replace;
76 replace = REPLACE_ALWAYS; /* always replace */
79 if (jcr->RegexWhere) {
80 where = jcr->RegexWhere; /* override */
82 } else if (jcr->job->RegexWhere) {
83 where = jcr->job->RegexWhere; /* no override take from job */
86 } else if (jcr->where) {
87 where = jcr->where; /* override */
89 } else if (jcr->job->RestoreWhere) {
90 where = jcr->job->RestoreWhere; /* no override take from job */
93 } else { /* nothing was specified */
94 where = ∅ /* use default */
98 jcr->prefix_links = jcr->job->PrefixLinks;
101 Mmsg(ret, cmd, replace, jcr->prefix_links, where);
102 unbash_spaces(where);
105 struct bootstrap_info
109 char storage[MAX_NAME_LENGTH+1];
112 #define UA_CMD_SIZE 1000
115 * Open the bootstrap file and find the first Storage=
116 * Returns ok if able to open
117 * It fills the storage name (should be the first line)
118 * and the file descriptor to the bootstrap file,
119 * it should be used for next operations, and need to be closed
122 static bool open_bootstrap_file(JCR *jcr, bootstrap_info &info)
129 if (!jcr->RestoreBootstrap) {
132 strncpy(info.storage, jcr->rstore->name(), MAX_NAME_LENGTH);
134 bs = fopen(jcr->RestoreBootstrap, "rb");
137 Jmsg(jcr, M_FATAL, 0, _("Could not open bootstrap file %s: ERR=%s\n"),
138 jcr->RestoreBootstrap, be.bstrerror());
139 set_jcr_job_status(jcr, JS_ErrorTerminated);
143 ua = new_ua_context(jcr);
144 ua->cmd = check_pool_memory_size(ua->cmd, UA_CMD_SIZE+1);
145 while (!fgets(ua->cmd, UA_CMD_SIZE, bs)) {
150 if (!strcasecmp(ua->argk[0], "Storage")) {
151 strncpy(info.storage, ua->argv[0], MAX_NAME_LENGTH);
157 fseek(bs, 0, SEEK_SET); /* return to the top of the file */
162 * This function compare the given storage name with the
163 * the current one. We compare the name and the address:port.
164 * Returns true if we use the same storage.
166 static bool is_on_same_storage(JCR *jcr, char *new_one)
170 /* with old FD, we send the whole bootstrap to the storage */
171 if (jcr->FDVersion < 2) {
174 /* we are in init loop ? shoudn't fall here */
179 if (!strcmp(new_one, jcr->rstore->name())) {
182 new_store = (STORE *)GetResWithName(R_STORAGE, new_one);
184 Jmsg(jcr, M_FATAL, 0,
185 _("Could not get storage resource '%s'.\n"), new_one);
186 set_jcr_job_status(jcr, JS_ErrorTerminated);
189 /* if Port and Hostname/IP are same, we are talking to the same
192 if (jcr->rstore->SDport != new_store->SDport ||
193 strcmp(jcr->rstore->address, new_store->address))
201 * Check if the current line contains Storage="xxx", and compare the
202 * result to the current storage. We use UAContext to analyse the bsr
205 * Returns true if we need to change the storage, and it set the new
206 * Storage resource name in "storage" arg.
208 static bool check_for_new_storage(JCR *jcr, bootstrap_info &info)
210 UAContext *ua = info.ua;
215 if (!strcasecmp(ua->argk[0], "Storage")) {
216 /* Continue if this is a volume from the same storage. */
217 if (is_on_same_storage(jcr, ua->argv[0])) {
220 /* note the next storage name */
221 strncpy(info.storage, ua->argv[0], MAX_NAME_LENGTH);
222 Dmsg1(5, "Change storage to %s\n", info.storage);
229 * Send bootstrap file to Storage daemon section by section.
231 static bool send_bootstrap_file(JCR *jcr, BSOCK *sock,
232 bootstrap_info &info)
235 const char *bootstrap = "bootstrap\n";
236 UAContext *ua = info.ua;
239 Dmsg1(400, "send_bootstrap_file: %s\n", jcr->RestoreBootstrap);
240 if (!jcr->RestoreBootstrap) {
243 sock->fsend(bootstrap);
245 while(fgets(ua->cmd, UA_CMD_SIZE, bs)) {
246 if (check_for_new_storage(jcr, info)) {
247 /* Otherwise, we need to contact another storage daemon.
248 * Reset bs to the beginning of the current segment.
250 fseeko(bs, pos, SEEK_SET);
253 sock->fsend("%s", ua->cmd);
256 sock->signal(BNET_EOD);
260 #define MAX_TRIES 6 * 360 /* 6 hours */
263 * Change the read storage resource for the current job.
265 static bool select_rstore(JCR *jcr, bootstrap_info &info)
271 if (!strcmp(jcr->rstore->name(), info.storage)) {
272 return true; /* same SD nothing to change */
275 if (!(ustore.store = (STORE *)GetResWithName(R_STORAGE,info.storage))) {
276 Jmsg(jcr, M_FATAL, 0,
277 _("Could not get storage resource '%s'.\n"), info.storage);
278 set_jcr_job_status(jcr, JS_ErrorTerminated);
283 * What does this do??????????? KES
285 if (jcr->store_bsock) {
286 jcr->store_bsock->destroy();
287 jcr->store_bsock = NULL;
291 * release current read storage and get a new one
295 set_rstorage(jcr, &ustore);
296 set_jcr_job_status(jcr, JS_WaitSD);
298 * Wait for up to 6 hours to increment read stoage counter
300 for (i=0; i < MAX_TRIES; i++) {
301 /* try to get read storage counter incremented */
302 if (inc_read_store(jcr)) {
303 set_jcr_job_status(jcr, JS_Running);
306 bmicrosleep(10, 0); /* sleep 10 secs */
307 if (job_canceled(jcr)) {
312 /* Failed to inc_read_store() */
314 Jmsg(jcr, M_FATAL, 0,
315 _("Could not acquire read storage lock for \"%s\""), info.storage);
320 * Clean the bootstrap_info struct
322 static void close_bootstrap_file(bootstrap_info &info)
328 free_ua_context(info.ua);
333 * The bootstrap is stored in a file, so open the file, and loop
334 * through it processing each storage device in turn. If the
335 * storage is different from the prior one, we open a new connection
336 * to the new storage and do a restore for that part.
337 * This permits handling multiple storage daemons for a single
338 * restore. E.g. your Full is stored on tape, and Incrementals
341 bool restore_bootstrap(JCR *jcr)
345 bool first_time = true;
347 POOL_MEM restore_cmd(PM_MESSAGE);
350 /* this command is used for each part */
351 build_restore_command(jcr, restore_cmd);
353 /* Open the bootstrap file */
354 if (!open_bootstrap_file(jcr, info)) {
357 /* Read the bootstrap file */
358 while (!feof(info.bs)) {
360 if (!select_rstore(jcr, info)) {
365 * Open a message channel connection with the Storage
366 * daemon. This is to let him know that our client
367 * will be contacting him for a backup session.
370 Dmsg0(10, "Open connection with storage daemon\n");
371 set_jcr_job_status(jcr, JS_WaitSD);
373 * Start conversation with Storage daemon
375 if (!connect_to_storage_daemon(jcr, 10, SDConnectTimeout, 1)) {
378 sd = jcr->store_bsock;
380 * Now start a job with the Storage daemon
382 if (!start_storage_daemon_job(jcr, jcr->rstorage, NULL)) {
388 * Start conversation with File daemon
390 set_jcr_job_status(jcr, JS_WaitFD);
391 jcr->keep_sd_auth_key = true; /* don't clear the sd_auth_key now */
392 if (!connect_to_file_daemon(jcr, 10, FDConnectTimeout, 1)) {
395 fd = jcr->file_bsock;
398 set_jcr_job_status(jcr, JS_WaitSD);
401 * Send the bootstrap file -- what Volumes/files to restore
403 if (!send_bootstrap_file(jcr, sd, info) ||
404 !response(jcr, sd, OKbootstrap, "Bootstrap", DISPLAY_ERROR)) {
408 if (!sd->fsend("run")) {
412 * Now start a Storage daemon message thread
414 if (!start_storage_daemon_message_thread(jcr)) {
417 Dmsg0(50, "Storage daemon connection OK\n");
420 * send Storage daemon address to the File daemon,
421 * then wait for File daemon to make connection
422 * with Storage daemon.
424 if (jcr->rstore->SDDport == 0) {
425 jcr->rstore->SDDport = jcr->rstore->SDport;
427 fd->fsend(storaddr, jcr->rstore->address, jcr->rstore->SDDport,
429 memset(jcr->sd_auth_key, 0, strlen(jcr->sd_auth_key));
431 Dmsg1(6, "dird>filed: %s\n", fd->msg);
432 if (!response(jcr, fd, OKstore, "Storage", DISPLAY_ERROR)) {
436 /* Only pass "global" commands to the FD once */
439 if (!send_runscripts_commands(jcr)) {
442 if (!send_restore_objects(jcr)) {
443 Dmsg0(000, "FAIL: Send restore objects\n");
448 fd->fsend("%s", restore_cmd.c_str());
450 if (!response(jcr, fd, OKrestore, "Restore", DISPLAY_ERROR)) {
454 if (jcr->FDVersion < 2) { /* Old FD */
455 break; /* we do only one loop */
457 if (!response(jcr, fd, OKstoreend, "Store end", DISPLAY_ERROR)) {
460 wait_for_storage_daemon_termination(jcr);
462 } /* the whole boostrap has been send */
464 if (fd && jcr->FDVersion >= 2) {
465 fd->fsend("endrestore");
471 close_bootstrap_file(info);
476 * Do a restore of the specified files
478 * Returns: 0 on failure
481 bool do_restore(JCR *jcr)
483 JOB_DBR rjr; /* restore job record */
486 free_wstorage(jcr); /* we don't write */
488 if (!allow_duplicate_job(jcr)) {
492 memset(&rjr, 0, sizeof(rjr));
493 jcr->jr.JobLevel = L_FULL; /* Full restore */
494 if (!db_update_job_start_record(jcr, jcr->db, &jcr->jr)) {
495 Jmsg(jcr, M_FATAL, 0, "%s", db_strerror(jcr->db));
498 Dmsg0(20, "Updated job start record\n");
500 Dmsg1(20, "RestoreJobId=%d\n", jcr->job->RestoreJobId);
502 if (!jcr->RestoreBootstrap) {
503 Jmsg(jcr, M_FATAL, 0, _("Cannot restore without a bootstrap file.\n"
504 "You probably ran a restore job directly. All restore jobs must\n"
505 "be run using the restore command.\n"));
510 /* Print Job Start message */
511 Jmsg(jcr, M_INFO, 0, _("Start Restore Job %s\n"), jcr->Job);
513 /* Read the bootstrap file and do the restore */
514 if (!restore_bootstrap(jcr)) {
518 /* Wait for Job Termination */
519 stat = wait_for_job_termination(jcr);
520 restore_cleanup(jcr, stat);
524 restore_cleanup(jcr, JS_ErrorTerminated);
528 bool do_restore_init(JCR *jcr)
535 * Release resources allocated during restore.
538 void restore_cleanup(JCR *jcr, int TermCode)
540 char sdt[MAX_TIME_LENGTH], edt[MAX_TIME_LENGTH];
541 char ec1[30], ec2[30], ec3[30];
542 char term_code[100], fd_term_msg[100], sd_term_msg[100];
543 const char *term_msg;
544 int msg_type = M_INFO;
547 Dmsg0(20, "In restore_cleanup\n");
548 update_job_end(jcr, TermCode);
550 if (jcr->unlink_bsr && jcr->RestoreBootstrap) {
551 unlink(jcr->RestoreBootstrap);
552 jcr->unlink_bsr = false;
555 if (job_canceled(jcr)) {
556 cancel_storage_daemon_job(jcr);
561 if (jcr->ExpectedFiles > jcr->jr.JobFiles) {
562 term_msg = _("Restore OK -- warning file count mismatch");
564 term_msg = _("Restore OK");
568 term_msg = _("Restore OK -- with warnings");
571 case JS_ErrorTerminated:
572 term_msg = _("*** Restore Error ***");
573 msg_type = M_ERROR; /* Generate error message */
574 if (jcr->store_bsock) {
575 jcr->store_bsock->signal(BNET_TERMINATE);
576 if (jcr->SD_msg_chan) {
577 pthread_cancel(jcr->SD_msg_chan);
582 term_msg = _("Restore Canceled");
583 if (jcr->store_bsock) {
584 jcr->store_bsock->signal(BNET_TERMINATE);
585 if (jcr->SD_msg_chan) {
586 pthread_cancel(jcr->SD_msg_chan);
591 term_msg = term_code;
592 sprintf(term_code, _("Inappropriate term code: %c\n"), TermCode);
595 bstrftimes(sdt, sizeof(sdt), jcr->jr.StartTime);
596 bstrftimes(edt, sizeof(edt), jcr->jr.EndTime);
597 if (jcr->jr.EndTime - jcr->jr.StartTime > 0) {
598 kbps = (double)jcr->jr.JobBytes / (1000 * (jcr->jr.EndTime - jcr->jr.StartTime));
606 jobstatus_to_ascii(jcr->FDJobStatus, fd_term_msg, sizeof(fd_term_msg));
607 jobstatus_to_ascii(jcr->SDJobStatus, sd_term_msg, sizeof(sd_term_msg));
609 Jmsg(jcr, msg_type, 0, _("%s %s %s (%s):\n"
610 " Build OS: %s %s %s\n"
613 " Restore Client: %s\n"
616 " Files Expected: %s\n"
617 " Files Restored: %s\n"
618 " Bytes Restored: %s\n"
621 " FD termination status: %s\n"
622 " SD termination status: %s\n"
623 " Termination: %s\n\n"),
624 BACULA, my_name, VERSION, LSMDATE,
625 HOST_OS, DISTNAME, DISTVER,
631 edit_uint64_with_commas((uint64_t)jcr->ExpectedFiles, ec1),
632 edit_uint64_with_commas((uint64_t)jcr->jr.JobFiles, ec2),
633 edit_uint64_with_commas(jcr->jr.JobBytes, ec3),
640 Dmsg0(20, "Leaving restore_cleanup\n");