]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/stored/bcopy.c
First cut of bat rerun a Job from Jobs Run
[bacula/bacula] / bacula / src / stored / bcopy.c
index 73416afbe405088e865ba036b22771cd4b502425..3a10ea02c14367803abe94f9c4a4975beaca55b5 100644 (file)
@@ -1,12 +1,12 @@
 /*
    Bacula® - The Network Backup Solution
 
-   Copyright (C) 2002-2007 Free Software Foundation Europe e.V.
+   Copyright (C) 2002-2010 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
+   modify it under the terms of version three of the GNU Affero General Public
    License as published by the Free Software Foundation and included
    in the file LICENSE.
 
    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
+   You should have received a copy of the GNU Affero 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 John Walker.
+   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.
 
 /* Dummy functions */
 int generate_daemon_event(JCR *jcr, const char *event) { return 1; }
+extern bool parse_sd_config(CONFIG *config, const char *configfile, int exit_code);
 
 /* Forward referenced functions */
+static void get_session_record(DEVICE *dev, DEV_RECORD *rec, SESSION_LABEL *sessrec);
 static bool record_cb(DCR *dcr, DEV_RECORD *rec);
 
 
@@ -52,11 +54,13 @@ static JCR *in_jcr;                    /* input jcr */
 static JCR *out_jcr;                   /* output jcr */
 static BSR *bsr = NULL;
 static const char *wd = "/tmp";
-static int list_records = 0;
+static bool list_records = false;
 static uint32_t records = 0;
 static uint32_t jobs = 0;
 static DEV_BLOCK *out_block;
+static SESSION_LABEL sessrec;
 
+static CONFIG *config;
 #define CONFIG_FILE "bacula-sd.conf"
 char *configfile = NULL;
 STORES *me = NULL;                    /* our Global resource */
@@ -72,7 +76,7 @@ PROG_COPYRIGHT
 "\nVersion: %s (%s)\n\n"
 "Usage: bcopy [-d debug_level] <input-archive> <output-archive>\n"
 "       -b bootstrap      specify a bootstrap file\n"
-"       -c <file>         specify configuration file\n"
+"       -c <file>         specify a Storage configuration file\n"
 "       -d <nn>           set debug level to <nn>\n"
 "       -dt               print timestamp in debug output\n"
 "       -i                specify input Volume names (separated by |)\n"
@@ -90,6 +94,7 @@ int main (int argc, char *argv[])
    char *iVolumeName = NULL;
    char *oVolumeName = NULL;
    bool ignore_label_errors = false;
+   bool ok;
 
    setlocale(LC_ALL, "");
    bindtextdomain("bacula", LOCALEDIR);
@@ -97,6 +102,7 @@ int main (int argc, char *argv[])
    init_stack_dump();
 
    my_name_is(argc, argv, "bcopy");
+   lmgr_init_thread();
    init_msg(NULL, NULL);
 
    while ((ch = getopt(argc, argv, "b:c:d:i:o:pvw:?")) != -1) {
@@ -166,7 +172,8 @@ int main (int argc, char *argv[])
       configfile = bstrdup(CONFIG_FILE);
    }
 
-   parse_config(configfile);
+   config = new_config_parser();
+   parse_sd_config(config, configfile, M_ERROR_TERM);
 
    /* Setup and acquire input device for reading */
    Dmsg0(100, "About to setup input jcr\n");
@@ -205,9 +212,12 @@ int main (int argc, char *argv[])
    }
    out_block = out_jcr->dcr->block;
 
-   read_records(in_jcr->dcr, record_cb, mount_next_read_volume);
-   if (!write_block_to_device(out_jcr->dcr)) {
-      Pmsg0(000, _("Write of last block failed.\n"));
+   ok = read_records(in_jcr->dcr, record_cb, mount_next_read_volume);
+
+   if (ok || out_dev->can_write()) {
+      if (!write_block_to_device(out_jcr->dcr)) {
+         Pmsg0(000, _("Write of last block failed.\n"));
+      }
    }
 
    Pmsg2(000, _("%u Jobs copied. %u records copied.\n"), jobs, records);
@@ -236,6 +246,7 @@ static bool record_cb(DCR *in_dcr, DEV_RECORD *rec)
     *
     */
    if (rec->FileIndex < 0) {
+      get_session_record(in_dcr->dev, rec, &sessrec);
 
       if (verbose > 1) {
          dump_label_record(in_dcr->dev, rec, 1);
@@ -248,9 +259,20 @@ static bool record_cb(DCR *in_dcr, DEV_RECORD *rec)
          Pmsg0(000, _("Volume label not copied.\n"));
          return true;
       case SOS_LABEL:
-         jobs++;
+         if (bsr && rec->match_stat < 1) {
+            /* Skipping record, because does not match BSR filter */
+            if (verbose) {
+             Pmsg0(-1, _("Copy skipped. Record does not match BSR filter.\n"));
+            }
+         } else {
+            jobs++;
+         }
          break;
       case EOS_LABEL:
+         if (bsr && rec->match_stat < 1) {
+            /* Skipping record, because does not match BSR filter */
+           return true;
+        }
          while (!write_record_to_block(out_block, rec)) {
             Dmsg2(150, "!write_record_to_block data_len=%d rem=%d\n", rec->data_len,
                        rec->remainder);
@@ -259,6 +281,7 @@ static bool record_cb(DCR *in_dcr, DEV_RECORD *rec)
                   out_dev->print_name(), out_dev->bstrerror());
                Jmsg(out_jcr, M_FATAL, 0, _("Cannot fixup device error. %s\n"),
                      out_dev->bstrerror());
+               return false;
             }
          }
          if (!write_block_to_device(out_jcr->dcr)) {
@@ -266,8 +289,9 @@ static bool record_cb(DCR *in_dcr, DEV_RECORD *rec)
                out_dev->print_name(), out_dev->bstrerror());
             Jmsg(out_jcr, M_FATAL, 0, _("Cannot fixup device error. %s\n"),
                   out_dev->bstrerror());
+            return false;
          }
