]> git.sur5r.net Git - bacula/bacula/commitdiff
- Corrected some typos in the make_xxx_tables.in files.
authorKern Sibbald <kern@sibbald.com>
Mon, 28 Feb 2005 14:02:09 +0000 (14:02 +0000)
committerKern Sibbald <kern@sibbald.com>
Mon, 28 Feb 2005 14:02:09 +0000 (14:02 +0000)
- Made preliminary split of pre-run and run code for each
  job type. This will permit early opening of SD for reserving
  drives.
- Add offline and autochanger fields to Device Query record.
- Correct pthread_mutex_init() for autochanger in SD.
- Tweak Makefile for LaTeX manual, plus add nav buttons.

git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@1850 91ce42f0-d328-0410-95d8-f526ca767f89

24 files changed:
bacula/kernstodo
bacula/src/cats/make_mysql_tables.in
bacula/src/cats/make_postgresql_tables.in
bacula/src/cats/make_sqlite3_tables.in
bacula/src/cats/make_sqlite_tables.in
bacula/src/cats/update_mysql_tables.in
bacula/src/cats/update_sqlite3_tables.in
bacula/src/cats/update_sqlite_tables.in
bacula/src/dird/admin.c
bacula/src/dird/backup.c
bacula/src/dird/dird.c
bacula/src/dird/dird_conf.c
bacula/src/dird/dird_conf.h
bacula/src/dird/job.c
bacula/src/dird/mac.c
bacula/src/dird/msgchan.c
bacula/src/dird/protos.h
bacula/src/dird/restore.c
bacula/src/dird/verify.c
bacula/src/jcr.h
bacula/src/stored/dev.h
bacula/src/stored/job.c
bacula/src/stored/stored_conf.c
bacula/src/version.h

index 29521136d20d472a67f5732eef0eb6db33607fb9..02418f11408cd4abae1323de888fe6175f46247a 100644 (file)
@@ -30,6 +30,10 @@ Suggestions for Preben:
 - Optimized bootstrap.
 
 For 1.37:
+- Linux Sony LIB-D81, AIT-3 library works.
+- If Bacula does not find the right tape in the Autochanger,
+  then mark the tape in error and move on rather than asking
+  for operator intervention.
 - Device resource needs the "name" of the SD.
 - Add and option to see if the file size changed
   during backup.
