]> git.sur5r.net Git - bacula/bacula/commitdiff
kes Separate read/write source strings to keep track of where
authorKern Sibbald <kern@sibbald.com>
Fri, 24 Nov 2006 09:58:28 +0000 (09:58 +0000)
committerKern Sibbald <kern@sibbald.com>
Fri, 24 Nov 2006 09:58:28 +0000 (09:58 +0000)
     storage devices are used in a job.
kes  Implement a new method of keeping track of which storage
     device is used in a Job.  USTORE keeps both a pointer to the
     resource and to the source string.
kes  Modify all code to use new storage set subroutines in job.c
kes  Modify migrate.c so that the definitive selection of the storage
     resource is done in the do_migration_init() routine prior to
     the job going into the job queue.  This permits accurate
     deadlock detection (same read and write storage resource).
kes  Remove bfill from btape (I think it was a left over stub).

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

19 files changed:
bacula/kernstodo
bacula/src/dird/backup.c
bacula/src/dird/dird_conf.h
bacula/src/dird/job.c
bacula/src/dird/jobq.c
bacula/src/dird/migrate.c
bacula/src/dird/msgchan.c
bacula/src/dird/protos.h
bacula/src/dird/scheduler.c
bacula/src/dird/ua_cmds.c
bacula/src/dird/ua_dotcmds.c
bacula/src/dird/ua_label.c
bacula/src/dird/ua_output.c
bacula/src/dird/ua_run.c
bacula/src/dird/ua_status.c
bacula/src/jcr.h
bacula/src/stored/btape.c
bacula/src/version.h
bacula/technotes-1.39

index db177e3f1db95cd79e5707e96a68a9cb6413f620..235b1017ddbd5310dc2569fcdc91312f459710e3 100644 (file)
@@ -41,6 +41,7 @@ Document:
  
 
 Priority:
+- Fix prog copyright (SD) all other files.
 - Migration Volume span bug
 - Rescue release
 - Bug reports
index 47e70441b7e7093256da9b1304544f75e14c010e..e1a0442a805c2019a303cbcd5c6652dc682d8d6a 100644 (file)
@@ -202,7 +202,6 @@ bool do_backup(JCR *jcr)
       goto bail_out;
    }
 
-
    if (!send_runscripts_commands(jcr)) {
       goto bail_out;
    }
@@ -466,7 +465,7 @@ void backup_cleanup(JCR *jcr, int TermCode)
         jcr->client->name(), cr.Uname,
         jcr->fileset->name(), jcr->FSCreateTime,
         jcr->pool->name(), jcr->pool_source,
-        jcr->wstore->name(), jcr->storage_source,
+        jcr->wstore->name(), jcr->wstore_source,
         schedt,
         sdt,
         edt,
index 69381516fc60d46bb4ae5b3be7e7b7b577056b74..ac4cfa109e78689f812f396e3e68190b0e4cf6cf 100644 (file)
@@ -307,6 +307,40 @@ inline char *STORE::dev_name() const
 
 inline char *STORE::name() const { return hdr.name; }
 
+/*
+ * This is a sort of "unified" store that has both the
+ *  storage pointer and the text of where the pointer was
+ *  found.
+ */
+class USTORE {
+public:
+   STORE *store;
+   POOLMEM *store_source;
+
+   /* Methods */
+   USTORE() { store = NULL; store_source = get_pool_memory(PM_MESSAGE); }
+   ~USTORE() { destroy(); }   
+   void set_source(const char *where);
+   void destroy();
+};
+
+inline void USTORE::destroy()
+{
+   if (store_source) {
+      free_pool_memory(store_source);
+      store_source = NULL;
+   }
+}
+
+
+inline void USTORE::set_source(const char *where)
+{
+   if (!store_source) {
+      store_source = get_pool_memory(PM_MESSAGE);
+   }
+   pm_strcpy(store_source, where);
+}
+
 
 /*
  *   Job Resource
index 798ff220379a82e17ee16df702516d43118e0e8f..43d5bdcdd3456cb5976ce02a9c081e49924eabf8 100644 (file)
@@ -87,6 +87,7 @@ JobId_t run_job(JCR *jcr)
 {
    int stat;
    if (setup_job(jcr)) {
+      Dmsg0(200, "Add jrc to work queue\n");
       /* Queue the job to be run */
       if ((stat = jobq_add(&job_queue, jcr)) != 0) {
          berrno be;
@@ -143,10 +144,6 @@ bool setup_job(JCR *jcr)
       jcr->pool_source = get_pool_memory(PM_MESSAGE);
       pm_strcpy(jcr->pool_source, _("unknown source"));
    }
