2 Bacula(R) - The Network Backup Solution
4 Copyright (C) 2000-2015 Kern Sibbald
6 The original author of Bacula is Kern Sibbald, with contributions
7 from many others, a complete list can be found in the file AUTHORS.
9 You may use this file and others of this release according to the
10 license defined in the LICENSE file, which includes the Affero General
11 Public License, v3.0 ("AGPLv3") and some additional permissions and
12 terms pursuant to its AGPLv3 Section 7.
14 This notice must be preserved when any source code is
15 conveyed and/or propagated.
17 Bacula(R) is a registered trademark of Kern Sibbald.
20 * Bacula Director -- restore.c -- responsible for restoring files
22 * Written by Kern Sibbald, November MM
24 * This routine is run as a separate thread.
26 * Current implementation is Catalog verification only (i.e. no
27 * verification versus tape).
29 * Basic tasks done here:
31 * Open Message Channel with Storage daemon to tell him a job will be starting.
32 * Open connection with File daemon and pass him commands
34 * Update the DB according to what files where restored????
43 /* Commands sent to File daemon */
44 static char restorecmd[] = "restore %sreplace=%c prelinks=%d where=%s\n";
45 static char restorecmdR[] = "restore %sreplace=%c prelinks=%d regexwhere=%s\n";
46 static char storaddr[] = "storage address=%s port=%d ssl=%d Authorization=%s\n";
48 /* Responses received from File daemon */
49 static char OKrestore[] = "2000 OK restore\n";
50 static char OKstore[] = "2000 OK storage\n";
51 static char OKstoreend[] = "2000 OK storage end\n";
53 /* Responses received from the Storage daemon */
54 static char OKbootstrap[] = "3000 OK bootstrap\n";
56 static void build_restore_command(JCR *jcr, POOL_MEM &ret)
58 char replace, *where, *cmd;
62 /* Build the restore command */
64 if (jcr->replace != 0) {
65 replace = jcr->replace;
66 } else if (jcr->job->replace != 0) {
67 replace = jcr->job->replace;
69 replace = REPLACE_ALWAYS; /* always replace */
72 if (jcr->RegexWhere) {
73 where = jcr->RegexWhere; /* override */
75 } else if (jcr->job->RegexWhere) {
76 where = jcr->job->RegexWhere; /* no override take from job */
79 } else if (jcr->where) {
80 where = jcr->where; /* override */
82 } else if (jcr->job->RestoreWhere) {
83 where = jcr->job->RestoreWhere; /* no override take from job */
86 } else { /* nothing was specified */
87 where = ∅ /* use default */
91 jcr->prefix_links = jcr->job->PrefixLinks;
94 if (jcr->FDVersion < 7) {
95 Mmsg(ret, cmd, "", replace, jcr->prefix_links, where);
97 snprintf(files, sizeof(files), "files=%d ", jcr->ExpectedFiles);
98 Mmsg(ret, cmd, files, replace, jcr->prefix_links, where);
100 unbash_spaces(where);
103 struct bootstrap_info
107 char storage[MAX_NAME_LENGTH+1];
110 #define UA_CMD_SIZE 1000
113 * Open the bootstrap file and find the first Storage=
114 * Returns ok if able to open
115 * It fills the storage name (should be the first line)
116 * and the file descriptor to the bootstrap file,
117 * it should be used for next operations, and need to be closed
120 static bool open_bootstrap_file(JCR *jcr, bootstrap_info &info)
127 if (!jcr->RestoreBootstrap) {
130 strncpy(info.storage, jcr->rstore->name(), MAX_NAME_LENGTH);
132 bs = bfopen(jcr->RestoreBootstrap, "rb");
135 Jmsg(jcr, M_FATAL, 0, _("Could not open bootstrap file %s: ERR=%s\n"),
136 jcr->RestoreBootstrap, be.bstrerror());
137 jcr->setJobStatus(JS_ErrorTerminated);
141 ua = new_ua_context(jcr);
142 ua->cmd = check_pool_memory_size(ua->cmd, UA_CMD_SIZE+1);
143 while (!fgets(ua->cmd, UA_CMD_SIZE, bs)) {
148 if (!strcasecmp(ua->argk[0], "Storage")) {
149 strncpy(info.storage, ua->argv[0], MAX_NAME_LENGTH);
155 fseek(bs, 0, SEEK_SET); /* return to the top of the file */
160 * This function compare the given storage name with the
161 * the current one. We compare the name and the address:port.
162 * Returns true if we use the same storage.
164 static bool is_on_same_storage(JCR *jcr, char *new_one)
168 /* with old FD, we send the whole bootstrap to the storage */
169 if (jcr->FDVersion < 2) {
172 /* we are in init loop ? shoudn't fail here */
177 if (!strcmp(new_one, jcr->rstore->name())) {
180 new_store = (STORE *)GetResWithName(R_STORAGE, new_one);
182 Jmsg(jcr, M_WARNING, 0,
183 _("Could not get storage resource '%s'.\n"), new_one);
184 /* If not storage found, use last one */
187 /* if Port and Hostname/IP are same, we are talking to the same
190 if (jcr->rstore->SDport != new_store->SDport ||
191 strcmp(jcr->rstore->address, new_store->address))
199 * Check if the current line contains Storage="xxx", and compare the
200 * result to the current storage. We use UAContext to analyse the bsr
203 * Returns true if we need to change the storage, and it set the new
204 * Storage resource name in "storage" arg.
206 static bool check_for_new_storage(JCR *jcr, bootstrap_info &info)
208 UAContext *ua = info.ua;
213 if (!strcasecmp(ua->argk[0], "Storage")) {
214 /* Continue if this is a volume from the same storage. */
215 if (is_on_same_storage(jcr, ua->argv[0])) {
218 /* note the next storage name */
219 strncpy(info.storage, ua->argv[0], MAX_NAME_LENGTH);
220 Dmsg1(5, "Change storage to %s\n", info.storage);
227 * Send bootstrap file to Storage daemon section by section.
229 static bool send_bootstrap_file(JCR *jcr, BSOCK *sock,
230 bootstrap_info &info)
233 const char *bootstrap = "bootstrap\n";
234 UAContext *ua = info.ua;
237 Dmsg1(400, "send_bootstrap_file: %s\n", jcr->RestoreBootstrap);
238 if (!jcr->RestoreBootstrap) {
241 sock->fsend(bootstrap);
243 while(fgets(ua->cmd, UA_CMD_SIZE, bs)) {
244 if (check_for_new_storage(jcr, info)) {
245 /* Otherwise, we need to contact another storage daemon.
246 * Reset bs to the beginning of the current segment.
248 fseeko(bs, pos, SEEK_SET);
251 sock->fsend("%s", ua->cmd);
254 sock->signal(BNET_EOD);
258 #define MAX_TRIES 6 * 360 /* 6 hours */
261 * Change the read storage resource for the current job.
263 static bool select_rstore(JCR *jcr, bootstrap_info &info)
269 if (!strcmp(jcr->rstore->name(), info.storage)) {
270 return true; /* same SD nothing to change */
273 if (!(ustore.store = (STORE *)GetResWithName(R_STORAGE,info.storage))) {
274 Jmsg(jcr, M_FATAL, 0,
275 _("Could not get storage resource '%s'.\n"), info.storage);
276 jcr->setJobStatus(JS_ErrorTerminated);
281 * This releases the store_bsock between calls to the SD.
284 free_bsock(jcr->store_bsock);
287 * release current read storage and get a new one
291 set_rstorage(jcr, &ustore);
292 jcr->setJobStatus(JS_WaitSD);
294 * Wait for up to 6 hours to increment read stoage counter
296 for (i=0; i < MAX_TRIES; i++) {
297 /* try to get read storage counter incremented */
298 if (inc_read_store(jcr)) {
299 jcr->setJobStatus(JS_Running);
302 bmicrosleep(10, 0); /* sleep 10 secs */
303 if (job_canceled(jcr)) {
308 /* Failed to inc_read_store() */
310 Jmsg(jcr, M_FATAL, 0,
311 _("Could not acquire read storage lock for \"%s\""), info.storage);
316 * Clean the bootstrap_info struct
318 static void close_bootstrap_file(bootstrap_info &info)
324 free_ua_context(info.ua);
329 * The bootstrap is stored in a file, so open the file, and loop
330 * through it processing each storage device in turn. If the
331 * storage is different from the prior one, we open a new connection
332 * to the new storage and do a restore for that part.
333 * This permits handling multiple storage daemons for a single
334 * restore. E.g. your Full is stored on tape, and Incrementals
337 bool restore_bootstrap(JCR *jcr)
339 int tls_need = BNET_TLS_NONE;
344 bool first_time = true;
346 POOL_MEM restore_cmd(PM_MESSAGE);
350 /* Open the bootstrap file */
351 if (!open_bootstrap_file(jcr, info)) {
354 /* Read the bootstrap file */
355 while (!feof(info.bs)) {
357 if (!select_rstore(jcr, info)) {
362 * Open a message channel connection with the Storage
363 * daemon. This is to let him know that our client
364 * will be contacting him for a backup session.
367 Dmsg0(10, "Open connection with storage daemon\n");
368 jcr->setJobStatus(JS_WaitSD);
370 * Start conversation with Storage daemon
372 if (!connect_to_storage_daemon(jcr, 10, SDConnectTimeout, 1)) {
375 sd = jcr->store_bsock;
377 * Now start a job with the Storage daemon
379 if (!start_storage_daemon_job(jcr, jcr->rstorage, NULL)) {
385 * Start conversation with File daemon
387 jcr->setJobStatus(JS_WaitFD);
388 jcr->keep_sd_auth_key = true; /* don't clear the sd_auth_key now */
389 if (!connect_to_file_daemon(jcr, 10, FDConnectTimeout, 1)) {
392 fd = jcr->file_bsock;
393 build_restore_command(jcr, restore_cmd);
396 jcr->setJobStatus(JS_Running);
399 * Send the bootstrap file -- what Volumes/files to restore
401 if (!send_bootstrap_file(jcr, sd, info) ||
402 !response(jcr, sd, OKbootstrap, "Bootstrap", DISPLAY_ERROR)) {
406 if (jcr->sd_calls_client) {
408 * SD must call "client" i.e. FD
410 if (jcr->FDVersion < 10) {
411 Jmsg(jcr, M_FATAL, 0, _("The File daemon does not support SDCallsClient.\n"));
414 if (!send_client_addr_to_sd(jcr)) {
417 if (!run_storage_and_start_message_thread(jcr, sd)) {
421 store_address = jcr->rstore->address; /* dummy */
422 store_port = 0; /* flag that SD calls FD */
426 * Default case where FD must call the SD
428 if (!run_storage_and_start_message_thread(jcr, sd)) {
433 * send Storage daemon address to the File daemon,
434 * then wait for File daemon to make connection
435 * with Storage daemon.
437 if (jcr->rstore->SDDport == 0) {
438 jcr->rstore->SDDport = jcr->rstore->SDport;
441 store_address = get_storage_address(jcr->client, jcr->rstore);
442 store_port = jcr->rstore->SDDport;
445 /* TLS Requirement */
446 if (jcr->rstore->tls_enable) {
447 if (jcr->rstore->tls_require) {
448 tls_need = BNET_TLS_REQUIRED;
450 tls_need = BNET_TLS_OK;
455 * Send storage address to FD
456 * if port==0 FD must wait for SD to call it.
458 fd->fsend(storaddr, store_address, store_port, tls_need, jcr->sd_auth_key);
459 memset(jcr->sd_auth_key, 0, strlen(jcr->sd_auth_key));
460 Dmsg1(6, "dird>filed: %s\n", fd->msg);
461 if (!response(jcr, fd, OKstore, "Storage", DISPLAY_ERROR)) {
465 /* Declare the job started to start the MaxRunTime check */
466 jcr->setJobStarted();
468 /* Only pass "global" commands to the FD once */
471 if (!send_runscripts_commands(jcr)) {
474 if (!send_component_info(jcr)) {
475 Pmsg0(000, "FAIL: Send component info\n");
478 if (!send_restore_objects(jcr)) {
479 Pmsg0(000, "FAIL: Send restore objects\n");
484 fd->fsend("%s", restore_cmd.c_str());
485 if (!response(jcr, fd, OKrestore, "Restore", DISPLAY_ERROR)) {
489 if (jcr->FDVersion < 2) { /* Old FD */
490 break; /* we do only one loop */
492 if (!response(jcr, fd, OKstoreend, "Store end", DISPLAY_ERROR)) {
495 wait_for_storage_daemon_termination(jcr);
497 } /* the whole boostrap has been send */
499 if (fd && jcr->FDVersion >= 2) {
500 fd->fsend("endrestore");
506 close_bootstrap_file(info);
511 * Do a restore of the specified files
513 * Returns: 0 on failure
516 bool do_restore(JCR *jcr)
518 JOB_DBR rjr; /* restore job record */
521 free_wstorage(jcr); /* we don't write */
523 if (!allow_duplicate_job(jcr)) {
527 memset(&rjr, 0, sizeof(rjr));
528 jcr->jr.JobLevel = L_FULL; /* Full restore */
529 if (!db_update_job_start_record(jcr, jcr->db, &jcr->jr)) {
530 Jmsg(jcr, M_FATAL, 0, "%s", db_strerror(jcr->db));
533 Dmsg0(20, "Updated job start record\n");
535 Dmsg1(20, "RestoreJobId=%d\n", jcr->job->RestoreJobId);
537 if (!jcr->RestoreBootstrap) {
538 Jmsg(jcr, M_FATAL, 0, _("Cannot restore without a bootstrap file.\n"
539 "You probably ran a restore job directly. All restore jobs must\n"
540 "be run using the restore command.\n"));
545 /* Print Job Start message */
546 Jmsg(jcr, M_INFO, 0, _("Start Restore Job %s\n"), jcr->Job);
549 jcr->sd_calls_client = jcr->client->sd_calls_client;
552 /* Read the bootstrap file and do the restore */
553 if (!restore_bootstrap(jcr)) {
557 /* Wait for Job Termination */
558 stat = wait_for_job_termination(jcr);
559 restore_cleanup(jcr, stat);
563 restore_cleanup(jcr, JS_ErrorTerminated);
567 bool do_restore_init(JCR *jcr)
574 * Release resources allocated during restore.
577 void restore_cleanup(JCR *jcr, int TermCode)
579 char sdt[MAX_TIME_LENGTH], edt[MAX_TIME_LENGTH];
580 char ec1[30], ec2[30], ec3[30];
581 char term_code[100], fd_term_msg[100], sd_term_msg[100];
582 const char *term_msg;
583 int msg_type = M_INFO;
587 Dmsg0(20, "In restore_cleanup\n");
588 update_job_end(jcr, TermCode);
590 if (jcr->component_fd) {
591 fclose(jcr->component_fd);
592 jcr->component_fd = NULL;
594 if (jcr->component_fname && *jcr->component_fname) {
595 unlink(jcr->component_fname);
597 free_and_null_pool_memory(jcr->component_fname);
599 if (jcr->unlink_bsr && jcr->RestoreBootstrap) {
600 unlink(jcr->RestoreBootstrap);
601 jcr->unlink_bsr = false;
604 if (job_canceled(jcr)) {
605 cancel_storage_daemon_job(jcr);
610 if (jcr->ExpectedFiles > jcr->jr.JobFiles) {
611 term_msg = _("Restore OK -- warning file count mismatch");
613 } else if (jcr->JobErrors > 0 || jcr->SDErrors > 0) {
614 term_msg = _("Restore OK -- with errors");
617 term_msg = _("Restore OK");
621 term_msg = _("Restore OK -- with warnings");
624 case JS_ErrorTerminated:
625 term_msg = _("*** Restore Error ***");
626 msg_type = M_ERROR; /* Generate error message */
627 if (jcr->store_bsock) {
628 jcr->store_bsock->signal(BNET_TERMINATE);
629 if (jcr->SD_msg_chan_started) {
630 pthread_cancel(jcr->SD_msg_chan);
635 term_msg = _("Restore Canceled");
636 if (jcr->store_bsock) {
637 jcr->store_bsock->signal(BNET_TERMINATE);
638 if (jcr->SD_msg_chan_started) {
639 pthread_cancel(jcr->SD_msg_chan);
644 term_msg = term_code;
645 sprintf(term_code, _("Inappropriate term code: %c\n"), TermCode);
648 bstrftimes(sdt, sizeof(sdt), jcr->jr.StartTime);
649 bstrftimes(edt, sizeof(edt), jcr->jr.EndTime);
651 RunTime = jcr->jr.EndTime - jcr->jr.StartTime;
655 kbps = (double)jcr->jr.JobBytes / (1000.0 * (double)RunTime);
660 jobstatus_to_ascii(jcr->FDJobStatus, fd_term_msg, sizeof(fd_term_msg));
661 jobstatus_to_ascii(jcr->SDJobStatus, sd_term_msg, sizeof(sd_term_msg));
663 Jmsg(jcr, msg_type, 0, _("%s %s %s (%s):\n"
664 " Build OS: %s %s %s\n"
667 " Restore Client: %s\n"
670 " Files Expected: %s\n"
671 " Files Restored: %s\n"
672 " Bytes Restored: %s\n"
675 " FD termination status: %s\n"
676 " SD termination status: %s\n"
677 " Termination: %s\n\n"),
678 BACULA, my_name, VERSION, LSMDATE,
679 HOST_OS, DISTNAME, DISTVER,
685 edit_uint64_with_commas((uint64_t)jcr->ExpectedFiles, ec1),
686 edit_uint64_with_commas((uint64_t)jcr->jr.JobFiles, ec2),
687 edit_uint64_with_commas(jcr->jr.JobBytes, ec3),
694 Dmsg0(20, "Leaving restore_cleanup\n");