]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/dird/restore.c
ebl tweak pointer to int convertion for win64
[bacula/bacula] / bacula / src / dird / restore.c
index c55b90e3b261824ab8767da8d2b3a7091e810b37..b57e6802dff6dd95461eff1af980e61d5f94563d 100644 (file)
@@ -1,3 +1,30 @@
+/*
+   Bacula® - The Network Backup Solution
+
+   Copyright (C) 2000-2008 Free Software Foundation Europe e.V.
+
+   The main author of Bacula is Kern Sibbald, with contributions from
+   many others, a complete list can be found in the file AUTHORS.
+   This program is Free Software; you can redistribute it and/or
+   modify it under the terms of version two of the GNU General Public
+   License as published by the Free Software Foundation and included
+   in the file LICENSE.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.
+
+   Bacula® is a registered trademark of Kern Sibbald.
+   The licensor of Bacula is the Free Software Foundation Europe
+   (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
+   Switzerland, email:ftf@fsfeurope.org.
+*/
 /*
  *   Bacula Director -- restore.c -- responsible for restoring files
  *
  *     Open DB
  *     Open Message Channel with Storage daemon to tell him a job will be starting.
  *     Open connection with File daemon and pass him commands
- *      to do the restore.
+ *       to do the restore.
  *     Update the DB according to what files where restored????
  *
  *   Version $Id$
  */
-/*
-   Copyright (C) 2000-2005 Kern Sibbald
-
-   This program is free software; you can redistribute it and/or
-   modify it under the terms of the GNU General Public License
-   version 2 as ammended with additional clauses defined in the
-   file LICENSE in the main source directory.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
-   the file LICENSE for additional details.
-
- */
 
 
 #include "bacula.h"
 #include "dird.h"
 
 /* Commands sent to File daemon */
-static char restorecmd[]   = "restore replace=%c prelinks=%d where=%s\n";
-static char storaddr[]     = "storage address=%s port=%d ssl=0\n";
+static char restorecmd[]  = "restore replace=%c prelinks=%d where=%s\n";
+static char restorecmdR[] = "restore replace=%c prelinks=%d regexwhere=%s\n";
+static char storaddr[]    = "storage address=%s port=%d ssl=0\n";
 
 /* Responses received from File daemon */
 static char OKrestore[]   = "2000 OK restore\n";
 static char OKstore[]     = "2000 OK storage\n";