-   if (!jcr->storage_source) {
-      jcr->storage_source = get_pool_memory(PM_MESSAGE);
-      pm_strcpy(jcr->storage_source, _("unknown source"));
-   }
 
    /*
     * Create Job record
@@ -160,12 +157,12 @@ bool setup_job(JCR *jcr)
    Dmsg4(100, "Created job record JobId=%d Name=%s Type=%c Level=%c\n",
        jcr->JobId, jcr->Job, jcr->jr.JobType, jcr->jr.JobLevel);
 
-   generate_daemon_event(jcr, "JobStart");
-
    if (!get_or_create_client_record(jcr)) {
       goto bail_out;
    }
 
+   generate_daemon_event(jcr, "JobStart");
+
    if (job_canceled(jcr)) {
       goto bail_out;
    }
@@ -209,8 +206,6 @@ bool setup_job(JCR *jcr)
    }
 
    generate_job_event(jcr, "JobInit");
-
-   Dmsg0(200, "Add jrc to work queue\n");
    return true;
 
 bail_out:
@@ -389,12 +384,17 @@ bool cancel_job(UAContext *ua, JCR *jcr)
                copy_wstorage(ua->jcr, jcr->wstorage, _("Job resource")); 
             }
          } else {
+            USTORE store;
             if (jcr->rstorage) {
-               set_wstorage(ua->jcr, jcr->rstore);
+               store.store = jcr->rstore;
+               pm_strcpy(store.store_source, jcr->rstore_source);
             } else {
-               set_wstorage(ua->jcr, jcr->wstore);
+               store.store = jcr->wstore;
+               pm_strcpy(store.store_source, jcr->wstore_source);
             }
+            set_wstorage(ua->jcr, &store);
          }
+
          if (!connect_to_storage_daemon(ua->jcr, 10, SDConnectTimeout, 1)) {
             bsendmsg(ua, _("Failed to connect to Storage daemon.\n"));
             return false;
@@ -616,7 +616,7 @@ DBId_t get_or_create_pool_record(JCR *jcr, char *pool_name)
 void apply_pool_overrides(JCR *jcr)
 {
    if (jcr->run_pool_override) {
-      pm_strcpy(jcr->pool_source, _("Run Pool override"));
+      pm_strcpy(jcr->pool_source, _("run pool override"));
    }
    /*
     * Apply any level related Pool selections
@@ -626,9 +626,9 @@ void apply_pool_overrides(JCR *jcr)
       if (jcr->full_pool) {
          jcr->pool = jcr->full_pool;
          if (jcr->run_full_pool_override) {
-            pm_strcpy(jcr->pool_source, _("Run FullPool override"));
+            pm_strcpy(jcr->pool_source, _("run FullPool override"));
          } else {
-            pm_strcpy(jcr->pool_source, _("Job FullPool override"));
+            pm_strcpy(jcr->pool_source, _("job FullPool override"));
          }
       }
       break;
@@ -636,9 +636,9 @@ void apply_pool_overrides(JCR *jcr)
       if (jcr->inc_pool) {
          jcr->pool = jcr->inc_pool;
          if (jcr->run_inc_pool_override) {
-            pm_strcpy(jcr->pool_source, _("Run IncPool override"));
+            pm_strcpy(jcr->pool_source, _("run IncPool override"));
          } else {
-            pm_strcpy(jcr->pool_source, _("Job IncPool override"));
+            pm_strcpy(jcr->pool_source, _("job IncPool override"));
          }
       }
       break;
@@ -646,9 +646,9 @@ void apply_pool_overrides(JCR *jcr)
       if (jcr->diff_pool) {
          jcr->pool = jcr->diff_pool;
          if (jcr->run_diff_pool_override) {
-            pm_strcpy(jcr->pool_source, _("Run DiffPool override"));
+            pm_strcpy(jcr->pool_source, _("run DiffPool override"));
          } else {
-            pm_strcpy(jcr->pool_source, _("Job DiffPool override"));
+            pm_strcpy(jcr->pool_source, _("job DiffPool override"));
          }
       }
       break;
@@ -834,9 +834,13 @@ void dird_free_jcr_pointers(JCR *jcr)
       free_pool_memory(jcr->pool_source);
       jcr->pool_source = NULL;
    }
-   if (jcr->storage_source) {
-      free_pool_memory(jcr->storage_source);
-      jcr->storage_source = NULL;
+   if (jcr->wstore_source) {
+      free_pool_memory(jcr->wstore_source);
+      jcr->wstore_source = NULL;
+   }
+   if (jcr->rstore_source) {
+      free_pool_memory(jcr->rstore_source);
+      jcr->rstore_source = NULL;
    }
    if (jcr->stime) {
       Dmsg0(200, "Free JCR stime\n");
@@ -888,12 +892,24 @@ void dird_free_jcr(JCR *jcr)
  *  or in the Pool record.  The Pool record overrides the Job 
  *  record.
  */
-STORE *get_job_storage(JOB *job)
+void get_job_storage(USTORE *store, JOB *job, RUN *run) 
 {
+   if (run && run->pool && run->pool->storage) {
+      store->store = (STORE *)run->pool->storage->first();
+      pm_strcpy(store->store_source, _("run pool override"));
+      return;
+   }
+   if (run && run->storage) {
+      store->store = run->storage;
+      pm_strcpy(store->store_source, _("run storage override"));
+      return;
+   }
    if (job->pool->storage) {
-      return (STORE *)job->pool->storage->first();
+      store->store = (STORE *)job->pool->storage->first();
+      pm_strcpy(store->store_source, _("job pool storage"));
    } else {
-      return (STORE *)job->storage->first();
+      store->store = (STORE *)job->storage->first();
+      pm_strcpy(store->store_source, _("job storage"));
    }
 }
 
@@ -924,16 +940,12 @@ void set_jcr_defaults(JCR *jcr, JOB *job)
       jcr->pool_source = get_pool_memory(PM_MESSAGE);
       pm_strcpy(jcr->pool_source, _("unknown source"));
    }
-   if (!jcr->storage_source) {
-      jcr->storage_source = get_pool_memory(PM_MESSAGE);
-      pm_strcpy(jcr->storage_source, _("unknown source"));
-   }
    jcr->JobPriority = job->Priority;
    /* Copy storage definitions -- deleted in dir_free_jcr above */
    if (job->storage) {
       copy_rwstorage(jcr, job->storage, _("Job resource"));
    } else {
-      copy_rwstorage(jcr, job->pool->storage, _("Job resource"));
+      copy_rwstorage(jcr, job->pool->storage, _("Pool resource"));
    }
    jcr->client = job->client;
    if (!jcr->client_name) {
@@ -974,6 +986,7 @@ void set_jcr_defaults(JCR *jcr, JOB *job)
          jcr->JobLevel = L_NONE;
          break;
       default:
+         jcr->JobLevel = L_FULL;
          break;
       }
    }
