Kern's ToDo List
- 27 January 2004
+ 28 February 2004
Documentation to do: (any release a little bit at a time)
- DB upgrade to version 5 in bacula-1.27b, DB upgrade to
http://howtos.linux.com/guides/nag2/x-087-2-nfs.mountd.shtml
For 1.33
+- Look at installation file permissions with Scott so that make install
+ and the rpms agree.
- Add a regression test for dbcheck.
- Add disk seeking on restore.
- Add atime preservation.
- Allow for optional cancelling of SD and FD in case DIR
gets a fatal error. Requested by Jesse Guardiani <jesse@wingnet.net>
-- Remove h_errno from bnet.c by including proper header.
- Do not err job if could not write bootstrap file.
- Bizarre message: Error: Could not open WriteBootstrap file:
- Build console in client only build.
- Look at ASSERT() at 384 src/lib/bnet.c
- Dates are wrong in restore list from Win32 FD.
- Dates are wrong in catalog from Win32 FD.
+- Remove h_errno from bnet.c by including proper header.
+
jobstatus_to_ascii(jcr->FDJobStatus, fd_term_msg, sizeof(fd_term_msg));
jobstatus_to_ascii(jcr->SDJobStatus, sd_term_msg, sizeof(sd_term_msg));
+// bmicrosleep(40, 0); /* for debugging SIGHUP */
+
Jmsg(jcr, msg_type, 0, _("Bacula " VERSION " (" LSMDATE "): %s\n\
JobId: %d\n\
Job: %s\n\
static char *configfile = NULL;
static char *runjob = NULL;
static int background = 1;
+static void init_reload(void);
/* Globals Exported */
DIRRES *director; /* Director resource */
my_name_is(argc, argv, "bacula-dir");
textdomain("bacula-dir");
init_msg(NULL, NULL); /* initialize message handler */
+ init_reload();
daemon_start_time = time(NULL);
while ((ch = getopt(argc, argv, "c:d:fg:r:stu:v?")) != -1) {
exit(sig);
}
+struct RELOAD_TABLE {
+ int job_count;
+ RES **res_table;
+};
+
+static const int max_reloads = 10;
+static RELOAD_TABLE reload_table[max_reloads];
+
+static void init_reload(void)
+{
+ for (int i=0; i < max_reloads; i++) {
+ reload_table[i].job_count = 0;
+ reload_table[i].res_table = NULL;
+ }
+}
+
+/*
+ * Called here at the end of every job that was
+ * hooked decrementing the active job_count. When
+ * it goes to zero, no one is using the associated
+ * resource table, so free it.
+ */
+static void reload_job_end_cb(JCR *jcr)
+{
+ int i = jcr->reload_id - 1;
+ RES **res_tab;
+ Dmsg1(000, "reload job_end JobId=%d\n", jcr->JobId);
+ if (--reload_table[i].job_count <= 0) {
+ int num = r_last - r_first + 1;
+ res_tab = reload_table[i].res_table;
+ Dmsg0(000, "Freeing resources\n");
+ for (int j=0; j<num; j++) {
+ free_resource(res_tab[j], r_first + j);
+ }
+ free(res_tab);
+ reload_table[i].job_count = 0;
+ reload_table[i].res_table = NULL;
+ }
+}
+
/*
* If we get here, we have received a SIGHUP, which means to
- * reread our configuration file.
- *
- * ***FIXME*** Check that there are no jobs running before
- * doing this.
+ * reread our configuration file.
*/
static void reload_config(int sig)
{
sigset_t set;
JCR *jcr;
int njobs = 0;
+ int table = -1;
if (already_here) {
abort(); /* Oops, recursion -> die */
}
- already_here = TRUE;
+ already_here = true;
sigfillset(&set);
sigprocmask(SIG_BLOCK, &set, NULL);
lock_jcr_chain();
LockRes();
+ for (int i=0; i < max_reloads; i++) {
+ if (reload_table[i].res_table == NULL) {
+ table = i;
+ break;
+ }
+ }
+ if (table < 0) {
+ Jmsg(NULL, M_ERROR, 0, _("Too many reload requests.\n"));
+ goto bail_out;
+ }
+
+ /*
+ * Hook all active jobs that are not already hooked (i.e.
+ * reload_id == 0
+ */
foreach_jcr(jcr) {
- if (jcr->JobId != 0) { /* this is a console */
+ /* JobId==0 => console */
+ if (jcr->JobId != 0 && jcr->reload_id == 0) {
+ 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);
if (njobs > 0) {
- goto bail_out;
+ reload_table[table].res_table = save_config_resources();
+ Dmsg1(000, "Saved old config in table %d\n", table);
+ } else {
+ free_config_resources();
}
- free_config_resources();
-
+ Dmsg0(000, "Calling parse config\n");
parse_config(configfile);
+ Dmsg0(000, "Reloaded config file\n");
if (!check_resources()) {
Jmsg(NULL, M_ERROR_TERM, 0, _("Please correct configuration file: %s\n"), configfile);
}
JCR_free_HANDLER *daemon_free_jcr; /* Local free routine */
dlist *msg_queue; /* Queued messages */
alist job_end_push; /* Job end pushed calls */
- int restart_count; /* SIGHUP restart count */
+ 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 */
* Free configuration resources
*
*/
-void
-free_config_resources()
+void free_config_resources()
{
- RES *res;
for (int i=r_first; i<=r_last; i++) {
- res = resources[i-r_first].res_head;
- free_resource(res, i);
- res = NULL;
+ free_resource(resources[i-r_first].res_head, i);
+ resources[i-r_first].res_head = NULL;
}
}
+
+RES **save_config_resources()
+{
+ int num = r_last - r_first + 1;
+ RES **res = (RES **)malloc(num*sizeof(RES *));
+ for (int i=0; i<num; i++) {
+ res[i] = resources[i].res_head;
+ resources[i].res_head = NULL;
+ }
+ return res;
+}
*/
-struct RES_ITEM; /* Declare forward referenced structure */
+struct RES_ITEM; /* Declare forward referenced structure */
typedef void (MSG_RES_HANDLER)(LEX *lc, RES_ITEM *item, int index, int pass);
/* This is the structure that defines
* tables.
*/
struct RES_ITEM {
- const char *name; /* Resource name i.e. Director, ... */
- MSG_RES_HANDLER *handler; /* Routine storing the resource item */
- void **value; /* Where to store the item */
- int code; /* item code/additional info */
- int flags; /* flags: default, required, ... */
- int default_value; /* default value */
+ const char *name; /* Resource name i.e. Director, ... */
+ MSG_RES_HANDLER *handler; /* Routine storing the resource item */
+ void **value; /* Where to store the item */
+ int code; /* item code/additional info */
+ int flags; /* flags: default, required, ... */
+ int default_value; /* default value */
};
/* For storing name_addr items in res_items table */
#define ITEM(x) ((void **)&res_all.x)
-#define MAX_RES_ITEMS 50 /* maximum resource items per RES */
+#define MAX_RES_ITEMS 50 /* maximum resource items per RES */
/* This is the universal header that is
* at the beginning of every resource
* record.
*/
struct RES {
- RES *next; /* pointer to next resource of this type */
- char *name; /* resource name */
- char *desc; /* resource description */
- int rcode; /* resource id or type */
- int refcnt; /* reference count for releasing */
+ RES *next; /* pointer to next resource of this type */
+ char *name; /* resource name */
+ char *desc; /* resource description */
+ int rcode; /* resource id or type */
+ int refcnt; /* reference count for releasing */
char item_present[MAX_RES_ITEMS]; /* set if item is present in conf file */
};
* This is the structure that defines the
* resources that are available to this daemon.
*/
-struct RES_TABLE {
- const char *name; /* resource name */
- RES_ITEM *items; /* list of resource keywords */
- int rcode; /* code if needed */
- RES *res_head; /* where to store it */
+struct RES_TABLE {
+ const char *name; /* resource name */
+ RES_ITEM *items; /* list of resource keywords */
+ int rcode; /* code if needed */
+ RES *res_head; /* where to store it */
};
/* Common Resource definitions */
-#define MAX_RES_NAME_LENGTH MAX_NAME_LENGTH-1 /* maximum resource name length */
+#define MAX_RES_NAME_LENGTH MAX_NAME_LENGTH-1 /* maximum resource name length */
-#define ITEM_REQUIRED 0x1 /* item required */
-#define ITEM_DEFAULT 0x2 /* default supplied */
+#define ITEM_REQUIRED 0x1 /* item required */
+#define ITEM_DEFAULT 0x2 /* default supplied */
#define ITEM_NO_EQUALS 0x4 /* Don't scan = after name */
/* Message Resource */
struct MSGS {
- RES hdr;
- char *mail_cmd; /* mail command */
- char *operator_cmd; /* Operator command */
- DEST *dest_chain; /* chain of destinations */
+ RES hdr;
+ char *mail_cmd; /* mail command */
+ char *operator_cmd; /* Operator command */
+ DEST *dest_chain; /* chain of destinations */
char send_msg[nbytes_for_bits(M_MAX+1)]; /* bit array of types */
};
/* Configuration routines */
void parse_config(char *cf);
void free_config_resources(void);
+RES **save_config_resources(void);
/* Resource routines */
RES *GetResWithName(int rcode, char *name);
#ifdef the_old_way
#define foreach_res(var, type) \
- for((var)=NULL; (((void *)(var))=GetNextRes((type), (RES *)var));)
+ for((var)=NULL; (((void *)(var))=GetNextRes((type), (RES *)var));)
#endif
#undef VERSION
#define VERSION "1.33.4"
#define VSTRING "1"
-#define BDATE "27 Feb 2004"
-#define LSMDATE "27Feb04"
+#define BDATE "28 Feb 2004"
+#define LSMDATE "28Feb04"
/* Debug flags */
#undef DEBUG