2 Bacula(R) - The Network Backup Solution
4 Copyright (C) 2000-2017 Kern Sibbald
6 The original author of Bacula is Kern Sibbald, with contributions
7 from many others, a complete list can be found in the file AUTHORS.
9 You may use this file and others of this release according to the
10 license defined in the LICENSE file, which includes the Affero General
11 Public License, v3.0 ("AGPLv3") and some additional permissions and
12 terms pursuant to its AGPLv3 Section 7.
14 This notice must be preserved when any source code is
15 conveyed and/or propagated.
17 Bacula(R) is a registered trademark of Kern Sibbald.
20 * Bacula Director daemon -- this is the main program
22 * Kern Sibbald, March MM
28 #include "lib/bregex.h"
34 #define NAMELEN(dirent) (strlen((dirent)->d_name))
36 #ifndef HAVE_READDIR_R
37 int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result);
40 /* Forward referenced subroutines */
41 void terminate_dird(int sig);
42 static bool check_resources();
43 static void cleanup_old_files();
44 static void resize_reload(int nb);
46 /* Exported subroutines */
47 extern "C" void reload_config(int sig);
48 extern void invalidate_schedules();
49 extern bool parse_dir_config(CONFIG *config, const char *configfile, int exit_code);
51 /* Imported subroutines */
52 JCR *wait_for_next_job(char *runjob);
53 void term_scheduler();
54 void term_ua_server();
55 void start_UA_server(dlist *addrs);
56 void init_job_server(int max_workers);
57 void term_job_server();
58 void store_jobtype(LEX *lc, RES_ITEM *item, int index, int pass);
59 void store_level(LEX *lc, RES_ITEM *item, int index, int pass);
60 void store_replace(LEX *lc, RES_ITEM *item, int index, int pass);
61 void store_migtype(LEX *lc, RES_ITEM *item, int index, int pass);
62 void init_device_resources();
65 static char *runjob = NULL;
66 static bool foreground = false;
67 static bool make_pid_file = true; /* create pid file */
68 static void init_reload(void);
69 static CONFIG *config;
70 static bool test_config = false;
72 /* Globals Exported */
73 DIRRES *director; /* Director resource */
76 char *configfile = NULL;
78 utime_t last_reload_time = 0;
81 /* Globals Imported */
82 extern dlist client_globals;
83 extern dlist store_globals;
84 extern dlist job_globals;
85 extern dlist sched_globals;
86 extern RES_ITEM job_items[];
88 extern "C" { // work around visual compiler mangling variables
96 CHECK_CONNECTION, /* Check catalog connection */
97 UPDATE_CATALOG, /* Ensure that catalog is ok with conf */
98 UPDATE_AND_FIX /* Ensure that catalog is ok, and fix old jobs */
100 static bool check_catalog(cat_op mode);
102 #define CONFIG_FILE "bacula-dir.conf" /* default configuration file */
104 static bool dir_sql_query(JCR *jcr, const char *cmd)
106 if (jcr && jcr->db && jcr->db->is_connected()) {
107 return db_sql_query(jcr->db, cmd, NULL, NULL);
112 static bool dir_sql_escape(JCR *jcr, BDB *mdb, char *snew, char *sold, int len)
114 if (jcr && jcr->db && jcr->db->is_connected()) {
115 db_escape_string(jcr, mdb, snew, sold, len);
125 "\n%sVersion: %s (%s)\n\n"
126 "Usage: bacula-dir [-f -s] [-c config_file] [-d debug_level] [config_file]\n"
127 " -c <file> set configuration file to file\n"
128 " -d <nn>[,<tags>] set debug level to <nn>, debug tags to <tags>\n"
129 " -dt print timestamp in debug output\n"
131 " -f run in foreground (for debugging)\n"
133 " -m print kaboom output (for debugging)\n"
134 " -r <job> run <job> now\n"
135 " -P do not create pid file\n"
137 " -t test - read configuration and exit\n"
139 " -v verbose user messages\n"
140 " -? print this message.\n"
141 "\n"), 2000, "", VERSION, BDATE);
147 * !!! WARNING !!! Use this function only when bacula is stopped.
148 * ie, after a fatal signal and before exiting the program
149 * Print information about a JCR
151 static void dir_debug_print(JCR *jcr, FILE *fp)
153 fprintf(fp, "\twstore=%p rstore=%p wjcr=%p client=%p reschedule_count=%d SD_msg_chan_started=%d\n",
154 jcr->wstore, jcr->rstore, jcr->wjcr, jcr->client, jcr->reschedule_count, (int)jcr->SD_msg_chan_started);
157 /*********************************************************************
159 * Main Bacula Director Server program
162 #if defined(HAVE_WIN32)
163 /* For Win32 main() is in src/win32 code ... */
164 #define main BaculaMain
167 /* DELETE ME when bugs in MA1512, MA1632 MA1639 are fixed */
168 extern void (*MA1512_reload_job_end_cb)(JCR *,void *);
169 static void reload_job_end_cb(JCR *jcr, void *ctx);
171 int main (int argc, char *argv[])
175 bool no_signals = false;
179 /* DELETE ME when bugs in MA1512, MA1632 MA1639 are fixed */
180 MA1512_reload_job_end_cb = reload_job_end_cb;
182 start_heap = sbrk(0);
183 setlocale(LC_ALL, "");
184 bindtextdomain("bacula", LOCALEDIR);
185 textdomain("bacula");
188 my_name_is(argc, argv, "bacula-dir");
189 init_msg(NULL, NULL); /* initialize message handler */
191 daemon_start_time = time(NULL);
192 setup_daemon_message_queue();
193 console_command = run_console_command;
195 while ((ch = getopt(argc, argv, "c:d:fg:mPr:stu:v?T")) != -1) {
197 case 'c': /* specify config file */
198 if (configfile != NULL) {
201 configfile = bstrdup(optarg);
204 case 'd': /* set debug level */
205 if (*optarg == 't') {
206 dbg_timestamp = true;
209 /* We probably find a tag list -d 10,sql,bvfs */
210 if ((p = strchr(optarg, ',')) != NULL) {
213 debug_level = atoi(optarg);
214 if (debug_level <= 0) {
218 debug_parse_tags(p+1, &debug_level_tags);
221 Dmsg1(10, "Debug level = %lld\n", debug_level);
228 case 'f': /* run in foreground */
232 case 'g': /* set group id */
236 case 'm': /* print kaboom output */
240 case 'P': /* no pid file */
241 make_pid_file = false;
244 case 'r': /* run job */
245 if (runjob != NULL) {
249 runjob = bstrdup(optarg);
253 case 's': /* turn off signals */
257 case 't': /* test config */
261 case 'u': /* set uid */
265 case 'v': /* verbose */
279 if (configfile != NULL) {
282 configfile = bstrdup(*argv);
290 if (!foreground && !test_config) {
292 init_stack_dump(); /* grab new pid */
296 init_signals(terminate_dird);
299 if (configfile == NULL) {
300 configfile = bstrdup(CONFIG_FILE);
303 config = New(CONFIG());
304 parse_dir_config(config, configfile, M_ERROR_TERM);
306 if (init_crypto() != 0) {
307 Jmsg((JCR *)NULL, M_ERROR_TERM, 0, _("Cryptography library initialization failed.\n"));
310 if (!check_resources()) {
311 Jmsg((JCR *)NULL, M_ERROR_TERM, 0, _("Please correct configuration file: %s\n"), configfile);
314 /* The configuration is correct */
315 director = (DIRRES *)GetNextRes(R_DIRECTOR, NULL);
318 /* Create pid must come after we are a daemon -- so we have our final pid */
320 create_pid_file(director->pid_directory, "bacula-dir",
321 get_first_port_host_order(director->DIRaddrs));
323 read_state_file(director->working_directory, "bacula-dir",
324 get_first_port_host_order(director->DIRaddrs));
327 set_jcr_in_tsd(INVALID_JCR);
328 set_thread_concurrency(director->MaxConcurrentJobs * 2 +
329 4 /* UA */ + 5 /* sched+watchdog+jobsvr+misc */);
330 lmgr_init_thread(); /* initialize the lockmanager stack */
332 load_dir_plugins(director->plugin_directory);
334 drop(uid, gid, false); /* reduce privileges if requested */
336 /* If we are in testing mode, we don't try to fix the catalog */
337 cat_op mode=(test_config)?CHECK_CONNECTION:UPDATE_AND_FIX;
339 if (!check_catalog(mode)) {
340 Jmsg((JCR *)NULL, M_ERROR_TERM, 0, _("Please correct configuration file: %s\n"), configfile);
347 my_name_is(0, NULL, director->name()); /* set user defined name */
351 /* Plug database interface for library routines */
352 p_sql_query = (sql_query_call)dir_sql_query;
353 p_sql_escape = (sql_escape_call)dir_sql_escape;
355 FDConnectTimeout = (int)director->FDConnectTimeout;
356 SDConnectTimeout = (int)director->SDConnectTimeout;
358 resize_reload(director->MaxReload);
360 #if !defined(HAVE_WIN32)
361 signal(SIGHUP, reload_config);
364 init_console_msg(working_directory);
366 Dmsg0(200, "Start UA server\n");
367 start_UA_server(director->DIRaddrs);
369 start_watchdog(); /* start network watchdog thread */
371 init_jcr_subsystem(); /* start JCR watchdogs etc. */
373 init_job_server(director->MaxConcurrentJobs);
375 dbg_jcr_add_hook(dir_debug_print); /* used to director variables */
376 dbg_jcr_add_hook(bdb_debug_print); /* used to debug B_DB connexion after fatal signal */
378 // init_device_resources();
380 Dmsg0(200, "wait for next job\n");
381 /* Main loop -- call scheduler to get next job to run */
382 while ( (jcr = wait_for_next_job(runjob)) ) {
383 run_job(jcr); /* run job */
384 free_jcr(jcr); /* release jcr */
385 set_jcr_in_tsd(INVALID_JCR);
386 if (runjob) { /* command line, run a single job? */
387 break; /* yes, terminate */
396 struct RELOAD_TABLE {
401 static int max_reloads = 32;
402 static RELOAD_TABLE *reload_table=NULL;
404 static void resize_reload(int nb)
406 if (nb <= max_reloads) {
410 reload_table = (RELOAD_TABLE*)realloc(reload_table, nb * sizeof(RELOAD_TABLE));
411 for (int i=max_reloads; i < nb ; i++) {
412 reload_table[i].job_count = 0;
413 reload_table[i].res_head = NULL;
418 static void init_reload(void)
420 reload_table = (RELOAD_TABLE*)malloc(max_reloads * sizeof(RELOAD_TABLE));
421 for (int i=0; i < max_reloads; i++) {
422 reload_table[i].job_count = 0;
423 reload_table[i].res_head = NULL;
428 * This subroutine frees a saved resource table.
429 * It was saved when a new table was created with "reload"
431 static void free_saved_resources(int table)
434 int num = r_last - r_first + 1;
435 RES_HEAD **res_tab = reload_table[table].res_head;
437 if (res_tab == NULL) {
438 Dmsg1(100, "res_tab for table %d already released.\n", table);
441 Dmsg1(100, "Freeing resources for table %d\n", table);
442 for (int j=0; j<num; j++) {
444 next = res_tab[j]->first;
447 next = res->res_next;
448 free_resource(res, r_first + j);
450 free(res_tab[j]->res_list);
456 reload_table[table].job_count = 0;
457 reload_table[table].res_head = NULL;
461 * Called here at the end of every job that was
462 * hooked decrementing the active job_count. When
463 * it goes to zero, no one is using the associated
464 * resource table, so free it.
466 static void reload_job_end_cb(JCR *jcr, void *ctx)
468 int reload_id = (int)((intptr_t)ctx);
469 Dmsg3(100, "reload job_end JobId=%d table=%d cnt=%d\n", jcr->JobId,
470 reload_id, reload_table[reload_id].job_count);
473 if (--reload_table[reload_id].job_count <= 0) {
474 free_saved_resources(reload_id);
480 static int find_free_reload_table_entry()
483 for (int i=0; i < max_reloads; i++) {
484 if (reload_table[i].res_head == NULL) {
492 static pthread_mutex_t reload_mutex = PTHREAD_MUTEX_INITIALIZER;
495 * If we get here, we have received a SIGHUP, which means to
496 * reread our configuration file.
498 * The algorithm used is as follows: we count how many jobs are
499 * running and mark the running jobs to make a callback on
500 * exiting. The old config is saved with the reload table
501 * id in a reload table. The new config file is read. Now, as
502 * each job exits, it calls back to the reload_job_end_cb(), which
503 * decrements the count of open jobs for the given reload table.
504 * When the count goes to zero, we release those resources.
505 * This allows us to have pointers into the resource table (from
506 * jobs), and once they exit and all the pointers are released, we
507 * release the old table. Note, if no new jobs are running since the
508 * last reload, then the old resources will be immediately release.
509 * A console is considered a job because it may have pointers to
510 * resources, but a SYSTEM job is not since it *should* not have any
511 * permanent pointers to jobs.
514 void reload_config(int sig)
516 static bool already_here = false;
517 #if !defined(HAVE_WIN32)
521 int njobs = 0; /* number of running jobs */
526 /* Wait to do the reload */
532 Qmsg(NULL, M_INFO, 0, _("Already doing a reload request, "
533 "request ignored.\n"));
536 Dmsg0(10, "Already doing a reload request, waiting a bit\n");
545 #if !defined(HAVE_WIN32)
547 sigaddset(&set, SIGHUP);
548 sigprocmask(SIG_BLOCK, &set, NULL);
554 table = find_free_reload_table_entry();
556 Qmsg(NULL, M_ERROR, 0, _("Too many (%d) open reload requests. "
557 "Request ignored.\n"), max_reloads);
561 Dmsg1(100, "Reload_config njobs=%d\n", njobs);
562 /* Save current res_head */
563 reload_table[table].res_head = res_head;
564 Dmsg1(100, "Saved old config in table %d\n", table);
566 /* Create a new res_head and parse into it */
567 ok = parse_dir_config(config, configfile, M_ERROR);
569 Dmsg0(100, "Reloaded config file\n");
570 if (!ok || !check_resources() || !check_catalog(UPDATE_CATALOG)) {
572 * We got an error, save broken point, restore old one,
573 * then release everything from broken pointer.
575 rtable = find_free_reload_table_entry(); /* save new, bad table */
577 Qmsg(NULL, M_ERROR, 0, _("Please correct configuration file: %s\n"), configfile);
578 Qmsg(NULL, M_ERROR_TERM, 0, _("Out of reload table entries. Giving up.\n"));
580 Qmsg(NULL, M_ERROR, 0, _("Please correct configuration file: %s\n"), configfile);
581 Qmsg(NULL, M_ERROR, 0, _("Resetting previous configuration.\n"));
583 /* Save broken res_head pointer */
584 reload_table[rtable].res_head = res_head;
586 /* Now restore old resource pointer */
587 res_head = reload_table[table].res_head;
588 table = rtable; /* release new, bad, saved table below */
590 invalidate_schedules();
592 /* We know that the configuration is correct and we will keep it,
593 * so we can update the global pointer to the director resource.
595 director = (DIRRES *)GetNextRes(R_DIRECTOR, NULL);
598 * Hook all active jobs so that they release this table
601 if (jcr->getJobType() != JT_SYSTEM) {
602 reload_table[table].job_count++;
603 job_end_push(jcr, reload_job_end_cb, (void *)((long int)table));
609 * Now walk through globals tables and plug them into the
613 foreach_dlist(cg, &client_globals) {
615 client = GetClientResWithName(cg->name);
617 Qmsg(NULL, M_INFO, 0, _("Client=%s not found. Assuming it was removed!!!\n"), cg->name);
619 client->globals = cg; /* Set globals pointer */
623 foreach_dlist(sg, &store_globals) {
625 store = GetStoreResWithName(sg->name);
627 Qmsg(NULL, M_INFO, 0, _("Storage=%s not found. Assuming it was removed!!!\n"), sg->name);
629 store->globals = sg; /* set globals pointer */
630 Dmsg2(200, "Reload found numConcurrent=%ld for Store %s\n",
631 sg->NumConcurrentJobs, sg->name);
635 foreach_dlist(jg, &job_globals) {
637 job = GetJobResWithName(jg->name);
639 Qmsg(NULL, M_INFO, 0, _("Job=%s not found. Assuming it was removed!!!\n"), jg->name);
641 job->globals = jg; /* Set globals pointer */
645 foreach_dlist(schg, &sched_globals) {
647 sched = GetSchedResWithName(schg->name);
649 Qmsg(NULL, M_INFO, 0, _("Schedule=%s not found. Assuming it was removed!!!\n"), schg->name);
651 sched->globals = schg; /* Set globals pointer */
656 /* Reset other globals */
657 set_working_directory(director->working_directory);
658 FDConnectTimeout = director->FDConnectTimeout;
659 SDConnectTimeout = director->SDConnectTimeout;
660 Dmsg0(10, "Director's configuration file reread.\n");
662 /* Now release saved resources, if no jobs using the resources */
664 free_saved_resources(table);
670 #if !defined(HAVE_WIN32)
671 sigprocmask(SIG_UNBLOCK, &set, NULL);
672 signal(SIGHUP, reload_config);
674 already_here = false;
677 /* Cleanup and then exit */
678 void terminate_dird(int sig)
680 static bool already_here = false;
682 if (already_here) { /* avoid recursive temination problems */
683 bmicrosleep(2, 0); /* yield */
687 debug_level = 0; /* turn off debug */
689 generate_daemon_event(NULL, "Exit");
692 write_state_file(director->working_directory, "bacula-dir", get_first_port_host_order(director->DIRaddrs));
694 delete_pid_file(director->pid_directory, "bacula-dir", get_first_port_host_order(director->DIRaddrs));
702 if (configfile != NULL) {
706 print_memory_pool_stats();
713 term_msg(); /* terminate message handler */
716 free_daemon_message_queue();
724 * Now walk through resource globals tables and release them
727 foreach_dlist(cg, &client_globals) {
729 if (cg->SetIPaddress) {
730 free(cg->SetIPaddress);
735 foreach_dlist(sg, &store_globals) {
740 foreach_dlist(jg, &job_globals) {
744 close_memory_pool(); /* release free memory in pool */
751 * Make a quick check to see that we have all the
754 * **** FIXME **** this routine could be a lot more
755 * intelligent and comprehensive.
757 static bool check_resources()
766 job = (JOB *)GetNextRes(R_JOB, NULL);
767 newDirector = (DIRRES *)GetNextRes(R_DIRECTOR, NULL);
769 Jmsg(NULL, M_FATAL, 0, _("No Director resource defined in %s\n"
770 "Without that I don't know who I am :-(\n"), configfile);
773 set_working_directory(newDirector->working_directory);
774 if (!newDirector->messages) { /* If message resource not specified */
775 newDirector->messages = (MSGS *)GetNextRes(R_MSGS, NULL);
776 if (!newDirector->messages) {
777 Jmsg(NULL, M_FATAL, 0, _("No Messages resource defined in %s\n"), configfile);
781 if (GetNextRes(R_DIRECTOR, (RES *)newDirector) != NULL) {
782 Jmsg(NULL, M_FATAL, 0, _("Only one Director resource permitted in %s\n"),
786 /* tls_require implies tls_enable */
787 if (newDirector->tls_require) {
789 newDirector->tls_enable = true;
791 Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
796 need_tls = newDirector->tls_enable || newDirector->tls_authenticate;
798 if (!newDirector->tls_certfile && need_tls) {
799 Jmsg(NULL, M_FATAL, 0, _("\"TLS Certificate\" file not defined for Director \"%s\" in %s.\n"),
800 newDirector->name(), configfile);
804 if (!newDirector->tls_keyfile && need_tls) {
805 Jmsg(NULL, M_FATAL, 0, _("\"TLS Key\" file not defined for Director \"%s\" in %s.\n"),
806 newDirector->name(), configfile);
810 if ((!newDirector->tls_ca_certfile && !newDirector->tls_ca_certdir) &&
811 need_tls && newDirector->tls_verify_peer) {
812 Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\" or \"TLS CA"
813 " Certificate Dir\" are defined for Director \"%s\" in %s."
814 " At least one CA certificate store is required"
815 " when using \"TLS Verify Peer\".\n"),
816 newDirector->name(), configfile);
820 /* If everything is well, attempt to initialize our per-resource TLS context */
821 if (OK && (need_tls || newDirector->tls_require)) {
822 /* Initialize TLS context:
823 * Args: CA certfile, CA certdir, Certfile, Keyfile,
824 * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
825 newDirector->tls_ctx = new_tls_context(newDirector->tls_ca_certfile,
826 newDirector->tls_ca_certdir, newDirector->tls_certfile,
827 newDirector->tls_keyfile, NULL, NULL, newDirector->tls_dhfile,
828 newDirector->tls_verify_peer);
830 if (!newDirector->tls_ctx) {
831 Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for Director \"%s\" in %s.\n"),
832 newDirector->name(), configfile);
839 Jmsg(NULL, M_FATAL, 0, _("No Job records defined in %s\n"), configfile);
842 foreach_res(job, R_JOB) {
846 JOB *jobdefs = job->jobdefs;
847 /* Handle RunScripts alists specifically */
848 if (jobdefs->RunScripts) {
851 if (!job->RunScripts) {
852 job->RunScripts = New(alist(10, not_owned_by_alist));
855 foreach_alist(rs, jobdefs->RunScripts) {
856 elt = copy_runscript(rs);
857 job->RunScripts->append(elt); /* we have to free it */
861 /* Transfer default items from JobDefs Resource */
862 for (i=0; job_items[i].name; i++) {
863 char **def_svalue, **svalue; /* string value */
864 uint32_t *def_ivalue, *ivalue; /* integer value */
865 bool *def_bvalue, *bvalue; /* bool value */
866 int64_t *def_lvalue, *lvalue; /* 64 bit values */
867 alist **def_avalue, **avalue; /* alist values */
870 Dmsg4(1400, "Job \"%s\", field \"%s\" bit=%d def=%d\n",
871 job->name(), job_items[i].name,
872 bit_is_set(i, job->hdr.item_present),
873 bit_is_set(i, job->jobdefs->hdr.item_present));
875 if (!bit_is_set(i, job->hdr.item_present) &&
876 bit_is_set(i, job->jobdefs->hdr.item_present)) {
877 Dmsg2(400, "Job \"%s\", field \"%s\": getting default.\n",
878 job->name(), job_items[i].name);
879 offset = (char *)(job_items[i].value) - (char *)&res_all;
881 * Handle strings and directory strings
883 if (job_items[i].handler == store_str ||
884 job_items[i].handler == store_dir) {
885 def_svalue = (char **)((char *)(job->jobdefs) + offset);
886 Dmsg5(400, "Job \"%s\", field \"%s\" def_svalue=%s item %d offset=%u\n",
887 job->name(), job_items[i].name, *def_svalue, i, offset);
888 svalue = (char **)((char *)job + offset);
890 Pmsg1(000, _("Hey something is wrong. p=0x%lu\n"), *svalue);
892 *svalue = bstrdup(*def_svalue);
893 set_bit(i, job->hdr.item_present);
897 } else if (job_items[i].handler == store_res) {
898 def_svalue = (char **)((char *)(job->jobdefs) + offset);
899 Dmsg4(400, "Job \"%s\", field \"%s\" item %d offset=%u\n",
900 job->name(), job_items[i].name, i, offset);
901 svalue = (char **)((char *)job + offset);
903 Pmsg1(000, _("Hey something is wrong. p=0x%lu\n"), *svalue);
905 *svalue = *def_svalue;
906 set_bit(i, job->hdr.item_present);
908 * Handle alist resources
910 } else if (job_items[i].handler == store_alist_res) {
913 def_avalue = (alist **)((char *)(job->jobdefs) + offset);
914 avalue = (alist **)((char *)job + offset);
916 *avalue = New(alist(10, not_owned_by_alist));
918 foreach_alist(elt, (*def_avalue)) {
919 (*avalue)->append(elt);
921 set_bit(i, job->hdr.item_present);
923 * Handle integer fields
924 * Note, our store_bit does not handle bitmaped fields
926 } else if (job_items[i].handler == store_bit ||
927 job_items[i].handler == store_pint32 ||
928 job_items[i].handler == store_jobtype ||
929 job_items[i].handler == store_level ||
930 job_items[i].handler == store_int32 ||
931 job_items[i].handler == store_size32 ||
932 job_items[i].handler == store_migtype ||
933 job_items[i].handler == store_replace) {
934 def_ivalue = (uint32_t *)((char *)(job->jobdefs) + offset);
935 Dmsg5(400, "Job \"%s\", field \"%s\" def_ivalue=%d item %d offset=%u\n",
936 job->name(), job_items[i].name, *def_ivalue, i, offset);
937 ivalue = (uint32_t *)((char *)job + offset);
938 *ivalue = *def_ivalue;
939 set_bit(i, job->hdr.item_present);
941 * Handle 64 bit integer fields
943 } else if (job_items[i].handler == store_time ||
944 job_items[i].handler == store_size64 ||
945 job_items[i].handler == store_speed ||
946 job_items[i].handler == store_int64) {
947 def_lvalue = (int64_t *)((char *)(job->jobdefs) + offset);
948 Dmsg5(400, "Job \"%s\", field \"%s\" def_lvalue=%" lld " item %d offset=%u\n",
949 job->name(), job_items[i].name, *def_lvalue, i, offset);
950 lvalue = (int64_t *)((char *)job + offset);
951 *lvalue = *def_lvalue;
952 set_bit(i, job->hdr.item_present);
956 } else if (job_items[i].handler == store_bool) {
957 def_bvalue = (bool *)((char *)(job->jobdefs) + offset);
958 Dmsg5(400, "Job \"%s\", field \"%s\" def_bvalue=%d item %d offset=%u\n",
959 job->name(), job_items[i].name, *def_bvalue, i, offset);
960 bvalue = (bool *)((char *)job + offset);
961 *bvalue = *def_bvalue;
962 set_bit(i, job->hdr.item_present);
968 * Ensure that all required items are present
970 for (i=0; job_items[i].name; i++) {
971 if (job_items[i].flags & ITEM_REQUIRED) {
972 if (!bit_is_set(i, job->hdr.item_present)) {
973 Jmsg(NULL, M_ERROR_TERM, 0, _("\"%s\" directive in Job \"%s\" resource is required, but not found.\n"),
974 job_items[i].name, job->name());
978 /* If this triggers, take a look at lib/parse_conf.h */
979 if (i >= MAX_RES_ITEMS) {
980 Emsg0(M_ERROR_TERM, 0, _("Too many items in Job resource\n"));
983 if (!job->storage && !job->pool->storage) {
984 Jmsg(NULL, M_FATAL, 0, _("No storage specified in Job \"%s\" nor in Pool.\n"),
989 /* Make sure the job doesn't use the Scratch Pool to start with */
991 if (!check_pool(job->JobType, job->JobLevel,
992 job->pool, job->next_pool, &name)) {
993 Jmsg(NULL, M_FATAL, 0,
994 _("%s \"Scratch\" not valid in Job \"%s\".\n"),
998 } /* End loop over Job res */
1001 /* Loop over Consoles */
1003 foreach_res(cons, R_CONSOLE) {
1004 /* tls_require implies tls_enable */
1005 if (cons->tls_require) {
1007 cons->tls_enable = true;
1009 Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
1015 need_tls = cons->tls_enable || cons->tls_authenticate;
1017 if (!cons->tls_certfile && need_tls) {
1018 Jmsg(NULL, M_FATAL, 0, _("\"TLS Certificate\" file not defined for Console \"%s\" in %s.\n"),
1019 cons->name(), configfile);
1023 if (!cons->tls_keyfile && need_tls) {
1024 Jmsg(NULL, M_FATAL, 0, _("\"TLS Key\" file not defined for Console \"%s\" in %s.\n"),
1025 cons->name(), configfile);
1029 if ((!cons->tls_ca_certfile && !cons->tls_ca_certdir)
1030 && need_tls && cons->tls_verify_peer) {
1031 Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\" or \"TLS CA"
1032 " Certificate Dir\" are defined for Console \"%s\" in %s."
1033 " At least one CA certificate store is required"
1034 " when using \"TLS Verify Peer\".\n"),
1035 cons->name(), configfile);
1038 /* If everything is well, attempt to initialize our per-resource TLS context */
1039 if (OK && (need_tls || cons->tls_require)) {
1040 /* Initialize TLS context:
1041 * Args: CA certfile, CA certdir, Certfile, Keyfile,
1042 * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
1043 cons->tls_ctx = new_tls_context(cons->tls_ca_certfile,
1044 cons->tls_ca_certdir, cons->tls_certfile,
1045 cons->tls_keyfile, NULL, NULL, cons->tls_dhfile, cons->tls_verify_peer);
1047 if (!cons->tls_ctx) {
1048 Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for File daemon \"%s\" in %s.\n"),
1049 cons->name(), configfile);
1056 /* Loop over Clients */
1058 foreach_res(client, R_CLIENT) {
1059 /* tls_require implies tls_enable */
1060 if (client->tls_require) {
1062 client->tls_enable = true;
1064 Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
1069 need_tls = client->tls_enable || client->tls_authenticate;
1070 if ((!client->tls_ca_certfile && !client->tls_ca_certdir) && need_tls) {
1071 Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\""
1072 " or \"TLS CA Certificate Dir\" are defined for File daemon \"%s\" in %s.\n"),
1073 client->name(), configfile);
1077 /* If everything is well, attempt to initialize our per-resource TLS context */
1078 if (OK && (need_tls || client->tls_require)) {
1079 /* Initialize TLS context:
1080 * Args: CA certfile, CA certdir, Certfile, Keyfile,
1081 * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
1082 client->tls_ctx = new_tls_context(client->tls_ca_certfile,
1083 client->tls_ca_certdir, client->tls_certfile,
1084 client->tls_keyfile, NULL, NULL, NULL,
1087 if (!client->tls_ctx) {
1088 Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for File daemon \"%s\" in %s.\n"),
1089 client->name(), configfile);
1095 /* Loop over all pools, check PoolType */
1097 foreach_res(pool, R_POOL) {
1098 if (!pool->pool_type) {
1099 /* This case is checked by the parse engine, we should not */
1100 Jmsg(NULL, M_FATAL, 0, _("PoolType required in Pool resource \"%s\".\n"), pool->hdr.name);
1104 if ((strcasecmp(pool->pool_type, NT_("backup")) != 0) &&
1105 (strcasecmp(pool->pool_type, NT_("copy")) != 0) &&
1106 (strcasecmp(pool->pool_type, NT_("cloned")) != 0) &&
1107 (strcasecmp(pool->pool_type, NT_("archive")) != 0) &&
1108 (strcasecmp(pool->pool_type, NT_("migration")) != 0) &&
1109 (strcasecmp(pool->pool_type, NT_("scratch")) != 0))
1111 Jmsg(NULL, M_FATAL, 0, _("Invalid PoolType \"%s\" in Pool resource \"%s\".\n"), pool->pool_type, pool->hdr.name);
1115 if (pool->NextPool && strcmp(pool->NextPool->name(), "Scratch") == 0) {
1116 Jmsg(NULL, M_FATAL, 0,
1117 _("NextPool \"Scratch\" not valid in Pool \"%s\".\n"),
1125 close_msg(NULL); /* close temp message handler */
1126 init_msg(NULL, newDirector->messages); /* open daemon message handler */
1127 last_reload_time = time(NULL);
1134 * - we can check the connection (mode=CHECK_CONNECTION)
1135 * - we can synchronize the catalog with the configuration (mode=UPDATE_CATALOG)
1136 * - we can synchronize, and fix old job records (mode=UPDATE_AND_FIX)
1137 * - we hook up the Autochange children with the parent, and
1138 * we hook the shared autochangers together.
1140 static bool check_catalog(cat_op mode)
1144 STORE *store, *ac_child;
1146 /* Loop over databases */
1148 foreach_res(catalog, R_CATALOG) {
1151 * Make sure we can open catalog, otherwise print a warning
1152 * message because the server is probably not running.
1154 db = db_init_database(NULL, catalog->db_driver, catalog->db_name,
1156 catalog->db_password, catalog->db_address,
1157 catalog->db_port, catalog->db_socket,
1158 catalog->db_ssl_mode, catalog->db_ssl_key,
1159 catalog->db_ssl_cert, catalog->db_ssl_ca,
1160 catalog->db_ssl_capath, catalog->db_ssl_cipher,
1161 catalog->mult_db_connections,
1162 catalog->disable_batch_insert);
1163 if (!db || !db_open_database(NULL, db)) {
1164 Pmsg2(000, _("Could not open Catalog \"%s\", database \"%s\".\n"),
1165 catalog->name(), catalog->db_name);
1166 Jmsg(NULL, M_FATAL, 0, _("Could not open Catalog \"%s\", database \"%s\".\n"),
1167 catalog->name(), catalog->db_name);
1169 Jmsg(NULL, M_FATAL, 0, _("%s"), db_strerror(db));
1170 Pmsg1(000, "%s", db_strerror(db));
1171 db_close_database(NULL, db);
1177 /* Display a message if the db max_connections is too low */
1178 if (!db_check_max_connections(NULL, db, director->MaxConcurrentJobs)) {
1179 Pmsg1(000, "Warning, settings problem for Catalog=%s\n", catalog->name());
1180 Pmsg1(000, "%s", db_strerror(db));
1183 /* we are in testing mode, so don't touch anything in the catalog */
1184 if (mode == CHECK_CONNECTION) {
1185 if (db) db_close_database(NULL, db);
1189 /* Loop over all pools, defining/updating them in each database */
1191 foreach_res(pool, R_POOL) {
1193 * If the Pool has a catalog resource create the pool only
1196 if (!pool->catalog || pool->catalog == catalog) {
1197 create_pool(NULL, db, pool, POOL_OP_UPDATE); /* update request */
1201 /* Once they are created, we can loop over them again, updating
1202 * references (RecyclePool)
1204 foreach_res(pool, R_POOL) {
1206 * If the Pool has a catalog resource update the pool only
1209 if (!pool->catalog || pool->catalog == catalog) {
1210 update_pool_references(NULL, db, pool);
1214 /* Ensure basic client record is in DB */
1216 foreach_res(client, R_CLIENT) {
1218 /* Create clients only if they use the current catalog */
1219 if (client->catalog != catalog) {
1220 Dmsg3(500, "Skip client=%s with cat=%s not catalog=%s\n",
1221 client->name(), client->catalog->name(), catalog->name());
1224 Dmsg2(500, "create cat=%s for client=%s\n",
1225 client->catalog->name(), client->name());
1226 memset(&cr, 0, sizeof(cr));
1227 bstrncpy(cr.Name, client->name(), sizeof(cr.Name));
1229 db_create_client_record(NULL, db, &cr);
1232 /* Ensure basic storage record is in DB */
1233 foreach_res(store, R_STORAGE) {
1236 memset(&sr, 0, sizeof(sr));
1237 memset(&mtr, 0, sizeof(mtr));
1238 if (store->media_type) {
1239 bstrncpy(mtr.MediaType, store->media_type, sizeof(mtr.MediaType));
1241 db_create_mediatype_record(NULL, db, &mtr);
1243 mtr.MediaTypeId = 0;
1245 bstrncpy(sr.Name, store->name(), sizeof(sr.Name));
1246 sr.AutoChanger = store->autochanger;
1247 if (!db_create_storage_record(NULL, db, &sr)) {
1248 Jmsg(NULL, M_FATAL, 0, _("Could not create storage record for %s\n"),
1252 store->StorageId = sr.StorageId; /* set storage Id */
1253 if (!sr.created) { /* if not created, update it */
1254 sr.AutoChanger = store->autochanger;
1255 if (!db_update_storage_record(NULL, db, &sr)) {
1256 Jmsg(NULL, M_FATAL, 0, _("Could not update storage record for %s\n"),
1262 /* tls_require implies tls_enable */
1263 if (store->tls_require) {
1265 store->tls_enable = true;
1267 Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
1272 need_tls = store->tls_enable || store->tls_authenticate;
1274 if ((!store->tls_ca_certfile && !store->tls_ca_certdir) && need_tls) {
1275 Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\""
1276 " or \"TLS CA Certificate Dir\" are defined for Storage \"%s\" in %s.\n"),
1277 store->name(), configfile);
1281 /* If everything is well, attempt to initialize our per-resource TLS context */
1282 if (OK && (need_tls || store->tls_require)) {
1283 /* Initialize TLS context:
1284 * Args: CA certfile, CA certdir, Certfile, Keyfile,
1285 * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
1286 store->tls_ctx = new_tls_context(store->tls_ca_certfile,
1287 store->tls_ca_certdir, store->tls_certfile,
1288 store->tls_keyfile, NULL, NULL, NULL, true);
1290 if (!store->tls_ctx) {
1291 Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for Storage \"%s\" in %s.\n"),
1292 store->name(), configfile);
1298 /* Link up all the children for each changer */
1299 foreach_res(store, R_STORAGE) {
1301 if (store->changer == store) { /* we are a real Autochanger */
1302 store->ac_group = get_pool_memory(PM_FNAME);
1303 store->ac_group[0] = 0;
1304 pm_strcat(store->ac_group, edit_int64(store->StorageId, sid));
1305 /* Now look for children who point to this storage */
1306 foreach_res(ac_child, R_STORAGE) {
1307 if (ac_child != store && ac_child->changer == store) {
1308 /* Found a child -- add StorageId */
1309 pm_strcat(store->ac_group, ",");
1310 pm_strcat(store->ac_group, edit_int64(ac_child->StorageId, sid));
1316 /* Link up all the shared storage devices */
1317 foreach_res(store, R_STORAGE) {
1318 if (store->ac_group) { /* we are a real Autochanger */
1319 /* Now look for Shared Storage who point to this storage */
1320 foreach_res(ac_child, R_STORAGE) {
1321 if (ac_child->shared_storage == store && ac_child->ac_group &&
1322 ac_child->shared_storage != ac_child) {
1323 pm_strcat(store->ac_group, ",");
1324 pm_strcat(store->ac_group, ac_child->ac_group);
1330 /* Loop over all counters, defining them in each database */
1331 /* Set default value in all counters */
1333 foreach_res(counter, R_COUNTER) {
1334 /* Write to catalog? */
1335 if (!counter->created && counter->Catalog == catalog) {
1337 bstrncpy(cr.Counter, counter->name(), sizeof(cr.Counter));
1338 cr.MinValue = counter->MinValue;
1339 cr.MaxValue = counter->MaxValue;
1340 cr.CurrentValue = counter->MinValue;
1341 if (counter->WrapCounter) {
1342 bstrncpy(cr.WrapCounter, counter->WrapCounter->name(), sizeof(cr.WrapCounter));
1344 cr.WrapCounter[0] = 0; /* empty string */
1346 if (db_create_counter_record(NULL, db, &cr)) {
1347 counter->CurrentValue = cr.CurrentValue;
1348 counter->created = true;
1349 Dmsg2(100, "Create counter %s val=%d\n", counter->name(), counter->CurrentValue);
1352 if (!counter->created) {
1353 counter->CurrentValue = counter->MinValue; /* default value */
1356 /* cleanup old job records */
1357 if (mode == UPDATE_AND_FIX) {
1358 db_sql_query(db, cleanup_created_job, NULL, NULL);
1359 db_sql_query(db, cleanup_running_job, NULL, NULL);
1362 /* Set SQL engine name in global for debugging */
1363 set_db_engine_name(db_get_engine_name(db));
1364 if (db) db_close_database(NULL, db);
1369 static void cleanup_old_files()
1372 struct dirent *entry, *result;
1374 int my_name_len = strlen(my_name);
1375 int len = strlen(director->working_directory);
1376 POOLMEM *cleanup = get_pool_memory(PM_MESSAGE);
1377 POOLMEM *basename = get_pool_memory(PM_MESSAGE);
1380 const int nmatch = 30;
1381 regmatch_t pmatch[nmatch];
1384 /* Exclude spaces and look for .mail, .tmp or .restore.xx.bsr files */
1385 const char *pat1 = "^[^ ]+\\.(restore\\.[^ ]+\\.bsr|mail|tmp)$";
1387 /* Setup working directory prefix */
1388 pm_strcpy(basename, director->working_directory);
1389 if (len > 0 && !IsPathSeparator(director->working_directory[len-1])) {
1390 pm_strcat(basename, "/");
1393 /* Compile regex expressions */
1394 rc = regcomp(&preg1, pat1, REG_EXTENDED);
1396 regerror(rc, &preg1, prbuf, sizeof(prbuf));
1397 Pmsg2(000, _("Could not compile regex pattern \"%s\" ERR=%s\n"),
1402 name_max = pathconf(".", _PC_NAME_MAX);
1403 if (name_max < 1024) {
1407 if (!(dp = opendir(director->working_directory))) {
1409 Pmsg2(000, "Failed to open working dir %s for cleanup: ERR=%s\n",
1410 director->working_directory, be.bstrerror());
1415 entry = (struct dirent *)malloc(sizeof(struct dirent) + name_max + 1000);
1417 if ((readdir_r(dp, entry, &result) != 0) || (result == NULL)) {
1420 /* Exclude any name with ., .., not my_name or containing a space */
1421 if (strcmp(result->d_name, ".") == 0 || strcmp(result->d_name, "..") == 0 ||
1422 strncmp(result->d_name, my_name, my_name_len) != 0) {
1423 Dmsg1(500, "Skipped: %s\n", result->d_name);
1427 /* Unlink files that match regexes */
1428 if (regexec(&preg1, result->d_name, nmatch, pmatch, 0) == 0) {
1429 pm_strcpy(cleanup, basename);
1430 pm_strcat(cleanup, result->d_name);
1431 Dmsg1(100, "Unlink: %s\n", cleanup);
1438 /* Be careful to free up the correct resources */
1442 free_pool_memory(cleanup);
1443 free_pool_memory(basename);