@@ -984,20 +997,36 @@ void set_jcr_defaults(JCR *jcr, JOB *job)
  */
 void copy_rwstorage(JCR *jcr, alist *storage, const char *where)
 {
-   copy_rstorage(jcr, storage, where);
-   copy_wstorage(jcr, storage, where);
+   switch(jcr->JobType) {
+   case JT_RESTORE:
+   case JT_VERIFY:
+   case JT_MIGRATE:
+      copy_rstorage(jcr, storage, where);
+      break;
+   default:
+      copy_wstorage(jcr, storage, where);
+      break;
+   }
 }
 
 
 /* Set storage override */
-void set_rwstorage(JCR *jcr, STORE *store)
+void set_rwstorage(JCR *jcr, USTORE *store)
 {
    if (!store) {
       Jmsg(jcr, M_FATAL, 0, _("No storage specified.\n"));
       return;
    }
-   set_rstorage(jcr, store);
-   set_wstorage(jcr, store);
+   switch(jcr->JobType) {
+   case JT_RESTORE:
+   case JT_VERIFY:
+   case JT_MIGRATE:
+      set_rstorage(jcr, store);
+      break;
+   default:
+      set_wstorage(jcr, store);
+      break;
+   }
 }
 
 void free_rwstorage(JCR *jcr)
@@ -1020,33 +1049,40 @@ void copy_rstorage(JCR *jcr, alist *storage, const char *where)
       foreach_alist(st, storage) {
          jcr->rstorage->append(st);
       }
-      pm_strcpy(jcr->storage_source, where);
-   }               
-   if (jcr->rstorage) {
-      jcr->rstore = (STORE *)jcr->rstorage->first();
+      if (!jcr->rstore_source) {
+         jcr->rstore_source = get_pool_memory(PM_MESSAGE);
+      }
+      pm_strcpy(jcr->rstore_source, where);
+      if (jcr->rstorage) {
+         jcr->rstore = (STORE *)jcr->rstorage->first();
+      }
    }
 }
 
 
 /* Set storage override */
-void set_rstorage(JCR *jcr, STORE *store)
+void set_rstorage(JCR *jcr, USTORE *store)
 {
    STORE *storage;
 
-   if (!store) {
+   if (!store->store) {
       return;
    }
    if (!jcr->rstorage) {
       jcr->rstorage = New(alist(10, not_owned_by_alist));
    }
-   jcr->rstore = store;
+   jcr->rstore = store->store;
+   if (!jcr->rstore_source) {
+      jcr->rstore_source = get_pool_memory(PM_MESSAGE);
+   }
+   pm_strcpy(jcr->rstore_source, store->store_source);
    foreach_alist(storage, jcr->rstorage) {
-      if (store == storage) {
+      if (store->store == storage) {
          return;
       }
    }
    /* Store not in list, so add it */
-   jcr->rstorage->prepend(store);
+   jcr->rstorage->prepend(store->store);
 }
 
 void free_rstorage(JCR *jcr)
@@ -1070,35 +1106,45 @@ void copy_wstorage(JCR *jcr, alist *storage, const char *where)
       }
       jcr->wstorage = New(alist(10, not_owned_by_alist));
       foreach_alist(st, storage) {
+         Dmsg1(50, "storage=%s\n", st->name());
          jcr->wstorage->append(st);
       }
-      pm_strcpy(jcr->storage_source, where);
-   }               
-   if (jcr->wstorage) {
-      jcr->wstore = (STORE *)jcr->wstorage->first();
+      if (!jcr->wstore_source) {
+         jcr->wstore_source = get_pool_memory(PM_MESSAGE);
+      }
+      pm_strcpy(jcr->wstore_source, where);
+      if (jcr->wstorage) {
+         jcr->wstore = (STORE *)jcr->wstorage->first();
+         Dmsg2(100, "wstore=%s where=%s\n", jcr->wstore->name(), jcr->wstore_source);
+      }
    }
 }
 
 
 /* Set storage override */
