This has been discussed a few times. My original email is below.
In a nutshell: if a "status director" command is issued using the
console AND there is at least one scheduled job reported, then the
console session will cause num_jobs_run to be incremented when the
console disconnects.
The attached patch (which I have been running live now for several
weeks, and also passes the regression tests against trunk) fixes
this. I had to implement option (1) from my original email. (2) did
not work at all, for various reasons.
The patch does 2 things:
1) Saves and restores the console JCR's job type
2) Only increments num_jobs_run if jcr->JobId > 0
Allan
-------- Original Message --------
Subject: Status Command Changes The Job Type
Date: Wed, 13 Feb 2008 20:23:21 +0000
From: Allan Black <[EMAIL PROTECTED]>
To: [email protected]
Just had a look at ua_status.c, because of something which
has been annoying me for a while.
If there are any scheduled jobs, the "st dir" command causes
num_jobs_run to be incremented when the console disconnects.
[ I noticed this while I was testing a script, and could not
understand why the "jobs run since started" kept increasing
every time I ran it ]
What is happening is this:
The console's JCR starts off with its JobType set to JT_ADMIN.
The list_scheduled_jobs() function calls prt_runtime() on any
jobs in the sched list. prt_runtime re-uses the console's JCR
to emulate the job which is being examined, and to do so, it
has to change some of the JCR's values.
In particular, prt_runtime() calls complete_jcr_for_job(),
which in turn calls set_jcr_defaults(), which sets the JCR's
JobType to be the Job's JobType, i.e. JT_BACKUP.
prt_runtime() restores the JCR's db field to its original
value (which is in the UAContext), but not any of the other
values.
As a result, when the console disconnects, the director frees
the JCR and increments num_jobs_run, because jcr->JobType is
set to JT_BACKUP.
This is a trivial bug, but of more concern to me is the fact
that the console's JCR has been 'corrupted'.
I would like to fix this, but would appreciate your opinions
on the correct way to go about it:
1) Restore the JobType to the correct value at the end of
prt_runtime(), either by saving it, or by explicitly
setting it to JT_ADMIN (I would probably prefer to
save/restore, just in case).
2) Create and destroy a new JCR object in prt_runtime()
instead of re-using the console's JCR.
I think 2 is technically the correct way to do it, since
there may be other fields in the JCR which are changed, but
it may be more difficult.
Allan
Index: src/dird/ua_status.c
===================================================================
--- src/dird/ua_status.c (revision 7004)
+++ src/dird/ua_status.c (working copy)
@@ -432,7 +432,9 @@
bool close_db = false;
JCR *jcr = ua->jcr;
MEDIA_DBR mr;
+ int orig_jobtype;
+ orig_jobtype = jcr->JobType;
memset(&mr, 0, sizeof(mr));
if (sp->job->JobType == JT_BACKUP) {
jcr->db = NULL;
@@ -475,6 +477,7 @@
db_close_database(jcr, jcr->db);
}
jcr->db = ua->db; /* restore ua db to jcr */
+ jcr->JobType = orig_jobtype;
}
/*
Index: src/lib/jcr.c
===================================================================
--- src/lib/jcr.c (revision 7004)
+++ src/lib/jcr.c (working copy)
@@ -405,7 +405,7 @@
#ifdef DEBUG
void b_free_jcr(const char *file, int line, JCR *jcr)
{
- struct s_last_job *je, last_job;
+ struct s_last_job *je;
Dmsg3(dbglvl, "Enter free_jcr jid=%u from %s:%d\n", jcr->JobId, file, line);
@@ -413,7 +413,7 @@
void free_jcr(JCR *jcr)
{
- struct s_last_job *je, last_job;
+ struct s_last_job *je;
Dmsg3(dbglvl, "Enter free_jcr jid=%u use_count=%d Job=%s\n",
jcr->JobId, jcr->use_count(), jcr->Job);
@@ -453,23 +453,23 @@
case JT_MIGRATE:
case JT_COPY:
case JT_ADMIN:
- num_jobs_run++;
- last_job.Errors = jcr->Errors;
- last_job.JobType = jcr->JobType;
- last_job.JobId = jcr->JobId;
- last_job.VolSessionId = jcr->VolSessionId;
- last_job.VolSessionTime = jcr->VolSessionTime;
- bstrncpy(last_job.Job, jcr->Job, sizeof(last_job.Job));
- last_job.JobFiles = jcr->JobFiles;
- last_job.JobBytes = jcr->JobBytes;
- last_job.JobStatus = jcr->JobStatus;
- last_job.JobLevel = jcr->JobLevel;
- last_job.start_time = jcr->start_time;
- last_job.end_time = time(NULL);
/* Keep list of last jobs, but not Console where JobId==0 */
- if (last_job.JobId > 0) {
+ if (jcr->JobId > 0) {
+ num_jobs_run++;
je = (struct s_last_job *)malloc(sizeof(struct s_last_job));
- memcpy((char *)je, (char *)&last_job, sizeof(last_job));
+ je->Errors = jcr->Errors;
+ je->JobType = jcr->JobType;
+ je->JobId = jcr->JobId;
+ je->VolSessionId = jcr->VolSessionId;
+ je->VolSessionTime = jcr->VolSessionTime;
+ bstrncpy(je->Job, jcr->Job, sizeof(je->Job));
+ je->JobFiles = jcr->JobFiles;
+ je->JobBytes = jcr->JobBytes;
+ je->JobStatus = jcr->JobStatus;
+ je->JobLevel = jcr->JobLevel;
+ je->start_time = jcr->start_time;
+ je->end_time = time(NULL);
+
if (!last_jobs) {
init_last_jobs_list();
}
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Bacula-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/bacula-devel