index 6f7d0b6d68dda4edd16ecf4bef7e94aa33c0473c..41ef3eff80a82ad704ea5bcc05d658bbb1621d97 100644 (file)
@@ -138,12 +138,19 @@ CREATE TABLE Media (
 CREATE INDEX inx8 ON Media (PoolId);
 
 CREATE TABLE MediaType (
-   MediaTypeId INTERGER UNSIGNED NOT NULL AUTO_INCREMENT,
+   MediaTypeId INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
    MediaType VARCHAR(128) NOT NULL,
    ReadOnly TINYINT DEFAULT 0,
    PRIMARY KEY(MediaTypeId)
    );
 
+CREATE TABLE Storage (
+   StorageId INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
+   Name VARCHAR(128) NOT NULL,
+   AutoChanger TINYINT DEFAULT 0,
+   PRIMARY KEY(StorageId)
+   );
+
 CREATE TABLE Device (
    DeviceId INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
    Name VARCHAR(128) NOT NULL,
@@ -163,12 +170,6 @@ CREATE TABLE Device (
    PRIMARY KEY(DeviceId)
    );
 
-CREATE TABLE Storage (
-   StorageId INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
-   Name VARCHAR(128) NOT NULL,
-   AutoChanger TINYINT DEFAULT 0,
-   PRIMARY KEY(StorageId)
-   );
 
 CREATE TABLE Pool (
    PoolId INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
index b1e759bb2c76bb389955fbd8b61ae08b2698c00d..f990fdcecccb6bf864e05411645b16d22bfdaa6d 100644 (file)
@@ -154,6 +154,13 @@ CREATE TABLE MediaType (
    PRIMARY KEY(MediaTypeId)
    );
 
+CREATE TABLE Storage (
+   StorageId SERIAL,
+   Name TEXT NOT NULL,
+   AutoChanger INTEGER DEFAULT 0,
+   PRIMARY KEY(StorageId)
+   );
+
 CREATE TABLE Device (
    DeviceId SERIAL,
    Name TEXT NOT NULL,
@@ -173,12 +180,6 @@ CREATE TABLE Device (
    PRIMARY KEY(DeviceId)
    );
 
-CREATE TABLE Storage (
-   StorageId SERIAL,
-   Name TEXT NOT NULL,
-   AutoChanger INTEGER DEFAULT 0,
-   PRIMARY KEY(StorageId)
-   );
 
 CREATE TABLE pool
 (
index 7bd3bd4b9763dd2a0e55eb54ede6bf544b7c0d6f..83dfb0e117eecb4bb53bcecbf1a8c290425fd174 100644 (file)
@@ -137,12 +137,19 @@ CREATE TABLE Media (
 CREATE INDEX inx8 ON Media (PoolId);
 
 CREATE TABLE MediaType (
-   MediaTypeId INTERGER,
+   MediaTypeId INTEGER,
    MediaType VARCHAR(128) NOT NULL,
    ReadOnly TINYINT DEFAULT 0,
    PRIMARY KEY(MediaTypeId)
    );
 
+CREATE TABLE Storage (
+   StorageId INTEGER,
+   Name VARCHAR(128) NOT NULL,
+   AutoChanger TINYINT DEFAULT 0,
+   PRIMARY KEY(StorageId)
+   );
+
 CREATE TABLE Device (
    DeviceId INTEGER,
    Name VARCHAR(128) NOT NULL,
@@ -162,13 +169,6 @@ CREATE TABLE Device (
    PRIMARY KEY(DeviceId)
    );
 
-CREATE TABLE Storage (
-   StorageId INTEGER,
-   Name VARCHAR(128) NOT NULL,
-   AutoChanger TINYINT DEFAULT 0,
-   PRIMARY KEY(StorageId)
-   );
-
 
 CREATE TABLE Pool (
    PoolId INTEGER,
index 7bd3bd4b9763dd2a0e55eb54ede6bf544b7c0d6f..83dfb0e117eecb4bb53bcecbf1a8c290425fd174 100644 (file)
@@ -137,12 +137,19 @@ CREATE TABLE Media (
 CREATE INDEX inx8 ON Media (PoolId);
 
 CREATE TABLE MediaType (
-   MediaTypeId INTERGER,
+   MediaTypeId INTEGER,
    MediaType VARCHAR(128) NOT NULL,
    ReadOnly TINYINT DEFAULT 0,
    PRIMARY KEY(MediaTypeId)
    );
 
+CREATE TABLE Storage (
+   StorageId INTEGER,
+   Name VARCHAR(128) NOT NULL,
+   AutoChanger TINYINT DEFAULT 0,
+   PRIMARY KEY(StorageId)
+   );
+
 CREATE TABLE Device (
    DeviceId INTEGER,
    Name VARCHAR(128) NOT NULL,
@@ -162,13 +169,6 @@ CREATE TABLE Device (
    PRIMARY KEY(DeviceId)
    );
 
-CREATE TABLE Storage (
-   StorageId INTEGER,
-   Name VARCHAR(128) NOT NULL,
-   AutoChanger TINYINT DEFAULT 0,
-   PRIMARY KEY(StorageId)
-   );
-
 
 CREATE TABLE Pool (
    PoolId INTEGER,
index aeb5cde41894528832bcbd5cc033e9f32f8fe89e..f86c0484efa58ef3eca50edaa7e83e9d263eebb1 100755 (executable)
@@ -29,6 +29,13 @@ CREATE TABLE MediaType (
    PRIMARY KEY(MediaTypeId)
    );
 
+CREATE TABLE Storage (
+   StorageId INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
+   Name VARCHAR(128) NOT NULL,
+   AutoChanger TINYINT DEFAULT 0,
+   PRIMARY KEY(StorageId)
+   );
+
 CREATE TABLE Device (
    DeviceId INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
    Name VARCHAR(128) NOT NULL,
@@ -48,13 +55,6 @@ CREATE TABLE Device (
    PRIMARY KEY(DeviceId)
    );
 
-CREATE TABLE Storage (
-   StorageId INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
-   Name VARCHAR(128) NOT NULL,
-   AutoChanger TINYINT DEFAULT 0,
-   PRIMARY KEY(StorageId)
-   );
-
 END-OF-DATA
 then
    echo "Update of Bacula MySQL tables succeeded."
index fc863e19d990e67f4cd1f47495da551bd6128c04..b4e4c355135118032fb5e1c412ff0532c3cb9712 100755 (executable)
@@ -204,6 +204,13 @@ CREATE TABLE MediaType (
    PRIMARY KEY(MediaTypeId)
    );
 
+CREATE TABLE Storage (
+   StorageId INTEGER,
+   Name VARCHAR(128) NOT NULL,
+   AutoChanger TINYINT DEFAULT 0,
+   PRIMARY KEY(StorageId)
+   );
+
 CREATE TABLE Device (
    DeviceId INTEGER,
    Name VARCHAR(128) NOT NULL,
@@ -223,13 +230,6 @@ CREATE TABLE Device (
    PRIMARY KEY(DeviceId)
    );
 
-CREATE TABLE Storage (
-   StorageId INTEGER,
-   Name VARCHAR(128) NOT NULL,
-   AutoChanger TINYINT DEFAULT 0,
-   PRIMARY KEY(StorageId)
-   );
-
 COMMIT;
 
 END-OF-DATA
index fc863e19d990e67f4cd1f47495da551bd6128c04..b409ee050def3e84b9852ea0a0844f2e35bd30b9 100755 (executable)
@@ -198,12 +198,19 @@ INSERT INTO Pool (
 DROP TABLE Pool_backup;
 
 CREATE TABLE MediaType (
-   MediaTypeId INTERGER,
+   MediaTypeId INTEGER,
    MediaType VARCHAR(128) NOT NULL,
    ReadOnly TINYINT DEFAULT 0,
    PRIMARY KEY(MediaTypeId)
    );
 
+CREATE TABLE Storage (
+   StorageId INTEGER,
+   Name VARCHAR(128) NOT NULL,
+   AutoChanger TINYINT DEFAULT 0,
+   PRIMARY KEY(StorageId)
+   );
+
 CREATE TABLE Device (
    DeviceId INTEGER,
    Name VARCHAR(128) NOT NULL,
@@ -223,12 +230,6 @@ CREATE TABLE Device (
    PRIMARY KEY(DeviceId)
    );
 
-CREATE TABLE Storage (
-   StorageId INTEGER,
-   Name VARCHAR(128) NOT NULL,
-   AutoChanger TINYINT DEFAULT 0,
-   PRIMARY KEY(StorageId)
-   );
 
 COMMIT;
 
index f85636ef4ae15cc400470c7e4f4113188fdb0496..19d067e6b2de275295a1a752d5f3188ca48c6dd6 100644 (file)
 #include "ua.h"
 
 
-/* Forward referenced functions */
-static void admin_cleanup(JCR *jcr, int TermCode);
-
-/* External functions */
+bool do_admin_init(JCR *jcr)
+{
+   return true;
+}
 
 /*
- *  Returns:  0 on failure
- *           1 on success
+ *  Returns:  false on failure
+ *           true  on success
  */
-int do_admin(JCR *jcr)
+bool do_admin(JCR *jcr)
 {
 
    jcr->jr.JobId = jcr->JobId;
@@ -57,13 +57,14 @@ int do_admin(JCR *jcr)
 
    set_jcr_job_status(jcr, JS_Running);
    admin_cleanup(jcr, JS_Terminated);
-   return 0;
+   return true;
 }
 
+
 /*
  * Release resources allocated during backup.
  */
-static void admin_cleanup(JCR *jcr, int TermCode)
+void admin_cleanup(JCR *jcr, int TermCode)
 {
    char sdt[50], edt[50];
    char term_code[100];
index 991f0ca98fc4ef04f553e8cc8b8ef708e629aa61..ecf379b1cd129921950d30839ed95b5fec7fc8cd 100644 (file)
@@ -48,35 +48,14 @@ static char OKstore[]    = "2000 OK storage\n";
 static char EndJob[]     = "2800 End Job TermCode=%d JobFiles=%u "
                            "ReadBytes=%lld JobBytes=%lld Errors=%u\n";
 
-
-/* Forward referenced functions */
-static void backup_cleanup(JCR *jcr, int TermCode, char *since, FILESET_DBR *fsr);
-
-/* External functions */
-
-/*
- * Do a backup of the specified FileSet
- *
- *  Returns:  0 on failure
- *           1 on success
+/* 
+ * Called here before the job is run to do the job
+ *   specific setup.
  */
-int do_backup(JCR *jcr)
+bool do_backup_init(JCR *jcr)
 {
-   char since[MAXSTRING];
-   int stat;
-   BSOCK   *fd;
-   POOL_DBR pr;
    FILESET_DBR fsr;
-   STORE *store;
-
-   since[0] = 0;
-
-   if (!get_or_create_fileset_record(jcr, &fsr)) {
-      goto bail_out;
-   }
-
-   get_level_since_time(jcr, since, sizeof(since));
-
+   POOL_DBR pr;
    /*
     * Get the Pool record -- first apply any level defined pools
     */
@@ -100,19 +79,48 @@ int do_backup(JCR *jcr)
    memset(&pr, 0, sizeof(pr));
    bstrncpy(pr.Name, jcr->pool->hdr.name, sizeof(pr.Name));
 
-   while (!db_get_pool_record(jcr, jcr->db, &pr)) { /* get by Name */
+   if (!db_get_pool_record(jcr, jcr->db, &pr)) { /* get by Name */
       /* Try to create the pool */
       if (create_pool(jcr, jcr->db, jcr->pool, POOL_OP_CREATE) < 0) {
          Jmsg(jcr, M_FATAL, 0, _("Pool %s not in database. %s"), pr.Name,
            db_strerror(jcr->db));
-        goto bail_out;
+        return false;
       } else {
          Jmsg(jcr, M_INFO, 0, _("Pool %s created in database.\n"), pr.Name);
+        if (!db_get_pool_record(jcr, jcr->db, &pr)) { /* get by Name */
+            Jmsg(jcr, M_FATAL, 0, _("Pool %s not in database. %s"), pr.Name,
+              db_strerror(jcr->db));
+           return false;
+        }
       }
    }
    jcr->PoolId = pr.PoolId;              /****FIXME**** this can go away */
    jcr->jr.PoolId = pr.PoolId;
 
+   jcr->since[0] = 0;
+
+   if (!get_or_create_fileset_record(jcr, &fsr)) {
+      return false;
+   }
+   bstrncpy(jcr->FSCreateTime, fsr.cCreateTime, sizeof(jcr->FSCreateTime));
+
+   get_level_since_time(jcr, jcr->since, sizeof(jcr->since));
+
+   return true;
+}
+
+/*
+ * Do a backup of the specified FileSet
+ *
+ *  Returns:  false on failure
+ *           true  on success
+ */
+bool do_backup(JCR *jcr)
+{
+   int stat;
+   BSOCK   *fd;
+   STORE *store;
+
 
    /* Print Job Start message */
    Jmsg(jcr, M_INFO, 0, _("Start Backup JobId %u, Job=%s\n"),
@@ -122,7 +130,7 @@ int do_backup(JCR *jcr)
    Dmsg2(100, "JobId=%d JobLevel=%c\n", jcr->jr.JobId, jcr->jr.JobLevel);
    if (!db_update_job_start_record(jcr, jcr->db, &jcr->jr)) {
       Jmsg(jcr, M_FATAL, 0, "%s", db_strerror(jcr->db));
-      goto bail_out;
+      return false;
    }
 
    /*
@@ -137,40 +145,40 @@ int do_backup(JCR *jcr)
     * Start conversation with Storage daemon
     */
    if (!connect_to_storage_daemon(jcr, 10, SDConnectTimeout, 1)) {
-      goto bail_out;
+      return false;
    }
    /*
     * Now start a job with the Storage daemon
     */
    if (!start_storage_daemon_job(jcr, jcr->storage, SD_APPEND)) {
-      goto bail_out;
+      return false;
    }
    /*
     * Now start a Storage daemon message thread
     */
    if (!start_storage_daemon_message_thread(jcr)) {
-      goto bail_out;
+      return false;
    }
    Dmsg0(150, "Storage daemon connection OK\n");
 
    set_jcr_job_status(jcr, JS_WaitFD);
    if (!connect_to_file_daemon(jcr, 10, FDConnectTimeout, 1)) {
-      goto bail_out;
+      return false;
    }
 
    set_jcr_job_status(jcr, JS_Running);
    fd = jcr->file_bsock;
 
    if (!send_include_list(jcr)) {
-      goto bail_out;
+      return false;
    }
 
    if (!send_exclude_list(jcr)) {
-      goto bail_out;
+      return false;
    }
 
    if (!send_level_command(jcr)) {
-      goto bail_out;
+      return false;
    }
 
    /*
@@ -183,30 +191,27 @@ int do_backup(JCR *jcr)
    bnet_fsend(fd, storaddr, store->address, store->SDDport,
              store->enable_ssl);
    if (!response(jcr, fd, OKstore, "Storage", DISPLAY_ERROR)) {
-      goto bail_out;
+      return false;
    }
 
 
    if (!send_run_before_and_after_commands(jcr)) {
-      goto bail_out;
+      return false;
    }
 
    /* Send backup command */
    bnet_fsend(fd, backupcmd);
    if (!response(jcr, fd, OKbackup, "backup", DISPLAY_ERROR)) {
-      goto bail_out;
+      return false;
    }
 
    /* Pickup Job termination data */
    stat = wait_for_job_termination(jcr);
-   backup_cleanup(jcr, stat, since, &fsr);
-   return 1;
-
-bail_out:
-   backup_cleanup(jcr, JS_ErrorTerminated, since, &fsr);
-   return 0;
+   backup_cleanup(jcr, stat);
+   return stat == JS_Terminated;
 }
 
+
 /*
  * Here we wait for the File daemon to signal termination,
  *   then we wait for the Storage daemon.  When both
@@ -276,7 +281,7 @@ int wait_for_job_termination(JCR *jcr)
 /*
  * Release resources allocated during backup.
  */
-static void backup_cleanup(JCR *jcr, int TermCode, char *since, FILESET_DBR *fsr)
+void backup_cleanup(JCR *jcr, int TermCode)
 {
    char sdt[50], edt[50];
    char ec1[30], ec2[30], ec3[30], ec4[30], ec5[30], compress[50];
@@ -464,9 +469,9 @@ static void backup_cleanup(JCR *jcr, int TermCode, char *since, FILESET_DBR *fsr
        edt,
        jcr->jr.JobId,
        jcr->jr.Job,
-       level_to_str(jcr->JobLevel), since,
+       level_to_str(jcr->JobLevel), jcr->since,
        jcr->client->hdr.name,
-       jcr->fileset->hdr.name, fsr->cCreateTime,
+       jcr->fileset->hdr.name, jcr->FSCreateTime,
        jcr->pool->hdr.name,
        jcr->store->hdr.name,
        sdt,
index 431583aa2dd899ed6354c597f7d95a616a28d4a9..7bf2c4b78dcaf07a0cfc6532bc2a3b4b578659c4 100644 (file)
@@ -42,8 +42,6 @@ extern "C" void reload_config(int sig);
 JCR *wait_for_next_job(char *runjob);
 void term_scheduler();
 void term_ua_server();
-int do_backup(JCR *jcr);
-void backup_cleanup(void);
 void start_UA_server(dlist *addrs);
 void init_job_server(int max_workers);
 void term_job_server();
index 99d9006c4cd7da0fa2c77e9695a22fc6f1d49ab5..25c2ecac89616d47f09e51af7de72f5718b1d637 100644 (file)
@@ -472,10 +472,11 @@ void dump_resource(int type, RES *reshdr, void sendit(void *sock, const char *fm
    case R_DEVICE:
       dev = &res->res_dev;
       sendit(sock, "Device: name=%s ok=%d num_writers=%d num_waiting=%d\n"
-"      use_cnt=%d open=%d append=%d read=%d labeled=%d\n"
+"      use_cnt=%d open=%d append=%d read=%d labeled=%d offline=%d autochgr=%d\n"
 "      volname=%s MediaType=%s\n",
         dev->hdr.name, dev->found, dev->num_writers, dev->num_waiting,
         dev->use_count, dev->open, dev->append, dev->read, dev->labeled,
+        dev->offline, dev->autochanger,
         dev->VolumeName, dev->MediaType);
       break;
    case R_STORAGE:
index 745dd554e2e51177e501714ec3b02953fbc206d2..19cc0983309bedfd789cdf6aa6c76f048325f8c9 100644 (file)
@@ -131,6 +131,8 @@ public:
    bool append;                       /* in append mode */
    bool read;
    bool labeled;
+   bool autochanger;
+   bool offline;
    char VolumeName[MAX_NAME_LENGTH];
    char MediaType[MAX_NAME_LENGTH];
 };
index da1d5d29aeda56df1ed1cf9920f75e85a5963989..fa2608f13ade60380c20ccbc2ee8b87edacf768e 100644 (file)
@@ -41,11 +41,6 @@ static bool job_check_maxruntime(JCR *control_jcr, JCR *jcr);
 /* Imported subroutines */
 extern void term_scheduler();
 extern void term_ua_server();
-extern int do_backup(JCR *jcr);
-extern bool do_mac(JCR *jcr);
-extern int do_admin(JCR *jcr);
-extern int do_restore(JCR *jcr);
-extern bool do_verify(JCR *jcr);
 
 /* Imported variables */
 extern time_t watchdog_time;
@@ -143,6 +138,44 @@ JobId_t run_job(JCR *jcr)
       jcr->fname = get_pool_memory(PM_FNAME);
    }
 
+   /* Now, do pre-run stuff, like setting job level (Inc/diff, ...) */
+   switch (jcr->JobType) {
+   case JT_BACKUP:
+      if (!do_backup_init(jcr)) {
+        backup_cleanup(jcr, JS_ErrorTerminated);
+      }
+      break;
+   case JT_VERIFY:
+      if (!do_verify_init(jcr)) {
+        verify_cleanup(jcr, JS_ErrorTerminated);
+      }
+      break;
+   case JT_RESTORE:
+      if (!do_restore_init(jcr)) {
+        restore_cleanup(jcr, JS_ErrorTerminated);
+      }
+      break;
+   case JT_ADMIN:
+      if (!do_admin_init(jcr)) {
+        admin_cleanup(jcr, JS_ErrorTerminated);
+      }
+      break;
+   case JT_MIGRATION:
+   case JT_COPY:
+   case JT_ARCHIVE:
+      if (!do_mac_init(jcr)) {            /* migration, archive, copy */
+        mac_cleanup(jcr, JS_ErrorTerminated);
+      }
+      break;
+   default:
+      Pmsg1(0, "Unimplemented job type: %d\n", jcr->JobType);
+      set_jcr_job_status(jcr, JS_ErrorTerminated);
+      break;
+   }
+   if (job_canceled(jcr)) {
+      goto bail_out;
+   }
+
    Dmsg0(200, "Add jrc to work queue\n");
 
    /* Queue the job to be run */
@@ -158,7 +191,10 @@ JobId_t run_job(JCR *jcr)
    return JobId;
 
 bail_out:
-   set_jcr_job_status(jcr, JS_ErrorTerminated);
+   if (jcr->fname) {
+      free_memory(jcr->fname);
+      jcr->fname = NULL;
+   }
    V(jcr->mutex);
    return JobId;
 
@@ -222,35 +258,40 @@ static void *job_thread(void *arg)
         }
         switch (jcr->JobType) {
         case JT_BACKUP:
-           do_backup(jcr);
-           if (jcr->JobStatus == JS_Terminated) {
+           if (do_backup(jcr)) {
               do_autoprune(jcr);
+           } else {
+              backup_cleanup(jcr, JS_ErrorTerminated);
            }
            break;
         case JT_VERIFY:
-           do_verify(jcr);
-           if (jcr->JobStatus == JS_Terminated) {
+           if (do_verify(jcr)) {
               do_autoprune(jcr);
+           } else {
+              verify_cleanup(jcr, JS_ErrorTerminated);
            }
            break;
         case JT_RESTORE:
-           do_restore(jcr);
-           if (jcr->JobStatus == JS_Terminated) {
+           if (do_restore(jcr)) {
               do_autoprune(jcr);
+           } else {
+              restore_cleanup(jcr, JS_ErrorTerminated);
            }
            break;
         case JT_ADMIN:
-           do_admin(jcr);
-           if (jcr->JobStatus == JS_Terminated) {
+           if (do_admin(jcr)) {
               do_autoprune(jcr);
+           } else {
+              admin_cleanup(jcr, JS_ErrorTerminated);
            }
            break;
         case JT_MIGRATION:
         case JT_COPY:
         case JT_ARCHIVE:
-           do_mac(jcr);              /* migration, archive, copy */
-           if (jcr->JobStatus == JS_Terminated) {
+           if (do_mac(jcr)) {              /* migration, archive, copy */
               do_autoprune(jcr);
+           } else {
+              mac_cleanup(jcr, JS_ErrorTerminated);
            }
            break;
         default:
index e385204a958f6a89fba2e9124a9f9c82d9bd7650..7946828696f23ea54ad37860ec71fb4cb245a449 100644 (file)
 #include "dird.h"
 #include "ua.h"
 
-/* Forward referenced functions */
-static void mac_cleanup(JCR *jcr, int TermCode, char *since, FILESET_DBR *fsr,
-                       const char *Type);
-
-/* External functions */
-
-/*
- * Do a Migration, Archive, or Copy of a previous job
- *
- *  Returns:  false on failure
- *           true  on success
+/* 
+ * Called here before the job is run to do the job
+ *   specific setup.
  */
-bool do_mac(JCR *jcr)
+bool do_mac_init(JCR *jcr)
 {
-   char since[MAXSTRING];
-   int stat;
+   FILESET_DBR fsr;
    POOL_DBR pr;
    JOB_DBR jr;
-   FILESET_DBR fsr;
    JobId_t input_jobid;
    char *Name;
-   const char *Type;
-
-   switch(jcr->JobType) {
-   case JT_MIGRATION:
-      Type = "Migration";
-      break;
-   case JT_ARCHIVE:
-      Type = "Archive";
-      break;
-   case JT_COPY:
-      Type = "Copy";
-      break;
-   default:
-      Type = "Unknown";
-      break;
-   }
 
    if (!get_or_create_fileset_record(jcr, &fsr)) {
-      goto bail_out;
+      return false;
    }
+   bstrncpy(jcr->FSCreateTime, fsr.cCreateTime, sizeof(jcr->FSCreateTime));
 
    /*
     * Find JobId of last job that ran.
@@ -90,7 +65,7 @@ bool do_mac(JCR *jcr)
    if (!db_find_last_jobid(jcr, jcr->db, Name, &jr)) {
       Jmsg(jcr, M_FATAL, 0, _(
            "Unable to find JobId of previous Job for this client.\n"));
-      goto bail_out;
+      return false;
    }
    input_jobid = jr.JobId;
    jcr->JobLevel = jr.JobLevel;
@@ -124,13 +99,42 @@ bool do_mac(JCR *jcr)
       if (create_pool(jcr, jcr->db, jcr->pool, POOL_OP_CREATE) < 0) {
          Jmsg(jcr, M_FATAL, 0, _("Pool %s not in database. %s"), pr.Name,
            db_strerror(jcr->db));
-        goto bail_out;
+        return false;
       } else {
          Jmsg(jcr, M_INFO, 0, _("Pool %s created in database.\n"), pr.Name);
       }
    }
    jcr->PoolId = pr.PoolId;              /****FIXME**** this can go away */
    jcr->jr.PoolId = pr.PoolId;
+   jcr->needs_sd = true;
+   return true;
+}
+
+/*
+ * Do a Migration, Archive, or Copy of a previous job
+ *
+ *  Returns:  false on failure
+ *           true  on success
+ */
+bool do_mac(JCR *jcr)
+{
+   int stat;
+   const char *Type;
+
+   switch(jcr->JobType) {
+   case JT_MIGRATION:
+      Type = "Migration";
+      break;
+   case JT_ARCHIVE:
+      Type = "Archive";
+      break;
+   case JT_COPY:
+      Type = "Copy";
+      break;
+   default:
+      Type = "Unknown";
+      break;
+   }
 
 
    /* Print Job Start message */
@@ -141,7 +145,7 @@ bool do_mac(JCR *jcr)
    Dmsg2(100, "JobId=%d JobLevel=%c\n", jcr->jr.JobId, jcr->jr.JobLevel);
    if (!db_update_job_start_record(jcr, jcr->db, &jcr->jr)) {
       Jmsg(jcr, M_FATAL, 0, "%s", db_strerror(jcr->db));
-      goto bail_out;
+      return false;
    }
 
    /*
@@ -156,19 +160,19 @@ bool do_mac(JCR *jcr)
     * Start conversation with Storage daemon
     */
    if (!connect_to_storage_daemon(jcr, 10, SDConnectTimeout, 1)) {
-      goto bail_out;
+      return false;
    }
    /*
     * Now start a job with the Storage daemon
     */
    if (!start_storage_daemon_job(jcr, jcr->storage, SD_APPEND)) {
-      goto bail_out;
+      return false;
    }
    /*
     * Now start a Storage daemon message thread
     */
    if (!start_storage_daemon_message_thread(jcr)) {
-      goto bail_out;
+      return false;
    }
    Dmsg0(150, "Storage daemon connection OK\n");
 
@@ -183,20 +187,15 @@ bool do_mac(JCR *jcr)
    } else {
       stat = jcr->SDJobStatus;
    }
-   mac_cleanup(jcr, stat, since, &fsr, Type);
-   return true;
-
-bail_out:
-   mac_cleanup(jcr, JS_ErrorTerminated, since, &fsr, Type);
-   return false;
+   mac_cleanup(jcr, stat);
+   return jcr->JobStatus == JS_Terminated;
 }
 
 
 /*
  * Release resources allocated during backup.
  */
-static void mac_cleanup(JCR *jcr, int TermCode, char *since, FILESET_DBR *fsr,
-                      const char *Type)
+void mac_cleanup(JCR *jcr, int TermCode)
 {
    char sdt[50], edt[50];
    char ec1[30], ec2[30], ec3[30], ec4[30], ec5[30], compress[50];
@@ -206,6 +205,22 @@ static void mac_cleanup(JCR *jcr, int TermCode, char *since, FILESET_DBR *fsr,
    MEDIA_DBR mr;
    double kbps, compression;
    utime_t RunTime;
+   const char *Type;
+
+   switch(jcr->JobType) {
+   case JT_MIGRATION:
+      Type = "Migration";
+      break;
+   case JT_ARCHIVE:
+      Type = "Archive";
+      break;
+   case JT_COPY:
+      Type = "Copy";
+      break;
+   default:
+      Type = "Unknown";
+      break;
+   }
 
    Dmsg2(100, "Enter mac_cleanup %d %c\n", TermCode, TermCode);
    dequeue_messages(jcr);            /* display any queued messages */
@@ -383,9 +398,9 @@ static void mac_cleanup(JCR *jcr, int TermCode, char *since, FILESET_DBR *fsr,
        edt,
        jcr->jr.JobId,
        jcr->jr.Job,
-       level_to_str(jcr->JobLevel), since,
+       level_to_str(jcr->JobLevel), jcr->since,
        jcr->client->hdr.name,
-       jcr->fileset->hdr.name, fsr->cCreateTime,
+       jcr->fileset->hdr.name, jcr->FSCreateTime,
        jcr->pool->hdr.name,
        sdt,
        edt,
index f0d4cf84427add19c51eba7946719304ae77a010..5461d466ba7ad67c016939db185c0fef97288e81 100644 (file)
@@ -50,7 +50,7 @@ static char query_device[] = "query device=%s";
 static char OKjob[]      = "3000 OK Job SDid=%d SDtime=%d Authorization=%100s\n";
 static char OK_device[]  = "3000 OK use device\n";
 static char OK_query[]  = "3001 OK query append=%d read=%d num_writers=%d "
-   "num_waiting=%d open=%d use_count=%d labeled=%d "
+   "num_waiting=%d open=%d use_count=%d labeled=%d offline=%d autochanger=%d "
    "media_type=%127s volume_name=%127s";
 
 /* Storage Daemon requests */
@@ -106,6 +106,7 @@ bool update_device_res(JCR *jcr, DEVICE *dev)
 {
    POOL_MEM device_name, media_type, volume_name;
    int dev_open, dev_append, dev_read, dev_labeled;
+   int dev_offline, dev_autochanger;
    BSOCK *sd;
    if (!connect_to_storage_daemon(jcr, 5, 30, 0)) {
       return false;
@@ -118,8 +119,9 @@ bool update_device_res(JCR *jcr, DEVICE *dev)
       Dmsg1(400, "<stored: %s", sd->msg);
       if (sscanf(sd->msg, OK_query, &dev_append, &dev_read,
          &dev->num_writers, &dev->num_waiting, &dev_open,
-         &dev->use_count, &dev_labeled, media_type.c_str(),
-         volume_name.c_str()) != 9) {
+         &dev->use_count, &dev_labeled, &dev_offline,  
+         &dev_autochanger,  media_type.c_str(),
+         volume_name.c_str()) != 11) {
         return false;
       }
       unbash_spaces(media_type);
@@ -130,6 +132,8 @@ bool update_device_res(JCR *jcr, DEVICE *dev)
       dev->append = dev_append;
       dev->read = dev_read;
       dev->labeled = dev_labeled;
+      dev->offline = dev_offline;
+      dev->autochanger = dev_autochanger;
       dev->found = true;
    } else {
       return false;
index e220d9eaf44985ac15a021314008b36d36b4a5dd..66ad717f99ef86b5ccd62da1c599b90e4ff4813c 100644 (file)
@@ -4,7 +4,7 @@
  *   Version $Id$
  */
 /*
-   Copyright (C) 2000-2004 Kern Sibbald and John Walker
+   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 as
 
  */
 
+/* admin.c */
+extern bool do_admin_init(JCR *jcr);
+extern bool do_admin(JCR *jcr);
+extern void admin_cleanup(JCR *jcr, int TermCode);
+
+
 /* authenticate.c */
 extern bool authenticate_storage_daemon(JCR *jcr, STORE *store);
 extern int authenticate_file_daemon(JCR *jcr);
@@ -39,6 +45,9 @@ extern int find_recycled_volume(JCR *jcr, bool InChanger, MEDIA_DBR *mr);
 
 /* backup.c */
 extern int wait_for_job_termination(JCR *jcr);
+extern bool do_backup_init(JCR *jcr);
+extern bool do_backup(JCR *jcr);
+extern void backup_cleanup(JCR *jcr, int TermCode);
 
 /* bsr.c */
 RBSR *new_bsr();
@@ -63,7 +72,7 @@ int variable_expansion(JCR *jcr, char *inp, POOLMEM **exp);
 
 /* fd_cmds.c */
 extern int connect_to_file_daemon(JCR *jcr, int retry_interval,
-                                 int max_retry_time, int verbose);
+                                  int max_retry_time, int verbose);
 extern int send_include_list(JCR *jcr);
 extern int send_exclude_list(JCR *jcr);
 extern int send_bootstrap_file(JCR *jcr);
@@ -71,7 +80,7 @@ extern int send_level_command(JCR *jcr);
 extern int get_attributes_and_put_in_catalog(JCR *jcr);
 extern int get_attributes_and_compare_to_catalog(JCR *jcr, JobId_t JobId);
 extern int put_file_into_catalog(JCR *jcr, long file_index, char *fname,
-                         char *link, char *attr, int stream);
+                          char *link, char *attr, int stream);
 extern void get_level_since_time(JCR *jcr, char *since, int since_len);
 extern int send_run_before_and_after_commands(JCR *jcr);
 
@@ -94,12 +103,18 @@ extern void init_jcr_job_record(JCR *jcr);
 extern void copy_storage(JCR *new_jcr, JCR *old_jcr);
 extern void set_storage(JCR *jcr, STORE *store);
 
+/* mac.c */
+extern bool do_mac(JCR *jcr);
+extern bool do_mac_init(JCR *jcr);
+extern void mac_cleanup(JCR *jcr, int TermCode);
+
+
 /* mountreq.c */
 extern void mount_request(JCR *jcr, BSOCK *bs, char *buf);
 
 /* msgchan.c */
 extern bool connect_to_storage_daemon(JCR *jcr, int retry_interval,
-                             int max_retry_time, int verbose);
+                              int max_retry_time, int verbose);
 extern int start_storage_daemon_job(JCR *jcr, alist *store, int append);
 extern int start_storage_daemon_message_thread(JCR *jcr);
 extern int bget_dirmsg(BSOCK *bs);
@@ -113,6 +128,12 @@ void check_if_volume_valid_or_recyclable(JCR *jcr, MEDIA_DBR *mr, const char **r
 /* newvol.c */
 bool newVolume(JCR *jcr, MEDIA_DBR *mr);
 
+/* restore.c */
+extern bool do_restore(JCR *jcr);
+extern bool do_restore_init(JCR *jcr);
+extern void restore_cleanup(JCR *jcr, int TermCode);
+
+
 /* ua_acl.c */
 bool acl_access_ok(UAContext *ua, int acl, char *item);
 bool acl_access_ok(UAContext *ua, int acl, char *item, int len);
@@ -151,28 +172,28 @@ JCR *new_control_jcr(const char *base_name, int job_type);
 void free_ua_context(UAContext *ua);
 
 /* ua_select.c */
-STORE  *select_storage_resource(UAContext *ua);
-JOB    *select_job_resource(UAContext *ua);
-JOB    *select_restore_job_resource(UAContext *ua);
-CLIENT *select_client_resource(UAContext *ua);
+STORE   *select_storage_resource(UAContext *ua);
+JOB     *select_job_resource(UAContext *ua);
+JOB     *select_restore_job_resource(UAContext *ua);
+CLIENT  *select_client_resource(UAContext *ua);
 FILESET *select_fileset_resource(UAContext *ua);
-int    select_pool_and_media_dbr(UAContext *ua, POOL_DBR *pr, MEDIA_DBR *mr);
-int    select_media_dbr(UAContext *ua, MEDIA_DBR *mr);
-bool   select_pool_dbr(UAContext *ua, POOL_DBR *pr);
-int    select_client_dbr(UAContext *ua, CLIENT_DBR *cr);
-
-void   start_prompt(UAContext *ua, const char *msg);
-void   add_prompt(UAContext *ua, const char *prompt);
-int    do_prompt(UAContext *ua, const char *automsg, const char *msg, char *prompt, int max_prompt);
+int     select_pool_and_media_dbr(UAContext *ua, POOL_DBR *pr, MEDIA_DBR *mr);
+int     select_media_dbr(UAContext *ua, MEDIA_DBR *mr);
+bool    select_pool_dbr(UAContext *ua, POOL_DBR *pr);
+int     select_client_dbr(UAContext *ua, CLIENT_DBR *cr);
+
+void    start_prompt(UAContext *ua, const char *msg);
+void    add_prompt(UAContext *ua, const char *prompt);
+int     do_prompt(UAContext *ua, const char *automsg, const char *msg, char *prompt, int max_prompt);
 CAT    *get_catalog_resource(UAContext *ua);
 STORE  *get_storage_resource(UAContext *ua, int use_default);
-int    get_media_type(UAContext *ua, char *MediaType, int max_media);
-bool   get_pool_dbr(UAContext *ua, POOL_DBR *pr);
-int    get_client_dbr(UAContext *ua, CLIENT_DBR *cr);
+int     get_media_type(UAContext *ua, char *MediaType, int max_media);
+bool    get_pool_dbr(UAContext *ua, POOL_DBR *pr);
+int     get_client_dbr(UAContext *ua, CLIENT_DBR *cr);
 POOL   *get_pool_resource(UAContext *ua);
 POOL   *select_pool_resource(UAContext *ua);
 CLIENT *get_client_resource(UAContext *ua);
-int    get_job_dbr(UAContext *ua, JOB_DBR *jr);
+int     get_job_dbr(UAContext *ua, JOB_DBR *jr);
 
 int find_arg_keyword(UAContext *ua, const char **list);
 int find_arg(UAContext *ua, const char *keyword);
@@ -195,3 +216,8 @@ int purge_jobs_from_volume(UAContext *ua, MEDIA_DBR *mr);
 
 /* ua_run.c */
 extern int run_cmd(UAContext *ua, const char *cmd);
+
+/* verify.c */
+extern bool do_verify(JCR *jcr);
+extern bool do_verify_init(JCR *jcr);
+extern void verify_cleanup(JCR *jcr, int TermCode);
index ef82f94dbaa6156f0c93e6a254c39fe98d8e070b..0b7fb49a64d3ca826f11ddb05b1543bf857bc122 100644 (file)
@@ -51,18 +51,13 @@ static char OKrestore[]   = "2000 OK restore\n";
 static char OKstore[]     = "2000 OK storage\n";
 static char OKsession[]   = "2000 OK session\n";
 
-/* Forward referenced functions */
-static void restore_cleanup(JCR *jcr, int status);
-
-/* External functions */
-
 /*
  * Do a restore of the specified files
  *
  *  Returns:  0 on failure
  *           1 on success
  */
-int do_restore(JCR *jcr)
+bool do_restore(JCR *jcr)
 {
    BSOCK   *fd;
    JOB_DBR rjr;                      /* restore job record */
@@ -72,7 +67,7 @@ int do_restore(JCR *jcr)
    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 0;
+      return false;
    }
    Dmsg0(20, "Updated job start record\n");
 
@@ -96,7 +91,7 @@ int do_restore(JCR *jcr)
          Jmsg2(jcr, M_FATAL, 0, _("Cannot get job record id=%d %s"), rjr.JobId,
            db_strerror(jcr->db));
         restore_cleanup(jcr, JS_ErrorTerminated);
-        return 0;
+        return false;
       }
 
       /*
@@ -108,7 +103,7 @@ int do_restore(JCR *jcr)
          Jmsg(jcr, M_FATAL, 0, _("Cannot find Volume names for restore Job %d. %s"),
            rjr.JobId, db_strerror(jcr->db));
         restore_cleanup(jcr, JS_ErrorTerminated);
-        return 0;
+        return false;
       }
       Dmsg1(20, "Got job Volume Names: %s\n", jcr->VolumeName);
    }
@@ -137,14 +132,14 @@ int do_restore(JCR *jcr)
     */
    if (!start_storage_daemon_job(jcr, jcr->storage, SD_READ)) {
       restore_cleanup(jcr, JS_ErrorTerminated);
-      return 0;
+      return false;
    }
    /*
     * Now start a Storage daemon message thread
     */
    if (!start_storage_daemon_message_thread(jcr)) {
       restore_cleanup(jcr, JS_ErrorTerminated);
-      return 0;
+      return false;
    }
    Dmsg0(50, "Storage daemon connection OK\n");
 
@@ -154,7 +149,7 @@ int do_restore(JCR *jcr)
    set_jcr_job_status(jcr, JS_WaitFD);
    if (!connect_to_file_daemon(jcr, 10, FDConnectTimeout, 1)) {
       restore_cleanup(jcr, JS_ErrorTerminated);
-      return 0;
+      return false;
    }
 
    fd = jcr->file_bsock;
@@ -162,12 +157,12 @@ int do_restore(JCR *jcr)
 
    if (!send_include_list(jcr)) {
       restore_cleanup(jcr, JS_ErrorTerminated);
-      return 0;
+      return false;
    }
 
    if (!send_exclude_list(jcr)) {
       restore_cleanup(jcr, JS_ErrorTerminated);
-      return 0;
+      return false;
    }
 
    /*
@@ -182,7 +177,7 @@ int do_restore(JCR *jcr)
    Dmsg1(6, "dird>filed: %s\n", fd->msg);
    if (!response(jcr, fd, OKstore, "Storage", DISPLAY_ERROR)) {
       restore_cleanup(jcr, JS_ErrorTerminated);
-      return 0;
+      return false;
    }
 
    /*
@@ -190,7 +185,7 @@ int do_restore(JCR *jcr)
     */
    if (!send_bootstrap_file(jcr)) {
       restore_cleanup(jcr, JS_ErrorTerminated);
-      return 0;
+      return false;
    }
 
    /*
@@ -208,13 +203,13 @@ int do_restore(JCR *jcr)
                rjr.EndBlock);
       if (!response(jcr, fd, OKsession, "Session", DISPLAY_ERROR)) {
         restore_cleanup(jcr, JS_ErrorTerminated);
-        return 0;
+        return false;
       }
    }
 
    if (!send_run_before_and_after_commands(jcr)) {
       restore_cleanup(jcr, JS_ErrorTerminated);
-      return 0;
+      return false;
    }
 
    /* Send restore command */
@@ -242,21 +237,26 @@ int do_restore(JCR *jcr)
 
    if (!response(jcr, fd, OKrestore, "Restore", DISPLAY_ERROR)) {
       restore_cleanup(jcr, JS_ErrorTerminated);
-      return 0;
+      return false;
    }
 
    /* Wait for Job Termination */
    int stat = wait_for_job_termination(jcr);
    restore_cleanup(jcr, stat);
 
-   return 1;
+   return true;
+}
+
+bool do_restore_init(JCR *jcr) 
+{
+   return true;
 }
 
 /*
  * Release resources allocated during restore.
  *
  */
-static void restore_cleanup(JCR *jcr, int TermCode)
+void restore_cleanup(JCR *jcr, int TermCode)
 {
    char sdt[MAX_TIME_LENGTH], edt[MAX_TIME_LENGTH];
    char ec1[30], ec2[30], ec3[30];
index 9f3082d4d4c176c497b2525529b695b6bdebf815..00970952f8a5926bda75134a4bd9d3581344c81c 100644 (file)
@@ -44,36 +44,27 @@ extern int debug_level;
 /* Commands sent to File daemon */
 static char verifycmd[]    = "verify level=%s\n";
 static char storaddr[]     = "storage address=%s port=%d ssl=0\n";
-static char sessioncmd[]   = "session %s %ld %ld %ld %ld %ld %ld\n";
 
 /* Responses received from File daemon */
 static char OKverify[]    = "2000 OK verify\n";
 static char OKstore[]     = "2000 OK storage\n";
-static char OKsession[]   = "2000 OK session\n";
 
 /* Forward referenced functions */
-static void verify_cleanup(JCR *jcr, int TermCode);
 static void prt_fname(JCR *jcr);
 static int missing_handler(void *ctx, int num_fields, char **row);
 
-/*
- * Do a verification of the specified files against the Catlaog
- *
- *  Returns:  false on failure
- *           true  on success
+
+/* 
+ * Called here before the job is run to do the job
+ *   specific setup.
  */
-bool do_verify(JCR *jcr)
+bool do_verify_init(JCR *jcr) 
 {
-   const char *level, *Name;
-   BSOCK   *fd;
-   JOB_DBR jr, verify_jr;
+   JOB_DBR jr;
    JobId_t verify_jobid = 0;
-   int stat;
+   const char *Name;
 
-   memset(&verify_jr, 0, sizeof(verify_jr));
-   if (!jcr->verify_jr) {
-      jcr->verify_jr = &verify_jr;
-   }
+   memset(&jcr->target_jr, 0, sizeof(jcr->target_jr));
 
    Dmsg1(9, "bdird: created client %s record\n", jcr->client->hdr.name);
 
@@ -105,21 +96,11 @@ bool do_verify(JCR *jcr)
            Jmsg(jcr, M_FATAL, 0, _(
                  "Unable to find JobId of previous Job for this client.\n"));
         }
-        goto bail_out;
+        return false;
       }
       verify_jobid = jr.JobId;
       Dmsg1(100, "Last full jobid=%d\n", verify_jobid);
    }
-
-   if (!db_update_job_start_record(jcr, jcr->db, &jcr->jr)) {
-      Jmsg(jcr, M_FATAL, 0, "%s", db_strerror(jcr->db));
-      goto bail_out;
-   }
-
-   /* Print Job Start message */
-   Jmsg(jcr, M_INFO, 0, _("Start Verify JobId=%d Level=%s Job=%s\n"),
-      jcr->JobId, level_to_str(jcr->JobLevel), jcr->Job);
-
    /*
     * Now get the job record for the previous backup that interests
     *  us. We use the verify_jobid that we found above.
@@ -127,19 +108,19 @@ bool do_verify(JCR *jcr)
    if (jcr->JobLevel == L_VERIFY_CATALOG ||
        jcr->JobLevel == L_VERIFY_VOLUME_TO_CATALOG ||
        jcr->JobLevel == L_VERIFY_DISK_TO_CATALOG) {
-      verify_jr.JobId = verify_jobid;
-      if (!db_get_job_record(jcr, jcr->db, &verify_jr)) {
+      jcr->target_jr.JobId = verify_jobid;
+      if (!db_get_job_record(jcr, jcr->db, &jcr->target_jr)) {
          Jmsg(jcr, M_FATAL, 0, _("Could not get job record for previous Job. ERR=%s"),
              db_strerror(jcr->db));
-        goto bail_out;
+        return false;
       }
-      if (verify_jr.JobStatus != 'T') {
+      if (jcr->target_jr.JobStatus != 'T') {
          Jmsg(jcr, M_FATAL, 0, _("Last Job %d did not terminate normally. JobStatus=%c\n"),
-           verify_jobid, verify_jr.JobStatus);
-        goto bail_out;
+           verify_jobid, jcr->target_jr.JobStatus);
+        return false;
       }
       Jmsg(jcr, M_INFO, 0, _("Verifying against JobId=%d Job=%s\n"),
-        verify_jr.JobId, verify_jr.Job);
+        jcr->target_jr.JobId, jcr->target_jr.Job);
    }
 
    /*
@@ -151,17 +132,17 @@ bool do_verify(JCR *jcr)
    if (jcr->JobLevel == L_VERIFY_VOLUME_TO_CATALOG) {
       RBSR *bsr = new_bsr();
       UAContext *ua;
-      bsr->JobId = verify_jr.JobId;
+      bsr->JobId = jcr->target_jr.JobId;
       ua = new_ua_context(jcr);
       complete_bsr(ua, bsr);
       bsr->fi = new_findex();
       bsr->fi->findex = 1;
-      bsr->fi->findex2 = verify_jr.JobFiles;
+      bsr->fi->findex2 = jcr->target_jr.JobFiles;
       jcr->ExpectedFiles = write_bsr_file(ua, bsr);
       if (jcr->ExpectedFiles == 0) {
         free_ua_context(ua);
         free_bsr(bsr);
-        goto bail_out;
+        return false;
       }
       free_ua_context(ua);
       free_bsr(bsr);
@@ -172,43 +153,70 @@ bool do_verify(JCR *jcr)
       Mmsg(fname, "%s/restore.bsr", working_directory);
       jcr->RestoreBootstrap = bstrdup(fname);
       free_pool_memory(fname);
+      jcr->needs_sd = true;
+
+   } else {
+      jcr->sd_auth_key = bstrdup("dummy");    /* dummy Storage daemon key */
+   }
+
+   if (jcr->JobLevel == L_VERIFY_DISK_TO_CATALOG && jcr->verify_job) {
+      jcr->fileset = jcr->verify_job->fileset;
+   }
+   Dmsg2(100, "ClientId=%u JobLevel=%c\n", jcr->target_jr.ClientId, jcr->JobLevel);
+   return true;
+}
+
+
+/*
+ * Do a verification of the specified files against the Catlaog
+ *
+ *  Returns:  false on failure
+ *           true  on success
+ */
+bool do_verify(JCR *jcr)
+{
+   const char *level;
+   BSOCK   *fd;
+   int stat;
+
+   if (!db_update_job_start_record(jcr, jcr->db, &jcr->jr)) {
+      Jmsg(jcr, M_FATAL, 0, "%s", db_strerror(jcr->db));
+      return false;
+   }
 
+   /* Print Job Start message */
+   Jmsg(jcr, M_INFO, 0, _("Start Verify JobId=%d Level=%s Job=%s\n"),
+      jcr->JobId, level_to_str(jcr->JobLevel), jcr->Job);
+
+   if (jcr->JobLevel == L_VERIFY_VOLUME_TO_CATALOG) {
       /*
        * Start conversation with Storage daemon
        */
       set_jcr_job_status(jcr, JS_Blocked);
       if (!connect_to_storage_daemon(jcr, 10, SDConnectTimeout, 1)) {
-        goto bail_out;
+        return false;
       }
       /*
        * Now start a job with the Storage daemon
        */
       if (!start_storage_daemon_job(jcr, jcr->storage, SD_READ)) {
-        goto bail_out;
+        return false;
       }
       /*
        * Now start a Storage daemon message thread
        */
       if (!start_storage_daemon_message_thread(jcr)) {
-        goto bail_out;
+        return false;
       }
       Dmsg0(50, "Storage daemon connection OK\n");
-   } else {
-      jcr->sd_auth_key = bstrdup("dummy");    /* dummy Storage daemon key */
    }
-
-   if (jcr->JobLevel == L_VERIFY_DISK_TO_CATALOG && jcr->verify_job) {
-      jcr->fileset = jcr->verify_job->fileset;
-   }
-   Dmsg2(100, "ClientId=%u JobLevel=%c\n", verify_jr.ClientId, jcr->JobLevel);
-
    /*
     * OK, now connect to the File daemon
     *  and ask him for the files.
     */
    set_jcr_job_status(jcr, JS_Blocked);
    if (!connect_to_file_daemon(jcr, 10, FDConnectTimeout, 1)) {
-      goto bail_out;
+      return false;
    }
 
    set_jcr_job_status(jcr, JS_Running);
@@ -217,12 +225,12 @@ bool do_verify(JCR *jcr)
 
    Dmsg0(30, ">filed: Send include list\n");
    if (!send_include_list(jcr)) {
-      goto bail_out;
+      return false;
    }
 
    Dmsg0(30, ">filed: Send exclude list\n");
    if (!send_exclude_list(jcr)) {
-      goto bail_out;
+      return false;
    }
 
    /*
@@ -245,33 +253,21 @@ bool do_verify(JCR *jcr)
       }
       bnet_fsend(fd, storaddr, jcr->store->address, jcr->store->SDDport);
       if (!response(jcr, fd, OKstore, "Storage", DISPLAY_ERROR)) {
-        goto bail_out;
+        return false;
       }
 
       /*
        * Send the bootstrap file -- what Volumes/files to restore
        */
       if (!send_bootstrap_file(jcr)) {
-        goto bail_out;
+        return false;
       }
 
-      /*
-       * The following code is deprecated
-       */
       if (!jcr->RestoreBootstrap) {
-        /*
-         * Pass the VolSessionId, VolSessionTime, Start and
-         * end File and Blocks on the session command.
-         */
-        bnet_fsend(fd, sessioncmd,
-                  jcr->VolumeName,
-                  jr.VolSessionId, jr.VolSessionTime,
-                  jr.StartFile, jr.EndFile, jr.StartBlock,
-                  jr.EndBlock);
-         if (!response(jcr, fd, OKsession, "Session", DISPLAY_ERROR)) {
-           goto bail_out;
-        }
+         Jmsg0(jcr, M_FATAL, 0, _("Deprecated feature ... use bootstrap.\n"));
+        return false;
       }
+
       level = "volume";
       break;
    case L_VERIFY_DATA:
@@ -283,11 +279,11 @@ bool do_verify(JCR *jcr)
    default:
       Jmsg2(jcr, M_FATAL, 0, _("Unimplemented Verify level %d(%c)\n"), jcr->JobLevel,
         jcr->JobLevel);
-      goto bail_out;
+      return false;
    }
 
    if (!send_run_before_and_after_commands(jcr)) {
-      goto bail_out;
+      return false;
    }
 
    /*
@@ -295,7 +291,7 @@ bool do_verify(JCR *jcr)
     */
    bnet_fsend(fd, verifycmd, level);
    if (!response(jcr, fd, OKverify, "Verify", DISPLAY_ERROR)) {
-      goto bail_out;
+      return false;
    }
 
    /*
@@ -309,19 +305,19 @@ bool do_verify(JCR *jcr)
       Dmsg0(10, "Verify level=catalog\n");
       jcr->sd_msg_thread_done = true;  /* no SD msg thread, so it is done */
       jcr->SDJobStatus = JS_Terminated;
-      get_attributes_and_compare_to_catalog(jcr, verify_jobid);
+      get_attributes_and_compare_to_catalog(jcr, jcr->target_jr.JobId);
       break;
 
    case L_VERIFY_VOLUME_TO_CATALOG:
       Dmsg0(10, "Verify level=volume\n");
-      get_attributes_and_compare_to_catalog(jcr, verify_jobid);
+      get_attributes_and_compare_to_catalog(jcr, jcr->target_jr.JobId);
       break;
 
    case L_VERIFY_DISK_TO_CATALOG:
       Dmsg0(10, "Verify level=disk_to_catalog\n");
       jcr->sd_msg_thread_done = true;  /* no SD msg thread, so it is done */
       jcr->SDJobStatus = JS_Terminated;
-      get_attributes_and_compare_to_catalog(jcr, verify_jobid);
+      get_attributes_and_compare_to_catalog(jcr, jcr->target_jr.JobId);
       break;
 
    case L_VERIFY_INIT:
@@ -334,23 +330,20 @@ bool do_verify(JCR *jcr)
 
    default:
       Jmsg1(jcr, M_FATAL, 0, _("Unimplemented verify level %d\n"), jcr->JobLevel);
-      goto bail_out;
+      return false;
    }
 
    stat = wait_for_job_termination(jcr);
    verify_cleanup(jcr, stat);
    return true;
-
-bail_out:
-   verify_cleanup(jcr, JS_ErrorTerminated);
-   return false;
 }
 
+
 /*
  * Release resources allocated during backup.
  *
  */
-static void verify_cleanup(JCR *jcr, int TermCode)
+void verify_cleanup(JCR *jcr, int TermCode)
 {
    char sdt[50], edt[50];
    char ec1[30], ec2[30];
@@ -433,7 +426,7 @@ static void verify_cleanup(JCR *jcr, int TermCode)
         jcr->fileset->hdr.name,
         level_to_str(jcr->JobLevel),
         jcr->client->hdr.name,
-        jcr->verify_jr->JobId,
+        jcr->target_jr.JobId,
         Name,
         sdt,
         edt,
@@ -464,7 +457,7 @@ static void verify_cleanup(JCR *jcr, int TermCode)
         jcr->fileset->hdr.name,
         level_to_str(jcr->JobLevel),
         jcr->client->hdr.name,
-        jcr->verify_jr->JobId,
+        jcr->target_jr.JobId,
         Name,
         sdt,
         edt,
@@ -474,10 +467,6 @@ static void verify_cleanup(JCR *jcr, int TermCode)
         term_msg);
    }
    Dmsg0(100, "Leave verify_cleanup()\n");
-   if (jcr->fname) {
-      free_memory(jcr->fname);
-      jcr->fname = NULL;
-   }
 }
 
 /*
@@ -524,7 +513,7 @@ int get_attributes_and_compare_to_catalog(JCR *jcr, JobId_t JobId)
            fname)) != 3) {
          Jmsg3(jcr, M_FATAL, 0, _("bird<filed: bad attributes, expected 3 fields got %d\n"
 " mslen=%d msg=%s\n"), len, fd->msglen, fd->msg);
-        goto bail_out;
+        return false;
       }
       /*
        * We read the Options or Signature into fname
@@ -565,7 +554,7 @@ int get_attributes_and_compare_to_catalog(JCR *jcr, JobId_t JobId)
          */
         fdbr.FileId = 0;
         if (!db_get_file_attributes_record(jcr, jcr->db, jcr->fname,
-             jcr->verify_jr, &fdbr)) {
+             &jcr->target_jr, &fdbr)) {
             Jmsg(jcr, M_INFO, 0, _("New file: %s\n"), jcr->fname);
             Dmsg1(020, _("File not in catalog: %s\n"), jcr->fname);
            stat = JS_Differences;
@@ -694,7 +683,7 @@ int get_attributes_and_compare_to_catalog(JCR *jcr, JobId_t JobId)
         if (jcr->FileIndex != (uint32_t)file_index) {
             Jmsg2(jcr, M_FATAL, 0, _("MD5/SHA1 index %d not same as attributes %d\n"),
               file_index, jcr->FileIndex);
-           goto bail_out;
+           return false;
         }
         if (do_SIG) {
            db_escape_string(buf, Opts_SIG, strlen(Opts_SIG));
@@ -718,7 +707,7 @@ int get_attributes_and_compare_to_catalog(JCR *jcr, JobId_t JobId)
       berrno be;
       Jmsg2(jcr, M_FATAL, 0, _("bdird<filed: bad attributes from filed n=%d : %s\n"),
                        n, be.strerror());
-      goto bail_out;
+      return false;
    }
 
    /* Now find all the files that are missing -- i.e. all files in
@@ -738,12 +727,7 @@ int get_attributes_and_compare_to_catalog(JCR *jcr, JobId_t JobId)
    }
    free_pool_memory(fname);
    set_jcr_job_status(jcr, stat);
-   return 1;
-
-bail_out:
-   free_pool_memory(fname);
-   set_jcr_job_status(jcr, JS_ErrorTerminated);
-   return 0;
+   return stat == JS_Terminated;
 }
 
 /*
index 8c3c74a605744d3d59ea4974090be35f21ada9b0..550be78ef8bc56dbbcad7287d9b8d388f2b698b2 100644 (file)
@@ -176,11 +176,12 @@ struct JCR {
    POOLMEM *fname;                    /* name to put into catalog */
    POOLMEM *stime;                    /* start time for incremental/differential */
    JOB_DBR jr;                        /* Job DB record for current job */
-   JOB_DBR *verify_jr;                /* Pointer to target job */
+   JOB_DBR target_jr;                 /* target job */
+   char FSCreateTime[MAX_TIME_LENGTH]; /* FileSet CreateTime as returned from DB */
+   char since[MAX_TIME_LENGTH];       /* since time */
    uint32_t RestoreJobId;             /* Id specified by UA */
    POOLMEM *client_uname;             /* client uname */
    int replace;                       /* Replace option */
-   int saveMaxConcurrentJobs;         /* save for restore jobs */
    int NumVols;                       /* Number of Volume used in pool */
    int reschedule_count;              /* Number of times rescheduled */
    bool spool_data;                   /* Spool data in SD */
@@ -188,6 +189,7 @@ struct JCR {
    bool term_wait_inited;             /* Set when cond var inited */
    bool fn_printed;                   /* printed filename */
    bool write_part_after_job;         /* Write part after job in SD */
+   bool needs_sd;                     /* set if SD needed by Job */
 #endif /* DIRECTOR_DAEMON */
 
 
index 0a274b2890af95900e96ac3bedc91d66dcf2e6d9..d439e8c1447d1ad9efc9e5720c5341999390e580 100644 (file)
@@ -114,6 +114,7 @@ enum {
 #define ST_NEXTVOL         (1<<13)    /* Start writing on next volume */
 #define ST_SHORT           (1<<14)    /* Short block read */
 #define ST_MOUNTED         (1<<15)    /* the device is mounted to the mount point */
+#define ST_OFFLINE         (1<<16)    /* set offline by operator */
 
 /* dev_blocked states (mutually exclusive) */
 enum {
@@ -247,6 +248,7 @@ public:
    int is_fifo() const;
    int is_dvd() const;
    int is_open() const;
+   int is_offline() const;
    int is_labeled() const;
    int is_busy() const;               /* either reading or writing */
    int at_eof() const;
@@ -260,9 +262,11 @@ public:
    void set_eot();
    void set_append();
    void set_read();
+   void set_offline();
    void clear_append();
    void clear_read();
    void clear_label();
+   void clear_offline();
 };
 
 /* Note, these return int not bool! */
@@ -271,6 +275,7 @@ inline int DEVICE::is_file() const { return state & ST_FILE; }
 inline int DEVICE::is_fifo() const { return state & ST_FIFO; }
 inline int DEVICE::is_dvd()  const { return state & ST_DVD; }
 inline int DEVICE::is_open() const { return state & ST_OPENED; }
+inline int DEVICE::is_offline() const { return state & ST_OFFLINE; }
 inline int DEVICE::is_labeled() const { return state & ST_LABEL; }
 inline int DEVICE::is_busy() const { return state & ST_READ || num_writers; }
 inline int DEVICE::at_eof() const { return state & ST_EOF; }
@@ -279,9 +284,11 @@ inline int DEVICE::can_append() const { return state & ST_APPEND; }
 inline int DEVICE::can_read() const { return state & ST_READ; }
 inline void DEVICE::set_append() { state |= ST_APPEND; }
 inline void DEVICE::set_read() { state |= ST_READ; }
+inline void DEVICE::set_offline() { state |= ST_OFFLINE; }
 inline void DEVICE::clear_append() { state &= ~ST_APPEND; }
 inline void DEVICE::clear_read() { state &= ~ST_READ; }
 inline void DEVICE::clear_label() { state &= ~ST_LABEL; }
+inline void DEVICE::clear_offline() { state &= ~ST_OFFLINE; }
 inline const char *DEVICE::strerror() const { return errmsg; }
 inline const char *DEVICE::archive_name() const { return dev_name; }
 
index ff52ecf69f8f65e57c3ceebe8d30b0910dfcb23b..d6dfa0e631f4db91d97d03eba1bb535265ceb3d1 100644 (file)
@@ -55,7 +55,7 @@ static char NOT_open[]  = "3925 Device \"%s\" could not be opened or does not ex
 static char BAD_use[]   = "3913 Bad use command: %s\n";
 static char BAD_job[]   = "3915 Bad Job command: %s\n";
 static char OK_query[]  = "3001 OK query append=%d read=%d num_writers=%d "
-   "num_waiting=%d open=%d use_count=%d labeled=%d "
+   "num_waiting=%d open=%d use_count=%d labeled=%d offline=%d autochanger=%d "
    "media_type=%s volume_name=%s";
 static char BAD_query[]   = "3917 Bad query command: %s\n";
 
@@ -385,6 +385,7 @@ bool query_cmd(JCR *jcr)
            return bnet_fsend(dir, OK_query, dev->can_append()!=0,
               dev->can_read()!=0, dev->num_writers, dev->num_waiting,
               dev->is_open()!=0, dev->use_count, dev->is_labeled()!=0,
+              dev->is_offline()!=0, device->changer_res!=NULL, 
               MediaType.c_str(), VolumeName.c_str());
         }
       }
index 4589a1daa734b11357cde13befbcc79c6c249601..3020768b146779526fc128756dbd23af32f5790c 100644 (file)
@@ -221,6 +221,9 @@ void dump_resource(int type, RES *reshdr, void sendit(void *sock, const char *fm
       sendit(sock, "         spool_directory=%s\n", NPRT(res->res_dev.spool_directory));
       sendit(sock, "         max_spool_size=%" lld " max_job_spool_size=%" lld "\n",
         res->res_dev.max_spool_size, res->res_dev.max_job_spool_size);
+      if (res->res_dev.changer_res) {
+         sendit(sock, "         changer=%p\n", res->res_dev.changer_res);
+      }
       bstrncpy(buf, "        ", sizeof(buf));
       if (res->res_dev.cap_bits & CAP_EOF) {
          bstrncat(buf, "CAP_EOF ", sizeof(buf));
@@ -266,7 +269,7 @@ void dump_resource(int type, RES *reshdr, void sendit(void *sock, const char *fm
       break;
    case R_AUTOCHANGER:
       DEVRES *dev;
-      sendit(sock, "Changer: name=%s Changer_devname=%s Changer_cmd=%s\n",
+      sendit(sock, "Changer: name=%s Changer_devname=%s\n      Changer_cmd=%s\n",
         res->res_changer.hdr.name,
         res->res_changer.changer_name, res->res_changer.changer_command);
       foreach_alist(dev, res->res_changer.device) {
@@ -466,10 +469,14 @@ void save_resource(int type, RES_ITEM *items, int pass)
         }
         /* we must explicitly copy the device alist pointer */
         res->res_changer.device   = res_all.res_changer.device;
+        /*
+         * Now update each device in this resource to point back 
+         *  to the changer resource.
+         */
         foreach_alist(dev, res->res_changer.device) {
            dev->changer_res = (AUTOCHANGER *)&res->res_changer;
         }
-        if ((errstat = pthread_mutex_init(&dev->changer_res->changer_mutex, NULL)) != 0) {
+        if ((errstat = pthread_mutex_init(&res->res_changer.changer_mutex, NULL)) != 0) {
            berrno be;
             Jmsg1(NULL, M_ERROR_TERM, 0, _("Unable to init mutex: ERR=%s\n"), 
                  be.strerror(errstat));
index dfc011e914601ff9b3847fca6fa1cf302684f97c..baf5e9ad62653ff1709862816cdadf78090414fb 100644 (file)
@@ -1,8 +1,8 @@
 /* */
 #undef  VERSION
 #define VERSION "1.37.4"
-#define BDATE   "26 February 2005"
-#define LSMDATE "26Feb05"
+#define BDATE   "28 February 2005"
+#define LSMDATE "28Feb05"
 
 /* Debug flags */
 #undef  DEBUG