+static char OKbootstrap[] = "2000 OK bootstrap\n";
 
 /*
  * Do a restore of the specified files
  *
  *  Returns:  0 on failure
- *           1 on success
+ *            1 on success
  */
 bool do_restore(JCR *jcr)
 {
    BSOCK   *fd;
-   JOB_DBR rjr;                      /* restore job record */
+   JOB_DBR rjr;                       /* restore job record */
+   char replace, *where, *cmd;
+   char empty = '\0';
+   int stat;
+
+   free_wstorage(jcr);                /* we don't write */
+
+   if (!allow_duplicate_job(jcr)) {
+      goto bail_out;
+   }
 
    memset(&rjr, 0, sizeof(rjr));
-   jcr->jr.JobLevel = L_FULL;        /* Full restore */
+   jcr->jr.JobLevel = L_FULL;         /* Full restore */
    if (!db_update_job_start_record(jcr, jcr->db, &jcr->jr)) {
       Jmsg(jcr, M_FATAL, 0, "%s", db_strerror(jcr->db));
-      restore_cleanup(jcr, JS_ErrorTerminated);
-      return false;
+      goto bail_out;
    }
    Dmsg0(20, "Updated job start record\n");
 
    Dmsg1(20, "RestoreJobId=%d\n", jcr->job->RestoreJobId);
 
    if (!jcr->RestoreBootstrap) {
-      Jmsg0(jcr, M_FATAL, 0, _("Cannot restore without bootstrap file.\n"));
-      restore_cleanup(jcr, JS_ErrorTerminated);
-      return false;
+      Jmsg0(jcr, M_FATAL, 0, _("Cannot restore without a bootstrap file.\n"
+          "You probably ran a restore job directly. All restore jobs must\n"
+          "be run using the restore command.\n"));
+      goto bail_out;
    }
 
 
@@ -88,79 +112,65 @@ bool do_restore(JCR *jcr)
     * Start conversation with Storage daemon
     */
    if (!connect_to_storage_daemon(jcr, 10, SDConnectTimeout, 1)) {
-      restore_cleanup(jcr, JS_ErrorTerminated);
-      return false;
+      goto bail_out;
    }
    /*
     * Now start a job with the Storage daemon
     */
-   if (!start_storage_daemon_job(jcr, jcr->storage, SD_READ)) {
-      restore_cleanup(jcr, JS_ErrorTerminated);
-      return false;
+   if (!start_storage_daemon_job(jcr, jcr->rstorage, NULL)) {
+      goto bail_out;
+   }
+   if (!jcr->store_bsock->fsend("run")) {
+      goto bail_out;
    }
    /*
     * Now start a Storage daemon message thread
     */
    if (!start_storage_daemon_message_thread(jcr)) {
-      restore_cleanup(jcr, JS_ErrorTerminated);
-      return false;
+      goto bail_out;
    }
    Dmsg0(50, "Storage daemon connection OK\n");
 
+
    /*
     * Start conversation with File daemon
     */
    set_jcr_job_status(jcr, JS_WaitFD);
    if (!connect_to_file_daemon(jcr, 10, FDConnectTimeout, 1)) {
-      restore_cleanup(jcr, JS_ErrorTerminated);
-      return false;
+      goto bail_out;
    }
 
    fd = jcr->file_bsock;
    set_jcr_job_status(jcr, JS_Running);
 
-   if (!send_include_list(jcr)) {
-      restore_cleanup(jcr, JS_ErrorTerminated);
-      return false;
-   }
-
-   if (!send_exclude_list(jcr)) {
-      restore_cleanup(jcr, JS_ErrorTerminated);
-      return false;
-   }
-
    /*
     * send Storage daemon address to the File daemon,
-    *  then wait for File daemon to make connection
-    *  with Storage daemon.
+    *   then wait for File daemon to make connection
+    *   with Storage daemon.
     */
-   if (jcr->store->SDDport == 0) {
-      jcr->store->SDDport = jcr->store->SDport;
+   if (jcr->rstore->SDDport == 0) {
+      jcr->rstore->SDDport = jcr->rstore->SDport;
    }
-   bnet_fsend(fd, storaddr, jcr->store->address, jcr->store->SDDport);
+   fd->fsend(storaddr, jcr->rstore->address, jcr->rstore->SDDport);
    Dmsg1(6, "dird>filed: %s\n", fd->msg);
    if (!response(jcr, fd, OKstore, "Storage", DISPLAY_ERROR)) {
-      restore_cleanup(jcr, JS_ErrorTerminated);
-      return false;
+      goto bail_out;
    }
 
    /*
     * Send the bootstrap file -- what Volumes/files to restore
     */
-   if (!send_bootstrap_file(jcr)) {
-      restore_cleanup(jcr, JS_ErrorTerminated);
-      return false;
+   if (!send_bootstrap_file(jcr, fd) ||
+       !response(jcr, fd, OKbootstrap, "Bootstrap", DISPLAY_ERROR)) {
+      goto bail_out;
    }
 
 
-   if (!send_run_before_and_after_commands(jcr)) {
-      restore_cleanup(jcr, JS_ErrorTerminated);
-      return false;
+   if (!send_runscripts_commands(jcr)) {
+      goto bail_out;
    }
 
    /* Send restore command */
-   char replace, *where;
-   char empty = '\0';
 
    if (jcr->replace != 0) {
       replace = jcr->replace;
@@ -169,32 +179,49 @@ bool do_restore(JCR *jcr)
    } else {
       replace = REPLACE_ALWAYS;       /* always replace */
    }
-   if (jcr->where) {
-      where = jcr->where;            /* override */
+   
+   if (jcr->RegexWhere) {
+      where = jcr->RegexWhere;             /* override */
+      cmd = restorecmdR;
+   } else if (jcr->job->RegexWhere) {
+      where = jcr->job->RegexWhere;   /* no override take from job */
+      cmd = restorecmdR;
+
+   } else if (jcr->where) {
+      where = jcr->where;             /* override */
+      cmd = restorecmd;
    } else if (jcr->job->RestoreWhere) {
       where = jcr->job->RestoreWhere; /* no override take from job */
-   } else {
-      where = ∅                /* None */
+      cmd = restorecmd;
+
+   } else {                           /* nothing was specified */
+      where = ∅                 /* use default */
+      cmd   = restorecmd;                    
    }
+   
    jcr->prefix_links = jcr->job->PrefixLinks;
+
    bash_spaces(where);
-   bnet_fsend(fd, restorecmd, replace, jcr->prefix_links, where);
+   fd->fsend(cmd, replace, jcr->prefix_links, where);
    unbash_spaces(where);
 
    if (!response(jcr, fd, OKrestore, "Restore", DISPLAY_ERROR)) {
-      restore_cleanup(jcr, JS_ErrorTerminated);
-      return false;
+      goto bail_out;
    }
 
    /* Wait for Job Termination */
-   int stat = wait_for_job_termination(jcr);
+   stat = wait_for_job_termination(jcr);
    restore_cleanup(jcr, stat);
-
    return true;
+
+bail_out:
+   restore_cleanup(jcr, JS_ErrorTerminated);
+   return false;
 }
 
 bool do_restore_init(JCR *jcr) 
 {
+   free_wstorage(jcr);
    return true;
 }
 
@@ -208,21 +235,21 @@ void restore_cleanup(JCR *jcr, int TermCode)
    char ec1[30], ec2[30], ec3[30];
    char term_code[100], fd_term_msg[100], sd_term_msg[100];
    const char *term_msg;
-   int msg_type;
+   int msg_type = M_INFO;
    double kbps;
 
    Dmsg0(20, "In restore_cleanup\n");
-   dequeue_messages(jcr);            /* display any queued messages */
-   set_jcr_job_status(jcr, TermCode);
+   update_job_end(jcr, TermCode);
 
    if (jcr->unlink_bsr && jcr->RestoreBootstrap) {
       unlink(jcr->RestoreBootstrap);
       jcr->unlink_bsr = false;
    }
 
-   update_job_end_record(jcr);
+   if (job_canceled(jcr)) {
+      cancel_storage_daemon_job(jcr);
+   }  
 
-   msg_type = M_INFO;                /* by default INFO message */
    switch (TermCode) {
    case JS_Terminated:
       if (jcr->ExpectedFiles > jcr->jr.JobFiles) {
@@ -234,21 +261,21 @@ void restore_cleanup(JCR *jcr, int TermCode)
    case JS_FatalError:
    case JS_ErrorTerminated:
       term_msg = _("*** Restore Error ***");
-      msg_type = M_ERROR;         /* Generate error message */
+      msg_type = M_ERROR;          /* Generate error message */
       if (jcr->store_bsock) {
-        bnet_sig(jcr->store_bsock, BNET_TERMINATE);
-        if (jcr->SD_msg_chan) {
-           pthread_cancel(jcr->SD_msg_chan);
-        }
+         jcr->store_bsock->signal(BNET_TERMINATE);
+         if (jcr->SD_msg_chan) {
+            pthread_cancel(jcr->SD_msg_chan);
+         }
       }
       break;
    case JS_Canceled:
       term_msg = _("Restore Canceled");
       if (jcr->store_bsock) {
-        bnet_sig(jcr->store_bsock, BNET_TERMINATE);
-        if (jcr->SD_msg_chan) {
-           pthread_cancel(jcr->SD_msg_chan);
-        }
+         jcr->store_bsock->signal(BNET_TERMINATE);
+         if (jcr->SD_msg_chan) {
+            pthread_cancel(jcr->SD_msg_chan);
+         }
       }
       break;
    default:
@@ -270,10 +297,11 @@ void restore_cleanup(JCR *jcr, int TermCode)
    jobstatus_to_ascii(jcr->FDJobStatus, fd_term_msg, sizeof(fd_term_msg));
    jobstatus_to_ascii(jcr->SDJobStatus, sd_term_msg, sizeof(sd_term_msg));
 
-   Jmsg(jcr, msg_type, 0, _("Bacula " VERSION " (" LSMDATE "): %s\n"
+   Jmsg(jcr, msg_type, 0, _("%s %s %s (%s): %s\n"
+"  Build OS:               %s %s %s\n"
 "  JobId:                  %d\n"
 "  Job:                    %s\n"
-"  Client:                 %s\n"
+"  Restore Client:         %s\n"
 "  Start time:             %s\n"
 "  End time:               %s\n"
 "  Files Expected:         %s\n"
@@ -284,20 +312,21 @@ void restore_cleanup(JCR *jcr, int TermCode)
 "  FD termination status:  %s\n"
 "  SD termination status:  %s\n"
 "  Termination:            %s\n\n"),
-       edt,
-       jcr->jr.JobId,
-       jcr->jr.Job,
-       jcr->client->hdr.name,
-       sdt,
-       edt,
-       edit_uint64_with_commas((uint64_t)jcr->ExpectedFiles, ec1),
-       edit_uint64_with_commas((uint64_t)jcr->jr.JobFiles, ec2),
-       edit_uint64_with_commas(jcr->jr.JobBytes, ec3),
-       (float)kbps,
-       jcr->Errors,
-       fd_term_msg,
-       sd_term_msg,
-       term_msg);
+        BACULA, my_name, VERSION, LSMDATE, edt,
+        HOST_OS, DISTNAME, DISTVER,
+        jcr->jr.JobId,
+        jcr->jr.Job,
+        jcr->client->name(),
+        sdt,
+        edt,
+        edit_uint64_with_commas((uint64_t)jcr->ExpectedFiles, ec1),
+        edit_uint64_with_commas((uint64_t)jcr->jr.JobFiles, ec2),
+        edit_uint64_with_commas(jcr->jr.JobBytes, ec3),
+        (float)kbps,
+        jcr->Errors,
+        fd_term_msg,
+        sd_term_msg,
+        term_msg);
 
    Dmsg0(20, "Leaving restore_cleanup\n");
 }