Kern's ToDo List
- 20 May 2005
+ 26 May 2005
Major development:
Project Developer
- Document testing
- Document that ChangerDevice is used for Alert command.
- Document new CDROM directory.
+- Document Heartbeat Interval in the dealing with firewalls section.
For 1.37:
-- From Chris Hull:
- it seems to be complaining about 12:00pm which should be a valid 12
- hour time. I changed the time to 11:59am and everything works fine.
- Also 12:00am works fine. 0:00pm also works (which I don't think
- should). None of the values 12:00pm - 12:59pm work for that matter.
=== rate design
jcr->last_rate
jcr->last_runtime
- Add "limit=n" for "list jobs"
- Make bootstrap filename unique.
- Make Dmsg look at global before calling subroutine.
+- From Chris Hull:
+ it seems to be complaining about 12:00pm which should be a valid 12
+ hour time. I changed the time to 11:59am and everything works fine.
+ Also 12:00am works fine. 0:00pm also works (which I don't think
+ should). None of the values 12:00pm - 12:59pm work for that matter.
+
General:
+Changes to 1.37.20:
+26May05
+- Make JCR a class and implement inc_use_count() and
+ dec_use_count() methods that ensure that the jcr is
+ locked when inc/dec the use count.
+- Remove the global jcr lock when traversing the jcr
+ chain.
+- Use dlist to implement the jcr chain rather than hand
+ crafted next and prev links.
+- Lock the jcr chain inside each function that modifies
+ the chain.
+
Changes to 1.37.19:
26May05
- Fix compile problem of ua_restore.c on broken compilers.
sigaddset(&set, SIGHUP);
sigprocmask(SIG_BLOCK, &set, NULL);
-// Jmsg(NULL, M_INFO, 0, "Entering experimental reload config code. Bug reports will not be accepted.\n");
-
lock_jcr_chain();
LockRes();
job_end_push(jcr, reload_job_end_cb, (void *)((long int)table));
njobs++;
}
- free_locked_jcr(jcr);
+ free_jcr(jcr);
}
}
SDConnectTimeout = director->SDConnectTimeout;
Dmsg0(0, "Director's configuration file reread.\n");
-// init_device_resources(); /* Update Device resources */
-
/* Now release saved resources, if no jobs using the resources */
if (njobs == 0) {
free_saved_resources(table);
Copyright (C) 2000-2005 Kern Sibbald
This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- 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 ammended 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.
*/
Dmsg1(800, "job_monitor_watchdog %p called\n", self);
- lock_jcr_chain();
-
foreach_jcr(jcr) {
bool cancel;
Dmsg2(800, "Skipping JCR %p (%s) with JobId 0\n",
jcr, jcr->Job);
/* Keep reference counts correct */
- free_locked_jcr(jcr);
+ free_jcr(jcr);
continue;
}
}
/* Keep reference counts correct */
- free_locked_jcr(jcr);
+ free_jcr(jcr);
}
- unlock_jcr_chain();
}
/*
sched_pkt = (wait_pkt *)malloc(sizeof(wait_pkt));
sched_pkt->jcr = jcr;
sched_pkt->jq = jq;
-// jcr->use_count--; /* release our use of jcr */
stat = pthread_create(&id, &jq->attr, sched_wait, (void *)sched_pkt);
if (stat != 0) { /* thread not created */
berrno be;
* Version $Id$
*
*/
-
/*
Copyright (C) 2004-2005 Kern Sibbald
This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- 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 ammended 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.
*/
Dmsg0(000, "Parse tuple error in job_write\n");
return NULL;
}
- lock_jcr_chain();
foreach_jcr(jcr) {
if (jcr->JobId == 0) {
- free_locked_jcr(jcr); /* OK to free now cuz chain is locked */
+ free_jcr(jcr);
continue;
}
if (jcr->JobId == JobId) {
found = true;
- break;
+ break;
}
}
if (!found) {
- unlock_jcr_chain();
/* ***FIXME*** raise exception */
return NULL;
}
- unlock_jcr_chain();
PyEval_ReleaseLock();
UAContext *ua = new_ua_context(jcr);
ua->batch = true;
return NULL;
}
free_ua_context(ua);
- free_locked_jcr(jcr);
+ free_jcr(jcr);
PyEval_AcquireLock();
Py_INCREF(Py_None);
return Py_None;
*
* Version $Id$
*/
-
/*
Copyright (C) 2000-2005 Kern Sibbald
This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- 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 ammended 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.
*/
if (!jcr) {
char buf[1000];
/* Count Jobs running */
- lock_jcr_chain();
foreach_jcr(jcr) {
if (jcr->JobId == 0) { /* this is us */
- free_locked_jcr(jcr);
+ free_jcr(jcr);
continue;
}
- free_locked_jcr(jcr);
+ free_jcr(jcr);
njobs++;
}
- unlock_jcr_chain();
if (njobs == 0) {
bsendmsg(ua, _("No Jobs running.\n"));
return 1;
}
start_prompt(ua, _("Select Job:\n"));
- lock_jcr_chain();
foreach_jcr(jcr) {
if (jcr->JobId == 0) { /* this is us */
- free_locked_jcr(jcr);
+ free_jcr(jcr);
continue;
}
bsnprintf(buf, sizeof(buf), "JobId=%d Job=%s", jcr->JobId, jcr->Job);
add_prompt(ua, buf);
- free_locked_jcr(jcr);
+ free_jcr(jcr);
}
- unlock_jcr_chain();
if (do_prompt(ua, _("Job"), _("Choose Job to cancel"), buf, sizeof(buf)) < 0) {
return 1;
bmicrosleep(0, 200000); /* let job actually start */
for (bool running=true; running; ) {
running = false;
- lock_jcr_chain();
foreach_jcr(jcr) {
if (jcr->JobId != 0) {
running = true;
- free_locked_jcr(jcr);
+ free_jcr(jcr);
break;
}
- free_locked_jcr(jcr);
+ free_jcr(jcr);
}
- unlock_jcr_chain();
if (running) {
bmicrosleep(1, 0);
}
*
* Version $Id$
*/
-
/*
- Copyright (C) 2000-2005 Kern Sibbald
+ Copyright (C) 2001-2005 Kern Sibbald
This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- 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 ammended 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.
*/
+
#include "bacula.h"
#include "dird.h"
if (strcasecmp(ua->argk[2], "current") == 0) {
bsendmsg(ua, OKqstatus, ua->argk[2]);
- lock_jcr_chain();
foreach_jcr(njcr) {
- if (njcr->JobId != 0) {
- bsendmsg(ua, DotStatusJob, njcr->JobId, njcr->JobStatus, njcr->JobErrors);
- }
- free_locked_jcr(njcr);
+ if (njcr->JobId != 0) {
+ bsendmsg(ua, DotStatusJob, njcr->JobId, njcr->JobStatus, njcr->JobErrors);
+ }
+ free_jcr(njcr);
}
- unlock_jcr_chain();
}
else if (strcasecmp(ua->argk[2], "last") == 0) {
bsendmsg(ua, OKqstatus, ua->argk[2]);
if ((last_jobs) && (last_jobs->size() > 0)) {
- job = (s_last_job*)last_jobs->last();
- bsendmsg(ua, DotStatusJob, job->JobId, job->JobStatus, job->Errors);
+ job = (s_last_job*)last_jobs->last();
+ bsendmsg(ua, DotStatusJob, job->JobId, job->JobStatus, job->Errors);
}
}
else {
for (i=1; i<ua->argc; i++) {
if (strcasecmp(ua->argk[i], _("all")) == 0) {
- do_all_status(ua);
- return 1;
+ do_all_status(ua);
+ return 1;
} else if (strcasecmp(ua->argk[i], _("dir")) == 0 ||
strcasecmp(ua->argk[i], _("director")) == 0) {
- do_director_status(ua);
- return 1;
+ do_director_status(ua);
+ return 1;
} else if (strcasecmp(ua->argk[i], _("client")) == 0) {
- client = get_client_resource(ua);
- if (client) {
- do_client_status(ua, client);
- }
- return 1;
+ client = get_client_resource(ua);
+ if (client) {
+ do_client_status(ua, client);
+ }
+ return 1;
} else {
- store = get_storage_resource(ua, 0);
- if (store) {
- do_storage_status(ua, store);
- }
- return 1;
+ store = get_storage_resource(ua, 0);
+ if (store) {
+ do_storage_status(ua, store);
+ }
+ return 1;
}
}
/* If no args, ask for status type */
add_prompt(ua, _("All"));
Dmsg0(20, "do_prompt: select daemon\n");
if ((item=do_prompt(ua, "", _("Select daemon type for status"), prmt, sizeof(prmt))) < 0) {
- return 1;
+ return 1;
}
Dmsg1(20, "item=%d\n", item);
switch (item) {
- case 0: /* Director */
- do_director_status(ua);
- break;
+ case 0: /* Director */
+ do_director_status(ua);
+ break;
case 1:
- store = select_storage_resource(ua);
- if (store) {
- do_storage_status(ua, store);
- }
- break;
+ store = select_storage_resource(ua);
+ if (store) {
+ do_storage_status(ua, store);
+ }
+ break;
case 2:
- client = select_client_resource(ua);
- if (client) {
- do_client_status(ua, client);
- }
- break;
+ client = select_client_resource(ua);
+ if (client) {
+ do_client_status(ua, client);
+ }
+ break;
case 3:
- do_all_status(ua);
- break;
+ do_all_status(ua);
+ break;
default:
- break;
+ break;
}
}
return 1;
foreach_res(store, R_STORAGE) {
found = false;
if (!acl_access_ok(ua, Storage_ACL, store->hdr.name)) {
- continue;
+ continue;
}
for (j=0; j<i; j++) {
- if (strcmp(unique_store[j]->address, store->address) == 0 &&
- unique_store[j]->SDport == store->SDport) {
- found = true;
- break;
- }
+ if (strcmp(unique_store[j]->address, store->address) == 0 &&
+ unique_store[j]->SDport == store->SDport) {
+ found = true;
+ break;
+ }
}
if (!found) {
- unique_store[i++] = store;
+ unique_store[i++] = store;
Dmsg2(40, "Stuffing: %s:%d\n", store->address, store->SDport);
}
}
foreach_res(client, R_CLIENT) {
found = false;
if (!acl_access_ok(ua, Client_ACL, client->hdr.name)) {
- continue;
+ continue;
}
for (j=0; j<i; j++) {
- if (strcmp(unique_client[j]->address, client->address) == 0 &&
- unique_client[j]->FDport == client->FDport) {
- found = true;
- break;
- }
+ if (strcmp(unique_client[j]->address, client->address) == 0 &&
+ unique_client[j]->FDport == client->FDport) {
+ found = true;
+ break;
+ }
}
if (!found) {
- unique_client[i++] = client;
+ unique_client[i++] = client;
Dmsg2(40, "Stuffing: %s:%d\n", client->address, client->FDport);
}
}
char dt[MAX_TIME_LENGTH];
bsendmsg(ua, "%s Version: " VERSION " (" BDATE ") %s %s %s\n", my_name,
- HOST_OS, DISTNAME, DISTVER);
+ HOST_OS, DISTNAME, DISTVER);
bstrftime_nc(dt, sizeof(dt), daemon_start_time);
bsendmsg(ua, _("Daemon started %s, %d Job%s run since started.\n"),
dt, num_jobs_run, num_jobs_run == 1 ? "" : "s");
if (debug_level > 0) {
char b1[35], b2[35], b3[35], b4[35];
bsendmsg(ua, _(" Heap: bytes=%s max_bytes=%s bufs=%s max_bufs=%s\n"),
- edit_uint64_with_commas(sm_bytes, b1),
- edit_uint64_with_commas(sm_max_bytes, b2),
- edit_uint64_with_commas(sm_buffers, b3),
- edit_uint64_with_commas(sm_max_buffers, b4));
+ edit_uint64_with_commas(sm_bytes, b1),
+ edit_uint64_with_commas(sm_max_bytes, b2),
+ edit_uint64_with_commas(sm_buffers, b3),
+ edit_uint64_with_commas(sm_max_buffers, b4));
}
/*
* List scheduled Jobs
store->hdr.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->hdr.name);
if (ua->jcr->store_bsock) {
- bnet_close(ua->jcr->store_bsock);
- ua->jcr->store_bsock = NULL;
+ bnet_close(ua->jcr->store_bsock);
+ ua->jcr->store_bsock = NULL;
}
return;
}
client->hdr.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->hdr.name);
if (ua->jcr->file_bsock) {
- bnet_close(ua->jcr->file_bsock);
- ua->jcr->file_bsock = NULL;
+ bnet_close(ua->jcr->file_bsock);
+ ua->jcr->file_bsock = NULL;
}
return;
}
/* Scheduling packet */
struct sched_pkt {
- dlink link; /* keep this as first item!!! */
+ dlink link; /* keep this as first item!!! */
JOB *job;
int level;
int priority;
jcr->db = NULL;
ok = complete_jcr_for_job(jcr, sp->job, sp->pool);
if (jcr->db) {
- close_db = true; /* new db opened, remember to close it */
+ close_db = true; /* new db opened, remember to close it */
}
if (ok) {
mr.PoolId = jcr->PoolId;
- ok = find_next_volume_for_append(jcr, &mr, 0);
+ ok = find_next_volume_for_append(jcr, &mr, 0);
}
if (!ok) {
bstrncpy(mr.VolumeName, "*unknown*", sizeof(mr.VolumeName));
if (close_db) {
db_close_database(jcr, jcr->db);
}
- jcr->db = ua->db; /* restore ua db to jcr */
+ jcr->db = ua->db; /* restore ua db to jcr */
}
LockRes();
foreach_res(job, R_JOB) {
if (!acl_access_ok(ua, Job_ACL, job->hdr.name)) {
- continue;
+ continue;
}
for (run=NULL; (run = find_next_run(run, job, runtime)); ) {
- level = job->JobLevel;
- if (run->level) {
- level = run->level;
- }
- priority = job->Priority;
- if (run->Priority) {
- priority = run->Priority;
- }
- if (!hdr_printed) {
- prt_runhdr(ua);
- hdr_printed = true;
- }
- sp = (sched_pkt *)malloc(sizeof(sched_pkt));
- sp->job = job;
- sp->level = level;
- sp->priority = priority;
- sp->runtime = runtime;
- sp->pool = run->pool;
- sched.binary_insert(sp, my_compare);
- num_jobs++;
+ level = job->JobLevel;
+ if (run->level) {
+ level = run->level;
+ }
+ priority = job->Priority;
+ if (run->Priority) {
+ priority = run->Priority;
+ }
+ if (!hdr_printed) {
+ prt_runhdr(ua);
+ hdr_printed = true;
+ }
+ sp = (sched_pkt *)malloc(sizeof(sched_pkt));
+ sp->job = job;
+ sp->level = level;
+ sp->priority = priority;
+ sp->runtime = runtime;
+ sp->pool = run->pool;
+ sched.binary_insert(sp, my_compare);
+ num_jobs++;
}
} /* end for loop over resources */
UnlockRes();
JCR *jcr;
int njobs = 0;
const char *msg;
- char *emsg; /* edited message */
+ char *emsg; /* edited message */
char dt[MAX_TIME_LENGTH];
char level[10];
bool pool_mem = false;
Dmsg0(200, "enter list_run_jobs()\n");
bsendmsg(ua, _("\nRunning Jobs:\n"));
- lock_jcr_chain();
foreach_jcr(jcr) {
njobs++;
- if (jcr->JobId == 0) { /* this is us */
- /* this is a console or other control job. We only show console
- * jobs in the status output.
- */
- if (jcr->JobType == JT_CONSOLE) {
- bstrftime_nc(dt, sizeof(dt), jcr->start_time);
+ if (jcr->JobId == 0) { /* this is us */
+ /* this is a console or other control job. We only show console
+ * jobs in the status output.
+ */
+ if (jcr->JobType == JT_CONSOLE) {
+ bstrftime_nc(dt, sizeof(dt), jcr->start_time);
bsendmsg(ua, _("Console connected at %s\n"), dt);
- }
- njobs--;
+ }
+ njobs--;
}
- free_locked_jcr(jcr);
+ free_jcr(jcr);
}
if (njobs == 0) {
- unlock_jcr_chain();
/* Note the following message is used in regress -- don't change */
bsendmsg(ua, _("No Jobs running.\n====\n"));
Dmsg0(200, "leave list_run_jobs()\n");
bsendmsg(ua, _("======================================================================\n"));
foreach_jcr(jcr) {
if (jcr->JobId == 0 || !acl_access_ok(ua, Job_ACL, jcr->job->hdr.name)) {
- free_locked_jcr(jcr);
- continue;
+ free_jcr(jcr);
+ continue;
}
njobs++;
switch (jcr->JobStatus) {
case JS_Created:
msg = _("is waiting execution");
- break;
+ break;
case JS_Running:
msg = _("is running");
- break;
+ break;
case JS_Blocked:
msg = _("is blocked");
- break;
+ break;
case JS_Terminated:
msg = _("has terminated");
- break;
+ break;
case JS_ErrorTerminated:
msg = _("has erred");
- break;
+ break;
case JS_Error:
msg = _("has errors");
- break;
+ break;
case JS_FatalError:
msg = _("has a fatal error");
- break;
+ break;
case JS_Differences:
msg = _("has verify differences");
- break;
+ break;
case JS_Canceled:
msg = _("has been canceled");
- break;
+ break;
case JS_WaitFD:
- emsg = (char *) get_pool_memory(PM_FNAME);
+ emsg = (char *) get_pool_memory(PM_FNAME);
Mmsg(emsg, _("is waiting on Client %s"), jcr->client->hdr.name);
- pool_mem = true;
- msg = emsg;
- break;
+ pool_mem = true;
+ msg = emsg;
+ break;
case JS_WaitSD:
- emsg = (char *) get_pool_memory(PM_FNAME);
+ emsg = (char *) get_pool_memory(PM_FNAME);
Mmsg(emsg, _("is waiting on Storage %s"), jcr->store->hdr.name);
- pool_mem = true;
- msg = emsg;
- break;
+ pool_mem = true;
+ msg = emsg;
+ break;
case JS_WaitStoreRes:
msg = _("is waiting on max Storage jobs");
- break;
+ break;
case JS_WaitClientRes:
msg = _("is waiting on max Client jobs");
- break;
+ break;
case JS_WaitJobRes:
msg = _("is waiting on max Job jobs");
- break;
+ break;
case JS_WaitMaxJobs:
msg = _("is waiting on max total jobs");
- break;
+ break;
case JS_WaitStartTime:
msg = _("is waiting for its start time");
- break;
+ break;
case JS_WaitPriority:
msg = _("is waiting for higher priority jobs to finish");
- break;
+ break;
default:
- emsg = (char *) get_pool_memory(PM_FNAME);
+ emsg = (char *) get_pool_memory(PM_FNAME);
Mmsg(emsg, _("is in unknown state %c"), jcr->JobStatus);
- pool_mem = true;
- msg = emsg;
- break;
+ pool_mem = true;
+ msg = emsg;
+ break;
}
/*
* Now report Storage daemon status code
*/
switch (jcr->SDJobStatus) {
case JS_WaitMount:
- if (pool_mem) {
- free_pool_memory(emsg);
- pool_mem = false;
- }
+ if (pool_mem) {
+ free_pool_memory(emsg);
+ pool_mem = false;
+ }
msg = _("is waiting for a mount request");
- break;
+ break;
case JS_WaitMedia:
- if (pool_mem) {
- free_pool_memory(emsg);
- pool_mem = false;
- }
+ if (pool_mem) {
+ free_pool_memory(emsg);
+ pool_mem = false;
+ }
msg = _("is waiting for an appendable Volume");
- break;
+ break;
case JS_WaitFD:
- if (!pool_mem) {
- emsg = (char *) get_pool_memory(PM_FNAME);
- pool_mem = true;
- }
+ if (!pool_mem) {
+ emsg = (char *) get_pool_memory(PM_FNAME);
+ pool_mem = true;
+ }
Mmsg(emsg, _("is waiting for Client %s to connect to Storage %s"),
- jcr->client->hdr.name, jcr->store->hdr.name);
- msg = emsg;
- break;
+ jcr->client->hdr.name, jcr->store->hdr.name);
+ msg = emsg;
+ break;
}
switch (jcr->JobType) {
case JT_ADMIN:
case JT_RESTORE:
bstrncpy(level, " ", sizeof(level));
- break;
+ break;
default:
- bstrncpy(level, level_to_str(jcr->JobLevel), sizeof(level));
- level[7] = 0;
- break;
+ bstrncpy(level, level_to_str(jcr->JobLevel), sizeof(level));
+ level[7] = 0;
+ break;
}
bsendmsg(ua, _("%6d %-6s %-20s %s\n"),
- jcr->JobId,
- level,
- jcr->Job,
- msg);
+ jcr->JobId,
+ level,
+ jcr->Job,
+ msg);
if (pool_mem) {
- free_pool_memory(emsg);
- pool_mem = false;
+ free_pool_memory(emsg);
+ pool_mem = false;
}
- free_locked_jcr(jcr);
+ free_jcr(jcr);
}
- unlock_jcr_chain();
bsendmsg(ua, "====\n");
Dmsg0(200, "leave list_run_jobs()\n");
}
char *p;
for (int i=0; i<3; i++) {
if ((p=strrchr(JobName, '.')) != NULL) {
- *p = 0;
- }
+ *p = 0;
+ }
}
if (!acl_access_ok(ua, Job_ACL, JobName)) {
- continue;
+ continue;
}
bstrftime_nc(dt, sizeof(dt), je->end_time);
case JT_ADMIN:
case JT_RESTORE:
bstrncpy(level, " ", sizeof(level));
- break;
+ break;
default:
- bstrncpy(level, level_to_str(je->JobLevel), sizeof(level));
- level[4] = 0;
- break;
+ bstrncpy(level, level_to_str(je->JobLevel), sizeof(level));
+ level[4] = 0;
+ break;
}
switch (je->JobStatus) {
case JS_Created:
termstat = "Created";
- break;
+ break;
case JS_FatalError:
case JS_ErrorTerminated:
termstat = "Error";
- break;
+ break;
case JS_Differences:
termstat = "Diffs";
- break;
+ break;
case JS_Canceled:
termstat = "Cancel";
- break;
+ break;
case JS_Terminated:
termstat = "OK";
- break;
+ break;
default:
termstat = "Other";
- break;
+ break;
}
bsendmsg(ua, _("%6d %-6s %8s %14s %-7s %-8s %s\n"),
- je->JobId,
- level,
- edit_uint64_with_commas(je->JobFiles, b1),
- edit_uint64_with_commas(je->JobBytes, b2),
- termstat,
- dt, JobName);
+ je->JobId,
+ level,
+ edit_uint64_with_commas(je->JobFiles, b1),
+ edit_uint64_with_commas(je->JobBytes, b2),
+ termstat,
+ dt, JobName);
}
bsendmsg(ua, "\n");
unlock_last_jobs_list();
msg = (char *)get_pool_memory(PM_MESSAGE);
found = 0;
len = Mmsg(msg, "%s Version: " VERSION " (" BDATE ") %s %s %s\n", my_name,
- HOST_OS, DISTNAME, DISTVER);
+ HOST_OS, DISTNAME, DISTVER);
sendit(msg, len, arg);
bstrftime_nc(dt, sizeof(dt), daemon_start_time);
len = Mmsg(msg, _("Daemon started %s, %d Job%s run since started.\n"),
- dt, num_jobs_run, num_jobs_run == 1 ? "" : "s");
+ dt, num_jobs_run, num_jobs_run == 1 ? "" : "s");
sendit(msg, len, arg);
#if defined(HAVE_CYGWIN) || defined(HAVE_WIN32)
if (/*debug_level > 0*/ true) {
if (!privs) {
- privs = enable_backup_privileges(NULL, 1);
+ privs = enable_backup_privileges(NULL, 1);
}
len = Mmsg(msg,
_(" Priv 0x%x\n APIs=%sOPT,%sATP,%sLPV,%sCFA,%sCFW,\n"
" %sWC2MB,%sMB2WC,%sFFFA,%sFFFW,%sFNFA,%sFNFW,%sSCDA,%sSCDW,\n"
" %sGCDA,%sGCDW\n"),
privs,
- p_OpenProcessToken?"":"!",
- p_AdjustTokenPrivileges?"":"!",
- p_LookupPrivilegeValue?"":"!",
+ p_OpenProcessToken?"":"!",
+ p_AdjustTokenPrivileges?"":"!",
+ p_LookupPrivilegeValue?"":"!",
p_CreateFileA?"":"!",
- p_CreateFileW?"":"!",
+ p_CreateFileW?"":"!",
p_wunlink?"":"!",
p_wmkdir?"":"!",
p_GetFileAttributesW?"":"!",
p_GetFileAttributesExA?"":"!",
- p_GetFileAttributesExW?"":"!",
+ p_GetFileAttributesExW?"":"!",
p_SetFileAttributesA?"":"!",
- p_SetFileAttributesW?"":"!",
- p_BackupRead?"":"!",
- p_BackupWrite?"":"!",
- p_SetProcessShutdownParameters?"":"!",
+ p_SetFileAttributesW?"":"!",
+ p_BackupRead?"":"!",
+ p_BackupWrite?"":"!",
+ p_SetProcessShutdownParameters?"":"!",
p_WideCharToMultiByte?"":"!",
p_MultiByteToWideChar?"":"!",
#endif
if (debug_level > 0) {
len = Mmsg(msg, _(" Heap: bytes=%s max_bytes=%s bufs=%s max_bufs=%s\n"),
- edit_uint64_with_commas(sm_bytes, b1),
- edit_uint64_with_commas(sm_max_bytes, b2),
- edit_uint64_with_commas(sm_buffers, b3),
- edit_uint64_with_commas(sm_max_buffers, b4));
+ edit_uint64_with_commas(sm_bytes, b1),
+ edit_uint64_with_commas(sm_max_bytes, b2),
+ edit_uint64_with_commas(sm_buffers, b3),
+ edit_uint64_with_commas(sm_max_buffers, b4));
sendit(msg, len, arg);
len = Mmsg(msg, _(" Sizeof: off_t=%d size_t=%d debug=%d trace=%d\n"),
- sizeof(off_t), sizeof(size_t), debug_level, get_trace());
+ sizeof(off_t), sizeof(size_t), debug_level, get_trace());
sendit(msg, len, arg);
}
Dmsg0(1000, "Begin status jcr loop.\n");
len = Mmsg(msg, _("Running Jobs:\n"));
sendit(msg, len, arg);
- lock_jcr_chain();
foreach_jcr(njcr) {
bstrftime_nc(dt, sizeof(dt), njcr->start_time);
if (njcr->JobId == 0) {
- len = Mmsg(msg, _("Director connected at: %s\n"), dt);
+ len = Mmsg(msg, _("Director connected at: %s\n"), dt);
} else {
- len = Mmsg(msg, _("JobId %d Job %s is running.\n"),
- njcr->JobId, njcr->Job);
- sendit(msg, len, arg);
- len = Mmsg(msg, _(" %s Job started: %s\n"),
- job_type_to_str(njcr->JobType), dt);
+ len = Mmsg(msg, _("JobId %d Job %s is running.\n"),
+ njcr->JobId, njcr->Job);
+ sendit(msg, len, arg);
+ len = Mmsg(msg, _(" %s Job started: %s\n"),
+ job_type_to_str(njcr->JobType), dt);
}
sendit(msg, len, arg);
if (njcr->JobId == 0) {
- free_locked_jcr(njcr);
- continue;
+ free_jcr(njcr);
+ continue;
}
sec = time(NULL) - njcr->start_time;
if (sec <= 0) {
- sec = 1;
+ sec = 1;
}
bps = (int)(njcr->JobBytes / sec);
len = Mmsg(msg, _(" Files=%s Bytes=%s Bytes/sec=%s\n"),
- edit_uint64_with_commas(njcr->JobFiles, b1),
- edit_uint64_with_commas(njcr->JobBytes, b2),
- edit_uint64_with_commas(bps, b3));
+ edit_uint64_with_commas(njcr->JobFiles, b1),
+ edit_uint64_with_commas(njcr->JobBytes, b2),
+ edit_uint64_with_commas(bps, b3));
sendit(msg, len, arg);
len = Mmsg(msg, _(" Files Examined=%s\n"),
- edit_uint64_with_commas(njcr->num_files_examined, b1));
+ edit_uint64_with_commas(njcr->num_files_examined, b1));
sendit(msg, len, arg);
if (njcr->JobFiles > 0) {
- P(njcr->mutex);
- len = Mmsg(msg, _(" Processing file: %s\n"), njcr->last_fname);
- V(njcr->mutex);
- sendit(msg, len, arg);
+ P(njcr->mutex);
+ len = Mmsg(msg, _(" Processing file: %s\n"), njcr->last_fname);
+ V(njcr->mutex);
+ sendit(msg, len, arg);
}
found = 1;
if (njcr->store_bsock) {
- len = Mmsg(msg, " SDReadSeqNo=%" lld " fd=%d\n",
- njcr->store_bsock->read_seqno, njcr->store_bsock->fd);
- sendit(msg, len, arg);
+ len = Mmsg(msg, " SDReadSeqNo=%" lld " fd=%d\n",
+ njcr->store_bsock->read_seqno, njcr->store_bsock->fd);
+ sendit(msg, len, arg);
} else {
- len = Mmsg(msg, _(" SDSocket closed.\n"));
- sendit(msg, len, arg);
+ len = Mmsg(msg, _(" SDSocket closed.\n"));
+ sendit(msg, len, arg);
}
- free_locked_jcr(njcr);
+ free_jcr(njcr);
}
- unlock_jcr_chain();
Dmsg0(1000, "Begin status jcr loop.\n");
if (!found) {
len = Mmsg(msg, _("No Jobs running.\n"));
switch (je->JobType) {
case JT_ADMIN:
case JT_RESTORE:
- bstrncpy(level, " ", sizeof(level));
- break;
+ bstrncpy(level, " ", sizeof(level));
+ break;
default:
- bstrncpy(level, level_to_str(je->JobLevel), sizeof(level));
- level[4] = 0;
- break;
+ bstrncpy(level, level_to_str(je->JobLevel), sizeof(level));
+ level[4] = 0;
+ break;
}
switch (je->JobStatus) {
case JS_Created:
- termstat = "Created";
- break;
+ termstat = "Created";
+ break;
case JS_FatalError:
case JS_ErrorTerminated:
- termstat = "Error";
- break;
+ termstat = "Error";
+ break;
case JS_Differences:
- termstat = "Diffs";
- break;
+ termstat = "Diffs";
+ break;
case JS_Canceled:
- termstat = "Cancel";
- break;
+ termstat = "Cancel";
+ break;
case JS_Terminated:
- termstat = "OK";
- break;
+ termstat = "OK";
+ break;
default:
- termstat = "Other";
- break;
+ termstat = "Other";
+ break;
}
bstrncpy(JobName, je->Job, sizeof(JobName));
/* There are three periods after the Job name */
char *p;
for (int i=0; i<3; i++) {
- if ((p=strrchr(JobName, '.')) != NULL) {
- *p = 0;
- }
+ if ((p=strrchr(JobName, '.')) != NULL) {
+ *p = 0;
+ }
}
bsnprintf(buf, sizeof(buf), _("%6d %-6s %8s %14s %-7s %-8s %s\n"),
- je->JobId,
- level,
- edit_uint64_with_commas(je->JobFiles, b1),
- edit_uint64_with_commas(je->JobBytes, b2),
- termstat,
- dt, JobName);
+ je->JobId,
+ level,
+ edit_uint64_with_commas(je->JobFiles, b1),
+ edit_uint64_with_commas(je->JobBytes, b2),
+ termstat,
+ dt, JobName);
sendit(buf, strlen(buf), arg);
}
sendit("====\n", 5, arg);
if (strcmp(time, "current") == 0) {
bnet_fsend(dir, OKqstatus, time);
- lock_jcr_chain();
foreach_jcr(njcr) {
- if (njcr->JobId != 0) {
- bnet_fsend(dir, DotStatusJob, njcr->JobId, njcr->JobStatus, njcr->JobErrors);
- }
- free_locked_jcr(njcr);
+ if (njcr->JobId != 0) {
+ bnet_fsend(dir, DotStatusJob, njcr->JobId, njcr->JobStatus, njcr->JobErrors);
+ }
+ free_jcr(njcr);
}
- unlock_jcr_chain();
}
else if (strcmp(time, "last") == 0) {
bnet_fsend(dir, OKqstatus, time);
if ((last_jobs) && (last_jobs->size() > 0)) {
- job = (s_last_job*)last_jobs->last();
- bnet_fsend(dir, DotStatusJob, job->JobId, job->JobStatus, job->Errors);
+ job = (s_last_job*)last_jobs->last();
+ bnet_fsend(dir, DotStatusJob, job->JobId, job->JobStatus, job->Errors);
}
}
else {
if (len > 0 && msg[len-1] == '\n') {
// when compiling with visual studio some strings are read-only
- // and cause access violations. So we creat a tmp copy.
+ // and cause access violations. So we creat a tmp copy.
char *_msg = (char *)alloca(len);
bstrncpy(_msg, msg, len);
msg = _msg;
JCR *njcr;
const char *termstat = _("Bacula Idle");
struct s_last_job *job;
- int stat = 0; /* Idle */
+ int stat = 0; /* Idle */
if (!last_jobs) {
goto done;
}
Dmsg0(1000, "Begin bac_status jcr loop.\n");
- lock_jcr_chain();
foreach_jcr(njcr) {
if (njcr->JobId != 0) {
- stat = JS_Running;
- termstat = _("Bacula Running");
- free_locked_jcr(njcr);
- break;
+ stat = JS_Running;
+ termstat = _("Bacula Running");
+ free_jcr(njcr);
+ break;
}
- free_locked_jcr(njcr);
+ free_jcr(njcr);
}
- unlock_jcr_chain();
if (stat != 0) {
goto done;
}
stat = job->JobStatus;
switch (job->JobStatus) {
case JS_Canceled:
- termstat = _("Last Job Canceled");
- break;
+ termstat = _("Last Job Canceled");
+ break;
case JS_ErrorTerminated:
case JS_FatalError:
- termstat = _("Last Job Failed");
- break;
+ termstat = _("Last Job Failed");
+ break;
default:
- if (job->Errors) {
- termstat = _("Last Job had Warnings");
- }
- break;
+ if (job->Errors) {
+ termstat = _("Last Job had Warnings");
+ }
+ break;
}
}
Dmsg0(1000, "End bac_status jcr loop.\n");
#define SD_READ 0
/* Forward referenced structures */
-struct JCR;
+class JCR;
struct FF_PKT;
typedef void (JCR_free_HANDLER)(JCR *jcr);
/* Job Control Record (JCR) */
-struct JCR {
+class JCR {
+public:
+ void inc_use_count(void) {P(mutex); use_count++; V(mutex); };
+ void dec_use_count(void) {P(mutex); use_count--; V(mutex); };
+
/* Global part of JCR common to all daemons */
- JCR *next;
- JCR *prev;
+ dlink link; /* JCR chain link */
volatile int use_count; /* use count */
pthread_t my_thread_id; /* id of thread controlling jcr */
pthread_mutex_t mutex; /* jcr mutex */
/* The following routines are found in lib/jcr.c */
extern bool init_jcr_subsystem(void);
extern JCR *new_jcr(int size, JCR_free_HANDLER *daemon_free_jcr);
-extern void free_locked_jcr(JCR *jcr);
extern JCR *get_jcr_by_id(uint32_t JobId);
extern JCR *get_jcr_by_session(uint32_t SessionId, uint32_t SessionTime);
extern JCR *get_jcr_by_partial_name(char *Job);
* Version $Id$
*/
/*
- Copyright (C) 2003-2005 Kern Sibbald
+ Copyright (C) 2004-2005 Kern Sibbald
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
#ifdef the_old_way
#define foreach_dlist(var, list) \
- for((var)=NULL; (((void *)(var))=(list)->next(var)); )
+ for((var)=NULL; (((void *)(var))=(list)->next(var)); )
#endif
void binary_insert(void *item, int compare(void *item1, void *item2));
void remove(void *item);
bool empty() const;
- int size() const;
+ int size() const;
void *next(const void *item) const;
void *prev(const void *item) const;
void destroy();
/*
- * Manipulation routines for Job Control Records
+ * Manipulation routines for Job Control Records and
+ * handling of last_jobs_list.
*
* Kern E. Sibbald, December 2000
*
*
* These routines are thread safe.
*
+ * The job list routines were re-written in May 2005 to
+ * eliminate the global lock while traversing the list, and
+ * to use the dlist subroutines. The locking is now done
+ * on the list each time the list is modified or traversed.
+ * That is it is "micro-locked" rather than globally locked.
+ * The result is that there is one lock/unlock for each entry
+ * in the list while traversing it rather than a single lock
+ * at the beginning of a traversal and one at the end. This
+ * incurs slightly more overhead, but effectively eliminates
+ * the possibilty of race conditions. In addition, with the
+ * exception of the global locking of the list during the
+ * re-reading of the config file, no recursion is needed.
+ *
*/
/*
Copyright (C) 2000-2005 Kern Sibbald
This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- 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 ammended 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.
*/
int num_jobs_run;
dlist *last_jobs = NULL;
const int max_last_jobs = 10;
-
-JCR *jobs = NULL; /* pointer to JCR chain */
+
+static dlist *jcrs = NULL; /* JCR chain */
static brwlock_t lock; /* lock for last jobs and JCR chain */
void init_last_jobs_list()
{
int errstat;
+ JCR *jcr;
struct s_last_job *job_entry = NULL;
if (!last_jobs) {
last_jobs = New(dlist(job_entry, &job_entry->link));
strerror(errstat));
}
}
-
+ if (!jcrs) {
+ jcrs = New(dlist(jcr, &jcr->link));
+ }
}
void term_last_jobs_list()
delete last_jobs;
last_jobs = NULL;
rwl_destroy(&lock);
+ delete jcrs;
}
}
sigaction(TIMEOUT_SIGNAL, &sigtimer, NULL);
lock_jcr_chain();
- jcr->prev = NULL;
- jcr->next = jobs;
- if (jobs) {
- jobs->prev = jcr;
+ if (!jcrs) {
+ jcrs = New(dlist(jcr, &jcr->link));
}
- jobs = jcr;
+ jcrs->append(jcr);
unlock_jcr_chain();
+
return jcr;
}
if (!jcr) {
Emsg0(M_ABORT, 0, "NULL jcr.\n");
}
- if (!jcr->prev) { /* if no prev */
- jobs = jcr->next; /* set new head */
- } else {
- jcr->prev->next = jcr->next; /* update prev */
- }
- if (jcr->next) {
- jcr->next->prev = jcr->prev;
- }
+ jcrs->remove(jcr);
Dmsg0(3400, "Leave remove_jcr\n");
}
dequeue_messages(jcr);
lock_jcr_chain();
- jcr->use_count--; /* decrement use count */
+ jcr->dec_use_count(); /* decrement use count */
if (jcr->use_count < 0) {
Emsg2(M_ERROR, 0, _("JCR use_count=%d JobId=%d\n"),
jcr->use_count, jcr->JobId);
}
-/*
- * Global routine to free a jcr
- * JCR chain is already locked
- */
-void free_locked_jcr(JCR *jcr)
-{
- jcr->use_count--; /* decrement use count */
- Dmsg2(3400, "Dec free_locked_jcr 0x%x use_count=%d\n", jcr, jcr->use_count);
- if (jcr->use_count > 0) { /* if in use */
- return;
- }
- remove_jcr(jcr);
- jcr->daemon_free_jcr(jcr); /* call daemon free routine */
- free_common_jcr(jcr);
-}
-
-
-
/*
* Given a JobId, find the JCR
* Returns: jcr on success
JCR *jcr;
lock_jcr_chain(); /* lock chain */
- for (jcr = jobs; jcr; jcr=jcr->next) {
+ foreach_dlist(jcr, jcrs) {
if (jcr->JobId == JobId) {
- P(jcr->mutex);
- jcr->use_count++;
- V(jcr->mutex);
+ jcr->inc_use_count();
Dmsg2(3400, "Inc get_jcr 0x%x use_count=%d\n", jcr, jcr->use_count);
break;
}
JCR *jcr;
lock_jcr_chain();
- for (jcr = jobs; jcr; jcr=jcr->next) {
+ foreach_dlist(jcr, jcrs) {
if (jcr->VolSessionId == SessionId &&
jcr->VolSessionTime == SessionTime) {
- P(jcr->mutex);
- jcr->use_count++;
- V(jcr->mutex);
+ jcr->inc_use_count();
Dmsg2(3400, "Inc get_jcr 0x%x use_count=%d\n", jcr, jcr->use_count);
break;
}
}
lock_jcr_chain();
len = strlen(Job);
- for (jcr = jobs; jcr; jcr=jcr->next) {
+ foreach_dlist(jcr, jcrs) {
if (strncmp(Job, jcr->Job, len) == 0) {
- P(jcr->mutex);
- jcr->use_count++;
- V(jcr->mutex);
+ jcr->inc_use_count();
Dmsg2(3400, "Inc get_jcr 0x%x use_count=%d\n", jcr, jcr->use_count);
break;
}
return NULL;
}
lock_jcr_chain();
- for (jcr = jobs; jcr; jcr=jcr->next) {
+ foreach_dlist(jcr, jcrs) {
if (strcmp(jcr->Job, Job) == 0) {
- P(jcr->mutex);
- jcr->use_count++;
- V(jcr->mutex);
+ jcr->inc_use_count();
Dmsg2(3400, "Inc get_jcr 0x%x use_count=%d\n", jcr, jcr->use_count);
break;
}
{
JCR *jcr;
- if (prev_jcr == NULL) {
- jcr = jobs;
- } else {
- jcr = prev_jcr->next;
- }
+ lock_jcr_chain();
+ jcr = (JCR *)jcrs->next(prev_jcr);
if (jcr) {
- P(jcr->mutex);
- jcr->use_count++;
- V(jcr->mutex);
+ jcr->inc_use_count();
Dmsg2(3400, "Inc get_next_jcr 0x%x use_count=%d\n", jcr, jcr->use_count);
}
+ unlock_jcr_chain();
return jcr;
}
/* Walk through all JCRs checking if any one is
* blocked for more than specified max time.
*/
- lock_jcr_chain();
foreach_jcr(jcr) {
- free_locked_jcr(jcr); /* OK to free now cuz chain is locked */
if (jcr->JobId == 0) {
+ free_jcr(jcr);
continue;
}
fd = jcr->store_bsock;
pthread_kill(jcr->my_thread_id, TIMEOUT_SIGNAL);
}
}
-
+ free_jcr(jcr);
}
- unlock_jcr_chain();
Dmsg0(3400, "Finished JCR timeout checks\n");
}
#include "jcr.h"
/* Exported globals */
-time_t watchdog_time = 0; /* this has granularity of SLEEP_TIME */
+time_t watchdog_time = 0; /* this has granularity of SLEEP_TIME */
time_t watchdog_sleep_time = 60; /* examine things every 60 seconds */
/* Locals */
/* Static globals */
static bool quit = false;;
static bool wd_is_init = false;
-static brwlock_t lock; /* watchdog lock */
+static brwlock_t lock; /* watchdog lock */
static pthread_t wd_tid;
static dlist *wd_queue;
* Start watchdog thread
*
* Returns: 0 on success
- * errno on failure
+ * errno on failure
*/
int start_watchdog(void)
{
if ((errstat=rwl_init(&lock)) != 0) {
Emsg1(M_ABORT, 0, _("Unable to initialize watchdog lock. ERR=%s\n"),
- strerror(errstat));
+ strerror(errstat));
}
wd_queue = New(dlist(dummy, &dummy->link));
wd_inactive = New(dlist(dummy, &dummy->link));
* Terminate the watchdog thread
*
* Returns: 0 on success
- * errno on failure
+ * errno on failure
*/
int stop_watchdog(void)
{
return 0;
}
- quit = true; /* notify watchdog thread to stop */
+ quit = true; /* notify watchdog thread to stop */
wd_is_init = false;
ping_watchdog();
wd_queue->remove(item);
p = (watchdog_t *)item;
if (p->destructor != NULL) {
- p->destructor(p);
+ p->destructor(p);
}
free(p);
}
wd_inactive->remove(item);
p = (watchdog_t *)item;
if (p->destructor != NULL) {
- p->destructor(p);
+ p->destructor(p);
}
free(p);
}
wd_lock();
foreach_dlist(p, wd_queue) {
if (wd == p) {
- wd_queue->remove(wd);
+ wd_queue->remove(wd);
Dmsg1(800, "Unregistered watchdog %p\n", wd);
- ok = true;
- goto get_out;
+ ok = true;
+ goto get_out;
}
}
foreach_dlist(p, wd_inactive) {
if (wd == p) {
- wd_inactive->remove(wd);
+ wd_inactive->remove(wd);
Dmsg1(800, "Unregistered inactive watchdog %p\n", wd);
- ok = true;
- goto get_out;
+ ok = true;
+ goto get_out;
}
}
watchdog_t *p;
/*
+ *
+ * NOTE. lock_jcr_chain removed, but the message below
+ * was left until we are sure there are no deadlocks.
+ *
* We lock the jcr chain here because a good number of the
* callback routines lock the jcr chain. We need to lock
* it here *before* the watchdog lock because the SD message
* lock in the same order, we get a deadlock -- each holds
* the other's needed lock.
*/
- lock_jcr_chain();
wd_lock();
walk_list:
watchdog_time = time(NULL);
next_time = watchdog_time + watchdog_sleep_time;
foreach_dlist(p, wd_queue) {
- if (p->next_fire <= watchdog_time) {
- /* Run the callback */
- p->callback(p);
+ if (p->next_fire <= watchdog_time) {
+ /* Run the callback */
+ p->callback(p);
/* Reschedule (or move to inactive list if it's a one-shot timer) */
- if (p->one_shot) {
- wd_queue->remove(p);
- wd_inactive->append(p);
- goto walk_list;
- } else {
- p->next_fire = watchdog_time + p->interval;
- }
- }
- if (p->next_fire < next_time) {
- next_time = p->next_fire;
- }
+ if (p->one_shot) {
+ wd_queue->remove(p);
+ wd_inactive->append(p);
+ goto walk_list;
+ } else {
+ p->next_fire = watchdog_time + p->interval;
+ }
+ }
+ if (p->next_fire < next_time) {
+ next_time = p->next_fire;
+ }
}
wd_unlock();
- unlock_jcr_chain();
/*
* Wait sleep time or until someone wakes us
timeout.tv_nsec = tv.tv_usec * 1000;
timeout.tv_sec = tv.tv_sec + next_time - time(NULL);
while (timeout.tv_nsec >= 1000000000) {
- timeout.tv_nsec -= 1000000000;
- timeout.tv_sec++;
+ timeout.tv_nsec -= 1000000000;
+ timeout.tv_sec++;
}
Dmsg1(1900, "pthread_cond_timedwait %d\n", timeout.tv_sec - tv.tv_sec);
int errstat;
if ((errstat=rwl_writelock(&lock)) != 0) {
Emsg1(M_ABORT, 0, "rwl_writelock failure. ERR=%s\n",
- strerror(errstat));
+ strerror(errstat));
}
}
int errstat;
if ((errstat=rwl_writeunlock(&lock)) != 0) {
Emsg1(M_ABORT, 0, "rwl_writeunlock failure. ERR=%s\n",
- strerror(errstat));
+ strerror(errstat));
}
}
* This would be better done by walking through
* all the devices.
*/
- lock_jcr_chain();
foreach_jcr(njcr) {
if (jcr == njcr) {
- free_locked_jcr(njcr);
+ free_jcr(njcr);
continue; /* us */
}
Dmsg2(300, "Compare to JobId=%d using Vol=%s\n", njcr->JobId, njcr->dcr->VolumeName);
if (njcr->dcr && strcmp(dcr->VolumeName, njcr->dcr->VolumeName) == 0) {
found = true;
Dmsg1(400, "Vol in use by JobId=%u\n", njcr->JobId);
- free_locked_jcr(njcr);
+ free_jcr(njcr);
break;
}
- free_locked_jcr(njcr);
+ free_jcr(njcr);
}
- unlock_jcr_chain();
if (!found) {
Dmsg0(400, "dir_find_next_appendable_volume return true\n");
return true; /* Got good Volume */
char b1[30], b2[30], b3[30];
bnet_fsend(user, _("\nRunning Jobs:\n"));
- lock_jcr_chain();
foreach_jcr(jcr) {
if (jcr->JobStatus == JS_WaitFD) {
bnet_fsend(user, _("%s Job %s waiting for Client connection.\n"),
}
#endif
}
- free_locked_jcr(jcr);
+ free_jcr(jcr);
}
- unlock_jcr_chain();
if (!found) {
bnet_fsend(user, _("No Jobs running.\n"));
}
if (strcmp(time.c_str(), "current") == 0) {
bnet_fsend(dir, OKqstatus, time.c_str());
- lock_jcr_chain();
foreach_jcr(njcr) {
if (njcr->JobId != 0) {
bnet_fsend(dir, DotStatusJob, njcr->JobId, njcr->JobStatus, njcr->JobErrors);
}
- free_locked_jcr(njcr);
+ free_jcr(njcr);
}
- unlock_jcr_chain();
}
else if (strcmp(time.c_str(), "last") == 0) {
bnet_fsend(dir, OKqstatus, time.c_str());
* them up so that they will report back the correct
* volume status.
*/
- lock_jcr_chain();
foreach_jcr(jcr) {
BSOCK *fd;
- free_locked_jcr(jcr);
if (jcr->JobId == 0) {
+ free_jcr(jcr);
continue; /* ignore console */
}
set_jcr_job_status(jcr, JS_Canceled);
pthread_cond_broadcast(&wait_device_release);
}
bmicrosleep(0, 50000);
- }
+ }
+ free_jcr(jcr);
}
- unlock_jcr_chain();
bmicrosleep(0, 500000); /* give them 1/2 sec to clean up */
}
Dmsg1(200, "In terminate_stored() sig=%d\n", sig);
-// LockRes();
foreach_res(device, R_DEVICE) {
if (device->dev) {
term_dev(device->dev);
}
}
-// UnlockRes();
if (configfile)
free(configfile);
/* */
#undef VERSION
-#define VERSION "1.37.19"
+#define VERSION "1.37.20"
#define BDATE "26 May 2005"
#define LSMDATE "26May05"