2 Bacula® - The Network Backup Solution
4 Copyright (C) 2000-20087 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 John Walker.
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????
52 /* Commands sent to File daemon */
53 static char restorecmd[] = "restore replace=%c prelinks=%d where=%s\n";
54 static char restorecmdR[] = "restore replace=%c prelinks=%d regexwhere=%s\n";
55 static char storaddr[] = "storage address=%s port=%d ssl=0\n";
57 /* Responses received from File daemon */
58 static char OKrestore[] = "2000 OK restore\n";
59 static char OKstore[] = "2000 OK storage\n";
60 static char OKbootstrap[] = "2000 OK bootstrap\n";
63 * Do a restore of the specified files
65 * Returns: 0 on failure
68 bool do_restore(JCR *jcr)
71 JOB_DBR rjr; /* restore job record */
73 free_wstorage(jcr); /* we don't write */
75 memset(&rjr, 0, sizeof(rjr));
76 jcr->jr.JobLevel = L_FULL; /* Full restore */
77 if (!db_update_job_start_record(jcr, jcr->db, &jcr->jr)) {
78 Jmsg(jcr, M_FATAL, 0, "%s", db_strerror(jcr->db));
79 restore_cleanup(jcr, JS_ErrorTerminated);
82 Dmsg0(20, "Updated job start record\n");
84 Dmsg1(20, "RestoreJobId=%d\n", jcr->job->RestoreJobId);
86 if (!jcr->RestoreBootstrap) {
87 Jmsg0(jcr, M_FATAL, 0, _("Cannot restore without a bootstrap file.\n"
88 "You probably ran a restore job directly. All restore jobs must\n"
89 "be run using the restore command.\n"));
90 restore_cleanup(jcr, JS_ErrorTerminated);
95 /* Print Job Start message */
96 Jmsg(jcr, M_INFO, 0, _("Start Restore Job %s\n"), jcr->Job);
99 * Open a message channel connection with the Storage
100 * daemon. This is to let him know that our client
101 * will be contacting him for a backup session.
104 Dmsg0(10, "Open connection with storage daemon\n");
105 set_jcr_job_status(jcr, JS_WaitSD);
107 * Start conversation with Storage daemon
109 if (!connect_to_storage_daemon(jcr, 10, SDConnectTimeout, 1)) {
110 restore_cleanup(jcr, JS_ErrorTerminated);
114 * Now start a job with the Storage daemon
116 if (!start_storage_daemon_job(jcr, jcr->rstorage, NULL)) {
117 restore_cleanup(jcr, JS_ErrorTerminated);
120 if (!jcr->store_bsock->fsend("run")) {
124 * Now start a Storage daemon message thread
126 if (!start_storage_daemon_message_thread(jcr)) {
127 restore_cleanup(jcr, JS_ErrorTerminated);
130 Dmsg0(50, "Storage daemon connection OK\n");
134 * Start conversation with File daemon
136 set_jcr_job_status(jcr, JS_WaitFD);
137 if (!connect_to_file_daemon(jcr, 10, FDConnectTimeout, 1)) {
138 restore_cleanup(jcr, JS_ErrorTerminated);
142 fd = jcr->file_bsock;
143 set_jcr_job_status(jcr, JS_Running);
146 * send Storage daemon address to the File daemon,
147 * then wait for File daemon to make connection
148 * with Storage daemon.
150 if (jcr->rstore->SDDport == 0) {
151 jcr->rstore->SDDport = jcr->rstore->SDport;
153 fd->fsend(storaddr, jcr->rstore->address, jcr->rstore->SDDport);
154 Dmsg1(6, "dird>filed: %s\n", fd->msg);
155 if (!response(jcr, fd, OKstore, "Storage", DISPLAY_ERROR)) {
156 restore_cleanup(jcr, JS_ErrorTerminated);
161 * Send the bootstrap file -- what Volumes/files to restore
163 if (!send_bootstrap_file(jcr, fd) ||
164 !response(jcr, fd, OKbootstrap, "Bootstrap", DISPLAY_ERROR)) {
165 restore_cleanup(jcr, JS_ErrorTerminated);
170 if (!send_runscripts_commands(jcr)) {
171 restore_cleanup(jcr, JS_ErrorTerminated);
175 /* Send restore command */
176 char replace, *where, *cmd;
179 if (jcr->replace != 0) {
180 replace = jcr->replace;
181 } else if (jcr->job->replace != 0) {
182 replace = jcr->job->replace;
184 replace = REPLACE_ALWAYS; /* always replace */
187 if (jcr->RegexWhere) {
188 where = jcr->RegexWhere; /* override */
190 } else if (jcr->job->RegexWhere) {
191 where = jcr->job->RegexWhere; /* no override take from job */
194 } else if (jcr->where) {
195 where = jcr->where; /* override */
197 } else if (jcr->job->RestoreWhere) {
198 where = jcr->job->RestoreWhere; /* no override take from job */
201 } else { /* nothing was specified */
202 where = ∅ /* use default */
206 jcr->prefix_links = jcr->job->PrefixLinks;
209 fd->fsend(cmd, replace, jcr->prefix_links, where);
210 unbash_spaces(where);
212 if (!response(jcr, fd, OKrestore, "Restore", DISPLAY_ERROR)) {
213 restore_cleanup(jcr, JS_ErrorTerminated);
217 /* Wait for Job Termination */
218 int stat = wait_for_job_termination(jcr);
219 restore_cleanup(jcr, stat);
224 bool do_restore_init(JCR *jcr)
231 * Release resources allocated during restore.
234 void restore_cleanup(JCR *jcr, int TermCode)
236 char sdt[MAX_TIME_LENGTH], edt[MAX_TIME_LENGTH];
237 char ec1[30], ec2[30], ec3[30];
238 char term_code[100], fd_term_msg[100], sd_term_msg[100];
239 const char *term_msg;
240 int msg_type = M_INFO;
243 Dmsg0(20, "In restore_cleanup\n");
244 update_job_end(jcr, TermCode);
246 if (jcr->unlink_bsr && jcr->RestoreBootstrap) {
247 unlink(jcr->RestoreBootstrap);
248 jcr->unlink_bsr = false;
251 if (job_canceled(jcr)) {
252 cancel_storage_daemon_job(jcr);
257 if (jcr->ExpectedFiles > jcr->jr.JobFiles) {
258 term_msg = _("Restore OK -- warning file count mismatch");
260 term_msg = _("Restore OK");
264 case JS_ErrorTerminated:
265 term_msg = _("*** Restore Error ***");
266 msg_type = M_ERROR; /* Generate error message */
267 if (jcr->store_bsock) {
268 jcr->store_bsock->signal(BNET_TERMINATE);
269 if (jcr->SD_msg_chan) {
270 pthread_cancel(jcr->SD_msg_chan);
275 term_msg = _("Restore Canceled");
276 if (jcr->store_bsock) {
277 jcr->store_bsock->signal(BNET_TERMINATE);
278 if (jcr->SD_msg_chan) {
279 pthread_cancel(jcr->SD_msg_chan);
284 term_msg = term_code;
285 sprintf(term_code, _("Inappropriate term code: %c\n"), TermCode);
288 bstrftimes(sdt, sizeof(sdt), jcr->jr.StartTime);
289 bstrftimes(edt, sizeof(edt), jcr->jr.EndTime);
290 if (jcr->jr.EndTime - jcr->jr.StartTime > 0) {
291 kbps = (double)jcr->jr.JobBytes / (1000 * (jcr->jr.EndTime - jcr->jr.StartTime));
299 jobstatus_to_ascii(jcr->FDJobStatus, fd_term_msg, sizeof(fd_term_msg));
300 jobstatus_to_ascii(jcr->SDJobStatus, sd_term_msg, sizeof(sd_term_msg));
302 Jmsg(jcr, msg_type, 0, _("Bacula %s %s (%s): %s\n"
303 " Build OS: %s %s %s\n"
306 " Restore Client: %s\n"
309 " Files Expected: %s\n"
310 " Files Restored: %s\n"
311 " Bytes Restored: %s\n"
314 " FD termination status: %s\n"
315 " SD termination status: %s\n"
316 " Termination: %s\n\n"),
317 my_name, VERSION, LSMDATE, edt,
318 HOST_OS, DISTNAME, DISTVER,
324 edit_uint64_with_commas((uint64_t)jcr->ExpectedFiles, ec1),
325 edit_uint64_with_commas((uint64_t)jcr->jr.JobFiles, ec2),
326 edit_uint64_with_commas(jcr->jr.JobBytes, ec3),
333 Dmsg0(20, "Leaving restore_cleanup\n");