- Test connect timeouts.
For 1.33 Testing/Documentation:
+- Document to start higher priorty jobs before lower ones.
- suppress "Do not forget to mount the drive!!!" if error
- Document new records in Director. SDAddress SDDeviceName, SDPassword.
FDPassword, FDAddress, DBAddress, DBPort, DBPassword.
- Add counter variable test.
For 1.33
+- Eliminate orphaned jobs: dbcheck, normal pruning, delet job command.
+ Hm. Well, there are the remaining orphaned job records:
+
+ | 105 | Llioness Save | 0000-00-00 00:00:00 | B | D | 0 | 0 | f |
+ | 110 | Llioness Save | 0000-00-00 00:00:00 | B | I | 0 | 0 | f |
+ | 115 | Llioness Save | 2003-09-10 02:22:03 | B | I | 0 | 0 | A |
+ | 128 | Catalog Save | 2003-09-11 03:53:32 | B | I | 0 | 0 | C |
+ | 131 | Catalog Save | 0000-00-00 00:00:00 | B | I | 0 | 0 | f |
+
+ As you can see, three of the five are failures. I already deleted the
+ one restore and one other failure using the by-client option. Deciding
+ what is an orphaned job is a tricky problem though, I agree. All these
+ records have or had 0 files/ 0 bytes, except for the restore. With no
+ files, of course, I don't know of the job ever actually becomes
+ associated with a Volume.
+
+ (I'm not sure if this is documented anywhere -- what are the meanings of
+ all the possible JobStatus codes?)
+
+ Looking at my database, it appears to me as though all the "orphaned"
+ jobs fit into one of two categories:
+
+ 1) The Job record has a StartTime but no EndTime, and the job is not
+ currently running;
+ or
+ 2) The Job record has an EndTime, indicating that it completed, but
+ it has no associated JobMedia record.
+
+
+ This does suggest an approach. If failed jobs (or jobs that, for some
+ other reason, write no files) are associated with a volume via a
+ JobMedia record, then they should be purged when the associated volume
+ is purged. I see two ways to handle jobs that are NOT associated with a
+ specific volume:
+
+ 1) purge them automatically whenever any volume is manually purged;
+ or
+ 2) add an option to the purge command to manually purge all jobs with
+ no associated volume.
+
+- Implement Label Format in Add and Label console commands.
+- make "btape /tmp" work.
- Make sure a rescheduled job is properly reported by status.
- Walk through the Pool records rather than the Job records
in dird.c to create/update pools.
/* Forward referenced functions */
static int do_list_cmd(UAContext *ua, char *cmd, e_list_type llist);
+static POOL *find_job_pool(JOB *job);
/*
* Turn auto display of console messages on/off
strcasecmp(ua->argk[i], _("nextvolume")) == 0) {
JOB *job;
JCR *jcr = ua->jcr;
+
i = find_arg_with_value(ua, "job");
if (i <= 0) {
if ((job = select_job_resource(ua)) == NULL) {
}
}
}
- if (!complete_jcr_for_job(jcr, job, NULL)) {
+ if (!complete_jcr_for_job(jcr, job, find_job_pool(job))) {
return 1;
}
return 1;
}
+static POOL *find_job_pool(JOB *job)
+{
+ time_t now, runtime, tomorrow;
+ RUN *run;
+ SCHED *sched;
+ struct tm tm;
+ int mday, wday, month, wpos, tmday, twday, tmonth, twpos, i, hour;
+ int tod, tom;
+
+ Dmsg0(200, "enter find_runs()\n");
+
+ sched = job->schedule;
+ if (sched == NULL) { /* scheduled? */
+ return NULL; /* no nothing to report */
+ }
+ /* Break down current time into components */
+ now = time(NULL);
+ localtime_r(&now, &tm);
+ mday = tm.tm_mday - 1;
+ wday = tm.tm_wday;
+ month = tm.tm_mon;
+ wpos = (tm.tm_mday - 1) / 7;
+
+ /* Break down tomorrow into components */
+ tomorrow = now + 60 * 60 * 24;
+ localtime_r(&tomorrow, &tm);
+ tmday = tm.tm_mday - 1;
+ twday = tm.tm_wday;
+ tmonth = tm.tm_mon;
+ twpos = (tm.tm_mday - 1) / 7;
+
+ for (run=sched->run; run; run=run->next) {
+ /*
+ * Find runs in next 24 hours
+ */
+ tod = (bit_is_set(mday, run->mday) || bit_is_set(wday, run->wday)) &&
+ bit_is_set(month, run->month) && bit_is_set(wpos, run->wpos);
+
+ tom = (bit_is_set(tmday, run->mday) || bit_is_set(twday, run->wday)) &&
+ bit_is_set(tmonth, run->month) && bit_is_set(wpos, run->wpos);
+
+ Dmsg2(200, "tod=%d tom=%d\n", tod, tom);
+ if (tod) { /* Jobs scheduled today (next 24 hours) */
+ /* find time (time_t) job is to be run */
+ localtime_r(&now, &tm);
+ hour = 0;
+ for (i=tm.tm_hour; i < 24; i++) {
+ if (bit_is_set(i, run->hour)) {
+ tm.tm_hour = i;
+ tm.tm_min = run->minute;
+ tm.tm_sec = 0;
+ runtime = mktime(&tm);
+ if (runtime > now) {
+ return run->pool; /* return pool */
+ }
+ }
+ }
+ }
+
+// Dmsg2(200, "runtime=%d now=%d\n", runtime, now);
+ if (tom) { /* look at jobs scheduled tomorrow */
+ localtime_r(&tomorrow, &tm);
+ hour = 0;
+ for (i=0; i < 24; i++) {
+ if (bit_is_set(i, run->hour)) {
+ hour = i;
+ break;
+ }
+ }
+ tm.tm_hour = hour;
+ tm.tm_min = run->minute;
+ tm.tm_sec = 0;
+ runtime = mktime(&tm);
+ Dmsg2(200, "truntime=%d now=%d\n", runtime, now);
+ if (runtime < tomorrow) {
+ return run->pool; /* return pool */
+ }
+ }
+ } /* end for loop over runs */
+ /* Nothing found */
+ return NULL;
+}
/*
* Fill in the remaining fields of the jcr as if it
* is going to run the job.