-         break;
+         return true;
       case EOM_LABEL:
          Pmsg0(000, _("EOM label not copied.\n"));
          return true;
@@ -275,11 +299,15 @@ static bool record_cb(DCR *in_dcr, DEV_RECORD *rec)
          Pmsg0(000, _("EOT label not copied.\n"));
          return true;
       default:
-         break;
+         return true;
       }
    }
 
    /*  Write record */
+   if (bsr && rec->match_stat < 1) {
+      /* Skipping record, because does not match BSR filter */
+      return true;
+   }
    records++;
    while (!write_record_to_block(out_block, rec)) {
       Dmsg2(150, "!write_record_to_block data_len=%d rem=%d\n", rec->data_len,
@@ -289,23 +317,59 @@ static bool record_cb(DCR *in_dcr, DEV_RECORD *rec)
             out_dev->print_name(), out_dev->bstrerror());
          Jmsg(out_jcr, M_FATAL, 0, _("Cannot fixup device error. %s\n"),
                out_dev->bstrerror());
-         break;
+         return false;
       }
    }
    return true;
 }
 
+static void get_session_record(DEVICE *dev, DEV_RECORD *rec, SESSION_LABEL *sessrec)
+{
+   const char *rtype;
+   memset(sessrec, 0, sizeof(sessrec));
+   switch (rec->FileIndex) {
+   case PRE_LABEL:
+      rtype = _("Fresh Volume Label");
+      break;
+   case VOL_LABEL:
+      rtype = _("Volume Label");
+      unser_volume_label(dev, rec);
+      break;
+   case SOS_LABEL:
+      rtype = _("Begin Job Session");
+      unser_session_label(sessrec, rec);
+      break;
+   case EOS_LABEL:
+      rtype = _("End Job Session");
+      unser_session_label(sessrec, rec);
+      break;
+   case 0:
+   case EOM_LABEL:
+      rtype = _("End of Medium");
+      break;
+   default:
+      rtype = _("Unknown");
+      break;
+   }
+   Dmsg5(10, "%s Record: VolSessionId=%d VolSessionTime=%d JobId=%d DataLen=%d\n",
+         rtype, rec->VolSessionId, rec->VolSessionTime, rec->Stream, rec->data_len);
+   if (verbose) {
+      Pmsg5(-1, _("%s Record: VolSessionId=%d VolSessionTime=%d JobId=%d DataLen=%d\n"),
+            rtype, rec->VolSessionId, rec->VolSessionTime, rec->Stream, rec->data_len);
+   }
+}
+
 
 /* Dummies to replace askdir.c */
 bool    dir_find_next_appendable_volume(DCR *dcr) { return 1;}
-bool    dir_update_volume_info(DCR *dcr, bool relabel) { return 1; }
-bool    dir_create_jobmedia_record(DCR *dcr) { return 1; }
+bool    dir_update_volume_info(DCR *dcr, bool relabel, bool update_LastWritten) { return 1; }
+bool    dir_create_jobmedia_record(DCR *dcr, bool zero) { return 1; }
 bool    dir_ask_sysop_to_create_appendable_volume(DCR *dcr) { return 1; }
 bool    dir_update_file_attributes(DCR *dcr, DEV_RECORD *rec) { return 1;}
 bool    dir_send_job_status(JCR *jcr) {return 1;}
 
 
-bool dir_ask_sysop_to_mount_volume(DCR *dcr)
+bool dir_ask_sysop_to_mount_volume(DCR *dcr, int /*mode*/)
 {
    DEVICE *dev = dcr->dev;
    fprintf(stderr, _("Mount Volume \"%s\" on device %s and press return when ready: "),
@@ -318,8 +382,8 @@ bool dir_ask_sysop_to_mount_volume(DCR *dcr)
 bool dir_get_volume_info(DCR *dcr, enum get_vol_info_rw  writing)
 {
    Dmsg0(100, "Fake dir_get_volume_info\n");
-   bstrncpy(dcr->VolCatInfo.VolCatName, dcr->VolumeName, sizeof(dcr->VolCatInfo.VolCatName));
+   dcr->setVolCatName(dcr->VolumeName);
    dcr->VolCatInfo.VolCatParts = find_num_dvd_parts(dcr);
-   Dmsg2(500, "Vol=%s num_parts=%d\n", dcr->VolCatInfo.VolCatName, dcr->VolCatInfo.VolCatParts);
+   Dmsg2(500, "Vol=%s num_parts=%d\n", dcr->getVolCatName(), dcr->VolCatInfo.VolCatParts);
    return 1;
 }