From 5e580f90285c76c8b00c173fdbc111f10659da94 Mon Sep 17 00:00:00 2001 From: Kern Sibbald Date: Tue, 6 Aug 2002 21:26:05 +0000 Subject: [PATCH] Bug fixes + documentation -- kes06Aug02 git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@79 91ce42f0-d328-0410-95d8-f526ca767f89 --- bacula/src/cats/sql.c | 4 +- bacula/src/dird/query.sql | 2 +- bacula/src/dird/scheduler.c | 79 ++++++++++++++++++++++++------------ bacula/src/dird/ua_restore.c | 10 +++-- bacula/src/dird/ua_status.c | 19 ++------- bacula/src/lib/tree.c | 3 ++ bacula/src/lib/util.c | 42 +++++++++---------- bacula/src/lib/watchdog.c | 9 +--- bacula/src/version.h | 4 +- 9 files changed, 93 insertions(+), 79 deletions(-) diff --git a/bacula/src/cats/sql.c b/bacula/src/cats/sql.c index c16f59e6cc..09079128b1 100644 --- a/bacula/src/cats/sql.c +++ b/bacula/src/cats/sql.c @@ -234,7 +234,7 @@ void db_start_transaction(B_DB *mdb) } if (!mdb->transaction) { my_sqlite_query(mdb, "BEGIN"); /* begin transaction */ - Dmsg0(000, "Start SQLite transaction\n"); + Dmsg0(400, "Start SQLite transaction\n"); mdb->transaction = 1; } db_unlock(mdb); @@ -249,7 +249,7 @@ void db_end_transaction(B_DB *mdb) if (mdb->transaction) { my_sqlite_query(mdb, "COMMIT"); /* end transaction */ mdb->transaction = 0; - Dmsg1(000, "End SQLite transaction changes=%d\n", mdb->changes); + Dmsg1(400, "End SQLite transaction changes=%d\n", mdb->changes); } mdb->changes = 0; db_unlock(mdb); diff --git a/bacula/src/dird/query.sql b/bacula/src/dird/query.sql index 097abe8040..053ef77a78 100644 --- a/bacula/src/dird/query.sql +++ b/bacula/src/dird/query.sql @@ -121,7 +121,7 @@ SELECT * from temp2; :List where a File is saved: *Enter Filename (no path): SELECT Job.JobId as JobId, Client.Name as Client, - CONCAT(Path.Path,Filename.Name) as Name, + Path.Path||Filename.Name as Name, StartTime,Level,JobFiles,JobBytes FROM Client,Job,File,Filename,Path WHERE Client.ClientId=Job.ClientId AND JobStatus='T' AND Job.JobId=File.JobId diff --git a/bacula/src/dird/scheduler.c b/bacula/src/dird/scheduler.c index 835f7e9840..4e09a5b3ca 100644 --- a/bacula/src/dird/scheduler.c +++ b/bacula/src/dird/scheduler.c @@ -35,6 +35,7 @@ /* Forward referenced subroutines */ static void find_runs(); +static void add_job(JOB *job, RUN *run, time_t now, time_t runtime); /* Imported subroutines */ @@ -66,6 +67,7 @@ JCR *wait_for_next_job(char *job_to_run) time_t now, runtime, nexttime; int jobindex, i; static int first = TRUE; + char dt[MAX_TIME_LENGTH]; Dmsg0(200, "Enter wait_for_next_job\n"); if (first) { @@ -73,6 +75,7 @@ JCR *wait_for_next_job(char *job_to_run) max_runjobs = 10; runjobs = (RUNJOB *) malloc(sizeof(RUNJOB) * max_runjobs); num_runjobs = 0; + rem_runjobs = 0; if (job_to_run) { /* one shot */ job = (JOB *)GetResWithName(R_JOB, job_to_run); if (!job) { @@ -83,15 +86,18 @@ JCR *wait_for_next_job(char *job_to_run) set_jcr_defaults(jcr, job); return jcr; } - find_runs(); } /* Wait until we have something in the * next hour or so. */ - while (num_runjobs == 0 || rem_runjobs == 0) { - sleep(60); + while (rem_runjobs == 0) { find_runs(); + if (rem_runjobs > 0) { + break; + } + sleep(60); } + /* * Sort through what is to be run in the next * two hours to find the first job to be run, @@ -101,12 +107,20 @@ JCR *wait_for_next_job(char *job_to_run) time(&now); nexttime = now + 60 * 60 * 24; /* a much later time */ jobindex = -1; + bstrftime(dt, sizeof(dt), now); + Dmsg2(400, "jobs=%d. Now is %s\n", rem_runjobs, dt); for (i=0; i 0 && runtime < nexttime) { /* find minimum time job */ nexttime = runtime; jobindex = i; } +#ifdef xxxx_debug + if (runtime > 0) { + bstrftime(dt, sizeof(dt), runjobs[i].runtime); + Dmsg2(000, " %s run %s\n", dt, runjobs[i].job->hdr.name); + } +#endif } if (jobindex < 0) { /* we really should have something now */ Emsg0(M_ABORT, 0, _("Scheduler logic error\n")); @@ -119,8 +133,8 @@ JCR *wait_for_next_job(char *job_to_run) twait = nexttime - now; if (twait <= 0) /* time to run it */ break; - if (twait > 20) /* sleep max 20 seconds */ - twait = 20; + if (twait > 1) /* sleep max 20 seconds */ + twait--; sleep(twait); } run = runjobs[jobindex].run; @@ -200,9 +214,6 @@ static void find_runs() } for (run=sched->run; run; run=run->next) { - if (now - run->last_run < 60 * 20) - continue; /* wait at least 20 minutes */ - /* Find runs scheduled in this our or in the * next hour (we may be one second before the next hour). */ @@ -212,27 +223,20 @@ static void find_runs() /* find time (time_t) job is to be run */ localtime_r(&now, &tm); - if (bit_is_set(next_hour, run->hour)) - tm.tm_hour++; - if (tm.tm_hour > 23) - tm.tm_hour = 0; tm.tm_min = run->minute; tm.tm_sec = 0; - runtime = mktime(&tm); - if (runtime < (now - 5 * 60)) /* give 5 min grace to pickup straglers */ - continue; - /* Make sure array is big enough */ - if (num_runjobs == max_runjobs) { - max_runjobs += 10; - runjobs = (RUNJOB *) realloc(runjobs, sizeof(RUNJOB) * max_runjobs); - if (!runjobs) - Emsg0(M_ABORT, 0, _("Out of memory\n")); + if (bit_is_set(hour, run->hour)) { + runtime = mktime(&tm); + add_job(job, run, now, runtime); + } + if (bit_is_set(next_hour, run->hour)) { + tm.tm_hour++; + if (tm.tm_hour > 23) { + tm.tm_hour = 0; + } + runtime = mktime(&tm); + add_job(job, run, now, runtime); } - /* accept to run this job */ - runjobs[num_runjobs].run = run; - runjobs[num_runjobs].job = job; - runjobs[num_runjobs++].runtime = runtime; /* when to run it */ - } } } @@ -241,3 +245,26 @@ static void find_runs() rem_runjobs = num_runjobs; Dmsg0(200, "Leave find_runs()\n"); } + +static void add_job(JOB *job, RUN *run, time_t now, time_t runtime) +{ + /* + * Don't run any job that ran less than a minute ago, but + * do run any job scheduled less than a minute ago. + */ + if ((runtime - run->last_run < 61) || (runtime+59 < now)) { + return; + } + + /* Make sure array is big enough */ + if (num_runjobs == max_runjobs) { + max_runjobs += 10; + runjobs = (RUNJOB *) realloc(runjobs, sizeof(RUNJOB) * max_runjobs); + if (!runjobs) + Emsg0(M_ABORT, 0, _("Out of memory\n")); + } + /* accept to run this job */ + runjobs[num_runjobs].run = run; + runjobs[num_runjobs].job = job; + runjobs[num_runjobs++].runtime = runtime; /* when to run it */ +} diff --git a/bacula/src/dird/ua_restore.c b/bacula/src/dird/ua_restore.c index 85a70e963d..905c7b8955 100644 --- a/bacula/src/dird/ua_restore.c +++ b/bacula/src/dird/ua_restore.c @@ -122,7 +122,6 @@ int restorecmd(UAContext *ua, char *cmd) return 0; } - /* * Build the directory tree */ @@ -187,7 +186,7 @@ static int user_select_jobids(UAContext *ua, struct s_full_ctx *full) "List Jobs where a given File is saved", "Enter list of JobIds to select", "Enter SQL list command", - "Select the most recent backup for a client" + "Select the most recent backup for a client", "Cancel", NULL }; @@ -287,6 +286,7 @@ static int user_select_jobids(UAContext *ua, struct s_full_ctx *full) memset(&jr, 0, sizeof(JOB_DBR)); + full->TotalFiles = 0; for (p=full->JobIds; ; ) { int stat = next_jobid_from_list(&p, &JobId); if (stat < 0) { @@ -301,7 +301,7 @@ static int user_select_jobids(UAContext *ua, struct s_full_ctx *full) bsendmsg(ua, _("Unable to get Job record. ERR=%s\n"), db_strerror(ua->db)); return 0; } - full->TotalFiles = jr.JobFiles; + full->TotalFiles += jr.JobFiles; } return 1; } @@ -495,6 +495,7 @@ static int complete_bsr(UAContext *ua, RBSR *bsr) { JOB_DBR jr; char VolumeNames[1000]; /* ****FIXME**** */ + char *p; if (bsr) { memset(&jr, 0, sizeof(jr)); @@ -509,6 +510,9 @@ static int complete_bsr(UAContext *ua, RBSR *bsr) bsendmsg(ua, _("Unable to get Job Volumes. ERR=%s\n"), db_strerror(ua->db)); return 0; } + if ((p = strchr(VolumeNames, '|'))) { + *p = 0; /* take first volume */ + } bsr->VolumeName = bstrdup(VolumeNames); return complete_bsr(ua, bsr->next); } diff --git a/bacula/src/dird/ua_status.c b/bacula/src/dird/ua_status.c index 9e5aece000..89e542a718 100644 --- a/bacula/src/dird/ua_status.c +++ b/bacula/src/dird/ua_status.c @@ -354,24 +354,11 @@ static void do_client_status(UAContext *ua, CLIENT *client) static void prt_runtime(UAContext *ua, JOB *job, time_t runtime) { - char dt[MAX_TIME_LENGTH], *type; + char dt[MAX_TIME_LENGTH]; bstrftime(dt, sizeof(dt), runtime); - switch (job->JobType) { - case JT_BACKUP: - type = _("Backup"); - break; - case JT_VERIFY: - type = _("Verify"); - break; - case JT_RESTORE: - type = _("Restore"); - break; - default: - type = _("Unknown type of"); - break; - } - bsendmsg(ua, _("%s job \"%s\" scheduled for %s\n"), type, job->hdr.name, dt); + bsendmsg(ua, _("%s job \"%s\" scheduled for %s\n"), + job_type_to_str(job->JobType), job->hdr.name, dt); } /* diff --git a/bacula/src/lib/tree.c b/bacula/src/lib/tree.c index 163198259f..daeba72ba9 100755 --- a/bacula/src/lib/tree.c +++ b/bacula/src/lib/tree.c @@ -60,6 +60,9 @@ TREE_ROOT *new_tree(int count) TREE_ROOT *root; uint32_t size; + if (count < 1000) { /* minimum tree size */ + count = 1000; + } root = (TREE_ROOT *)malloc(sizeof(TREE_ROOT)); memset(root, 0, sizeof(TREE_ROOT)); root->type = TN_ROOT; diff --git a/bacula/src/lib/util.c b/bacula/src/lib/util.c index 6156a8cc2b..f2cf12de38 100644 --- a/bacula/src/lib/util.c +++ b/bacula/src/lib/util.c @@ -385,23 +385,23 @@ char *job_status_to_str(int stat) switch (stat) { case JS_Terminated: - str = "OK"; + str = _("OK"); break; case JS_ErrorTerminated: case JS_Error: - str = "Error"; + str = _("Error"); break; case JS_FatalError: - str = "Fatal Error"; + str = _("Fatal Error"); break; case JS_Cancelled: - str = "Cancelled"; + str = _("Cancelled"); break; case JS_Differences: - str = "Differences"; + str = _("Differences"); break; default: - str = "Unknown term code"; + str = _("Unknown term code"); break; } return str; @@ -417,18 +417,18 @@ char *job_type_to_str(int type) switch (type) { case JT_BACKUP: - str = "Backup"; + str = _("Backup"); break; case JT_VERIFY: - str = "Verify"; + str = _("Verify"); break; case JT_RESTORE: - str = "Restore"; + str = _("Restore"); break; case JT_ADMIN: - str = "Admin"; + str = _("Admin"); default: - str = "Unknown Job Type"; + str = _("Unknown Type"); break; } return str; @@ -443,34 +443,34 @@ char *job_level_to_str(int level) switch (level) { case L_FULL: - str = "full"; + str = _("Full"); break; case L_INCREMENTAL: - str = "incremental"; + str = _("Incremental"); break; case L_DIFFERENTIAL: - str = "differential"; + str = _("Differential"); break; case L_LEVEL: - str = "level"; + str = _("Level"); break; case L_SINCE: - str = "since"; + str = _("Since"); break; case L_VERIFY_CATALOG: - str = "verify catalog"; + str = _("Verify Catalog"); break; case L_VERIFY_INIT: - str = "verify init"; + str = _("Verify Init Catalog"); break; case L_VERIFY_VOLUME_TO_CATALOG: - str = "verify volume to catalog"; + str = _("Verify Volume to Catalog"); break; case L_VERIFY_DATA: - str = "verify data"; + str = _("Verify Data"); break; default: - str = "Unknown Job level"; + str = _("Unknown Job Level"); break; } return str; diff --git a/bacula/src/lib/watchdog.c b/bacula/src/lib/watchdog.c index abed81efaa..b53b60fae6 100755 --- a/bacula/src/lib/watchdog.c +++ b/bacula/src/lib/watchdog.c @@ -191,19 +191,12 @@ static void *watchdog_thread(void *arg) timeout.tv_sec = tv.tv_sec + SLEEP_TIME; Dmsg1(200, "pthread_cond_timedwait sec=%d\n", timeout.tv_sec); -#ifdef xxxxxxxxxxxxxxx_was_HAVE_CYGWIN - /* CYGWIN dies with a page fault the second - * time that pthread_cond_timedwait() is called - * so fake it out. - */ - sleep(SLEEP_TIME); -#else stat = pthread_cond_timedwait(&timer, &mutex, &timeout); Dmsg1(200, "pthread_cond_timedwait stat=%d\n", stat); -#endif } /* end of big for loop */ + pthread_mutex_unlock(&mutex); /* for good form */ Dmsg0(200, "End watchdog\n"); return NULL; } diff --git a/bacula/src/version.h b/bacula/src/version.h index ff327ad0d8..3a19e4931a 100644 --- a/bacula/src/version.h +++ b/bacula/src/version.h @@ -1,8 +1,8 @@ /* */ #define VERSION "1.24" #define VSTRING "1" -#define DATE "05 August 2002" -#define LSMDATE "05Aug02" +#define DATE "06 August 2002" +#define LSMDATE "06Aug02" /* Debug flags */ #define DEBUG 1 -- 2.39.5