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 /* Declare the job started to start the MaxRunTime check */
436 jcr->setJobStarted();
438 /* Only pass "global" commands to the FD once */
441 if (!send_runscripts_commands(jcr)) {
444 if (!send_restore_objects(jcr)) {
445 Dmsg0(000, "FAIL: Send restore objects\n");
450 fd->fsend("%s", restore_cmd.c_str());
452 if (!response(jcr, fd, OKrestore, "Restore", DISPLAY_ERROR)) {
456 if (jcr->FDVersion < 2) { /* Old FD */
457 break; /* we do only one loop */
459 if (!response(jcr, fd, OKstoreend, "Store end", DISPLAY_ERROR)) {
462 wait_for_storage_daemon_termination(jcr);
464 } /* the whole boostrap has been send */
466 if (fd && jcr->FDVersion >= 2) {
467 fd->fsend("endrestore");
473 close_bootstrap_file(info);
478 * Do a restore of the specified files
480 * Returns: 0 on failure
483 bool do_restore(JCR *jcr)
485 JOB_DBR rjr; /* restore job record */
488 free_wstorage(jcr); /* we don't write */
490 if (!allow_duplicate_job(jcr)) {
494 memset(&rjr, 0, sizeof(rjr));
495 jcr->jr.JobLevel = L_FULL; /* Full restore */
496 if (!db_update_job_start_record(jcr, jcr->db, &jcr->jr)) {
497 Jmsg(jcr, M_FATAL, 0, "%s", db_strerror(jcr->db));
500 Dmsg0(20, "Updated job start record\n");
502 Dmsg1(20, "RestoreJobId=%d\n", jcr->job->RestoreJobId);
504 if (!jcr->RestoreBootstrap) {
505 Jmsg(jcr, M_FATAL, 0, _("Cannot restore without a bootstrap file.\n"
506 "You probably ran a restore job directly. All restore jobs must\n"
507 "be run using the restore command.\n"));
512 /* Print Job Start message */
513 Jmsg(jcr, M_INFO, 0, _("Start Restore Job %s\n"), jcr->Job);
515 /* Read the bootstrap file and do the restore */
516 if (!restore_bootstrap(jcr)) {
520 /* Wait for Job Termination */
521 stat = wait_for_job_termination(jcr);
522 restore_cleanup(jcr, stat);
526 restore_cleanup(jcr, JS_ErrorTerminated);
530 bool do_restore_init(JCR *jcr)
537 * Release resources allocated during restore.
540 void restore_cleanup(JCR *jcr, int TermCode)
542 char sdt[MAX_TIME_LENGTH], edt[MAX_TIME_LENGTH];
543 char ec1[30], ec2[30], ec3[30];
544 char term_code[100], fd_term_msg[100], sd_term_msg[100];
545 const char *term_msg;
546 int msg_type = M_INFO;
549 Dmsg0(20, "In restore_cleanup\n");
550 update_job_end(jcr, TermCode);
552 if (jcr->unlink_bsr && jcr->RestoreBootstrap) {
553 unlink(jcr->RestoreBootstrap);
554 jcr->unlink_bsr = false;
557 if (job_canceled(jcr)) {
558 cancel_storage_daemon_job(jcr);
563 if (jcr->ExpectedFiles > jcr->jr.JobFiles) {
564 term_msg = _("Restore OK -- warning file count mismatch");
566 term_msg = _("Restore OK");
570 term_msg = _("Restore OK -- with warnings");
573 case JS_ErrorTerminated:
574 term_msg = _("*** Restore Error ***");
575 msg_type = M_ERROR; /* Generate error message */
576 if (jcr->store_bsock) {
577 jcr->store_bsock->signal(BNET_TERMINATE);
578 if (jcr->SD_msg_chan) {
579 pthread_cancel(jcr->SD_msg_chan);
584 term_msg = _("Restore Canceled");
585 if (jcr->store_bsock) {
586 jcr->store_bsock->signal(BNET_TERMINATE);
587 if (jcr->SD_msg_chan) {
588 pthread_cancel(jcr->SD_msg_chan);
593 term_msg = term_code;
594 sprintf(term_code, _("Inappropriate term code: %c\n"), TermCode);
597 bstrftimes(sdt, sizeof(sdt), jcr->jr.StartTime);
598 bstrftimes(edt, sizeof(edt), jcr->jr.EndTime);
599 if (jcr->jr.EndTime - jcr->jr.StartTime > 0) {
600 kbps = (double)jcr->jr.JobBytes / (1000 * (jcr->jr.EndTime - jcr->jr.StartTime));
608 jobstatus_to_ascii(jcr->FDJobStatus, fd_term_msg, sizeof(fd_term_msg));
609 jobstatus_to_ascii(jcr->SDJobStatus, sd_term_msg, sizeof(sd_term_msg));
611 Jmsg(jcr, msg_type, 0, _("%s %s %s (%s):\n"
612 " Build OS: %s %s %s\n"
615 " Restore Client: %s\n"
618 " Files Expected: %s\n"
619 " Files Restored: %s\n"
620 " Bytes Restored: %s\n"
623 " FD termination status: %s\n"
624 " SD termination status: %s\n"
625 " Termination: %s\n\n"),
626 BACULA, my_name, VERSION, LSMDATE,
627 HOST_OS, DISTNAME, DISTVER,
633 edit_uint64_with_commas((uint64_t)jcr->ExpectedFiles, ec1),
634 edit_uint64_with_commas((uint64_t)jcr->jr.JobFiles, ec2),
635 edit_uint64_with_commas(jcr->jr.JobBytes, ec3),
642 Dmsg0(20, "Leaving restore_cleanup\n");