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 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????
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
114 /* Open the bootstrap file and find the first Storage=
115 * Returns ok if able to open
116 * It fills the storage name (should be the first line)
117 * and the file descriptor to the bootstrap file,
118 * it should be used for next operations, and need to be closed
121 static bool open_bootstrap_file(JCR *jcr, bootstrap_info &info)
128 if (!jcr->RestoreBootstrap) {
131 strncpy(info.storage, jcr->rstore->name(), MAX_NAME_LENGTH);
133 bs = fopen(jcr->RestoreBootstrap, "rb");
136 Jmsg(jcr, M_FATAL, 0, _("Could not open bootstrap file %s: ERR=%s\n"),
137 jcr->RestoreBootstrap, be.bstrerror());
138 set_jcr_job_status(jcr, JS_ErrorTerminated);
142 ua = new_ua_context(jcr);
143 ua->cmd = check_pool_memory_size(ua->cmd, UA_CMD_SIZE+1);
144 while (!fgets(ua->cmd, UA_CMD_SIZE, bs)) {
149 if (!strcasecmp(ua->argk[0], "Storage")) {
150 strncpy(info.storage, ua->argv[0], MAX_NAME_LENGTH);
156 fseek(bs, 0, SEEK_SET); /* return to the top of the file */
161 * This function compare the given storage name with the
162 * the current one. We compare the name and the address:port.
163 * Returns true if we use the same storage.
165 static bool is_on_same_storage(JCR *jcr, char *new_one)
169 /* with old FD, we send the whole bootstrap to the storage */
170 if (jcr->FDVersion < 2) {
173 /* we are in init loop ? shoudn't fall here */
178 if (!strcmp(new_one, jcr->rstore->name())) {
181 new_store = (STORE *)GetResWithName(R_STORAGE, new_one);
183 Jmsg(jcr, M_FATAL, 0,
184 _("Could not get storage resource '%s'.\n"), new_one);
185 set_jcr_job_status(jcr, JS_ErrorTerminated);
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)
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 set_jcr_job_status(jcr, JS_ErrorTerminated);
281 * What does this do??????????? KES
283 if (jcr->store_bsock) {
284 jcr->store_bsock->destroy();
285 jcr->store_bsock = NULL;
289 * release current read storage and get a new one
293 set_rstorage(jcr, &ustore);
294 set_jcr_job_status(jcr, JS_WaitSD);
296 * Wait for up to 6 hours to increment read stoage counter
298 for (i=0; i < MAX_TRIES; i++) {
299 /* try to get read storage counter incremented */
300 if (inc_read_store(jcr)) {
301 set_jcr_job_status(jcr, JS_Running);
304 bmicrosleep(10, 0); /* sleep 10 secs */
305 if (job_canceled(jcr)) {
310 /* Failed to inc_read_store() */
312 Jmsg(jcr, M_FATAL, 0,
313 _("Could not acquire read storage lock for \"%s\""), info.storage);
318 * Clean the bootstrap_info struct
320 static void close_bootstrap_file(bootstrap_info &info)
326 free_ua_context(info.ua);
331 * Take a bootstrap and for each different storage, we change the storage
332 * resource and start a new restore session between the client and the storage
335 bool restore_bootstrap(JCR *jcr)
337 BSOCK *fd = NULL, *sd;
338 bool end_loop = false;
339 bool first_time = true;
341 POOL_MEM restore_cmd(PM_MESSAGE);
344 /* this command is used for each part */
345 build_restore_command(jcr, restore_cmd);
347 if (!open_bootstrap_file(jcr, info)) {
350 while (!end_loop && !feof(info.bs)) {
352 if (!select_rstore(jcr, info)) {
357 * Open a message channel connection with the Storage
358 * daemon. This is to let him know that our client
359 * will be contacting him for a backup session.
362 Dmsg0(10, "Open connection with storage daemon\n");
363 set_jcr_job_status(jcr, JS_WaitSD);
365 * Start conversation with Storage daemon
367 if (!connect_to_storage_daemon(jcr, 10, SDConnectTimeout, 1)) {
370 sd = jcr->store_bsock;
372 * Now start a job with the Storage daemon
374 if (!start_storage_daemon_job(jcr, jcr->rstorage, NULL)) {
380 * Start conversation with File daemon
382 set_jcr_job_status(jcr, JS_WaitFD);
383 jcr->keep_sd_auth_key = true; /* don't clear the sd_auth_key now */
384 if (!connect_to_file_daemon(jcr, 10, FDConnectTimeout, 1)) {
388 fd = jcr->file_bsock;
391 set_jcr_job_status(jcr, JS_WaitSD);
394 * Send the bootstrap file -- what Volumes/files to restore
396 if (!send_bootstrap_file(jcr, sd, info) ||
397 !response(jcr, sd, OKbootstrap, "Bootstrap", DISPLAY_ERROR)) {
401 if (!sd->fsend("run")) {
405 * Now start a Storage daemon message thread
407 if (!start_storage_daemon_message_thread(jcr)) {
410 Dmsg0(50, "Storage daemon connection OK\n");
413 * send Storage daemon address to the File daemon,
414 * then wait for File daemon to make connection
415 * with Storage daemon.
417 if (jcr->rstore->SDDport == 0) {
418 jcr->rstore->SDDport = jcr->rstore->SDport;
420 fd->fsend(storaddr, jcr->rstore->address, jcr->rstore->SDDport,
422 memset(jcr->sd_auth_key, 0, strlen(jcr->sd_auth_key));
424 Dmsg1(6, "dird>filed: %s\n", fd->msg);
425 if (!response(jcr, fd, OKstore, "Storage", DISPLAY_ERROR)) {
430 if (!send_runscripts_commands(jcr)) {
436 fd->fsend("%s", restore_cmd.c_str());
438 if (!response(jcr, fd, OKrestore, "Restore", DISPLAY_ERROR)) {
442 if (jcr->FDVersion < 2) { /* Old FD */
443 end_loop=true; /* we do only one loop */
446 if (!response(jcr, fd, OKstoreend, "Store end", DISPLAY_ERROR)) {
449 wait_for_storage_daemon_termination(jcr);
451 } /* the whole boostrap has been send */
453 if (fd && jcr->FDVersion >= 2) {
454 fd->fsend("endrestore");
460 close_bootstrap_file(info);
465 * Do a restore of the specified files
467 * Returns: 0 on failure
470 bool do_restore(JCR *jcr)
472 JOB_DBR rjr; /* restore job record */
475 free_wstorage(jcr); /* we don't write */
477 if (!allow_duplicate_job(jcr)) {
481 memset(&rjr, 0, sizeof(rjr));
482 jcr->jr.JobLevel = L_FULL; /* Full restore */
483 if (!db_update_job_start_record(jcr, jcr->db, &jcr->jr)) {
484 Jmsg(jcr, M_FATAL, 0, "%s", db_strerror(jcr->db));
487 Dmsg0(20, "Updated job start record\n");
489 Dmsg1(20, "RestoreJobId=%d\n", jcr->job->RestoreJobId);
491 if (!jcr->RestoreBootstrap) {
492 Jmsg(jcr, M_FATAL, 0, _("Cannot restore without a bootstrap file.\n"
493 "You probably ran a restore job directly. All restore jobs must\n"
494 "be run using the restore command.\n"));
499 /* Print Job Start message */
500 Jmsg(jcr, M_INFO, 0, _("Start Restore Job %s\n"), jcr->Job);
502 if (!restore_bootstrap(jcr)) {
506 /* Wait for Job Termination */
507 stat = wait_for_job_termination(jcr);
508 restore_cleanup(jcr, stat);
512 restore_cleanup(jcr, JS_ErrorTerminated);
516 bool do_restore_init(JCR *jcr)
523 * Release resources allocated during restore.
526 void restore_cleanup(JCR *jcr, int TermCode)
528 char sdt[MAX_TIME_LENGTH], edt[MAX_TIME_LENGTH];
529 char ec1[30], ec2[30], ec3[30];
530 char term_code[100], fd_term_msg[100], sd_term_msg[100];
531 const char *term_msg;
532 int msg_type = M_INFO;
535 Dmsg0(20, "In restore_cleanup\n");
536 update_job_end(jcr, TermCode);
538 if (jcr->unlink_bsr && jcr->RestoreBootstrap) {
539 unlink(jcr->RestoreBootstrap);
540 jcr->unlink_bsr = false;
543 if (job_canceled(jcr)) {
544 cancel_storage_daemon_job(jcr);
549 if (jcr->ExpectedFiles > jcr->jr.JobFiles) {
550 term_msg = _("Restore OK -- warning file count mismatch");
552 term_msg = _("Restore OK");
556 term_msg = _("Restore OK -- with warnings");
559 case JS_ErrorTerminated:
560 term_msg = _("*** Restore Error ***");
561 msg_type = M_ERROR; /* Generate error message */
562 if (jcr->store_bsock) {
563 jcr->store_bsock->signal(BNET_TERMINATE);
564 if (jcr->SD_msg_chan) {
565 pthread_cancel(jcr->SD_msg_chan);
570 term_msg = _("Restore Canceled");
571 if (jcr->store_bsock) {
572 jcr->store_bsock->signal(BNET_TERMINATE);
573 if (jcr->SD_msg_chan) {
574 pthread_cancel(jcr->SD_msg_chan);
579 term_msg = term_code;
580 sprintf(term_code, _("Inappropriate term code: %c\n"), TermCode);
583 bstrftimes(sdt, sizeof(sdt), jcr->jr.StartTime);
584 bstrftimes(edt, sizeof(edt), jcr->jr.EndTime);
585 if (jcr->jr.EndTime - jcr->jr.StartTime > 0) {
586 kbps = (double)jcr->jr.JobBytes / (1000 * (jcr->jr.EndTime - jcr->jr.StartTime));
594 jobstatus_to_ascii(jcr->FDJobStatus, fd_term_msg, sizeof(fd_term_msg));
595 jobstatus_to_ascii(jcr->SDJobStatus, sd_term_msg, sizeof(sd_term_msg));
597 Jmsg(jcr, msg_type, 0, _("%s %s %s (%s): %s\n"
598 " Build OS: %s %s %s\n"
601 " Restore Client: %s\n"
604 " Files Expected: %s\n"
605 " Files Restored: %s\n"
606 " Bytes Restored: %s\n"
609 " FD termination status: %s\n"
610 " SD termination status: %s\n"
611 " Termination: %s\n\n"),
612 BACULA, my_name, VERSION, LSMDATE, edt,
613 HOST_OS, DISTNAME, DISTVER,
619 edit_uint64_with_commas((uint64_t)jcr->ExpectedFiles, ec1),
620 edit_uint64_with_commas((uint64_t)jcr->jr.JobFiles, ec2),
621 edit_uint64_with_commas(jcr->jr.JobBytes, ec3),
628 Dmsg0(20, "Leaving restore_cleanup\n");