/* DELETE ME when bugs in MA1512, MA1632 MA1639 are fixed */
extern void (*MA1512_reload_job_end_cb)(JCR *,void *);
static void reload_job_end_cb(JCR *jcr, void *ctx);
+static void connect_and_init_globals();
/* We use a dedicated thread to find the next jobs to run
* in order to avoid issues with a HUP signal that might
config = New(CONFIG());
parse_dir_config(config, configfile, M_ERROR_TERM);
+ connect_and_init_globals();
/* If the director variable is not set, check_resources() will stop the process */
if (init_crypto() != 0) {
static pthread_mutex_t reload_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+/*
+ * Walk through "globals" tables and plug them into the matching resource
+ * After a reload_config() we need to connect the existing "globals" to
+ * the new version of the resources, or create new globals for brand
+ * new resources.
+ * "globals" are first created when loading the resources for the first time
+ */
+static void connect_and_init_globals()
+{
+ CLIENT_GLOBALS *cg;
+ CLIENT *client;
+ foreach_dlist(cg, &client_globals) {
+ client = GetClientResWithName(cg->name);
+ if (!client) {
+ Dmsg1(50, _("Client=%s not found. Assuming it was removed!!!\n"), cg->name);
+ } else {
+ client->globals = cg; /* Set globals pointer */
+ }
+ }
+ foreach_res(client, R_CLIENT) {
+ if (client->globals == NULL) {
+ client->create_client_globals(); /* if no globals exist, then create it */
+ }
+ }
+ STORE_GLOBALS *sg;
+ STORE *store;
+ foreach_dlist(sg, &store_globals) {
+ store = GetStoreResWithName(sg->name);
+ if (!store) {
+ Dmsg1(50, _("Storage=%s not found. Assuming it was removed!!!\n"), sg->name);
+ } else {
+ store->globals = sg; /* set globals pointer */
+ Dmsg2(200, "Reload found numConcurrent=%ld for Store %s\n",
+ sg->NumConcurrentJobs, sg->name);
+ }
+ }
+ foreach_res(store, R_STORAGE) {
+ if (store->globals == NULL) {
+ store->create_store_globals(); /* if no globals exist, then create it */
+ }
+ }
+ JOB_GLOBALS *jg;
+ JOB *job;
+ foreach_dlist(jg, &job_globals) {
+ job = GetJobResWithName(jg->name);
+ if (!job) {
+ Dmsg1(50, _("Job=%s not found. Assuming it was removed!!!\n"), jg->name);
+ } else {
+ job->globals = jg; /* Set globals pointer */
+ }
+ }
+ foreach_res(job, R_JOB) {
+ if (job->globals == NULL) {
+ job->create_job_globals(); /* if no globals exist, then create it */
+ }
+ }
+ SCHED_GLOBALS *schg;
+ SCHED *sched;
+ foreach_dlist(schg, &sched_globals) {
+ sched = GetSchedResWithName(schg->name);
+ if (!sched) {
+ Dmsg1(50, _("Schedule=%s not found. Assuming it was removed!!!\n"), schg->name);
+ } else {
+ sched->globals = schg; /* Set globals pointer */
+ }
+ }
+ foreach_res(sched, R_SCHEDULE) {
+ if (sched->globals == NULL) {
+ sched->create_sched_globals(); /* if no globals exist, then create it */
+ }
+ }
+}
+
/*
* If we get here, we have received a SIGHUP, which means to
* reread our configuration file.
}
}
endeach_jcr(jcr);
- /*
- * Now walk through globals tables and plug them into the
- * new resources.
- */
- CLIENT_GLOBALS *cg;
- foreach_dlist(cg, &client_globals) {
- CLIENT *client;
- client = GetClientResWithName(cg->name);
- if (!client) {
- Qmsg(NULL, M_INFO, 0, _("Client=%s not found. Assuming it was removed!!!\n"), cg->name);
- } else {
- client->globals = cg; /* Set globals pointer */
- }
- }
- STORE_GLOBALS *sg;
- foreach_dlist(sg, &store_globals) {
- STORE *store;
- store = GetStoreResWithName(sg->name);
- if (!store) {
- Qmsg(NULL, M_INFO, 0, _("Storage=%s not found. Assuming it was removed!!!\n"), sg->name);
- } else {
- store->globals = sg; /* set globals pointer */
- Dmsg2(200, "Reload found numConcurrent=%ld for Store %s\n",
- sg->NumConcurrentJobs, sg->name);
- }
- }
- JOB_GLOBALS *jg;
- foreach_dlist(jg, &job_globals) {
- JOB *job;
- job = GetJobResWithName(jg->name);
- if (!job) {
- Qmsg(NULL, M_INFO, 0, _("Job=%s not found. Assuming it was removed!!!\n"), jg->name);
- } else {
- job->globals = jg; /* Set globals pointer */
- }
- }
- SCHED_GLOBALS *schg;
- foreach_dlist(schg, &sched_globals) {
- SCHED *sched;
- sched = GetSchedResWithName(schg->name);
- if (!sched) {
- Qmsg(NULL, M_INFO, 0, _("Schedule=%s not found. Assuming it was removed!!!\n"), schg->name);
- } else {
- sched->globals = schg; /* Set globals pointer */
- }
- };
+ connect_and_init_globals();
}
/* Reset other globals */
int32_t CLIENT::getNumConcurrentJobs()
{
- if (!globals) {
- return 0;
- }
+ LOCK_GUARD(globals_mutex);
return globals->NumConcurrentJobs;
}
-void CLIENT::setNumConcurrentJobs(int32_t num)
+int32_t CLIENT::incNumConcurrentJobs(int32_t inc)
{
- P(globals_mutex);
- if (!globals) {
- create_client_globals();
- }
- globals->NumConcurrentJobs = num;
+ P(globals_mutex); // be sure globals is initialized
+ int32_t num = globals->NumConcurrentJobs += inc;
V(globals_mutex);
ASSERT(num >= 0);
Dmsg2(200, "Set NumConcurrentJobs=%ld for Client %s\n",
- num, globals->name);
+ num, globals->name);
+ return num;
}
BSOCK *CLIENT::getBSOCK(int timeout)
{
P(globals_mutex);
- if (!globals) {
- create_client_globals();
- }
if (!globals->socket) {
globals->socket = New(BsockMeeting());
}
bool CLIENT::getBSOCK_state(POOLMEM *&buf)
{
P(globals_mutex);
- if (!globals) {
- create_client_globals();
- }
if (!globals->socket) {
globals->socket = New(BsockMeeting());
}
void CLIENT::setBSOCK(BSOCK *sock)
{
P(globals_mutex);
- if (!globals) {
- create_client_globals();
- }
if (!globals->socket) {
globals->socket = New(BsockMeeting());
}
void CLIENT::setAddress(char *addr)
{
P(globals_mutex);
- if (!globals) {
- create_client_globals();
- }
if (globals->SetIPaddress) {
free(globals->SetIPaddress);
}
bool CLIENT::is_enabled()
{
- if (!globals || globals->enabled < 0) {
+ LOCK_GUARD(globals_mutex);
+ if (globals->enabled < 0) { /* not yet modified, use default from resource */
return Enabled;
}
return globals->enabled;
void CLIENT::setEnabled(bool val)
{
P(globals_mutex);
- if (!globals) {
- create_client_globals();
- }
/* TODO: We probably need to set -1 (not set) when we are back to the default value */
globals->enabled = val? 1 : 0;
V(globals_mutex);
int32_t JOB::getNumConcurrentJobs()
{
- if (!globals) {
- return 0;
- }
+ LOCK_GUARD(globals_mutex);
return globals->NumConcurrentJobs;
}
-void JOB::setNumConcurrentJobs(int32_t num)
+int32_t JOB::incNumConcurrentJobs(int32_t inc)
{
P(globals_mutex);
- if (!globals) {
- create_job_globals();
- }
- globals->NumConcurrentJobs = num;
+ int32_t num = globals->NumConcurrentJobs += inc;
V(globals_mutex);
ASSERT(num >= 0);
Dmsg2(200, "Set NumConcurrentJobs=%ld for Job %s\n",
num, globals->name);
+ return num;
}
bool JOB::is_enabled()
{
- if (!globals || globals->enabled < 0) {
+ LOCK_GUARD(globals_mutex);
+ if (globals->enabled < 0) { /* not yet modified, use default from resource */
return Enabled;
}
return globals->enabled;
void JOB::setEnabled(bool val)
{
P(globals_mutex);
- if (!globals) {
- create_job_globals();
- }
globals->enabled = val ? 1 : 0;
V(globals_mutex);
Dmsg2(200, "Set Enabled=%d for Job %s\n",
int32_t STORE::getNumConcurrentReadJobs()
{
- if (!globals) {
- return 0;
- }
+ LOCK_GUARD(globals_mutex);
return globals->NumConcurrentReadJobs;
}
-void STORE::setNumConcurrentReadJobs(int32_t num)
+int32_t STORE::incNumConcurrentReadJobs(int32_t inc)
{
P(globals_mutex);
- if (!globals) {
- create_store_globals();
- }
- globals->NumConcurrentReadJobs = num;
+ int32_t num = globals->NumConcurrentReadJobs += inc;
V(globals_mutex);
Dmsg2(200, "Set NumConcurrentReadJobs=%ld for Store %s\n",
num, globals->name);
ASSERT(num >= 0);
+ return num;
}
int32_t STORE::getNumConcurrentJobs()
{
- if (!globals) {
- return 0;
- }
+ LOCK_GUARD(globals_mutex);
return globals->NumConcurrentJobs;
}
-void STORE::setNumConcurrentJobs(int32_t num)
+int32_t STORE::incNumConcurrentJobs(int32_t inc)
{
P(globals_mutex);
- if (!globals) {
- create_store_globals();
- }
- globals->NumConcurrentJobs = num;
+ int32_t num = globals->NumConcurrentJobs += inc;
V(globals_mutex);
Dmsg2(200, "Set numconcurrentJobs=%ld for Store %s\n",
num, globals->name);
ASSERT(num >= 0);
+ return num;
}
bool STORE::is_enabled()
{
- if (!globals || globals->enabled < 0) {
+ LOCK_GUARD(globals_mutex);
+ if (globals->enabled < 0) { /* not yet modified, use default from resource */
return Enabled;
}
return globals->enabled;
void STORE::setEnabled(bool val)
{
P(globals_mutex);
- if (!globals) {
- create_store_globals();
- }
globals->enabled = val ? 1 : 0;
V(globals_mutex);
Dmsg2(200, "Set Enabled=%d for Storage %s\n",
bool SCHED::is_enabled()
{
- if (!globals || globals->enabled < 0) {
+ LOCK_GUARD(globals_mutex);
+ if (globals->enabled < 0) { /* not yet modified, use default from resource */
return Enabled;
}
return globals->enabled;
void SCHED::setEnabled(bool val)
{
P(globals_mutex);
- if (!globals) {
- create_sched_globals();
- }
globals->enabled = val ? 1 : 0;
V(globals_mutex);
Dmsg2(200, "Set Enabled=%d for Schedule %s\n",
class CLIENT {
public:
RES hdr;
- CLIENT_GLOBALS *globals; /* global variables */
+ CLIENT_GLOBALS *globals; /* data shared by all version of the res */
uint32_t FDport; /* Where File daemon listens */
utime_t FileRetention; /* file retention period in seconds */
utime_t JobRetention; /* job retention period in seconds */
char *name() const;
void create_client_globals();
int32_t getNumConcurrentJobs();
- void setNumConcurrentJobs(int32_t num);
+ int32_t incNumConcurrentJobs(int32_t inc);
char *address(POOLMEM *&buf);
void setAddress(char *addr);
bool is_enabled();
class STORE {
public:
RES hdr;
- STORE_GLOBALS *globals; /* global variables */
+ STORE_GLOBALS *globals; /* data shared by all version of the res */
uint32_t SDport; /* port where Directors connect */
uint32_t SDDport; /* data port for File daemon */
char *address;
void create_store_globals();
int32_t getNumConcurrentJobs();
int32_t getNumConcurrentReadJobs();
- void setNumConcurrentJobs(int32_t num);
- void setNumConcurrentReadJobs(int32_t num);
+ int32_t incNumConcurrentJobs(int32_t inc);
+ int32_t incNumConcurrentReadJobs(int32_t inc);
bool is_enabled();
void setEnabled(bool val);
};
class JOB {
public:
RES hdr;
- JOB_GLOBALS *globals; /* global variables */
+ JOB_GLOBALS *globals; /* data shared by all version of the res */
uint32_t JobType; /* job type (backup, verify, restore */
uint32_t JobLevel; /* default backup/verify level */
uint32_t RestoreJobId; /* What -- JobId to restore */
char *name() const;
void create_job_globals();
int32_t getNumConcurrentJobs();
- void setNumConcurrentJobs(int32_t num);
+ int32_t incNumConcurrentJobs(int32_t inc);
bool is_enabled();
void setEnabled(bool val);
};
/* Procedure to update the client->NumConcurrentJobs */
static void update_client_numconcurrentjobs(JCR *jcr, int val)
{
- int num;
if (!jcr->client) {
return;
}
if (jcr->no_client_used() || jcr->wasVirtualFull) {
break;
}
- num = jcr->client->getNumConcurrentJobs();
- jcr->client->setNumConcurrentJobs(num + val);
+ jcr->client->incNumConcurrentJobs(val);
break;
}
}
* put into the ready queue.
*/
if (jcr->acquired_resource_locks) {
- int num;
dec_read_store(jcr);
dec_write_store(jcr);
update_client_numconcurrentjobs(jcr, -1);
- num = jcr->job->getNumConcurrentJobs() - 1;
- jcr->job->setNumConcurrentJobs(num);
+ jcr->job->incNumConcurrentJobs(-1);
jcr->acquired_resource_locks = false;
}
Dmsg1(200, "Wstore=%s\n", jcr->wstore->name());
int num = jcr->wstore->getNumConcurrentJobs();
if (num < jcr->wstore->MaxConcurrentJobs) {
- Dmsg1(200, "Inc wncj=%d\n", num + 1);
- jcr->wstore->setNumConcurrentJobs(num + 1);
+ num = jcr->wstore->incNumConcurrentJobs(1);
+ Dmsg1(200, "Inc wncj=%d\n", num);
} else if (jcr->rstore) {
dec_read_store(jcr);
skip_this_jcr = true;
}
}
if (jcr->job->getNumConcurrentJobs() < jcr->job->MaxConcurrentJobs) {
- int num;
- num = jcr->job->getNumConcurrentJobs() + 1;
- jcr->job->setNumConcurrentJobs(num);
+ jcr->job->incNumConcurrentJobs(1);
} else {
/* Back out previous locks */
dec_write_store(jcr);
maxread == 0 || /* No limit set */
numread < maxread)) /* Below the limit */
{
- num++;
- numread++;
- jcr->rstore->setNumConcurrentReadJobs(numread);
- jcr->rstore->setNumConcurrentJobs(num);
+ numread = jcr->rstore->incNumConcurrentReadJobs(1);
+ num = jcr->rstore->incNumConcurrentJobs(1);
Dmsg1(200, "Inc rncj=%d\n", num);
V(rstore_mutex);
return true;
{
if (jcr->rstore) {
P(rstore_mutex);
- int numread = jcr->rstore->getNumConcurrentReadJobs() - 1;
- int num = jcr->rstore->getNumConcurrentJobs() - 1;
- jcr->rstore->setNumConcurrentReadJobs(numread);
- jcr->rstore->setNumConcurrentJobs(num);
+ jcr->rstore->incNumConcurrentReadJobs(-1);
+ int num = jcr->rstore->incNumConcurrentJobs(-1);
Dmsg1(200, "Dec rncj=%d\n", num);
V(rstore_mutex);
}
static void dec_write_store(JCR *jcr)
{
if (jcr->wstore) {
- int num = jcr->wstore->getNumConcurrentJobs() - 1;
+ int num = jcr->wstore->incNumConcurrentJobs(-1);
Dmsg1(200, "Dec wncj=%d\n", num);
- jcr->wstore->setNumConcurrentJobs(num);
}
}
Emsg3(M_ABORT, 0, _("rwl_writelock failure at %s:%d: ERR=%s\n"),
file, line, strerror(errstat));
}
- res_locked++;
+ res_locked++; /* for debug only */
}
void b_UnlockRes(const char *file, int line)
Emsg3(M_ABORT, 0, _("rwl_writeunlock failure at %s:%d:. ERR=%s\n"),
file, line, strerror(errstat));
}
- res_locked--;
+ res_locked--; /* for debug only */
#ifdef TRACE_RES
Pmsg4(000, "UnLockRes locked=%d wactive=%d at %s:%d\n",
res_locked, res_lock.w_active, file, line);