General:
08Jul06
+ ======================= Warning ==========================
+ Separate read and write storage in Jobs in the Director. This
+ is a major rewrite of some of the low level code and hence has
+ a high probability of introducing bugs.
+ ==========================================================
+
+- Move the job init code up to *before* the job is put into
+ the job queue (resource allocation queue). This permits the
+ job to establish whether it will read or write or do both.
+- Add name() methods to all the resource classes.
+- Implement separate read and write storage resource
+ allocation/deallocation in jobq.c
+
======================= Warning ==========================
Implemented new method of getting the default Storage from the Media
record rather than from the MediaType for restore. As a fall
*/
/*
- Copyright (C) 2000-2004 Kern Sibbald and John Walker
+ Copyright (C) 2003-2006 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
- published by the Free Software Foundation; either version 2 of
- the License, or (at your option) any later version.
+ modify it under the terms of the GNU General Public License
+ version 2 as amended with additional clauses defined in the
+ file LICENSE in the main source directory.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public
- License along with this program; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA.
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ the file LICENSE for additional details.
*/
bool do_admin_init(JCR *jcr)
{
+ free_rstorage(jcr);
return true;
}
/*
* Returns: false on failure
- * true on success
+ * true on success
*/
bool do_admin(JCR *jcr)
{
/* Print Job Start message */
Jmsg(jcr, M_INFO, 0, _("Start Admin JobId %d, Job=%s\n"),
- jcr->JobId, jcr->Job);
+ jcr->JobId, jcr->Job);
set_jcr_job_status(jcr, JS_Running);
admin_cleanup(jcr, JS_Terminated);
memset(&mr, 0, sizeof(mr));
set_jcr_job_status(jcr, TermCode);
- update_job_end_record(jcr); /* update database */
+ update_job_end_record(jcr); /* update database */
if (!db_get_job_record(jcr, jcr->db, &jcr->jr)) {
Jmsg(jcr, M_WARNING, 0, _("Error getting job record for stats: %s"),
- db_strerror(jcr->db));
+ db_strerror(jcr->db));
set_jcr_job_status(jcr, JS_ErrorTerminated);
}
- msg_type = M_INFO; /* by default INFO message */
+ msg_type = M_INFO; /* by default INFO message */
switch (jcr->JobStatus) {
case JS_Terminated:
term_msg = _("Admin OK");
case JS_FatalError:
case JS_ErrorTerminated:
term_msg = _("*** Admin Error ***");
- msg_type = M_ERROR; /* Generate error message */
+ msg_type = M_ERROR; /* Generate error message */
break;
case JS_Canceled:
term_msg = _("Admin Canceled");
" Start time: %s\n"
" End time: %s\n"
" Termination: %s\n\n"),
- edt,
- jcr->jr.JobId,
- jcr->jr.Job,
- sdt,
- edt,
- term_msg);
+ edt,
+ jcr->jr.JobId,
+ jcr->jr.Job,
+ sdt,
+ edt,
+ term_msg);
Dmsg0(100, "Leave admin_cleanup()\n");
}
bool do_backup_init(JCR *jcr)
{
+ free_rstorage(jcr); /* we don't read so release */
+
if (!get_or_create_fileset_record(jcr)) {
return false;
}
}
/* If pool storage specified, use it instead of job storage */
- copy_storage(jcr, jcr->pool->storage, _("Pool resource"));
+ copy_wstorage(jcr, jcr->pool->storage, _("Pool resource"));
- if (!jcr->storage) {
+ if (!jcr->wstorage) {
Jmsg(jcr, M_FATAL, 0, _("No Storage specification found in Job or Pool.\n"));
return false;
}
create_clones(jcr); /* run any clone jobs */
+ Dmsg2(000, "rstore=%p wstore=%p\n", jcr->rstore, jcr->wstore);
+
return true;
}
/*
* Now start a job with the Storage daemon
*/
- if (!start_storage_daemon_job(jcr, NULL, jcr->storage)) {
+ if (!start_storage_daemon_job(jcr, NULL, jcr->wstorage)) {
return false;
}
/*
* send Storage daemon address to the File daemon
*/
- store = jcr->store;
+ store = jcr->wstore;
if (store->SDDport == 0) {
store->SDDport = store->SDport;
}
jcr->jr.JobId,
jcr->jr.Job,
level_to_str(jcr->JobLevel), jcr->since,
- jcr->client->hdr.name, cr.Uname,
- jcr->fileset->hdr.name, jcr->FSCreateTime,
- jcr->pool->hdr.name, jcr->pool_source,
- jcr->store->hdr.name, jcr->storage_source,
+ jcr->client->name(), cr.Uname,
+ jcr->fileset->name(), jcr->FSCreateTime,
+ jcr->pool->name(), jcr->pool_source,
+ jcr->wstore->name(), jcr->storage_source,
schedt,
sdt,
edt,
ok = db_get_pool_record(jcr, jcr->db, &pr);
if (ok) {
mr.PoolId = pr.PoolId;
- mr.StorageId = jcr->store->StorageId;
+ mr.StorageId = jcr->wstore->StorageId;
ok = find_next_volume_for_append(jcr, &mr, index, true /*permit create new vol*/);
Dmsg3(100, "find_media idx=%d ok=%d vol=%s\n", index, ok, mr.VolumeName);
}
*/
if (mr.PoolId != jcr->jr.PoolId) {
reason = _("not in Pool");
- } else if (strcmp(mr.MediaType, jcr->store->media_type) != 0) {
+ } else if (strcmp(mr.MediaType, jcr->wstore->media_type) != 0) {
reason = _("not correct MediaType");
} else {
/*
mr.VolWriteTime = sdmr.VolWriteTime;
mr.VolParts = sdmr.VolParts;
bstrncpy(mr.VolStatus, sdmr.VolStatus, sizeof(mr.VolStatus));
- if (jcr->store->StorageId) {
- mr.StorageId = jcr->store->StorageId;
+ if (jcr->wstore->StorageId) {
+ mr.StorageId = jcr->wstore->StorageId;
}
Dmsg2(400, "db_update_media_record. Stat=%s Vol=%s\n", mr.VolStatus, mr.VolumeName);
bool tls_enable; /* Enable TLS */
bool tls_require; /* Require TLS */
bool tls_verify_peer; /* TLS Verify Client Certificate */
+
+ /* Methods */
+ char *name() const;
};
+inline char *DIRRES::name() const { return hdr.name; }
+
/*
* Device Resource
* This resource is a bit different from the other resources
char ChangerName[MAX_NAME_LENGTH];
char VolumeName[MAX_NAME_LENGTH];
char MediaType[MAX_NAME_LENGTH];
+
+ /* Methods */
+ char *name() const;
};
+inline char *DEVICE::name() const { return hdr.name; }
+
/*
* Console ACL positions
*/
bool tls_enable; /* Enable TLS */
bool tls_require; /* Require TLS */
bool tls_verify_peer; /* TLS Verify Client Certificate */
+
+ /* Methods */
+ char *name() const;
};
+inline char *CONRES::name() const { return hdr.name; }
+
/*
* Catalog Resource
char *db_user;
char *db_name;
int mult_db_connections; /* set if multiple connections wanted */
+
+ /* Methods */
+ char *name() const;
};
+inline char *CAT::name() const { return hdr.name; }
+
/*
* Client Resource
bool tls_enable; /* Enable TLS */
bool tls_require; /* Require TLS */
bool AutoPrune; /* Do automatic pruning? */
+
+ /* Methods */
+ char *name() const;
};
+inline char *CLIENT::name() const { return hdr.name; }
+
+
/*
* Store Resource
*
JOB *jobdefs; /* Job defaults */
alist *run_cmds; /* Run commands */
uint32_t NumConcurrentJobs; /* number of concurrent jobs running */
+
+ /* Methods */
+ char *name() const;
};
+inline char *JOB::name() const { return hdr.name; }
+
#undef MAX_FOPTS
#define MAX_FOPTS 34
char MD5[30]; /* base 64 representation of MD5 */
bool ignore_fs_changes; /* Don't force Full if FS changed */
bool enable_vss; /* Enable Volume Shadow Copy */
+
+ /* Methods */
+ char *name() const;
};
+inline char *FILESET::name() const { return hdr.name; }
/*
* Schedule Resource
COUNTER *WrapCounter; /* Wrap counter name */
CAT *Catalog; /* Where to store */
bool created; /* Created in DB */
+ /* Methods */
+ char *name() const;
};
+inline char *COUNTER::name() const { return hdr.name; }
+
/*
* Pool Resource
*
bool recycle_current_volume; /* attempt recycle of current volume */
bool AutoPrune; /* default for pool auto prune */
bool Recycle; /* default for media recycle yes/no */
+
+ /* Methods */
+ char *name() const;
};
+inline char *POOL::name() const { return hdr.name; }
+
switch (code) {
case 1: /* Job */
- str = jcr->job->hdr.name;
+ str = jcr->job->name();
break;
case 2: /* Director's name */
str = my_name;
str = buf;
break;
case 6: /* Client */
- str = jcr->client->hdr.name;
+ str = jcr->client->name();
if (!str) {
str = " ";
}
str = buf;
break;
case 8: /* Pool */
- str = jcr->pool->hdr.name;
+ str = jcr->pool->name();
break;
case 9: /* Storage */
- str = jcr->store->hdr.name;
+ if (jcr->wstore) {
+ str = jcr->wstore->name();
+ } else {
+ str = jcr->rstore->name();
+ }
break;
case 10: /* Catalog */
- str = jcr->catalog->hdr.name;
+ str = jcr->catalog->name();
break;
case 11: /* MediaType */
- str = jcr->store->media_type;
+ if (jcr->wstore) {
+ str = jcr->wstore->media_type;
+ } else {
+ str = jcr->rstore->media_type;
+ }
break;
case 12: /* JobName */
str = jcr->Job;
buf[var_len] = 0;
LockRes();
for (COUNTER *counter=NULL; (counter = (COUNTER *)GetNextRes(R_COUNTER, (RES *)counter)); ) {
- if (strcmp(counter->hdr.name, buf) == 0) {
+ if (strcmp(counter->name(), buf) == 0) {
Dmsg2(100, "Counter=%s val=%d\n", buf, counter->CurrentValue);
/* -1 => return size of array */
if (var_index == -1) {
COUNTER_DBR cr;
JCR *jcr = (JCR *)my_ctx;
memset(&cr, 0, sizeof(cr));
- bstrncpy(cr.Counter, counter->hdr.name, sizeof(cr.Counter));
+ bstrncpy(cr.Counter, counter->name(), sizeof(cr.Counter));
cr.MinValue = counter->MinValue;
cr.MaxValue = counter->MaxValue;
cr.CurrentValue = counter->CurrentValue;
Dmsg1(100, "New value=%d\n", cr.CurrentValue);
if (counter->WrapCounter) {
- bstrncpy(cr.WrapCounter, counter->WrapCounter->hdr.name, sizeof(cr.WrapCounter));
+ bstrncpy(cr.WrapCounter, counter->WrapCounter->name(), sizeof(cr.WrapCounter));
} else {
cr.WrapCounter[0] = 0;
}
if (!db_update_counter_record(jcr, jcr->db, &cr)) {
Jmsg(jcr, M_ERROR, 0, _("Count not update counter %s: ERR=%s\n"),
- counter->hdr.name, db_strerror(jcr->db));
+ counter->name(), db_strerror(jcr->db));
}
}
}
Dmsg1(100, "Val=%s\n", buf);
LockRes();
for (COUNTER *counter=NULL; (counter = (COUNTER *)GetNextRes(R_COUNTER, (RES *)counter)); ) {
- if (strcmp(counter->hdr.name, buf) == 0) {
- Dmsg2(100, "counter=%s val=%s\n", counter->hdr.name, buf);
+ if (strcmp(counter->name(), buf) == 0) {
+ Dmsg2(100, "counter=%s val=%s\n", counter->name(), buf);
break;
}
}
goto bail_out;
}
- Dmsg0(200, "Add jrc to work queue\n");
- return true;
-
-bail_out:
- return false;
-}
-
-
-/*
- * This is the engine called by jobq.c:jobq_add() when we were pulled
- * from the work queue.
- * At this point, we are running in our own thread and all
- * necessary resources are allocated -- see jobq.c
- */
-static void *job_thread(void *arg)
-{
- JCR *jcr = (JCR *)arg;
-
- jcr->my_thread_id = pthread_self();
- pthread_detach(jcr->my_thread_id);
- sm_check(__FILE__, __LINE__, true);
-
- Dmsg0(200, "=====Start Job=========\n");
- jcr->start_time = time(NULL); /* set the real start time */
- jcr->jr.StartTime = jcr->start_time;
-
- if (jcr->job->MaxStartDelay != 0 && jcr->job->MaxStartDelay <
- (utime_t)(jcr->start_time - jcr->sched_time)) {
- Jmsg(jcr, M_FATAL, 0, _("Job canceled because max start delay time exceeded.\n"));
- set_jcr_job_status(jcr, JS_Canceled);
- }
-
- /* TODO : check if it is used somewhere */
- if (jcr->job->RunScripts == NULL)
- {
- Dmsg0(200, "Warning, job->RunScripts is empty\n");
- jcr->job->RunScripts = New(alist(10, not_owned_by_alist));
- }
-
- /*
- * Note, we continue, even if the job is canceled above. This
- * will permit proper setting of the job start record and
- * the error (cancel) will be picked up below.
- */
-
- generate_job_event(jcr, "JobInit");
- set_jcr_job_status(jcr, JS_Running); /* this will be set only if no error */
-
/*
* Now, do pre-run stuff, like setting job level (Inc/diff, ...)
break;
}
+ generate_job_event(jcr, "JobInit");
+
+ Dmsg0(200, "Add jrc to work queue\n");
+ return true;
+
+bail_out:
+ return false;
+}
+
+
+/*
+ * This is the engine called by jobq.c:jobq_add() when we were pulled
+ * from the work queue.
+ * At this point, we are running in our own thread and all
+ * necessary resources are allocated -- see jobq.c
+ */
+static void *job_thread(void *arg)
+{
+ JCR *jcr = (JCR *)arg;
+
+ jcr->my_thread_id = pthread_self();
+ pthread_detach(jcr->my_thread_id);
+ sm_check(__FILE__, __LINE__, true);
+
+ Dmsg0(200, "=====Start Job=========\n");
+ set_jcr_job_status(jcr, JS_Running); /* this will be set only if no error */
+ jcr->start_time = time(NULL); /* set the real start time */
+ jcr->jr.StartTime = jcr->start_time;
+
+ if (jcr->job->MaxStartDelay != 0 && jcr->job->MaxStartDelay <
+ (utime_t)(jcr->start_time - jcr->sched_time)) {
+ Jmsg(jcr, M_FATAL, 0, _("Job canceled because max start delay time exceeded.\n"));
+ set_jcr_job_status(jcr, JS_Canceled);
+ }
+
+ /* TODO : check if it is used somewhere */
+ if (jcr->job->RunScripts == NULL) {
+ Dmsg0(200, "Warning, job->RunScripts is empty\n");
+ jcr->job->RunScripts = New(alist(10, not_owned_by_alist));
+ }
+
if (!db_update_job_start_record(jcr, jcr->db, &jcr->jr)) {
Jmsg(jcr, M_FATAL, 0, "%s", db_strerror(jcr->db));
}
/* Cancel Storage daemon */
if (jcr->store_bsock) {
- if (!ua->jcr->storage) {
- copy_storage(ua->jcr, jcr->storage, _("Job resource"));
+ if (!ua->jcr->wstorage) {
+ if (jcr->rstorage) {
+ copy_wstorage(ua->jcr, jcr->rstorage, _("Job resource"));
+ } else {
+ copy_wstorage(ua->jcr, jcr->wstorage, _("Job resource"));
+ }
} else {
- set_storage(ua->jcr, jcr->store);
+ if (jcr->rstorage) {
+ set_wstorage(ua->jcr, jcr->rstore);
+ } else {
+ set_wstorage(ua->jcr, jcr->wstore);
+ }
}
if (!connect_to_storage_daemon(ua->jcr, 10, SDConnectTimeout, 1)) {
bsendmsg(ua, _("Failed to connect to Storage daemon.\n"));
}
/* Delete lists setup to hold storage pointers */
- if (jcr->storage) {
- delete jcr->storage;
- }
+ free_rwstorage(jcr);
+
jcr->job_end_push.destroy();
Dmsg0(200, "End dird free_jcr\n");
}
}
jcr->JobPriority = job->Priority;
/* Copy storage definitions -- deleted in dir_free_jcr above */
- copy_storage(jcr, job->storage, _("Job resource"));
+ copy_rwstorage(jcr, job->storage, _("Job resource"));
jcr->client = job->client;
if (!jcr->client_name) {
jcr->client_name = get_pool_memory(PM_NAME);
}
}
+/*
+ * Copy the storage definitions from an alist to the JCR
+ */
+void copy_rwstorage(JCR *jcr, alist *storage, const char *where)
+{
+ copy_rstorage(jcr, storage, where);
+ copy_wstorage(jcr, storage, where);
+}
+
+
+/* Set storage override */
+void set_rwstorage(JCR *jcr, STORE *store)
+{
+ set_rstorage(jcr, store);
+ set_wstorage(jcr, store);
+}
+
+void free_rwstorage(JCR *jcr)
+{
+ free_rstorage(jcr);
+ free_wstorage(jcr);
+}
+
+/*
+ * Copy the storage definitions from an alist to the JCR
+ */
+void copy_rstorage(JCR *jcr, alist *storage, const char *where)
+{
+ if (storage) {
+ STORE *st;
+ if (jcr->rstorage) {
+ delete jcr->rstorage;
+ }
+ jcr->rstorage = New(alist(10, not_owned_by_alist));
+ foreach_alist(st, storage) {
+ jcr->rstorage->append(st);
+ }
+ pm_strcpy(jcr->storage_source, where);
+ }
+ if (jcr->rstorage) {
+ jcr->rstore = (STORE *)jcr->rstorage->first();
+ }
+}
+
+
+/* Set storage override */
+void set_rstorage(JCR *jcr, STORE *store)
+{
+ STORE *storage;
+
+ jcr->rstore = store;
+ foreach_alist(storage, jcr->rstorage) {
+ if (store == storage) {
+ return;
+ }
+ }
+ /* Store not in list, so add it */
+ jcr->rstorage->prepend(store);
+}
+
+void free_rstorage(JCR *jcr)
+{
+ if (jcr->rstorage) {
+ delete jcr->rstorage;
+ jcr->rstorage = NULL;
+ }
+ jcr->rstore = NULL;
+}
/*
* Copy the storage definitions from an alist to the JCR
*/
-void copy_storage(JCR *jcr, alist *storage, const char *where)
+void copy_wstorage(JCR *jcr, alist *storage, const char *where)
{
if (storage) {
STORE *st;
- if (jcr->storage) {
- delete jcr->storage;
+ if (jcr->wstorage) {
+ delete jcr->wstorage;
}
- jcr->storage = New(alist(10, not_owned_by_alist));
+ jcr->wstorage = New(alist(10, not_owned_by_alist));
foreach_alist(st, storage) {
- jcr->storage->append(st);
+ jcr->wstorage->append(st);
}
pm_strcpy(jcr->storage_source, where);
}
- if (jcr->storage) {
- jcr->store = (STORE *)jcr->storage->first();
+ if (jcr->wstorage) {
+ jcr->wstore = (STORE *)jcr->wstorage->first();
}
}
/* Set storage override */
-void set_storage(JCR *jcr, STORE *store)
+void set_wstorage(JCR *jcr, STORE *store)
{
STORE *storage;
- jcr->store = store;
- foreach_alist(storage, jcr->storage) {
+ jcr->wstore = store;
+ foreach_alist(storage, jcr->wstorage) {
if (store == storage) {
return;
}
}
/* Store not in list, so add it */
- jcr->storage->prepend(store);
+ jcr->wstorage->prepend(store);
+}
+
+void free_wstorage(JCR *jcr)
+{
+ if (jcr->wstorage) {
+ delete jcr->wstorage;
+ jcr->wstorage = NULL;
+ }
+ jcr->wstore = NULL;
}
+
+
void create_clones(JCR *jcr)
{
/*
* put into the ready queue.
*/
if (jcr->acquired_resource_locks) {
- jcr->store->NumConcurrentJobs--;
+ if (jcr->rstore) {
+ jcr->rstore->NumConcurrentJobs = 0;
+ Dmsg1(000, "Dec rncj=%d\n", jcr->rstore->NumConcurrentJobs);
+ }
+ if (jcr->wstore) {
+ jcr->wstore->NumConcurrentJobs--;
+ Dmsg1(000, "Dec wncj=%d\n", jcr->wstore->NumConcurrentJobs);
+ }
jcr->client->NumConcurrentJobs--;
jcr->job->NumConcurrentJobs--;
+ jcr->acquired_resource_locks = false;
}
/*
njcr->JobLevel = jcr->JobLevel;
njcr->JobStatus = -1;
set_jcr_job_status(njcr, jcr->JobStatus);
- copy_storage(njcr, jcr->storage, _("previous Job"));
+ if (jcr->rstore) {
+ copy_rstorage(njcr, jcr->rstorage, _("previous Job"));
+ } else {
+ free_rstorage(njcr);
+ }
+ if (jcr->wstore) {
+ copy_wstorage(njcr, jcr->wstorage, _("previous Job"));
+ } else {
+ free_wstorage(njcr);
+ }
njcr->messages = jcr->messages;
Dmsg0(2300, "Call to run new job\n");
V(jq->mutex);
/* Got all locks, now remove it from wait queue and append it
* to the ready queue
*/
- jcr->acquired_resource_locks = true;
jq->waiting_jobs->remove(je);
jq->ready_jobs->append(je);
Dmsg1(2300, "moved JobId=%d from wait to ready queue\n", je->jcr->JobId);
{
bool skip_this_jcr = false;
- if (jcr->JobType == JT_RESTORE || jcr->JobType == JT_VERIFY) {
+ jcr->acquired_resource_locks = false;
+ if (jcr->rstore) {
+ Dmsg1(000, "Rstore=%s\n", jcr->rstore->name());
/*
* Let only one Restore/verify job run at a time regardless
* of MaxConcurrentJobs.
*/
- if (jcr->store->NumConcurrentJobs == 0) {
- jcr->store->NumConcurrentJobs = 1;
+ if (jcr->rstore->NumConcurrentJobs == 0) {
+ jcr->rstore->NumConcurrentJobs = 1;
+ Dmsg0(000, "Set rncj=1\n");
} else {
+ Dmsg1(000, "Fail rncj=%d\n", jcr->rstore->NumConcurrentJobs);
set_jcr_job_status(jcr, JS_WaitStoreRes);
return false;
}
- /* We are not doing a Restore or Verify */
- } else if (jcr->store->NumConcurrentJobs == 0 &&
- jcr->store->NumConcurrentJobs < jcr->store->MaxConcurrentJobs) {
- /* Simple case, first job */
- jcr->store->NumConcurrentJobs = 1;
- } else if (jcr->store->NumConcurrentJobs < jcr->store->MaxConcurrentJobs) {
- jcr->store->NumConcurrentJobs++;
- } else {
- skip_this_jcr = true;
+ }
+
+ if (jcr->wstore) {
+ if (jcr->wstore->NumConcurrentJobs == 0 &&
+ jcr->wstore->NumConcurrentJobs < jcr->wstore->MaxConcurrentJobs) {
+ /* Simple case, first job */
+ jcr->wstore->NumConcurrentJobs = 1;
+ Dmsg0(000, "Set wncj=1\n");
+ } else if (jcr->wstore->NumConcurrentJobs < jcr->wstore->MaxConcurrentJobs) {
+ jcr->wstore->NumConcurrentJobs++;
+ Dmsg1(000, "Inc wncj=%d\n", jcr->wstore->NumConcurrentJobs);
+ } else if (jcr->rstore) {
+ jcr->rstore->NumConcurrentJobs = 0; /* back out rstore */
+ Dmsg1(000, "Fail wncj=%d\n", jcr->wstore->NumConcurrentJobs);
+ skip_this_jcr = true;
+ } else {
+ Dmsg1(000, "Fail wncj=%d\n", jcr->wstore->NumConcurrentJobs);
+ skip_this_jcr = true;
+ }
}
if (skip_this_jcr) {
set_jcr_job_status(jcr, JS_WaitStoreRes);
jcr->client->NumConcurrentJobs++;
} else {
/* Back out previous locks */
- jcr->store->NumConcurrentJobs--;
+ if (jcr->wstore) {
+ jcr->wstore->NumConcurrentJobs--;
+ Dmsg1(000, "Dec wncj=%d\n", jcr->wstore->NumConcurrentJobs);
+ }
+ if (jcr->rstore) {
+ jcr->rstore->NumConcurrentJobs = 0;
+ Dmsg1(000, "Dec rncj=%d\n", jcr->rstore->NumConcurrentJobs);
+ }
set_jcr_job_status(jcr, JS_WaitClientRes);
return false;
}
jcr->job->NumConcurrentJobs++;
} else {
/* Back out previous locks */
- jcr->store->NumConcurrentJobs--;
+ if (jcr->wstore) {
+ jcr->wstore->NumConcurrentJobs--;
+ Dmsg1(000, "Dec wncj=%d\n", jcr->wstore->NumConcurrentJobs);
+ }
+ if (jcr->rstore) {
+ jcr->rstore->NumConcurrentJobs = 0;
+ Dmsg1(000, "Dec rncj=%d\n", jcr->rstore->NumConcurrentJobs);
+ }
jcr->client->NumConcurrentJobs--;
set_jcr_job_status(jcr, JS_WaitJobRes);
return false;
}
/* Check actual device availability */
/* ***FIXME****/
+
+
+ jcr->acquired_resource_locks = true;
return true;
}
}
/* If pool storage specified, use it instead of job storage */
- copy_storage(jcr, jcr->pool->storage, _("Pool resource"));
+ copy_wstorage(jcr, jcr->pool->storage, _("Pool resource"));
- if (!jcr->storage) {
+ if (!jcr->wstorage) {
Jmsg(jcr, M_FATAL, 0, _("No Storage specification found in Job or Pool.\n"));
return false;
}
/* ***FIXME*** */
/* If pool storage specified, use it for restore */
- copy_storage(prev_jcr, pool->storage, _("Pool resource"));
+ copy_rstorage(prev_jcr, pool->storage, _("Pool resource"));
+ copy_rstorage(jcr, pool->storage, _("Pool resource"));
/* If the original backup pool has a NextPool, make sure a
* record exists in the database.
}
/* If pool storage specified, use it instead of job storage for backup */
- copy_storage(jcr, jcr->pool->storage, _("Pool resource"));
+ copy_wstorage(jcr, jcr->pool->storage, _("Pool resource"));
/* Print Job Start message */
Jmsg(jcr, M_INFO, 0, _("Start Migration JobId %s, Job=%s\n"),
* Now start a job with the Storage daemon
*/
Dmsg2(dbglevel, "Read store=%s, write store=%s\n",
- ((STORE *)prev_jcr->storage->first())->hdr.name,
- ((STORE *)jcr->storage->first())->hdr.name);
- if (!start_storage_daemon_job(jcr, prev_jcr->storage, jcr->storage)) {
+ ((STORE *)jcr->rstorage->first())->name(),
+ ((STORE *)jcr->wstorage->first())->name());
+ if (!start_storage_daemon_job(jcr, jcr->rstorage, jcr->wstorage)) {
return false;
}
Dmsg0(150, "Storage daemon connection OK\n");
edit_uint64(jcr->jr.JobId, ec8),
jcr->jr.Job,
level_to_str(jcr->JobLevel), jcr->since,
- jcr->client->hdr.name,
- jcr->fileset->hdr.name, jcr->FSCreateTime,
- jcr->pool->hdr.name, jcr->pool_source,
- jcr->store->hdr.name, jcr->storage_source,
+ jcr->client->name(),
+ jcr->fileset->name(), jcr->FSCreateTime,
+ jcr->pool->name(), jcr->pool_source,
+ jcr->wstore->name(), jcr->storage_source,
sdt,
edt,
edit_utime(RunTime, elapsed, sizeof(elapsed)),
if (jcr->store_bsock) {
return true; /* already connected */
}
- store = (STORE *)jcr->storage->first();
+
+ /* If there is a write storage use it */
+ if (jcr->wstorage) {
+ store = (STORE *)jcr->wstorage->first();
+ } else {
+ store = (STORE *)jcr->rstorage->first();
+ }
/*
* Open message channel with the Storage daemon
memset(mr, 0, sizeof(MEDIA_DBR));
set_pool_dbr_defaults_in_media_dbr(mr, &pr);
jcr->VolumeName[0] = 0;
- bstrncpy(mr->MediaType, jcr->store->media_type, sizeof(mr->MediaType));
+ bstrncpy(mr->MediaType, jcr->wstore->media_type, sizeof(mr->MediaType));
if (generate_job_event(jcr, "NewVolume") == 1 && jcr->VolumeName[0] &&
is_volume_name_legal(NULL, jcr->VolumeName)) {
bstrncpy(mr->VolumeName, jcr->VolumeName, sizeof(mr->VolumeName));
int retry = 0;
bool ok;
bool InChanger;
- STORE *store = jcr->store;
+ STORE *store = jcr->wstore;
bstrncpy(mr->MediaType, store->media_type, sizeof(mr->MediaType));
Dmsg2(100, "CatReq FindMedia: PoolId=%d, MediaType=%s\n", (int)mr->PoolId, mr->MediaType);
extern JobId_t run_job(JCR *jcr);
extern bool cancel_job(UAContext *ua, JCR *jcr);
extern void init_jcr_job_record(JCR *jcr);
-extern void copy_storage(JCR *jcr, alist *storage, const char *where);
-extern void set_storage(JCR *jcr, STORE *store);
+extern void copy_rwstorage(JCR *jcr, alist *storage, const char *where);
+extern void set_rwstorage(JCR *jcr, STORE *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 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 free_rstorage(JCR *jcr);
extern bool setup_job(JCR *jcr);
extern void create_clones(JCR *jcr);
extern bool create_restore_bootstrap_file(JCR *jcr);
goto bail_out;
}
case 6: /* Pool */
- return Py_BuildValue(getvars[i].fmt, jcr->pool->hdr.name);
+ return Py_BuildValue(getvars[i].fmt, jcr->pool->name());
case 7: /* Storage */
- return Py_BuildValue(getvars[i].fmt, jcr->store->hdr.name);
+ if (jcr->wstore) {
+ return Py_BuildValue(getvars[i].fmt, jcr->wstore->name());
+ } else if (jcr->rstore) {
+ return Py_BuildValue(getvars[i].fmt, jcr->rstore->name());
+ } else {
+ goto bail_out;
+ }
case 8:
- return Py_BuildValue(getvars[i].fmt, jcr->catalog->hdr.name);
+ return Py_BuildValue(getvars[i].fmt, jcr->catalog->name());
case 9: /* MediaType */
- return Py_BuildValue(getvars[i].fmt, jcr->store->media_type);
+ if (jcr->wstore) {
+ return Py_BuildValue(getvars[i].fmt, jcr->wstore->media_type);
+ } else if (jcr->rstore) {
+ return Py_BuildValue(getvars[i].fmt, jcr->rstore->media_type);
+ } else {
+ goto bail_out;
+ }
case 10: /* JobName */
return Py_BuildValue(getvars[i].fmt, jcr->Job);
case 11: /* JobStatus */
BSOCK *fd;
JOB_DBR rjr; /* restore job record */
+ free_wstorage(jcr); /* we don't write */
+
memset(&rjr, 0, sizeof(rjr));
jcr->jr.JobLevel = L_FULL; /* Full restore */
if (!db_update_job_start_record(jcr, jcr->db, &jcr->jr)) {
/*
* Now start a job with the Storage daemon
*/
- if (!start_storage_daemon_job(jcr, jcr->storage, NULL)) {
+ if (!start_storage_daemon_job(jcr, jcr->rstorage, NULL)) {
restore_cleanup(jcr, JS_ErrorTerminated);
return false;
}
* then wait for File daemon to make connection
* with Storage daemon.
*/
- if (jcr->store->SDDport == 0) {
- jcr->store->SDDport = jcr->store->SDport;
+ if (jcr->rstore->SDDport == 0) {
+ jcr->rstore->SDDport = jcr->rstore->SDport;
}
- bnet_fsend(fd, storaddr, jcr->store->address, jcr->store->SDDport);
+ bnet_fsend(fd, storaddr, jcr->rstore->address, jcr->rstore->SDDport);
Dmsg1(6, "dird>filed: %s\n", fd->msg);
if (!response(jcr, fd, OKstore, "Storage", DISPLAY_ERROR)) {
restore_cleanup(jcr, JS_ErrorTerminated);
bool do_restore_init(JCR *jcr)
{
+ free_wstorage(jcr);
return true;
}
jcr->run_diff_pool_override = true;
}
if (run->storage) {
- set_storage(jcr, run->storage); /* override storage */
+ set_rwstorage(jcr, run->storage); /* override storage */
}
if (run->msgs) {
jcr->messages = run->msgs; /* override messages */
* Version $Id$
*/
/*
- Copyright (C) 2000-2005 Kern Sibbald
+ Copyright (C) 2000-2006 Kern Sibbald
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
return 1;
}
- while (ua->jcr->storage->size()) {
- ua->jcr->storage->remove(0);
+ while (ua->jcr->wstorage->size()) {
+ ua->jcr->wstorage->remove(0);
}
len = strlen(ua->argk[0]);
BSOCK *sd;
JCR *jcr = ua->jcr;
- set_storage(jcr, store);
+ set_wstorage(jcr, store);
/* Try connecting for up to 15 seconds */
bsendmsg(ua, _("Connecting to Storage daemon %s at %s:%d\n"),
- store->hdr.name, store->address, store->SDport);
+ store->name(), store->address, store->SDport);
if (!connect_to_storage_daemon(jcr, 1, 15, 0)) {
bsendmsg(ua, _("Failed to connect to Storage daemon.\n"));
return;
if (!store) {
return;
}
- set_storage(jcr, store);
+ set_wstorage(jcr, store);
drive = get_storage_drive(ua, store);
Dmsg3(120, "Found storage, MediaType=%s DevName=%s drive=%d\n",
if (!store) {
return;
}
- set_storage(ua->jcr, store);
+ set_wstorage(ua->jcr, store);
drive = get_storage_drive(ua, store);
scan = find_arg(ua, NT_("scan")) >= 0;
if (!store) {
return 1;
}
- set_storage(ua->jcr, store);
+ set_wstorage(ua->jcr, store);
drive = get_storage_drive(ua, store);
if (label_barcodes) {
*/
static void label_from_barcodes(UAContext *ua, int drive)
{
- STORE *store = ua->jcr->store;
+ STORE *store = ua->jcr->wstore;
POOL_DBR pr;
MEDIA_DBR mr, omr;
vol_list_t *vl, *vol_list = NULL;
if (!(sd=open_sd_bsock(ua))) {
return false;
}
- bstrncpy(dev_name, ua->jcr->store->dev_name(), sizeof(dev_name));
+ bstrncpy(dev_name, ua->jcr->wstore->dev_name(), sizeof(dev_name));
bash_spaces(dev_name);
bash_spaces(mr->VolumeName);
bash_spaces(mr->MediaType);
if (media_record_exists) { /* we update it */
mr->VolBytes = 1;
mr->InChanger = 1;
- mr->StorageId = ua->jcr->store->StorageId;
+ mr->StorageId = ua->jcr->wstore->StorageId;
if (!db_update_media_record(ua->jcr, ua->db, mr)) {
bsendmsg(ua, "%s", db_strerror(ua->db));
ok = false;
set_pool_dbr_defaults_in_media_dbr(mr, pr);
mr->VolBytes = 1; /* flag indicating Volume labeled */
mr->InChanger = 1;
- mr->StorageId = ua->jcr->store->StorageId;
+ mr->StorageId = ua->jcr->wstore->StorageId;
mr->Enabled = 1;
if (db_create_media_record(ua->jcr, ua->db, mr)) {
bsendmsg(ua, _("Catalog record for Volume \"%s\", Slot %d successfully created.\n"),
static BSOCK *open_sd_bsock(UAContext *ua)
{
- STORE *store = ua->jcr->store;
+ STORE *store = ua->jcr->wstore;
if (!ua->jcr->store_bsock) {
bsendmsg(ua, _("Connecting to Storage daemon %s at %s:%d ...\n"),
- store->hdr.name, store->address, store->SDport);
+ store->name(), store->address, store->SDport);
if (!connect_to_storage_daemon(ua->jcr, 10, SDConnectTimeout, 1)) {
bsendmsg(ua, _("Failed to connect to Storage daemon.\n"));
return NULL;
static char *get_volume_name_from_SD(UAContext *ua, int Slot, int drive)
{
- STORE *store = ua->jcr->store;
+ STORE *store = ua->jcr->wstore;
BSOCK *sd;
char dev_name[MAX_NAME_LENGTH];
char *VolName = NULL;
*/
static vol_list_t *get_vol_list_from_SD(UAContext *ua, bool scan)
{
- STORE *store = ua->jcr->store;
+ STORE *store = ua->jcr->wstore;
char dev_name[MAX_NAME_LENGTH];
BSOCK *sd;
vol_list_t *vl;
*/
static int get_num_slots_from_SD(UAContext *ua)
{
- STORE *store = ua->jcr->store;
+ STORE *store = ua->jcr->wstore;
char dev_name[MAX_NAME_LENGTH];
BSOCK *sd;
int slots = 0;
*/
int get_num_drives_from_SD(UAContext *ua)
{
- STORE *store = ua->jcr->store;
+ STORE *store = ua->jcr->wstore;
char dev_name[MAX_NAME_LENGTH];
BSOCK *sd;
int drives = 0;
memset(&pr, 0, sizeof(pr));
pr.PoolId = jcr->jr.PoolId;
if (! db_get_pool_record(ua->jcr, ua->db, &pr)) {
- strcpy(pr.Name, "*UnknownPool*");
+ bstrncpy(pr.Name, "*UnknownPool*", sizeof(pr.Name));
}
mr.PoolId = jcr->jr.PoolId;
if (run->storage) {
- jcr->store = run->storage;
+ jcr->wstore = run->storage;
} else {
- jcr->store = (STORE *)job->storage->first();
+ jcr->wstore = (STORE *)job->storage->first();
}
- mr.StorageId = jcr->store->StorageId;
+ mr.StorageId = jcr->wstore->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));
Mmsg(ua->cmd,
"run job=\"%s\" client=\"%s\" storage=\"%s\" bootstrap=\"%s\""
" where=\"%s\" files=%d catalog=\"%s\"",
- job->hdr.name, rx.ClientName, rx.store?rx.store->hdr.name:"",
- jcr->RestoreBootstrap, rx.where, rx.selected_files, ua->catalog->hdr.name);
+ job->name(), rx.ClientName, rx.store?rx.store->name():"",
+ jcr->RestoreBootstrap, rx.where, rx.selected_files, ua->catalog->name());
} else {
Mmsg(ua->cmd,
"run job=\"%s\" client=\"%s\" storage=\"%s\" bootstrap=\"%s\""
" files=%d catalog=\"%s\"",
- job->hdr.name, rx.ClientName, rx.store?rx.store->hdr.name:"",
- jcr->RestoreBootstrap, rx.selected_files, ua->catalog->hdr.name);
+ job->name(), rx.ClientName, rx.store?rx.store->name():"",
+ jcr->RestoreBootstrap, rx.selected_files, ua->catalog->name());
}
if (find_arg(ua, NT_("yes")) > 0) {
pm_strcat(ua->cmd, " yes"); /* pass it on to the run command */
}
- Dmsg1(100, "Submitting: %s\n", ua->cmd);
+ Dmsg1(200, "Submitting: %s\n", ua->cmd);
parse_ua_args(ua);
run_cmd(ua, ua->cmd);
free_rx(&rx);
if (rx->pool) {
POOL_DBR pr;
memset(&pr, 0, sizeof(pr));
- bstrncpy(pr.Name, rx->pool->hdr.name, sizeof(pr.Name));
+ bstrncpy(pr.Name, rx->pool->name(), sizeof(pr.Name));
if (db_get_pool_record(ua->jcr, ua->db, &pr)) {
bsnprintf(pool_select, sizeof(pool_select), "AND Media.PoolId=%s ",
edit_int64(pr.PoolId, ed1));
return 0;
}
-#ifdef xxxx_needed
-/*
- * Called here with each name to be added to the list. The name is
- * added to the list if it is not already in the list.
- *
- * Used to make unique list of FileSets
- */
-static int unique_name_list_handler(void *ctx, int num_fields, char **row)
-{
- NAME_LIST *name = (NAME_LIST *)ctx;
-
- if (name->num_ids == MAX_ID_LIST_LEN) {
- return 1;
- }
- if (name->num_ids == name->max_ids) {
- if (name->max_ids == 0) {
- name->max_ids = 1000;
- name->name = (char **)bmalloc(sizeof(char *) * name->max_ids);
- } else {
- name->max_ids = (name->max_ids * 3) / 2;
- name->name = (char **)brealloc(name->name, sizeof(char *) * name->max_ids);
- }
- }
- for (int i=0; i<name->num_ids; i++) {
- if (strcmp(name->name[i], row[0]) == 0) {
- return 0; /* already in list, return */
- }
- }
- /* Add new name to list */
- name->name[name->num_ids++] = bstrdup(row[0]);
- return 0;
-}
-
-
-/*
- * Print names in the list
- */
-static void print_name_list(UAContext *ua, NAME_LIST *name_list)
-{
- for (int i=0; i < name_list->num_ids; i++) {
- bsendmsg(ua, "%s\n", name_list->name[i]);
- }
-}
-#endif
-
-
/*
* Free names in the list
*/
STORE *store;
if (rx.store) {
+ Dmsg1(200, "Already have store=%s\n", rx.store->name());
return;
}
/*
*/
LockRes();
foreach_res(store, R_STORAGE) {
- if (strcmp(Storage, store->hdr.name) == 0) {
- if (acl_access_ok(ua, Storage_ACL, store->hdr.name)) {
+ if (strcmp(Storage, store->name()) == 0) {
+ if (acl_access_ok(ua, Storage_ACL, store->name())) {
rx.store = store;
}
break;
int i = find_arg_with_value(ua, "storage");
if (i > 0) {
store = (STORE *)GetResWithName(R_STORAGE, ua->argv[i]);
- if (store && !acl_access_ok(ua, Storage_ACL, store->hdr.name)) {
+ if (store && !acl_access_ok(ua, Storage_ACL, store->name())) {
store = NULL;
}
}
if (store && (store != rx.store)) {
bsendmsg(ua, _("Warning default storage overridden by \"%s\" on command line.\n"),
- store->hdr.name);
+ store->name());
rx.store = store;
+ Dmsg1(200, "Set store=%s\n", rx.store->name());
}
return;
}
LockRes();
foreach_res(store, R_STORAGE) {
if (strcmp(MediaType, store->media_type) == 0) {
- if (acl_access_ok(ua, Storage_ACL, store->hdr.name)) {
+ if (acl_access_ok(ua, Storage_ACL, store->name())) {
rx.store = store;
+ Dmsg1(200, "Set store=%s\n", rx.store->name());
bsendmsg(ua, _("Storage \"%s\" not found, using Storage \"%s\" from MediaType \"%s\".\n"),
- Storage, store->hdr.name, MediaType);
+ Storage, store->name(), MediaType);
}
UnlockRes();
return;
/* Take command line arg, or ask user if none */
rx.store = get_storage_resource(ua, false /* don't use default */);
+ Dmsg1(200, "Set store=%s\n", rx.store->name());
}
-
-
-#ifdef xxxx_needed
-static void get_storage_from_mediatype(UAContext *ua, NAME_LIST *name_list, RESTORE_CTX *rx)
-{
- STORE *store;
-
- if (name_list->num_ids > 1) {
- bsendmsg(ua, _("Warning, the JobIds that you selected refer to more than one MediaType.\n"
- "Restore may not be possible. The MediaTypes used are:\n"));
- print_name_list(ua, name_list);
-// rx->store = select_storage_resource(ua);
- return;
- }
-
- if (name_list->num_ids == 0) {
- bsendmsg(ua, _("No MediaType found for your JobIds.\n"));
- rx->store = select_storage_resource(ua);
- return;
- }
- if (rx->store) {
- return;
- }
- /*
- * We have a single MediaType, look it up in our Storage resource
- */
- LockRes();
- foreach_res(store, R_STORAGE) {
- if (strcmp(name_list->name[0], store->media_type) == 0) {
- if (acl_access_ok(ua, Storage_ACL, store->hdr.name)) {
- rx->store = store;
- }
- break;
- }
- }
- UnlockRes();
-
- if (rx->store) {
- /* Check if an explicit storage resource is given */
- store = NULL;
- int i = find_arg_with_value(ua, "storage");
- if (i > 0) {
- store = (STORE *)GetResWithName(R_STORAGE, ua->argv[i]);
- if (store && !acl_access_ok(ua, Storage_ACL, store->hdr.name)) {
- store = NULL;
- }
- }
- if (store && (store != rx->store)) {
- bsendmsg(ua, _("Warning default storage overridden by %s on command line.\n"),
- store->hdr.name);
- rx->store = store;
- }
- return;
- }
-
- /* Take command line arg, or ask user if none */
- rx->store = get_storage_resource(ua, false /* don't use default */);
-
- if (!rx->store) {
- bsendmsg(ua, _("\nWarning. Unable to find Storage resource for\n"
- "MediaType \"%s\", needed by the Jobs you selected.\n"
- "You will be allowed to select a Storage device later.\n"),
- name_list->name[0]);
- }
-}
-#endif
}
if (!job) {
return 0;
- } else if (!acl_access_ok(ua, Job_ACL, job->hdr.name)) {
+ } else if (!acl_access_ok(ua, Job_ACL, job->name())) {
bsendmsg(ua, _("No authorization. Job \"%s\".\n"),
- job->hdr.name);
+ job->name());
return 0;
}
}
if (!store) {
return 1;
- } else if (!acl_access_ok(ua, Storage_ACL, store->hdr.name)) {
+ } else if (!acl_access_ok(ua, Storage_ACL, store->name())) {
bsendmsg(ua, _("No authorization. Storage \"%s\".\n"),
- store->hdr.name);
+ store->name());
return 0;
}
- Dmsg1(800, "Using storage=%s\n", store->hdr.name);
+ Dmsg1(800, "Using storage=%s\n", store->name());
if (pool_name) {
pool = (POOL *)GetResWithName(R_POOL, pool_name);
}
if (!pool) {
return 0;
- } else if (!acl_access_ok(ua, Pool_ACL, pool->hdr.name)) {
+ } else if (!acl_access_ok(ua, Pool_ACL, pool->name())) {
bsendmsg(ua, _("No authorization. Pool \"%s\".\n"),
- pool->hdr.name);
+ pool->name());
return 0;
}
- Dmsg1(800, "Using pool\n", pool->hdr.name);
+ Dmsg1(800, "Using pool\n", pool->name());
if (client_name) {
client = (CLIENT *)GetResWithName(R_CLIENT, client_name);
}
if (!client) {
return 0;
- } else if (!acl_access_ok(ua, Client_ACL, client->hdr.name)) {
+ } else if (!acl_access_ok(ua, Client_ACL, client->name())) {
bsendmsg(ua, _("No authorization. Client \"%s\".\n"),
- client->hdr.name);
+ client->name());
return 0;
}
- Dmsg1(800, "Using client=%s\n", client->hdr.name);
+ Dmsg1(800, "Using client=%s\n", client->name());
if (fileset_name) {
fileset = (FILESET *)GetResWithName(R_FILESET, fileset_name);
}
if (!fileset) {
return 0;
- } else if (!acl_access_ok(ua, FileSet_ACL, fileset->hdr.name)) {
+ } else if (!acl_access_ok(ua, FileSet_ACL, fileset->name())) {
bsendmsg(ua, _("No authorization. FileSet \"%s\".\n"),
- fileset->hdr.name);
+ fileset->name());
return 0;
}
jcr->verify_job = verify_job;
jcr->previous_job = previous_job;
- set_storage(jcr, store);
+ set_rwstorage(jcr, store);
jcr->client = client;
jcr->fileset = fileset;
jcr->pool = pool;
"When: %s\n"
"Priority: %d\n"),
_("Admin"),
- job->hdr.name,
- jcr->fileset->hdr.name,
- NPRT(jcr->client->hdr.name),
- NPRT(jcr->store->hdr.name),
+ job->name(),
+ jcr->fileset->name(),
+ NPRT(jcr->client->name()),
+ NPRT(jcr->wstore->name()),
bstrutime(dt, sizeof(dt), jcr->sched_time),
jcr->JobPriority);
jcr->JobLevel = L_FULL;
"When: %s\n"
"Priority: %d\n"),
_("Backup"),
- job->hdr.name,
- jcr->fileset->hdr.name,
+ job->name(),
+ jcr->fileset->name(),
level_to_str(jcr->JobLevel),
- jcr->client->hdr.name,
- jcr->store->hdr.name,
- NPRT(jcr->pool->hdr.name),
+ jcr->client->name(),
+ jcr->wstore->name(),
+ NPRT(jcr->pool->name()),
bstrutime(dt, sizeof(dt), jcr->sched_time),
jcr->JobPriority);
} else { /* JT_VERIFY */
const char *Name;
if (jcr->verify_job) {
- Name = jcr->verify_job->hdr.name;
+ Name = jcr->verify_job->name();
} else {
Name = "";
}
"When: %s\n"
"Priority: %d\n"),
_("Verify"),
- job->hdr.name,
- jcr->fileset->hdr.name,
+ job->name(),
+ jcr->fileset->name(),
level_to_str(jcr->JobLevel),
- jcr->client->hdr.name,
- jcr->store->hdr.name,
- NPRT(jcr->pool->hdr.name),
+ jcr->client->name(),
+ jcr->rstore->name(),
+ NPRT(jcr->pool->name()),
Name,
verify_list,
bstrutime(dt, sizeof(dt), jcr->sched_time),
"When: %s\n"
"Catalog: %s\n"
"Priority: %d\n"),
- job->hdr.name,
+ job->name(),
NPRT(jcr->RestoreBootstrap),
jcr->where?jcr->where:NPRT(job->RestoreWhere),
replace,
- jcr->fileset->hdr.name,
- jcr->client->hdr.name,
- jcr->store->hdr.name,
+ jcr->fileset->name(),
+ jcr->client->name(),
+ jcr->rstore->name(),
bstrutime(dt, sizeof(dt), jcr->sched_time),
- jcr->catalog->hdr.name,
+ jcr->catalog->name(),
jcr->JobPriority);
} else {
bsendmsg(ua, _("Run Restore job\n"
"When: %s\n"
"Catalog: %s\n"
"Priority: %d\n"),
- job->hdr.name,
+ job->name(),
NPRT(jcr->RestoreBootstrap),
jcr->where?jcr->where:NPRT(job->RestoreWhere),
replace,
- jcr->client->hdr.name,
- jcr->store->hdr.name,
+ jcr->client->name(),
+ jcr->rstore->name(),
jcr->RestoreJobId==0?"*None*":edit_uint64(jcr->RestoreJobId, ec1),
bstrutime(dt, sizeof(dt), jcr->sched_time),
- jcr->catalog->hdr.name,
+ jcr->catalog->name(),
jcr->JobPriority);
}
break;
"When: %s\n"
"Catalog: %s\n"
"Priority: %d\n"),
- job->hdr.name,
+ job->name(),
NPRT(jcr->RestoreBootstrap),
- jcr->fileset->hdr.name,
- jcr->client->hdr.name,
- jcr->store->hdr.name,
+ jcr->fileset->name(),
+ jcr->client->name(),
+ jcr->wstore->name(),
jcr->MigrateJobId==0?"*None*":edit_uint64(jcr->MigrateJobId, ec1),
bstrutime(dt, sizeof(dt), jcr->sched_time),
- jcr->catalog->hdr.name,
+ jcr->catalog->name(),
jcr->JobPriority);
break;
default:
/* Storage */
store = select_storage_resource(ua);
if (store) {
- set_storage(jcr, store);
+ set_rwstorage(jcr, store);
goto try_again;
}
break;
bsendmsg(ua, _("JobId %s is not running.\n"), edit_int64(jobid, ed1));
return NULL;
}
- store = jcr->store;
+ store = jcr->wstore;
free_jcr(jcr);
break;
bsendmsg(ua, _("Job \"%s\" is not running.\n"), ua->argv[i]);
return NULL;
}
- store = jcr->store;
+ store = jcr->wstore;
free_jcr(jcr);
break;
} else if (strcasecmp(ua->argk[i], NT_("ujobid")) == 0) {
bsendmsg(ua, _("Job \"%s\" is not running.\n"), ua->argv[i]);
return NULL;
}
- store = jcr->store;
+ store = jcr->wstore;
free_jcr(jcr);
break;
}
i = 0;
foreach_res(store, R_STORAGE) {
found = false;
- if (!acl_access_ok(ua, Storage_ACL, store->hdr.name)) {
+ if (!acl_access_ok(ua, Storage_ACL, store->name())) {
continue;
}
for (j=0; j<i; j++) {
i = 0;
foreach_res(client, R_CLIENT) {
found = false;
- if (!acl_access_ok(ua, Client_ACL, client->hdr.name)) {
+ if (!acl_access_ok(ua, Client_ACL, client->name())) {
continue;
}
for (j=0; j<i; j++) {
{
BSOCK *sd;
- set_storage(ua->jcr, store);
+ set_wstorage(ua->jcr, store);
/* Try connecting for up to 15 seconds */
bsendmsg(ua, _("Connecting to Storage daemon %s at %s:%d\n"),
- store->hdr.name, store->address, store->SDport);
+ store->name(), store->address, store->SDport);
if (!connect_to_storage_daemon(ua->jcr, 1, 15, 0)) {
bsendmsg(ua, _("\nFailed to connect to Storage daemon %s.\n====\n"),
- store->hdr.name);
+ store->name());
if (ua->jcr->store_bsock) {
bnet_close(ua->jcr->store_bsock);
ua->jcr->store_bsock = NULL;
/* Try to connect for 15 seconds */
bsendmsg(ua, _("Connecting to Client %s at %s:%d\n"),
- client->hdr.name, client->address, client->FDport);
+ client->name(), client->address, client->FDport);
if (!connect_to_file_daemon(ua->jcr, 1, 15, 0)) {
bsendmsg(ua, _("Failed to connect to Client %s.\n====\n"),
- client->hdr.name);
+ client->name());
if (ua->jcr->file_bsock) {
bnet_close(ua->jcr->file_bsock);
ua->jcr->file_bsock = NULL;
}
bsendmsg(ua, _("%-14s %-8s %3d %-18s %-18s %s\n"),
level_ptr, job_type_to_str(sp->job->JobType), sp->priority, dt,
- sp->job->hdr.name, mr.VolumeName);
+ sp->job->name(), mr.VolumeName);
if (close_db) {
db_close_database(jcr, jcr->db);
}
/* Loop through all jobs */
LockRes();
foreach_res(job, R_JOB) {
- if (!acl_access_ok(ua, Job_ACL, job->hdr.name) || !job->enabled) {
+ if (!acl_access_ok(ua, Job_ACL, job->name()) || !job->enabled) {
continue;
}
for (run=NULL; (run = find_next_run(run, job, runtime, days)); ) {
bsendmsg(ua, _(" JobId Level Name Status\n"));
bsendmsg(ua, _("======================================================================\n"));
foreach_jcr(jcr) {
- if (jcr->JobId == 0 || !acl_access_ok(ua, Job_ACL, jcr->job->hdr.name)) {
+ if (jcr->JobId == 0 || !acl_access_ok(ua, Job_ACL, jcr->job->name())) {
continue;
}
njobs++;
break;
case JS_WaitFD:
emsg = (char *) get_pool_memory(PM_FNAME);
- Mmsg(emsg, _("is waiting on Client %s"), jcr->client->hdr.name);
+ Mmsg(emsg, _("is waiting on Client %s"), jcr->client->name());
pool_mem = true;
msg = emsg;
break;
case JS_WaitSD:
emsg = (char *) get_pool_memory(PM_FNAME);
- Mmsg(emsg, _("is waiting on Storage %s"), jcr->store->hdr.name);
+ if (jcr->wstore) {
+ Mmsg(emsg, _("is waiting on Storage %s"), jcr->wstore->name());
+ } else {
+ Mmsg(emsg, _("is waiting on Storage %s"), jcr->rstore->name());
+ }
pool_mem = true;
msg = emsg;
break;
pool_mem = true;
}
Mmsg(emsg, _("is waiting for Client %s to connect to Storage %s"),
- jcr->client->hdr.name, jcr->store->hdr.name);
+ jcr->client->name(), jcr->wstore->name());
msg = emsg;
break;
}
JobId_t verify_jobid = 0;
const char *Name;
+ free_wstorage(jcr); /* we don't write */
+
memset(&jcr->previous_jr, 0, sizeof(jcr->previous_jr));
Dmsg1(9, "bdird: created client %s record\n", jcr->client->hdr.name);
/*
* Now start a job with the Storage daemon
*/
- if (!start_storage_daemon_job(jcr, jcr->storage, NULL)) {
+ if (!start_storage_daemon_job(jcr, jcr->rstorage, NULL)) {
return false;
}
if (!bnet_fsend(jcr->store_bsock, "run")) {
/*
* send Storage daemon address to the File daemon
*/
- if (jcr->store->SDDport == 0) {
- jcr->store->SDDport = jcr->store->SDport;
+ if (jcr->rstore->SDDport == 0) {
+ jcr->rstore->SDDport = jcr->rstore->SDport;
}
- bnet_fsend(fd, storaddr, jcr->store->address, jcr->store->SDDport);
+ bnet_fsend(fd, storaddr, jcr->rstore->address, jcr->rstore->SDDport);
if (!response(jcr, fd, OKstore, "Storage", DISPLAY_ERROR)) {
return false;
}
pthread_mutex_t mutex; /* jcr mutex */
volatile int _use_count; /* use count */
public:
- void inc_use_count(void) {P(mutex); _use_count++; V(mutex); };
- void dec_use_count(void) {P(mutex); _use_count--; V(mutex); };
+ void lock() {P(mutex); };
+ void unlock() {V(mutex); };
+ void inc_use_count(void) {lock(); _use_count++; unlock(); };
+ void dec_use_count(void) {lock(); _use_count--; unlock(); };
int use_count() { return _use_count; };
void init_mutex(void) {pthread_mutex_init(&mutex, NULL); };
void destroy_mutex(void) {pthread_mutex_destroy(&mutex); };
- void lock() {P(mutex); };
- void unlock() {V(mutex); };
bool is_job_canceled() {return job_canceled(this); };
/* Global part of JCR common to all daemons */
BSOCK *ua; /* User agent */
JOB *job; /* Job resource */
JOB *verify_job; /* Job resource of verify previous job */
- alist *storage; /* Storage possibilities */
- STORE *store; /* Storage daemon selected */
+ alist *rstorage; /* Read storage possibilities */
+ STORE *rstore; /* Selected read storage */
+ alist *wstorage; /* Write storage possibilities */
+ STORE *wstore; /* Selected write storage */
CLIENT *client; /* Client resource */
POOL *pool; /* Pool resource */
POOL *full_pool; /* Full backup pool resource */