Priority:
+- Fix prog copyright (SD) all other files.
- Migration Volume span bug
- Rescue release
- Bug reports
goto bail_out;
}
-
if (!send_runscripts_commands(jcr)) {
goto bail_out;
}
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,
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
{
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;
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
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;
}
}
generate_job_event(jcr, "JobInit");
-
- Dmsg0(200, "Add jrc to work queue\n");
return true;
bail_out:
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;
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
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;
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;
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;
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");
* 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"));
}
}
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) {
jcr->JobLevel = L_NONE;
break;
default:
+ jcr->JobLevel = L_FULL;
break;
}
}
*/
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)
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)
}
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)
}
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;
}
/*
* 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;
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) {
}
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);
} else {
Jmsg(jcr, M_INFO, 0, _("Previous Job has no data to migrate.\n"));
}
- migration_cleanup(jcr, jcr->JobStatus);
return true; /* no work */
}
/* 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);
" 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"
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)),
}
/* 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;
}
/*
/* 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);
/* 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);
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);
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 */
{
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);
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];
}
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);
}
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));
*/
void update_slots(UAContext *ua)
{
- STORE *store;
+ USTORE store;
vol_list_t *vl, *vol_list = NULL;
MEDIA_DBR mr;
char *slot_list;
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) {
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);
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;
}
}
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]) {
*/
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;
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);
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) {
}
}
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);
JOB *job;
JCR *jcr = ua->jcr;
POOL *pool;
+ USTORE store;
RUN *run;
time_t runtime;
bool found = false;
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));
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;
}
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);
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;
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;
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);
time_t runtime;
RUN *run;
JOB *job;
- STORE* store;
int level, num_jobs = 0;
int priority;
bool hdr_printed = false;
continue;
}
for (run=NULL; (run = find_next_run(run, job, runtime, days)); ) {
+ USTORE store;
level = job->JobLevel;
if (run->level) {
level = run->level;
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;
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++;
}
};
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 */
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();
}
-/*
- * 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")},
#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 */
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