-void set_wstorage(JCR *jcr, STORE *store)
+void set_wstorage(JCR *jcr, USTORE *store)
 {
    STORE *storage;
 
-   if (!store) {
+   if (!store->store) {
       return;
    }
    if (!jcr->wstorage) {
       jcr->wstorage = New(alist(10, not_owned_by_alist));
    }
-   jcr->wstore = store;
+   jcr->wstore = store->store;
+   if (!jcr->wstore_source) {
+      jcr->wstore_source = get_pool_memory(PM_MESSAGE);
+   }
+   pm_strcpy(jcr->wstore_source, store->store_source);
+   Dmsg2(50, "wstore=%s where=%s\n", jcr->wstore->name(), jcr->wstore_source);
    foreach_alist(storage, jcr->wstorage) {
-      if (store == storage) {
+      if (store->store == storage) {
          return;
       }
    }
    /* Store not in list, so add it */
-   jcr->wstorage->prepend(store);
+   jcr->wstorage->prepend(store->store);
 }
 
 void free_wstorage(JCR *jcr)
index 2c02aa5e778b174c23ba0b06693d1db9030cfffa..6246fcdb5c215532de004d77a03089e7838500cc 100755 (executable)
@@ -702,9 +702,12 @@ static bool acquire_resources(JCR *jcr)
    }
    
    if (jcr->wstore) {
+      Dmsg1(200, "Wstore=%s\n", jcr->wstore->name());
       if (jcr->rstore == jcr->wstore) {           /* deadlock */
          jcr->rstore->NumConcurrentJobs = 0;      /* back out rstore */
-         Jmsg(jcr, M_FATAL, 0, _("Job canceled. Attempt to read and write same device.\n"));
+         Jmsg(jcr, M_FATAL, 0, _("Job canceled. Attempt to read and write same device.\n"
+            "    Read storage \"%s\" (From %s) -- Write storage \"%s\" (From %s)\n"), 
+            jcr->rstore->name(), jcr->rstore_source, jcr->wstore->name(), jcr->wstore_source);
          set_jcr_job_status(jcr, JS_Canceled);
          return false;
       }
index c8e90f0d203f054925613202aa6f4e4f46317409..6f660a6b59bad2ef729b43f844a027004282751e 100644 (file)
@@ -66,10 +66,37 @@ static int get_next_dbid_from_list(char **p, DBId_t *DBId);
 
 /* 
  * Called here before the job is run to do the job
- *   specific setup.
+ *   specific setup.  Note, one of the important things to
+ *   complete in this init code is to make the definitive
+ *   choice of input and output storage devices.  This is
+ *   because immediately after the init, the job is queued
+ *   in the jobq.c code, and it checks that all the resources
+ *   (storage resources in particular) are available, so these
+ *   must all be properly defined.
+ *
+ *  previous_jr refers to the job DB record of the Job that is
+ *    going to be migrated.
+ *  prev_job refers to the job resource of the Job that is
+ *    going to be migrated.
+ *  jcr is the jcr for the current "migration" job.  It is a
+ *    control job that is put in the DB as a migration job, which
+ *    means that this job migrated a previous job to a new job.
+ *    No Volume or File data is associated with this control
+ *    job.
+ *  mig_jcr refers to the newly migrated job that is run by
+ *    the current jcr.  It is a backup job that moves (migrates) the
+ *    data written for the previous_jr into the new pool.  This
+ *    job (mig_jcr) becomes the new backup job that replaces
+ *    the original backup job.
  */
 bool do_migration_init(JCR *jcr)
 {
+   POOL_DBR pr;
+   POOL *pool;
+   char ed1[100];
+   JOB *job, *prev_job;
+   JCR *mig_jcr;                   /* newly migrated job */
+
    /* If we find a job or jobs to migrate it is previous_jr.JobId */
    if (!get_job_to_migrate(jcr)) {
       return false;
@@ -97,7 +124,7 @@ bool do_migration_init(JCR *jcr)
       return false;
    }
 
-  /* If pool storage specified, use it instead of job storage */
+   /* If pool storage specified, use it instead of job storage */
    copy_wstorage(jcr, jcr->pool->storage, _("Pool resource"));
 
    if (jcr->wstorage->size() == 0) {
@@ -106,40 +133,7 @@ bool do_migration_init(JCR *jcr)
    }
 
    create_restore_bootstrap_file(jcr);
-   return true;
-}
-
-/*
- * Do a Migration of a previous job
- *
- *  Returns:  false on failure
- *            true  on success
- */
-bool do_migration(JCR *jcr)
-{
-   POOL_DBR pr;
-   POOL *pool;
-   char ed1[100];
-   BSOCK *sd;
-   JOB *job, *prev_job;
-   JCR *mig_jcr;                   /* newly migrated job */
 
-   /* 
-    *  previous_jr refers to the job DB record of the Job that is
-    *    going to be migrated.
-    *  prev_job refers to the job resource of the Job that is
-    *    going to be migrated.
-    *  jcr is the jcr for the current "migration" job.  It is a
-    *    control job that is put in the DB as a migration job, which
-    *    means that this job migrated a previous job to a new job.
-    *    No Volume or File data is associated with this control
-    *    job.
-    *  mig_jcr refers to the newly migrated job that is run by
-    *    the current jcr.  It is a backup job that moves (migrates) the
-    *    data written for the previous_jr into the new pool.  This
-    *    job (mig_jcr) becomes the new backup job that replaces
-    *    the original backup job.
-    */
    if (jcr->previous_jr.JobId == 0 || jcr->ExpectedFiles == 0) {
       set_jcr_job_status(jcr, JS_Terminated);
       Dmsg1(dbglevel, "JobId=%d expected files == 0\n", (int)jcr->JobId);
@@ -148,7 +142,6 @@ bool do_migration(JCR *jcr)
       } else {
          Jmsg(jcr, M_INFO, 0, _("Previous Job has no data to migrate.\n"));
       }
-      migration_cleanup(jcr, jcr->JobStatus);
       return true;                    /* no work */
    }
 
@@ -248,6 +241,23 @@ bool do_migration(JCR *jcr)
    /* If pool storage specified, use it instead of job storage for backup */
    copy_wstorage(jcr, jcr->pool->storage, _("Next pool resource"));
 
+
+   return true;
+}
+
+/*
+ * Do a Migration of a previous job
+ *
+ *  Returns:  false on failure
+ *            true  on success
+ */
+bool do_migration(JCR *jcr)
+{
+   char ed1[100];
+   BSOCK *sd;
+   JCR *mig_jcr = jcr->mig_jcr;    /* newly migrated job */
+
+
    /* Print Job Start message */
    Jmsg(jcr, M_INFO, 0, _("Start Migration JobId %s, Job=%s\n"),
         edit_uint64(jcr->JobId, ed1), jcr->Job);
@@ -1078,7 +1088,8 @@ void migration_cleanup(JCR *jcr, int TermCode)
 "  Client:                 %s\n"
 "  FileSet:                \"%s\" %s\n"
 "  Pool:                   \"%s\" (From %s)\n"
-"  Storage:                \"%s\" (From %s)\n"
+"  Read Storage:           \"%s\" (From %s_\n"
+"  Write Storage:          \"%s\" (From %s)\n"
 "  Start time:             %s\n"
 "  End time:               %s\n"
 "  Elapsed time:           %s\n"
@@ -1104,7 +1115,8 @@ void migration_cleanup(JCR *jcr, int TermCode)
         jcr->client->name(),
         jcr->fileset->name(), jcr->FSCreateTime,
         jcr->pool->name(), jcr->pool_source,
-        jcr->wstore->name(), jcr->storage_source,
+        jcr->rstore->name(), jcr->rstore_source,
+        jcr->wstore->name(), jcr->wstore_source,
         sdt,
         edt,
         edit_utime(RunTime, elapsed, sizeof(elapsed)),
index f83152fcca824b1c4f7fe4a9026ac203b2bec706..3980b3af4dd6c4731d9b176aee34987207f01218 100644 (file)
@@ -84,10 +84,10 @@ bool connect_to_storage_daemon(JCR *jcr, int retry_interval,
    }
 
    /* If there is a write storage use it */
-   if (jcr->wstorage) {
-      store = (STORE *)jcr->wstorage->first();
+   if (jcr->wstore) {
+      store = jcr->wstore;
    } else {
-      store = (STORE *)jcr->rstorage->first();
+      store = jcr->rstore;
    }
 
    /*
@@ -216,7 +216,8 @@ bool start_storage_daemon_job(JCR *jcr, alist *rstore, alist *wstore)
    /* Do read side of storage daemon */
    if (ok && rstore) {
       foreach_alist(storage, rstore) {
-         pm_strcpy(store_name, storage->hdr.name);
+         Dmsg1(100, "Rstore=%s\n", storage->name());
+         pm_strcpy(store_name, storage->name());
          bash_spaces(store_name);
          pm_strcpy(media_type, storage->media_type);
          bash_spaces(media_type);
@@ -246,7 +247,8 @@ bool start_storage_daemon_job(JCR *jcr, alist *rstore, alist *wstore)
    /* Do write side of storage daemon */
    if (ok && wstore) {
       foreach_alist(storage, wstore) {
-         pm_strcpy(store_name, storage->hdr.name);
+         Dmsg1(100, "Wstore=%s\n", storage->name());
+         pm_strcpy(store_name, storage->name());
          bash_spaces(store_name);
          pm_strcpy(media_type, storage->media_type);
          bash_spaces(media_type);
index 1c48fc9ab140205fed774145a54eb433adad6921..25dbfa3db42a5d5f726ffa2b126e6f1b85e9c6e2 100644 (file)
@@ -111,16 +111,16 @@ extern DBId_t get_or_create_pool_record(JCR *jcr, char *pool_name);
 extern void apply_pool_overrides(JCR *jcr);
 extern JobId_t run_job(JCR *jcr);
 extern bool cancel_job(UAContext *ua, JCR *jcr);
-extern STORE *get_job_storage(JOB *job);
+extern void get_job_storage(USTORE *store, JOB *job, RUN *run);
 extern void init_jcr_job_record(JCR *jcr);
 extern void copy_rwstorage(JCR *jcr, alist *storage, const char *where);
-extern void set_rwstorage(JCR *jcr, STORE *store);
+extern void set_rwstorage(JCR *jcr, USTORE *store);
 extern void free_rwstorage(JCR *jcr);
 extern void copy_wstorage(JCR *jcr, alist *storage, const char *where);
-extern void set_wstorage(JCR *jcr, STORE *store);
+extern void set_wstorage(JCR *jcr, USTORE *store);
 extern void free_wstorage(JCR *jcr);
 extern void copy_rstorage(JCR *jcr, alist *storage, const char *where);
-extern void set_rstorage(JCR *jcr, STORE *store);
+extern void set_rstorage(JCR *jcr, USTORE *store);
 extern void free_rstorage(JCR *jcr);
 extern bool setup_job(JCR *jcr);
 extern void create_clones(JCR *jcr);
index 6b9550442fc6791a9b48e8c8e187a192ead48918..f06e2378a00e3b716693d3fdced177e2f637b6f0 100644 (file)
@@ -218,7 +218,10 @@ again:
       jcr->run_diff_pool_override = true;
    }
    if (run->storage) {
-      set_rwstorage(jcr, run->storage); /* override storage */
+      USTORE store;
+      store.store = run->storage;
+      pm_strcpy(store.store_source, _("run override"));
+      set_rwstorage(jcr, &store);     /* override storage */
    }
    if (run->msgs) {
       jcr->messages = run->msgs;      /* override messages */
index a019c3be6c8fae4519742a53d8525b6ef00e2ec7..8e6bb272d9f1d1f24212e55e97921ac3e4e21bf4 100644 (file)
@@ -684,8 +684,11 @@ static void do_storage_setdebug(UAContext *ua, STORE *store, int level, int trac
 {
    BSOCK *sd;
    JCR *jcr = ua->jcr;
-
-   set_wstorage(jcr, store);
+   USTORE lstore;
+   
+   lstore.store = store;
+   pm_strcpy(lstore.store_source, _("unknown source"));
+   set_wstorage(jcr, &lstore);
    /* Try connecting for up to 15 seconds */
    bsendmsg(ua, _("Connecting to Storage daemon %s at %s:%d\n"),
       store->name(), store->address, store->SDport);
@@ -1309,7 +1312,7 @@ static int delete_pool(UAContext *ua)
 
 static void do_mount_cmd(UAContext *ua, const char *command)
 {
-   STORE *store;
+   USTORE store;
    BSOCK *sd;
    JCR *jcr = ua->jcr;
    char dev_name[MAX_NAME_LENGTH];
@@ -1321,25 +1324,26 @@ static void do_mount_cmd(UAContext *ua, const char *command)
    }
    Dmsg2(120, "%s: %s\n", command, ua->UA_sock->msg);
 
-   store = get_storage_resource(ua, true/*arg is storage*/);
-   if (!store) {
+   store.store = get_storage_resource(ua, true/*arg is storage*/);
+   pm_strcpy(store.store_source, _("unknown source"));
+   if (!store.store) {
       return;
    }
-   set_wstorage(jcr, store);
-   drive = get_storage_drive(ua, store);
+   set_wstorage(jcr, &store);
+   drive = get_storage_drive(ua, store.store);
    if (strcmp(command, "mount") == 0) {
-      slot = get_storage_slot(ua, store);
+      slot = get_storage_slot(ua, store.store);
    }
 
    Dmsg3(120, "Found storage, MediaType=%s DevName=%s drive=%d\n",
-      store->media_type, store->dev_name(), drive);
+      store.store->media_type, store.store->dev_name(), drive);
 
    if (!connect_to_storage_daemon(jcr, 10, SDConnectTimeout, 1)) {
       bsendmsg(ua, _("Failed to connect to Storage daemon.\n"));
       return;
    }
    sd = jcr->store_bsock;
-   bstrncpy(dev_name, store->dev_name(), sizeof(dev_name));
+   bstrncpy(dev_name, store.store->dev_name(), sizeof(dev_name));
    bash_spaces(dev_name);
    if (slot > 0) {
       bnet_fsend(sd, "%s %s drive=%d slot=%d", command, dev_name, drive, slot);
index 2552cd2f7039c6c31f4a3bb7fd16676b4c1375ac..3d0d9bb53a92df71699c1944ba18a593950fb069 100644 (file)
@@ -291,13 +291,13 @@ static int defaultscmd(UAContext *ua, const char *cmd)
       }
       job = (JOB *)GetResWithName(R_JOB, ua->argv[1]);
       if (job) {
-         STORE *store;
+         USTORE store;
          bsendmsg(ua, "job=%s", job->hdr.name);
          bsendmsg(ua, "pool=%s", job->pool->hdr.name);
          bsendmsg(ua, "messages=%s", job->messages->hdr.name);
          bsendmsg(ua, "client=%s", job->client->hdr.name);
-         store = get_job_storage(job);
-         bsendmsg(ua, "storage=%s", store->hdr.name);
+         get_job_storage(&store, job, NULL);
+         bsendmsg(ua, "storage=%s", store.store->name());
          bsendmsg(ua, "where=%s", job->RestoreWhere?job->RestoreWhere:"");
          bsendmsg(ua, "level=%s", level_to_str(job->JobLevel));
          bsendmsg(ua, "type=%s", job_type_to_str(job->JobType));
index cfbb7a6c89b6fb6873b431a671e4d6238a5005fc..fbd26f8e0ba82e227151b713ed3991c1553b6229 100644 (file)
@@ -162,7 +162,7 @@ bail_out:
  */
 void update_slots(UAContext *ua)
 {
-   STORE *store;
+   USTORE store;
    vol_list_t *vl, *vol_list = NULL;
    MEDIA_DBR mr;
    char *slot_list;
@@ -177,12 +177,13 @@ void update_slots(UAContext *ua)
    if (!open_db(ua)) {
       return;
    }
-   store = get_storage_resource(ua, true/*arg is storage*/);
-   if (!store) {
+   store.store = get_storage_resource(ua, true/*arg is storage*/);
+   if (!store.store) {
       return;
    }
-   set_wstorage(ua->jcr, store);
-   drive = get_storage_drive(ua, store);
+   pm_strcpy(store.store_source, _("command line"));
+   set_wstorage(ua->jcr, &store);
+   drive = get_storage_drive(ua, store.store);
 
    scan = find_arg(ua, NT_("scan")) >= 0;
    if ((i=find_arg_with_value(ua, NT_("Enabled"))) >= 0) {
@@ -242,7 +243,7 @@ void update_slots(UAContext *ua)
       memset(&mr, 0, sizeof(mr));
       mr.Slot = vl->Slot;
       mr.InChanger = 1;
-      mr.StorageId = store->StorageId;
+      mr.StorageId = store.store->StorageId;
       /* Set InChanger to zero for this Slot */
       db_lock(ua->db);
       db_make_inchanger_unique(ua->jcr, ua->db, &mr);
@@ -256,10 +257,10 @@ void update_slots(UAContext *ua)
       bstrncpy(mr.VolumeName, vl->VolName, sizeof(mr.VolumeName));
       db_lock(ua->db);
       if (db_get_media_record(ua->jcr, ua->db, &mr)) {
-         if (mr.Slot != vl->Slot || !mr.InChanger || mr.StorageId != store->StorageId) {
+         if (mr.Slot != vl->Slot || !mr.InChanger || mr.StorageId != store.store->StorageId) {
             mr.Slot = vl->Slot;
             mr.InChanger = 1;
-            mr.StorageId = store->StorageId;
+            mr.StorageId = store.store->StorageId;
             if (have_enabled) {
                mr.Enabled = Enabled;
             }
@@ -284,7 +285,7 @@ void update_slots(UAContext *ua)
    }
    memset(&mr, 0, sizeof(mr));
    mr.InChanger = 1;
-   mr.StorageId = store->StorageId;
+   mr.StorageId = store.store->StorageId;
    db_lock(ua->db);
    for (int i=1; i <= max_slots; i++) {
       if (slot_list[i]) {
@@ -310,7 +311,7 @@ bail_out:
  */
 static int do_label(UAContext *ua, const char *cmd, int relabel)
 {
-   STORE *store;
+   USTORE store;
    BSOCK *sd;
    char dev_name[MAX_NAME_LENGTH];
    MEDIA_DBR mr, omr;
@@ -341,12 +342,13 @@ static int do_label(UAContext *ua, const char *cmd, int relabel)
       label_barcodes = true;
    }
 
-   store = get_storage_resource(ua, true/*use default*/);
-   if (!store) {
+   store.store = get_storage_resource(ua, true/*use default*/);
+   if (!store.store) {
       return 1;
    }
-   set_wstorage(ua->jcr, store);
-   drive = get_storage_drive(ua, store);
+   pm_strcpy(store.store_source, _("command line"));
+   set_wstorage(ua->jcr, &store);
+   drive = get_storage_drive(ua, store.store);
 
    if (label_barcodes) {
       label_from_barcodes(ua, drive);
@@ -416,16 +418,16 @@ checkName:
    if (i >= 0) {
       mr.Slot = atoi(ua->argv[i]);
       mr.InChanger = 1;               /* assumed if we are labeling it */
-   } else if (store->autochanger) {
+   } else if (store.store->autochanger) {
       if (!get_pint(ua, _("Enter slot (0 or Enter for none): "))) {
          return 1;
       }
       mr.Slot = ua->pint32_val;
       mr.InChanger = 1;               /* assumed if we are labeling it */
    }
-   mr.StorageId = store->StorageId;
+   mr.StorageId = store.store->StorageId;
 
-   bstrncpy(mr.MediaType, store->media_type, sizeof(mr.MediaType));
+   bstrncpy(mr.MediaType, store.store->media_type, sizeof(mr.MediaType));
 
    /* Must select Pool if not already done */
    if (pr.PoolId == 0) {
@@ -455,7 +457,7 @@ checkName:
          }
       }
       if (ua->automount) {
-         bstrncpy(dev_name, store->dev_name(), sizeof(dev_name));
+         bstrncpy(dev_name, store.store->dev_name(), sizeof(dev_name));
          bsendmsg(ua, _("Requesting to mount %s ...\n"), dev_name);
          bash_spaces(dev_name);
          bnet_fsend(sd, "mount %s drive=%d", dev_name, drive);
index ce329205d568a7cb14daaa7be0830236e1e3c0e7..2e2dcf61e0d6446fb6f2d932d5377a7d0c156b9f 100644 (file)
@@ -448,6 +448,7 @@ static bool list_nextvol(UAContext *ua, int ndays)
    JOB *job;
    JCR *jcr = ua->jcr;
    POOL *pool;
+   USTORE store;
    RUN *run;
    time_t runtime;
    bool found = false;
@@ -480,12 +481,8 @@ static bool list_nextvol(UAContext *ua, int ndays)
          bstrncpy(pr.Name, "*UnknownPool*", sizeof(pr.Name));
       }
       mr.PoolId = jcr->jr.PoolId;
-      if (run->storage) {
-         jcr->wstore = run->storage;
-      } else {
-         jcr->wstore = get_job_storage(job);
-      }
-      mr.StorageId = jcr->wstore->StorageId;
+      get_job_storage(&store, job, run);
+      mr.StorageId = store.store->StorageId;
       if (!find_next_volume_for_append(jcr, &mr, 1, false/*no create*/)) {
          bsendmsg(ua, _("Could not find next Volume for Job %s (%s, %s).\n"),
             job->hdr.name, pr.Name, level_to_str(run->level));
index ddc82bd2065da9602b8ab264e946da8727e63074..bfa2e2844fc3ad2a8ffac8389d4dc829f09ca8a6 100644 (file)
@@ -70,7 +70,7 @@ int run_cmd(UAContext *ua, const char *cmd)
    JOB *job = NULL;
    JOB *verify_job = NULL;
    JOB *previous_job = NULL;
-   STORE *store = NULL;
+   USTORE store;
    CLIENT *client = NULL;
    FILESET *fileset = NULL;
    POOL *pool = NULL;
@@ -345,24 +345,26 @@ int run_cmd(UAContext *ua, const char *cmd)
    }
 
    if (store_name) {
-      store = (STORE *)GetResWithName(R_STORAGE, store_name);
-      if (!store) {
+      store.store = (STORE *)GetResWithName(R_STORAGE, store_name);
+      pm_strcpy(store.store_source, _("command line"));
+      if (!store.store) {
          if (*store_name != 0) {
             bsendmsg(ua, _("Storage \"%s\" not found.\n"), store_name);
          }
-         store = select_storage_resource(ua);
+         store.store = select_storage_resource(ua);
+         pm_strcpy(store.store_source, _("user selection"));
       }
    } else {
-      store = get_job_storage(job);            /* use default */
+      get_job_storage(&store, job, NULL);      /* use default */
    }
-   if (!store) {
+   if (!store.store) {
       return 1;
-   } else if (!acl_access_ok(ua, Storage_ACL, store->name())) {
+   } else if (!acl_access_ok(ua, Storage_ACL, store.store->name())) {
       bsendmsg(ua, _("No authorization. Storage \"%s\".\n"),
-               store->name());
+               store.store->name());
       return 0;
    }
-   Dmsg1(800, "Using storage=%s\n", store->name());
+   Dmsg1(800, "Using storage=%s\n", store.store->name());
 
    if (pool_name) {
       pool = (POOL *)GetResWithName(R_POOL, pool_name);
@@ -451,7 +453,7 @@ int run_cmd(UAContext *ua, const char *cmd)
 
    jcr->verify_job = verify_job;
    jcr->previous_job = previous_job;
-   set_rwstorage(jcr, store);
+   set_rwstorage(jcr, &store);
    jcr->client = client;
    jcr->fileset = fileset;
    jcr->pool = pool;
@@ -800,9 +802,10 @@ try_again:
          goto try_again;
       case 1:
          /* Storage */
-         store = select_storage_resource(ua);
-         if (store) {
-            set_rwstorage(jcr, store);
+         store.store = select_storage_resource(ua);
+         if (store.store) {
+            pm_strcpy(store.store_source, _("user selection"));
+            set_rwstorage(jcr, &store);
             goto try_again;
          }
          break;
index 89afc6fb255cbc1957c15d2f0cfcff1c3953edb5..fc1c2d889ad4d4b569520119e92719e55181ae01 100644 (file)
@@ -288,8 +288,11 @@ static void do_director_status(UAContext *ua)
 static void do_storage_status(UAContext *ua, STORE *store)
 {
    BSOCK *sd;
+   USTORE lstore;
 
-   set_wstorage(ua->jcr, store);
+   lstore.store = store;
+   pm_strcpy(lstore.store_source, _("unknown source"));
+   set_wstorage(ua->jcr, &lstore);
    /* Try connecting for up to 15 seconds */
    bsendmsg(ua, _("Connecting to Storage daemon %s at %s:%d\n"),
       store->name(), store->address, store->SDport);
@@ -445,7 +448,6 @@ static void list_scheduled_jobs(UAContext *ua)
    time_t runtime;
    RUN *run;
    JOB *job;
-   STORE* store;
    int level, num_jobs = 0;
    int priority;
    bool hdr_printed = false;
@@ -472,6 +474,7 @@ static void list_scheduled_jobs(UAContext *ua)
          continue;
       }
       for (run=NULL; (run = find_next_run(run, job, runtime, days)); ) {
+         USTORE store;
          level = job->JobLevel;
          if (run->level) {
             level = run->level;
@@ -480,11 +483,6 @@ static void list_scheduled_jobs(UAContext *ua)
          if (run->Priority) {
             priority = run->Priority;
          }
-         if (run->storage) {
-            store = run->storage;
-         } else {
-            store = get_job_storage(job);
-         }
          if (!hdr_printed) {
             prt_runhdr(ua);
             hdr_printed = true;
@@ -495,7 +493,8 @@ static void list_scheduled_jobs(UAContext *ua)
          sp->priority = priority;
          sp->runtime = runtime;
          sp->pool = run->pool;
-         sp->store = store;
+         get_job_storage(&store, job, run);
+         sp->store = store.store;
          sched.binary_insert_multiple(sp, my_compare);
          num_jobs++;
       }
index 8d15a91ef9a6d1bf1f5aeb991385244a468132a1..4f53c2baaabdeaf8fbcc8cacb9fc70edbf9096af 100644 (file)
@@ -236,7 +236,8 @@ public:
    };
    POOLMEM *client_uname;             /* client uname */
    POOLMEM *pool_source;              /* Where pool came from */
-   POOLMEM *storage_source;           /* Where storage came from */
+   POOLMEM *rstore_source;            /* Where read storage came from */
+   POOLMEM *wstore_source;            /* Where write storage came from */
    int replace;                       /* Replace option */
    int NumVols;                       /* Number of Volume used in pool */
    int reschedule_count;              /* Number of times rescheduled */
index 8c7f3de857d97861cd6e6a0dc06fc8b99bfe4228..c59d6e8dacfb97f28d7e1b0768340e7f41af2ca0 100644 (file)
@@ -92,7 +92,6 @@ static bool my_mount_next_read_volume(DCR *dcr);
 static void scan_blocks();
 static void set_volume_name(const char *VolName, int volnum);
 static void rawfill_cmd();
-static void bfill_cmd();
 static bool open_the_device();
 static void autochangercmd();
 static void do_unfill();
@@ -2522,60 +2521,12 @@ static void rawfill_cmd()
 }
 
 
-/*
- * Fill a tape using Bacula block writes
- */
-static void bfill_cmd()
-{
-   DEV_BLOCK *block = dcr->block;
-   uint32_t block_num = 0;
-   uint32_t *p;
-   int my_errno;
-   int fd;
-   uint32_t i;
-
-   fd = open("/dev/urandom", O_RDONLY);
-   if (fd) {
-      read(fd, block->buf, block->buf_len);
-      close(fd);
-   } else {
-      uint32_t *p = (uint32_t *)block->buf;
-      srandom(time(NULL));
-      for (i=0; i<block->buf_len/sizeof(uint32_t); i++) {
-         p[i] = random();
-      }
-   }
-   p = (uint32_t *)block->buf;
-   Pmsg1(0, _("Begin writing Bacula blocks of %u bytes.\n"), block->buf_len);
-   for ( ;; ) {
-      *p = block_num;
-      block->binbuf = block->buf_len;
-      block->bufp = block->buf + block->binbuf;
-      if (!write_block_to_dev(dcr)) {
-         break;
-      }
-      if ((block_num++ % 100) == 0) {
-         printf("+");
-         fflush(stdout);
-      }
-      p[0] += p[13];
-      for (i=1; i<(block->buf_len/sizeof(uint32_t)-1); i++) {
-         p[i] += p[i-1];
-      }
-   }
-   my_errno = errno;
-   printf("\n");
-   printf(_("Write failed at block %u.\n"), block_num);
-   weofcmd();
-}
-
 
 struct cmdstruct { const char *key; void (*func)(); const char *help; };
 static struct cmdstruct commands[] = {
  {NT_("autochanger"),autochangercmd, _("test autochanger")},
  {NT_("bsf"),       bsfcmd,       _("backspace file")},
  {NT_("bsr"),       bsrcmd,       _("backspace record")},
- {NT_("bfill"),     bfill_cmd,    _("fill tape using Bacula writes")},
  {NT_("cap"),       capcmd,       _("list device capabilities")},
  {NT_("clear"),     clearcmd,     _("clear tape errors")},
  {NT_("eod"),       eodcmd,       _("go to end of Bacula data for append")},
index ff576be27a5e7da32df68425ed6474b165bad5a6..5346f4f2a8f9c28d8c0997ea1b80b49139237751 100644 (file)
@@ -4,8 +4,9 @@
 
 #undef  VERSION
 #define VERSION "1.39.29"
-#define BDATE   "20 November 2006"
-#define LSMDATE "20Nov06"
+#define BDATE   "24 November 2006"
+#define LSMDATE "24Nov06"
+
 #define PROG_COPYRIGHT "Copyright (C) 2000-%s Free Software Foundation Europe e.V.\n"
 #define BYEAR "2006"       /* year for copyright messages in progs */
 
index b19a25f78e3e7eb0e772cd10f2537b5bad7f3237..933422cfe2be0c99003c606ad07828b92a1d95cb 100644 (file)
@@ -2,6 +2,18 @@
 
 General:
 22Nov06
+kes  Separate read/write source strings to keep track of where
+     storage devices are used in a job.
+kes  Implement a new method of keeping track of which storage 
+     device is used in a Job.  USTORE keeps both a pointer to the
+     resource and to the source string.
+kes  Modify all code to use new storage set subroutines in job.c
+kes  Modify migrate.c so that the definitive selection of the storage
+     resource is done in the do_migration_init() routine prior to
+     the job going into the job queue.  This permits accurate 
+     deadlock detection (same read and write storage resource).
+kes  Remove bfill from btape (I think it was a left over stub).
+22Nov06
 kes  Make sure that the storage for a job is pulled first from
      the Pool and if not from the Job.  
 kes  Ensure that either the Pool or the Job specifies a Storage