2 Bacula® - The Network Backup Solution
4 Copyright (C) 2000-2011 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 jcr->setJobStatus(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 fail here */
179 if (!strcmp(new_one, jcr->rstore->name())) {
182 new_store = (STORE *)GetResWithName(R_STORAGE, new_one);
184 Jmsg(jcr, M_WARNING, 0,
185 _("Could not get storage resource '%s'.\n"), new_one);
188 /* if Port and Hostname/IP are same, we are talking to the same
191 if (jcr->rstore->SDport != new_store->SDport ||
192 strcmp(jcr->rstore->address, new_store->address))
200 * Check if the current line contains Storage="xxx", and compare the
201 * result to the current storage. We use UAContext to analyse the bsr
204 * Returns true if we need to change the storage, and it set the new
205 * Storage resource name in "storage" arg.
207 static bool check_for_new_storage(JCR *jcr, bootstrap_info &info)
209 UAContext *ua = info.ua;
214 if (!strcasecmp(ua->argk[0], "Storage")) {
215 /* Continue if this is a volume from the same storage. */
216 if (is_on_same_storage(jcr, ua->argv[0])) {
219 /* note the next storage name */
220 strncpy(info.storage, ua->argv[0], MAX_NAME_LENGTH);
221 Dmsg1(5, "Change storage to %s\n", info.storage);
228 * Send bootstrap file to Storage daemon section by section.
230 static bool send_bootstrap_file(JCR *jcr, BSOCK *sock,
231 bootstrap_info &info)
234 const char *bootstrap = "bootstrap\n";
235 UAContext *ua = info.ua;
238 Dmsg1(400, "send_bootstrap_file: %s\n", jcr->RestoreBootstrap);
239 if (!jcr->RestoreBootstrap) {
242 sock->fsend(bootstrap);
244 while(fgets(ua->cmd, UA_CMD_SIZE, bs)) {
245 if (check_for_new_storage(jcr, info)) {
246 /* Otherwise, we need to contact another storage daemon.
247 * Reset bs to the beginning of the current segment.
249 fseeko(bs, pos, SEEK_SET);
252 sock->fsend("%s", ua->cmd);
255 sock->signal(BNET_EOD);
259 #define MAX_TRIES 6 * 360 /* 6 hours */
262 * Change the read storage resource for the current job.
264 static bool select_rstore(JCR *jcr, bootstrap_info &info)
270 if (!strcmp(jcr->rstore->name(), info.storage)) {
271 return true; /* same SD nothing to change */
274 if (!(ustore.store = (STORE *)GetResWithName(R_STORAGE,info.storage))) {
275 Jmsg(jcr, M_FATAL, 0,
276 _("Could not get storage resource '%s'.\n"), info.storage);
277 jcr->setJobStatus(JS_ErrorTerminated);
282 * What does this do??????????? KES
284 if (jcr->store_bsock) {
285 jcr->store_bsock->destroy();
286 jcr->store_bsock = NULL;
290 * release current read storage and get a new one
294 set_rstorage(jcr, &ustore);
295 jcr->setJobStatus(JS_WaitSD);
297 * Wait for up to 6 hours to increment read stoage counter
299 for (i=0; i < MAX_TRIES; i++) {
300 /* try to get read storage counter incremented */
301 if (inc_read_store(jcr)) {
302 jcr->setJobStatus(JS_Running);
305 bmicrosleep(10, 0); /* sleep 10 secs */
306 if (job_canceled(jcr)) {
311 /* Failed to inc_read_store() */
313 Jmsg(jcr, M_FATAL, 0,
314 _("Could not acquire read storage lock for \"%s\""), info.storage);
319 * Clean the bootstrap_info struct
321 static void close_bootstrap_file(bootstrap_info &info)
327 free_ua_context(info.ua);
332 * The bootstrap is stored in a file, so open the file, and loop
333 * through it processing each storage device in turn. If the
334 * storage is different from the prior one, we open a new connection
335 * to the new storage and do a restore for that part.
336 * This permits handling multiple storage daemons for a single
337 * restore. E.g. your Full is stored on tape, and Incrementals
340 bool restore_bootstrap(JCR *jcr)
344 bool first_time = true;
346 POOL_MEM restore_cmd(PM_MESSAGE);
349 /* this command is used for each part */
350 build_restore_command(jcr, restore_cmd);
352 /* Open the bootstrap file */
353 if (!open_bootstrap_file(jcr, info)) {
356 /* Read the bootstrap file */
357 while (!feof(info.bs)) {
359 if (!select_rstore(jcr, info)) {
364 * Open a message channel connection with the Storage
365 * daemon. This is to let him know that our client
366 * will be contacting him for a backup session.
369 Dmsg0(10, "Open connection with storage daemon\n");
370 jcr->setJobStatus(JS_WaitSD);
372 * Start conversation with Storage daemon
374 if (!connect_to_storage_daemon(jcr, 10, SDConnectTimeout, 1)) {
377 sd = jcr->store_bsock;
379 * Now start a job with the Storage daemon
381 if (!start_storage_daemon_job(jcr, jcr->rstorage, NULL)) {
387 * Start conversation with File daemon
389 jcr->setJobStatus(JS_WaitFD);
390 jcr->keep_sd_auth_key = true; /* don't clear the sd_auth_key now */
391 if (!connect_to_file_daemon(jcr, 10, FDConnectTimeout, 1)) {
394 fd = jcr->file_bsock;
397 jcr->setJobStatus(JS_Running);
400 * Send the bootstrap file -- what Volumes/files to restore
402 if (!send_bootstrap_file(jcr, sd, info) ||
403 !response(jcr, sd, OKbootstrap, "Bootstrap", DISPLAY_ERROR)) {
407 if (!sd->fsend("run")) {
411 * Now start a Storage daemon message thread
413 if (!start_storage_daemon_message_thread(jcr)) {
416 Dmsg0(50, "Storage daemon connection OK\n");
419 * send Storage daemon address to the File daemon,
420 * then wait for File daemon to make connection
421 * with Storage daemon.
423 if (jcr->rstore->SDDport == 0) {
424 jcr->rstore->SDDport = jcr->rstore->SDport;
426 fd->fsend(storaddr, jcr->rstore->address, jcr->rstore->SDDport,
428 memset(jcr->sd_auth_key, 0, strlen(jcr->sd_auth_key));
430 Dmsg1(6, "dird>filed: %s\n", fd->msg);
431 if (!response(jcr, fd, OKstore, "Storage", DISPLAY_ERROR)) {
435 /* Only pass "global" commands to the FD once */
438 if (!send_runscripts_commands(jcr)) {
441 if (!send_restore_objects(jcr)) {
442 Dmsg0(000, "FAIL: Send restore objects\n");
447 fd->fsend("%s", restore_cmd.c_str());
449 if (!response(jcr, fd, OKrestore, "Restore", DISPLAY_ERROR)) {
453 if (jcr->FDVersion < 2) { /* Old FD */
454 break; /* we do only one loop */
456 if (!response(jcr, fd, OKstoreend, "Store end", DISPLAY_ERROR)) {
459 wait_for_storage_daemon_termination(jcr);
461 } /* the whole boostrap has been send */
463 if (fd && jcr->FDVersion >= 2) {
464 fd->fsend("endrestore");
470 close_bootstrap_file(info);
475 * Do a restore of the specified files
477 * Returns: 0 on failure
480 bool do_restore(JCR *jcr)
482 JOB_DBR rjr; /* restore job record */
485 free_wstorage(jcr); /* we don't write */
487 if (!allow_duplicate_job(jcr)) {
491 memset(&rjr, 0, sizeof(rjr));
492 jcr->jr.JobLevel = L_FULL; /* Full restore */
493 if (!db_update_job_start_record(jcr, jcr->db, &jcr->jr)) {
494 Jmsg(jcr, M_FATAL, 0, "%s", db_strerror(jcr->db));
497 Dmsg0(20, "Updated job start record\n");
499 Dmsg1(20, "RestoreJobId=%d\n", jcr->job->RestoreJobId);
501 if (!jcr->RestoreBootstrap) {
502 Jmsg(jcr, M_FATAL, 0, _("Cannot restore without a bootstrap file.\n"
503 "You probably ran a restore job directly. All restore jobs must\n"
504 "be run using the restore command.\n"));
509 /* Print Job Start message */
510 Jmsg(jcr, M_INFO, 0, _("Start Restore Job %s\n"), jcr->Job);
512 /* Read the bootstrap file and do the restore */
513 if (!restore_bootstrap(jcr)) {
517 /* Wait for Job Termination */
518 stat = wait_for_job_termination(jcr);
519 restore_cleanup(jcr, stat);
523 restore_cleanup(jcr, JS_ErrorTerminated);
527 bool do_restore_init(JCR *jcr)
534 * Release resources allocated during restore.
537 void restore_cleanup(JCR *jcr, int TermCode)
539 char sdt[MAX_TIME_LENGTH], edt[MAX_TIME_LENGTH];
540 char ec1[30], ec2[30], ec3[30];
541 char term_code[100], fd_term_msg[100], sd_term_msg[100];
542 const char *term_msg;
543 int msg_type = M_INFO;
546 Dmsg0(20, "In restore_cleanup\n");
547 update_job_end(jcr, TermCode);
549 if (jcr->unlink_bsr && jcr->RestoreBootstrap) {
550 unlink(jcr->RestoreBootstrap);
551 jcr->unlink_bsr = false;
554 if (job_canceled(jcr)) {
555 cancel_storage_daemon_job(jcr);
560 if (jcr->ExpectedFiles > jcr->jr.JobFiles) {
561 term_msg = _("Restore OK -- warning file count mismatch");
563 term_msg = _("Restore OK");
567 term_msg = _("Restore OK -- with warnings");
570 case JS_ErrorTerminated:
571 term_msg = _("*** Restore Error ***");
572 msg_type = M_ERROR; /* Generate error message */
573 if (jcr->store_bsock) {
574 jcr->store_bsock->signal(BNET_TERMINATE);
575 if (jcr->SD_msg_chan) {
576 pthread_cancel(jcr->SD_msg_chan);
581 term_msg = _("Restore Canceled");
582 if (jcr->store_bsock) {
583 jcr->store_bsock->signal(BNET_TERMINATE);
584 if (jcr->SD_msg_chan) {
585 pthread_cancel(jcr->SD_msg_chan);
590 term_msg = term_code;
591 sprintf(term_code, _("Inappropriate term code: %c\n"), TermCode);
594 bstrftimes(sdt, sizeof(sdt), jcr->jr.StartTime);
595 bstrftimes(edt, sizeof(edt), jcr->jr.EndTime);
596 if (jcr->jr.EndTime - jcr->jr.StartTime > 0) {
597 kbps = (double)jcr->jr.JobBytes / (1000 * (jcr->jr.EndTime - jcr->jr.StartTime));
605 jobstatus_to_ascii(jcr->FDJobStatus, fd_term_msg, sizeof(fd_term_msg));
606 jobstatus_to_ascii(jcr->SDJobStatus, sd_term_msg, sizeof(sd_term_msg));
608 Jmsg(jcr, msg_type, 0, _("%s %s %s (%s):\n"
609 " Build OS: %s %s %s\n"
612 " Restore Client: %s\n"
615 " Files Expected: %s\n"
616 " Files Restored: %s\n"
617 " Bytes Restored: %s\n"
620 " FD termination status: %s\n"
621 " SD termination status: %s\n"
622 " Termination: %s\n\n"),
623 BACULA, my_name, VERSION, LSMDATE,
624 HOST_OS, DISTNAME, DISTVER,
630 edit_uint64_with_commas((uint64_t)jcr->ExpectedFiles, ec1),
631 edit_uint64_with_commas((uint64_t)jcr->jr.JobFiles, ec2),
632 edit_uint64_with_commas(jcr->jr.JobBytes, ec3),
639 Dmsg0(20, "Leaving restore_cleanup\n");