From a6e61c49801cb64ef3c5570addc8c4d9cc7a906e Mon Sep 17 00:00:00 2001 From: Kern Sibbald Date: Tue, 22 Jun 2004 13:07:01 +0000 Subject: [PATCH] Fix reload algorithm + reload orphaned buffer + term_wait destruction git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@1439 91ce42f0-d328-0410-95d8-f526ca767f89 --- bacula/src/dird/dird.c | 50 ++++++++++++-------------------- bacula/src/dird/job.c | 6 +++- bacula/src/dird/verify.c | 6 ++-- bacula/src/filed/job.c | 2 +- bacula/src/filed/status.c | 2 +- bacula/src/jcr.h | 12 ++++---- bacula/src/lib/jcr.c | 15 ++++++---- bacula/src/lib/protos.h | 2 +- bacula/src/stored/authenticate.c | 2 +- bacula/src/stored/btape.c | 6 +--- bacula/src/stored/job.c | 2 +- 11 files changed, 47 insertions(+), 58 deletions(-) diff --git a/bacula/src/dird/dird.c b/bacula/src/dird/dird.c index c119440985..6d2ef2d6ea 100644 --- a/bacula/src/dird/dird.c +++ b/bacula/src/dird/dird.c @@ -316,18 +316,15 @@ static void free_saved_resources(int table) * it goes to zero, no one is using the associated * resource table, so free it. */ -static void reload_job_end_cb(JCR *jcr) +static void reload_job_end_cb(JCR *jcr, void *ctx) { - if (jcr->reload_id == 0) { - return; /* nothing to do */ - } - int i = jcr->reload_id - 1; + int reload_id = (int)ctx; Dmsg3(000, "reload job_end JobId=%d table=%d cnt=%d\n", jcr->JobId, - i, reload_table[i].job_count); + reload_id, reload_table[reload_id].job_count); lock_jcr_chain(); LockRes(); - if (--reload_table[i].job_count <= 0) { - free_saved_resources(i); + if (--reload_table[reload_id].job_count <= 0) { + free_saved_resources(reload_id); } UnlockRes(); unlock_jcr_chain(); @@ -350,9 +347,8 @@ static int find_free_reload_table_entry() * reread our configuration file. * * The algorithm used is as follows: we count how many jobs are - * running since the last reload and set those jobs to make a - * callback. Also, we set each job with the current reload table - * id. . The old config is saved with the reload table + * running and mark the running jobs to make a callback on + * exiting. The old config is saved with the reload table * id in a reload table. The new config file is read. Now, as * each job exits, it calls back to the reload_job_end_cb(), which * decrements the count of open jobs for the given reload table. @@ -371,7 +367,7 @@ void reload_config(int sig) static bool already_here = false; sigset_t set; JCR *jcr; - int njobs = 0; + int njobs = 0; /* number of running jobs */ int table, rtable; if (already_here) { @@ -393,19 +389,6 @@ void reload_config(int sig) goto bail_out; } - /* - * Hook all active jobs that are not already hooked (i.e. - * reload_id == 0 - */ - foreach_jcr(jcr) { - if (jcr->reload_id == 0 && jcr->JobType != JT_SYSTEM) { - reload_table[table].job_count++; - jcr->reload_id = table + 1; - job_end_push(jcr, reload_job_end_cb); - njobs++; - } - free_locked_jcr(jcr); - } Dmsg1(000, "Reload_config njobs=%d\n", njobs); reload_table[table].res_table = save_config_resources(); Dmsg1(000, "Saved old config in table %d\n", table); @@ -430,15 +413,18 @@ void reload_config(int sig) res_head[i] = res_tab[i]; } table = rtable; /* release new, bad, saved table below */ - if (njobs != 0) { - foreach_jcr(jcr) { - if (jcr->reload_id == table) { - jcr->reload_id = 0; - } - free_locked_jcr(jcr); + } else { + /* + * Hook all active jobs so that they release this table + */ + foreach_jcr(jcr) { + if (jcr->JobType != JT_SYSTEM) { + reload_table[table].job_count++; + job_end_push(jcr, reload_job_end_cb, (void *)table); + njobs++; } + free_locked_jcr(jcr); } - njobs = 0; /* force bad tabel to be released below */ } /* Reset globals */ diff --git a/bacula/src/dird/job.c b/bacula/src/dird/job.c index de336b01af..19a0faf38c 100644 --- a/bacula/src/dird/job.c +++ b/bacula/src/dird/job.c @@ -98,6 +98,7 @@ void run_job(JCR *jcr) Jmsg1(jcr, M_FATAL, 0, _("Unable to init job cond variable: ERR=%s\n"), strerror(errstat)); goto bail_out; } + jcr->term_wait_inited = true; /* * Open database @@ -654,7 +655,10 @@ void dird_free_jcr(JCR *jcr) free_pool_memory(jcr->client_uname); jcr->client_uname = NULL; } - pthread_cond_destroy(&jcr->term_wait); + if (jcr->term_wait_inited) { + pthread_cond_destroy(&jcr->term_wait); + } + jcr->job_end_push.destroy(); Dmsg0(200, "End dird free_jcr\n"); } diff --git a/bacula/src/dird/verify.c b/bacula/src/dird/verify.c index cc72716005..c34dcd470a 100644 --- a/bacula/src/dird/verify.c +++ b/bacula/src/dird/verify.c @@ -549,7 +549,7 @@ int get_attributes_and_compare_to_catalog(JCR *jcr, JobId_t JobId) jcr->FileIndex = file_index; /* remember attribute file_index */ decode_stat(attr, &statf, &LinkFIf); /* decode file stat packet */ do_SIG = NO_SIG; - jcr->fn_printed = FALSE; + jcr->fn_printed = false; pm_strcpy(&jcr->fname, fname); /* move filename into JCR */ Dmsg2(040, "dirdfname); @@ -718,7 +718,7 @@ int get_attributes_and_compare_to_catalog(JCR *jcr, JobId_t JobId) /* Now find all the files that are missing -- i.e. all files in * the database where the MarkedId != current JobId */ - jcr->fn_printed = FALSE; + jcr->fn_printed = false; sprintf(buf, "SELECT Path.Path,Filename.Name FROM File,Path,Filename " "WHERE File.JobId=%d " @@ -753,7 +753,7 @@ static int missing_handler(void *ctx, int num_fields, char **row) if (!jcr->fn_printed) { Jmsg(jcr, M_INFO, 0, "\n"); Jmsg(jcr, M_INFO, 0, _("The following files are missing:\n")); - jcr->fn_printed = TRUE; + jcr->fn_printed = true; } Jmsg(jcr, M_INFO, 0, " %s%s\n", row[0]?row[0]:"", row[1]?row[1]:""); return 0; diff --git a/bacula/src/filed/job.c b/bacula/src/filed/job.c index ed8833fba9..dadea8b142 100644 --- a/bacula/src/filed/job.c +++ b/bacula/src/filed/job.c @@ -275,7 +275,7 @@ static int hello_cmd(JCR *jcr) return 0; } Dmsg0(120, "OK Authenticate\n"); - jcr->authenticated = TRUE; + jcr->authenticated = true; return 1; } diff --git a/bacula/src/filed/status.c b/bacula/src/filed/status.c index 395acddb03..715a80af69 100755 --- a/bacula/src/filed/status.c +++ b/bacula/src/filed/status.c @@ -164,7 +164,7 @@ static void list_terminated_jobs(void sendit(const char *msg, int len, void *sa sendit("\n", 1, arg); /* send separately */ msg = _("Terminated Jobs:\n"); sendit(msg, strlen(msg), arg); - msg = _(" JobId Level Files Bytes Status Finished Name \n"); + msg = _(" JobId Level Files Bytes Status Finished Name \n"); sendit(msg, strlen(msg), arg); msg = _("======================================================================\n"); sendit(msg, strlen(msg), arg); diff --git a/bacula/src/jcr.h b/bacula/src/jcr.h index 720d3ef432..1c9471e9aa 100644 --- a/bacula/src/jcr.h +++ b/bacula/src/jcr.h @@ -103,7 +103,6 @@ struct JCR { JCR_free_HANDLER *daemon_free_jcr; /* Local free routine */ dlist *msg_queue; /* Queued messages */ alist job_end_push; /* Job end pushed calls */ - int reload_id; /* SIGHUP reload table id */ bool dequeuing; /* dequeuing messages */ POOLMEM *errmsg; /* edited error message */ char Job[MAX_NAME_LENGTH]; /* Unique name of this Job */ @@ -119,7 +118,6 @@ struct JCR { int JobType; /* backup, restore, verify ... */ int JobLevel; /* Job level */ int JobPriority; /* Job priority */ - int authenticated; /* set when client authenticated */ time_t sched_time; /* job schedule time, i.e. when it should start */ time_t start_time; /* when job actually started */ time_t run_time; /* used for computing speed */ @@ -131,10 +129,11 @@ struct JCR { MSGS *jcr_msgs; /* Copy of message resource -- actually used */ uint32_t ClientId; /* Client associated with Job */ char *where; /* prefix to restore files to */ - bool prefix_links; /* Prefix links with Where path */ - bool gui; /* set if gui using console */ int cached_pnl; /* cached path length */ POOLMEM *cached_path; /* cached path */ + bool prefix_links; /* Prefix links with Where path */ + bool gui; /* set if gui using console */ + bool authenticated; /* set when client authenticated */ /* Daemon specific part of JCR */ /* This should be empty in the library */ @@ -168,7 +167,6 @@ struct JCR { FileId_t FileId; /* Last file id inserted */ uint32_t FileIndex; /* Last FileIndex processed */ POOLMEM *fname; /* name to put into catalog */ - int fn_printed; /* printed filename */ POOLMEM *stime; /* start time for incremental/differential */ JOB_DBR jr; /* Job DB record for current job */ JOB_DBR *verify_jr; /* Pointer to target job */ @@ -176,10 +174,12 @@ struct JCR { POOLMEM *client_uname; /* client uname */ int replace; /* Replace option */ int saveMaxConcurrentJobs; /* save for restore jobs */ - bool acquired_resource_locks; /* set if resource locks acquired */ int NumVols; /* Number of Volume used in pool */ int reschedule_count; /* Number of times rescheduled */ bool spool_data; /* Spool data in SD */ + bool acquired_resource_locks; /* set if resource locks acquired */ + bool term_wait_inited; /* Set when cond var inited */ + bool fn_printed; /* printed filename */ #endif /* DIRECTOR_DAEMON */ diff --git a/bacula/src/lib/jcr.c b/bacula/src/lib/jcr.c index 10dd419d6b..eebb5244de 100755 --- a/bacula/src/lib/jcr.c +++ b/bacula/src/lib/jcr.c @@ -158,18 +158,21 @@ void unlock_last_jobs_list() /* * Push a subroutine address into the job end callback stack */ -void job_end_push(JCR *jcr, void job_end_cb(JCR *jcr)) +void job_end_push(JCR *jcr, void job_end_cb(JCR *jcr,void *), void *ctx) { - jcr->job_end_push.prepend((void *)job_end_cb); + jcr->job_end_push.append((void *)job_end_cb); + jcr->job_end_push.append(ctx); } /* Pop each job_end subroutine and call it */ static void job_end_pop(JCR *jcr) { - void (*job_end_cb)(JCR *jcr); - for (int i=0; ijob_end_push.size(); i++) { - job_end_cb = (void (*)(JCR *))jcr->job_end_push.get(i); - job_end_cb(jcr); + void (*job_end_cb)(JCR *jcr, void *ctx); + void *ctx; + for (int i=jcr->job_end_push.size()-1; i > 0; ) { + ctx = jcr->job_end_push.get(i--); + job_end_cb = (void (*)(JCR *,void *))jcr->job_end_push.get(i--); + job_end_cb(jcr, ctx); } } diff --git a/bacula/src/lib/protos.h b/bacula/src/lib/protos.h index a60caa4d4b..a5fb6dd78b 100644 --- a/bacula/src/lib/protos.h +++ b/bacula/src/lib/protos.h @@ -128,7 +128,7 @@ void unlock_last_jobs_list(); void read_last_jobs_list(int fd, uint64_t addr); uint64_t write_last_jobs_list(int fd, uint64_t addr); void write_state_file(char *dir, const char *progname, int port); -void job_end_push(JCR *jcr, void job_end_cb(JCR *jcr)); +void job_end_push(JCR *jcr, void job_end_cb(JCR *jcr,void *), void *ctx); /* lex.c */ diff --git a/bacula/src/stored/authenticate.c b/bacula/src/stored/authenticate.c index 4bc6a1cae9..24c1383125 100644 --- a/bacula/src/stored/authenticate.c +++ b/bacula/src/stored/authenticate.c @@ -124,7 +124,7 @@ int authenticate_filed(JCR *jcr) btimer_t *tid = start_bsock_timer(fd, 60 * 5); if (cram_md5_auth(fd, jcr->sd_auth_key, ssl_need) && cram_md5_get_auth(fd, jcr->sd_auth_key, ssl_need)) { - jcr->authenticated = TRUE; + jcr->authenticated = true; } stop_bsock_timer(tid); if (!jcr->authenticated) { diff --git a/bacula/src/stored/btape.c b/bacula/src/stored/btape.c index 15c407b7d3..731860c097 100644 --- a/bacula/src/stored/btape.c +++ b/bacula/src/stored/btape.c @@ -72,9 +72,6 @@ static void qfillcmd(); static void statcmd(); static void unfillcmd(); static int flush_block(DEV_BLOCK *block, int dump); -#ifdef xxx_needed -static int record_cb(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec); -#endif static int quickie_cb(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec); static bool compare_blocks(DEV_BLOCK *last_block, DEV_BLOCK *block); static int my_mount_next_read_volume(JCR *jcr, DEVICE *dev, DEV_BLOCK *block); @@ -1896,7 +1893,6 @@ This may take a long time -- hours! ...\n\n"); ok = false; } - Pmsg2(-1, _("\n\nDone filling tape%s. Now beginning re-read of %stape ...\n"), simple?"":"s", simple?"":"first "); @@ -1984,8 +1980,8 @@ static void do_unfill() force_close_dev(dev); get_cmd(_("Mount first tape. Press enter when ready: ")); } - free_vol_list(jcr); + jcr->dcr = new_dcr(jcr, dev); set_volume_name("TestVolume1", 1); jcr->bsr = NULL; create_vol_list(jcr); diff --git a/bacula/src/stored/job.c b/bacula/src/stored/job.c index 0e76449a55..fc8c882b2b 100644 --- a/bacula/src/stored/job.c +++ b/bacula/src/stored/job.c @@ -216,7 +216,7 @@ void handle_filed_connection(BSOCK *fd, char *job_name) Dmsg1(100, "Authentication failed Job %s\n", jcr->Job); Jmsg(jcr, M_FATAL, 0, _("Unable to authenticate File daemon\n")); } else { - jcr->authenticated = TRUE; + jcr->authenticated = true; Dmsg1(110, "OK Authentication Job %s\n", jcr->Job); } -- 2.39.5