2 Bacula(R) - The Network Backup Solution
4 Copyright (C) 2000-2015 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.
21 * Bacula Director daemon -- this is the main program
23 * Kern Sibbald, March MM
30 #include "lib/bregex.h"
36 #define NAMELEN(dirent) (strlen((dirent)->d_name))
38 #ifndef HAVE_READDIR_R
39 int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result);
42 /* Forward referenced subroutines */
43 void terminate_dird(int sig);
44 static bool check_resources();
45 static void cleanup_old_files();
47 /* Exported subroutines */
48 extern "C" void reload_config(int sig);
49 extern void invalidate_schedules();
50 extern bool parse_dir_config(CONFIG *config, const char *configfile, int exit_code);
52 /* Imported subroutines */
53 JCR *wait_for_next_job(char *runjob);
54 void term_scheduler();
55 void term_ua_server();
56 void start_UA_server(dlist *addrs);
57 void init_job_server(int max_workers);
58 void term_job_server();
59 void store_jobtype(LEX *lc, RES_ITEM *item, int index, int pass);
60 void store_level(LEX *lc, RES_ITEM *item, int index, int pass);
61 void store_replace(LEX *lc, RES_ITEM *item, int index, int pass);
62 void store_migtype(LEX *lc, RES_ITEM *item, int index, int pass);
63 void init_device_resources();
66 static char *runjob = NULL;
67 static bool background = true;
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;
80 /* Globals Imported */
81 extern RES_ITEM job_items[];
83 extern "C" { // work around visual compiler mangling variables
91 CHECK_CONNECTION, /* Check catalog connection */
92 UPDATE_CATALOG, /* Ensure that catalog is ok with conf */
93 UPDATE_AND_FIX /* Ensure that catalog is ok, and fix old jobs */
95 static bool check_catalog(cat_op mode);
97 #define CONFIG_FILE "bacula-dir.conf" /* default configuration file */
99 static bool dir_sql_query(JCR *jcr, const char *cmd)
101 if (jcr && jcr->db && jcr->db->is_connected()) {
102 return db_sql_query(jcr->db, cmd, NULL, NULL);
107 static bool dir_sql_escape(JCR *jcr, BDB *mdb, char *snew, char *sold, int len)
109 if (jcr && jcr->db && jcr->db->is_connected()) {
110 db_escape_string(jcr, mdb, snew, sold, len);
120 "\nVersion: %s (%s)\n\n"
121 "Usage: bacula-dir [-f -s] [-c config_file] [-d debug_level] [config_file]\n"
122 " -c <file> set configuration file to file\n"
123 " -d <nn>[,<tags>] set debug level to <nn>, debug tags to <tags>\n"
124 " -dt print timestamp in debug output\n"
126 " -f run in foreground (for debugging)\n"
128 " -m print kaboom output (for debugging)\n"
129 " -r <job> run <job> now\n"
131 " -t test - read configuration and exit\n"
133 " -v verbose user messages\n"
134 " -? print this message.\n"
135 "\n"), 2000, VERSION, BDATE);
141 * !!! WARNING !!! Use this function only when bacula is stopped.
142 * ie, after a fatal signal and before exiting the program
143 * Print information about a JCR
145 static void dir_debug_print(JCR *jcr, FILE *fp)
147 fprintf(fp, "\twstore=%p rstore=%p wjcr=%p client=%p reschedule_count=%d SD_msg_chan_started=%d\n",
148 jcr->wstore, jcr->rstore, jcr->wjcr, jcr->client, jcr->reschedule_count, (int)jcr->SD_msg_chan_started);
151 /*********************************************************************
153 * Main Bacula Director Server program
156 #if defined(HAVE_WIN32)
157 /* For Win32 main() is in src/win32 code ... */
158 #define main BaculaMain
161 int main (int argc, char *argv[])
165 bool no_signals = false;
169 start_heap = sbrk(0);
170 setlocale(LC_ALL, "");
171 bindtextdomain("bacula", LOCALEDIR);
172 textdomain("bacula");
175 my_name_is(argc, argv, "bacula-dir");
176 init_msg(NULL, NULL); /* initialize message handler */
178 daemon_start_time = time(NULL);
180 console_command = run_console_command;
182 while ((ch = getopt(argc, argv, "c:d:fg:mr:stu:v?T")) != -1) {
184 case 'c': /* specify config file */
185 if (configfile != NULL) {
188 configfile = bstrdup(optarg);
191 case 'd': /* set debug level */
192 if (*optarg == 't') {
193 dbg_timestamp = true;
196 /* We probably find a tag list -d 10,sql,bvfs */
197 if ((p = strchr(optarg, ',')) != NULL) {
200 debug_level = atoi(optarg);
201 if (debug_level <= 0) {
205 debug_parse_tags(p+1, &debug_level_tags);
208 Dmsg1(10, "Debug level = %lld\n", debug_level);
215 case 'f': /* run in foreground */
219 case 'g': /* set group id */
223 case 'm': /* print kaboom output */
227 case 'r': /* run job */
228 if (runjob != NULL) {
232 runjob = bstrdup(optarg);
236 case 's': /* turn off signals */
240 case 't': /* test config */
244 case 'u': /* set uid */
248 case 'v': /* verbose */
262 init_signals(terminate_dird);
266 if (configfile != NULL) {
269 configfile = bstrdup(*argv);
277 if (!test_config) { /* we don't need to do this block in test mode */
280 init_stack_dump(); /* grab new pid */
284 if (configfile == NULL) {
285 configfile = bstrdup(CONFIG_FILE);
288 config = new_config_parser();
290 parse_dir_config(config, configfile, M_ERROR_TERM);
292 if (init_crypto() != 0) {
293 Jmsg((JCR *)NULL, M_ERROR_TERM, 0, _("Cryptography library initialization failed.\n"));
296 if (!check_resources()) {
297 Jmsg((JCR *)NULL, M_ERROR_TERM, 0, _("Please correct configuration file: %s\n"), configfile);
301 /* Create pid must come after we are a daemon -- so we have our final pid */
302 create_pid_file(director->pid_directory, "bacula-dir",
303 get_first_port_host_order(director->DIRaddrs));
304 read_state_file(director->working_directory, "bacula-dir",
305 get_first_port_host_order(director->DIRaddrs));
308 set_jcr_in_tsd(INVALID_JCR);
309 set_thread_concurrency(director->MaxConcurrentJobs * 2 +
310 4 /* UA */ + 5 /* sched+watchdog+jobsvr+misc */);
311 lmgr_init_thread(); /* initialize the lockmanager stack */
313 load_dir_plugins(director->plugin_directory);
315 drop(uid, gid, false); /* reduce privileges if requested */
317 /* If we are in testing mode, we don't try to fix the catalog */
318 cat_op mode=(test_config)?CHECK_CONNECTION:UPDATE_AND_FIX;
320 if (!check_catalog(mode)) {
321 Jmsg((JCR *)NULL, M_ERROR_TERM, 0, _("Please correct configuration file: %s\n"), configfile);
328 my_name_is(0, NULL, director->name()); /* set user defined name */
332 /* Plug database interface for library routines */
333 p_sql_query = (sql_query_call)dir_sql_query;
334 p_sql_escape = (sql_escape_call)dir_sql_escape;
336 FDConnectTimeout = (int)director->FDConnectTimeout;
337 SDConnectTimeout = (int)director->SDConnectTimeout;
339 #if !defined(HAVE_WIN32)
340 signal(SIGHUP, reload_config);
343 init_console_msg(working_directory);
345 Dmsg0(200, "Start UA server\n");
346 start_UA_server(director->DIRaddrs);
348 start_watchdog(); /* start network watchdog thread */
350 init_jcr_subsystem(); /* start JCR watchdogs etc. */
352 init_job_server(director->MaxConcurrentJobs);
354 dbg_jcr_add_hook(dir_debug_print); /* used to director variables */
355 dbg_jcr_add_hook(bdb_debug_print); /* used to debug B_DB connexion after fatal signal */
357 // init_device_resources();
359 Dmsg0(200, "wait for next job\n");
360 /* Main loop -- call scheduler to get next job to run */
361 while ( (jcr = wait_for_next_job(runjob)) ) {
362 run_job(jcr); /* run job */
363 free_jcr(jcr); /* release jcr */
364 set_jcr_in_tsd(INVALID_JCR);
365 if (runjob) { /* command line, run a single job? */
366 break; /* yes, terminate */
375 struct RELOAD_TABLE {
380 static const int max_reloads = 50;
381 static RELOAD_TABLE reload_table[max_reloads];
383 static void init_reload(void)
385 for (int i=0; i < max_reloads; i++) {
386 reload_table[i].job_count = 0;
387 reload_table[i].res_table = NULL;
392 * This subroutine frees a saved resource table.
393 * It was saved when a new table was created with "reload"
395 static void free_saved_resources(int table)
397 int num = r_last - r_first + 1;
398 RES **res_tab = reload_table[table].res_table;
400 Dmsg1(100, "res_tab for table %d already released.\n", table);
403 Dmsg1(100, "Freeing resources for table %d\n", table);
404 for (int j=0; j<num; j++) {
405 free_resource(res_tab[j], r_first + j);
408 reload_table[table].job_count = 0;
409 reload_table[table].res_table = NULL;
413 * Called here at the end of every job that was
414 * hooked decrementing the active job_count. When
415 * it goes to zero, no one is using the associated
416 * resource table, so free it.
418 static void reload_job_end_cb(JCR *jcr, void *ctx)
420 int reload_id = (int)((intptr_t)ctx);
421 Dmsg3(100, "reload job_end JobId=%d table=%d cnt=%d\n", jcr->JobId,
422 reload_id, reload_table[reload_id].job_count);
425 if (--reload_table[reload_id].job_count <= 0) {
426 free_saved_resources(reload_id);
432 static int find_free_reload_table_entry()
435 for (int i=0; i < max_reloads; i++) {
436 if (reload_table[i].res_table == NULL) {
445 * If we get here, we have received a SIGHUP, which means to
446 * reread our configuration file.
448 * The algorithm used is as follows: we count how many jobs are
449 * running and mark the running jobs to make a callback on
450 * exiting. The old config is saved with the reload table
451 * id in a reload table. The new config file is read. Now, as
452 * each job exits, it calls back to the reload_job_end_cb(), which
453 * decrements the count of open jobs for the given reload table.
454 * When the count goes to zero, we release those resources.
455 * This allows us to have pointers into the resource table (from
456 * jobs), and once they exit and all the pointers are released, we
457 * release the old table. Note, if no new jobs are running since the
458 * last reload, then the old resources will be immediately release.
459 * A console is considered a job because it may have pointers to
460 * resources, but a SYSTEM job is not since it *should* not have any
461 * permanent pointers to jobs.
464 void reload_config(int sig)
466 static bool already_here = false;
467 #if !defined(HAVE_WIN32)
471 int njobs = 0; /* number of running jobs */
476 abort(); /* Oops, recursion -> die */
480 #if !defined(HAVE_WIN32)
482 sigaddset(&set, SIGHUP);
483 sigprocmask(SIG_BLOCK, &set, NULL);
489 table = find_free_reload_table_entry();
491 Jmsg(NULL, M_ERROR, 0, _("Too many open reload requests. Request ignored.\n"));
495 Dmsg1(100, "Reload_config njobs=%d\n", njobs);
496 reload_table[table].res_table = config->save_resources();
497 Dmsg1(100, "Saved old config in table %d\n", table);
499 ok = parse_dir_config(config, configfile, M_ERROR);
501 Dmsg0(100, "Reloaded config file\n");
502 if (!ok || !check_resources() || !check_catalog(UPDATE_CATALOG)) {
503 rtable = find_free_reload_table_entry(); /* save new, bad table */
505 Jmsg(NULL, M_ERROR, 0, _("Please correct configuration file: %s\n"), configfile);
506 Jmsg(NULL, M_ERROR_TERM, 0, _("Out of reload table entries. Giving up.\n"));
508 Jmsg(NULL, M_ERROR, 0, _("Please correct configuration file: %s\n"), configfile);
509 Jmsg(NULL, M_ERROR, 0, _("Resetting previous configuration.\n"));
511 reload_table[rtable].res_table = config->save_resources();
512 /* Now restore old resource values */
513 int num = r_last - r_first + 1;
514 RES **res_tab = reload_table[table].res_table;
515 for (int i=0; i<num; i++) {
516 res_head[i] = res_tab[i];
518 table = rtable; /* release new, bad, saved table below */
520 invalidate_schedules();
522 * Hook all active jobs so that they release this table
525 if (jcr->getJobType() != JT_SYSTEM) {
526 reload_table[table].job_count++;
527 job_end_push(jcr, reload_job_end_cb, (void *)((long int)table));
535 set_working_directory(director->working_directory);
536 FDConnectTimeout = director->FDConnectTimeout;
537 SDConnectTimeout = director->SDConnectTimeout;
538 Dmsg0(10, "Director's configuration file reread.\n");
540 /* Now release saved resources, if no jobs using the resources */
542 free_saved_resources(table);
548 #if !defined(HAVE_WIN32)
549 sigprocmask(SIG_UNBLOCK, &set, NULL);
550 signal(SIGHUP, reload_config);
552 already_here = false;
555 /* Cleanup and then exit */
556 void terminate_dird(int sig)
558 static bool already_here = false;
560 if (already_here) { /* avoid recursive temination problems */
561 bmicrosleep(2, 0); /* yield */
565 debug_level = 0; /* turn off debug */
567 generate_daemon_event(NULL, "Exit");
570 write_state_file(director->working_directory, "bacula-dir", get_first_port_host_order(director->DIRaddrs));
571 delete_pid_file(director->pid_directory, "bacula-dir", get_first_port_host_order(director->DIRaddrs));
578 if (configfile != NULL) {
582 print_memory_pool_stats();
585 config->free_resources();
590 term_msg(); /* terminate message handler */
592 close_memory_pool(); /* release free memory in pool */
599 * Make a quick check to see that we have all the
602 * **** FIXME **** this routine could be a lot more
603 * intelligent and comprehensive.
605 static bool check_resources()
613 job = (JOB *)GetNextRes(R_JOB, NULL);
614 director = (DIRRES *)GetNextRes(R_DIRECTOR, NULL);
616 Jmsg(NULL, M_FATAL, 0, _("No Director resource defined in %s\n"
617 "Without that I don't know who I am :-(\n"), configfile);
620 set_working_directory(director->working_directory);
621 if (!director->messages) { /* If message resource not specified */
622 director->messages = (MSGS *)GetNextRes(R_MSGS, NULL);
623 if (!director->messages) {
624 Jmsg(NULL, M_FATAL, 0, _("No Messages resource defined in %s\n"), configfile);
628 if (GetNextRes(R_DIRECTOR, (RES *)director) != NULL) {
629 Jmsg(NULL, M_FATAL, 0, _("Only one Director resource permitted in %s\n"),
633 /* tls_require implies tls_enable */
634 if (director->tls_require) {
636 director->tls_enable = true;
638 Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
643 need_tls = director->tls_enable || director->tls_authenticate;
645 if (!director->tls_certfile && need_tls) {
646 Jmsg(NULL, M_FATAL, 0, _("\"TLS Certificate\" file not defined for Director \"%s\" in %s.\n"),
647 director->name(), configfile);
651 if (!director->tls_keyfile && need_tls) {
652 Jmsg(NULL, M_FATAL, 0, _("\"TLS Key\" file not defined for Director \"%s\" in %s.\n"),
653 director->name(), configfile);
657 if ((!director->tls_ca_certfile && !director->tls_ca_certdir) &&
658 need_tls && director->tls_verify_peer) {
659 Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\" or \"TLS CA"
660 " Certificate Dir\" are defined for Director \"%s\" in %s."
661 " At least one CA certificate store is required"
662 " when using \"TLS Verify Peer\".\n"),
663 director->name(), configfile);
667 /* If everything is well, attempt to initialize our per-resource TLS context */
668 if (OK && (need_tls || director->tls_require)) {
669 /* Initialize TLS context:
670 * Args: CA certfile, CA certdir, Certfile, Keyfile,
671 * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
672 director->tls_ctx = new_tls_context(director->tls_ca_certfile,
673 director->tls_ca_certdir, director->tls_certfile,
674 director->tls_keyfile, NULL, NULL, director->tls_dhfile,
675 director->tls_verify_peer);
677 if (!director->tls_ctx) {
678 Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for Director \"%s\" in %s.\n"),
679 director->name(), configfile);
686 Jmsg(NULL, M_FATAL, 0, _("No Job records defined in %s\n"), configfile);
689 foreach_res(job, R_JOB) {
693 /* Handle Storage alists specifically */
694 JOB *jobdefs = job->jobdefs;
695 if (jobdefs->storage && !job->storage) {
697 job->storage = New(alist(10, not_owned_by_alist));
698 foreach_alist(st, jobdefs->storage) {
699 job->storage->append(st);
702 /* Handle RunScripts alists specifically */
703 if (jobdefs->RunScripts) {
706 if (!job->RunScripts) {
707 job->RunScripts = New(alist(10, not_owned_by_alist));
710 foreach_alist(rs, jobdefs->RunScripts) {
711 elt = copy_runscript(rs);
712 job->RunScripts->append(elt); /* we have to free it */
716 /* Transfer default items from JobDefs Resource */
717 for (i=0; job_items[i].name; i++) {
718 char **def_svalue, **svalue; /* string value */
719 uint32_t *def_ivalue, *ivalue; /* integer value */
720 bool *def_bvalue, *bvalue; /* bool value */
721 int64_t *def_lvalue, *lvalue; /* 64 bit values */
724 Dmsg4(1400, "Job \"%s\", field \"%s\" bit=%d def=%d\n",
725 job->name(), job_items[i].name,
726 bit_is_set(i, job->hdr.item_present),
727 bit_is_set(i, job->jobdefs->hdr.item_present));
729 if (!bit_is_set(i, job->hdr.item_present) &&
730 bit_is_set(i, job->jobdefs->hdr.item_present)) {
731 Dmsg2(400, "Job \"%s\", field \"%s\": getting default.\n",
732 job->name(), job_items[i].name);
733 offset = (char *)(job_items[i].value) - (char *)&res_all;
735 * Handle strings and directory strings
737 if (job_items[i].handler == store_str ||
738 job_items[i].handler == store_dir) {
739 def_svalue = (char **)((char *)(job->jobdefs) + offset);
740 Dmsg5(400, "Job \"%s\", field \"%s\" def_svalue=%s item %d offset=%u\n",
741 job->name(), job_items[i].name, *def_svalue, i, offset);
742 svalue = (char **)((char *)job + offset);
744 Pmsg1(000, _("Hey something is wrong. p=0x%lu\n"), *svalue);
746 *svalue = bstrdup(*def_svalue);
747 set_bit(i, job->hdr.item_present);
751 } else if (job_items[i].handler == store_res) {
752 def_svalue = (char **)((char *)(job->jobdefs) + offset);
753 Dmsg4(400, "Job \"%s\", field \"%s\" item %d offset=%u\n",
754 job->name(), job_items[i].name, i, offset);
755 svalue = (char **)((char *)job + offset);
757 Pmsg1(000, _("Hey something is wrong. p=0x%lu\n"), *svalue);
759 *svalue = *def_svalue;
760 set_bit(i, job->hdr.item_present);
762 * Handle alist resources
764 } else if (job_items[i].handler == store_alist_res) {
765 if (bit_is_set(i, job->jobdefs->hdr.item_present)) {
766 set_bit(i, job->hdr.item_present);
769 * Handle integer fields
770 * Note, our store_bit does not handle bitmaped fields
772 } else if (job_items[i].handler == store_bit ||
773 job_items[i].handler == store_pint32 ||
774 job_items[i].handler == store_jobtype ||
775 job_items[i].handler == store_level ||
776 job_items[i].handler == store_int32 ||
777 job_items[i].handler == store_size32 ||
778 job_items[i].handler == store_migtype ||
779 job_items[i].handler == store_replace) {
780 def_ivalue = (uint32_t *)((char *)(job->jobdefs) + offset);
781 Dmsg5(400, "Job \"%s\", field \"%s\" def_ivalue=%d item %d offset=%u\n",
782 job->name(), job_items[i].name, *def_ivalue, i, offset);
783 ivalue = (uint32_t *)((char *)job + offset);
784 *ivalue = *def_ivalue;
785 set_bit(i, job->hdr.item_present);
787 * Handle 64 bit integer fields
789 } else if (job_items[i].handler == store_time ||
790 job_items[i].handler == store_size64 ||
791 job_items[i].handler == store_speed ||
792 job_items[i].handler == store_int64) {
793 def_lvalue = (int64_t *)((char *)(job->jobdefs) + offset);
794 Dmsg5(400, "Job \"%s\", field \"%s\" def_lvalue=%" lld " item %d offset=%u\n",
795 job->name(), job_items[i].name, *def_lvalue, i, offset);
796 lvalue = (int64_t *)((char *)job + offset);
797 *lvalue = *def_lvalue;
798 set_bit(i, job->hdr.item_present);
802 } else if (job_items[i].handler == store_bool) {
803 def_bvalue = (bool *)((char *)(job->jobdefs) + offset);
804 Dmsg5(400, "Job \"%s\", field \"%s\" def_bvalue=%d item %d offset=%u\n",
805 job->name(), job_items[i].name, *def_bvalue, i, offset);
806 bvalue = (bool *)((char *)job + offset);
807 *bvalue = *def_bvalue;
808 set_bit(i, job->hdr.item_present);
814 * Ensure that all required items are present
816 for (i=0; job_items[i].name; i++) {
817 if (job_items[i].flags & ITEM_REQUIRED) {
818 if (!bit_is_set(i, job->hdr.item_present)) {
819 Jmsg(NULL, M_ERROR_TERM, 0, _("\"%s\" directive in Job \"%s\" resource is required, but not found.\n"),
820 job_items[i].name, job->name());
824 /* If this triggers, take a look at lib/parse_conf.h */
825 if (i >= MAX_RES_ITEMS) {
826 Emsg0(M_ERROR_TERM, 0, _("Too many items in Job resource\n"));
829 if (!job->storage && !job->pool->storage) {
830 Jmsg(NULL, M_FATAL, 0, _("No storage specified in Job \"%s\" nor in Pool.\n"),
834 } /* End loop over Job res */
837 /* Loop over Consoles */
839 foreach_res(cons, R_CONSOLE) {
840 /* tls_require implies tls_enable */
841 if (cons->tls_require) {
843 cons->tls_enable = true;
845 Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
851 need_tls = cons->tls_enable || cons->tls_authenticate;
853 if (!cons->tls_certfile && need_tls) {
854 Jmsg(NULL, M_FATAL, 0, _("\"TLS Certificate\" file not defined for Console \"%s\" in %s.\n"),
855 cons->name(), configfile);
859 if (!cons->tls_keyfile && need_tls) {
860 Jmsg(NULL, M_FATAL, 0, _("\"TLS Key\" file not defined for Console \"%s\" in %s.\n"),
861 cons->name(), configfile);
865 if ((!cons->tls_ca_certfile && !cons->tls_ca_certdir)
866 && need_tls && cons->tls_verify_peer) {
867 Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\" or \"TLS CA"
868 " Certificate Dir\" are defined for Console \"%s\" in %s."
869 " At least one CA certificate store is required"
870 " when using \"TLS Verify Peer\".\n"),
871 cons->name(), configfile);
874 /* If everything is well, attempt to initialize our per-resource TLS context */
875 if (OK && (need_tls || cons->tls_require)) {
876 /* Initialize TLS context:
877 * Args: CA certfile, CA certdir, Certfile, Keyfile,
878 * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
879 cons->tls_ctx = new_tls_context(cons->tls_ca_certfile,
880 cons->tls_ca_certdir, cons->tls_certfile,
881 cons->tls_keyfile, NULL, NULL, cons->tls_dhfile, cons->tls_verify_peer);
883 if (!cons->tls_ctx) {
884 Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for File daemon \"%s\" in %s.\n"),
885 cons->name(), configfile);
892 /* Loop over Clients */
894 foreach_res(client, R_CLIENT) {
895 /* tls_require implies tls_enable */
896 if (client->tls_require) {
898 client->tls_enable = true;
900 Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
905 need_tls = client->tls_enable || client->tls_authenticate;
906 if ((!client->tls_ca_certfile && !client->tls_ca_certdir) && need_tls) {
907 Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\""
908 " or \"TLS CA Certificate Dir\" are defined for File daemon \"%s\" in %s.\n"),
909 client->name(), configfile);
913 /* If everything is well, attempt to initialize our per-resource TLS context */
914 if (OK && (need_tls || client->tls_require)) {
915 /* Initialize TLS context:
916 * Args: CA certfile, CA certdir, Certfile, Keyfile,
917 * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
918 client->tls_ctx = new_tls_context(client->tls_ca_certfile,
919 client->tls_ca_certdir, client->tls_certfile,
920 client->tls_keyfile, NULL, NULL, NULL,
923 if (!client->tls_ctx) {
924 Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for File daemon \"%s\" in %s.\n"),
925 client->name(), configfile);
933 close_msg(NULL); /* close temp message handler */
934 init_msg(NULL, director->messages); /* open daemon message handler */
935 last_reload_time = time(NULL);
942 * - we can check the connection (mode=CHECK_CONNECTION)
943 * - we can synchronize the catalog with the configuration (mode=UPDATE_CATALOG)
944 * - we can synchronize, and fix old job records (mode=UPDATE_AND_FIX)
946 static bool check_catalog(cat_op mode)
951 /* Loop over databases */
953 foreach_res(catalog, R_CATALOG) {
956 * Make sure we can open catalog, otherwise print a warning
957 * message because the server is probably not running.
959 db = db_init_database(NULL, catalog->db_driver, catalog->db_name,
961 catalog->db_password, catalog->db_address,
962 catalog->db_port, catalog->db_socket,
963 catalog->db_ssl_key, catalog->db_ssl_cert, catalog->db_ssl_ca,
964 catalog->db_ssl_capath, catalog->db_ssl_cipher,
965 catalog->mult_db_connections,
966 catalog->disable_batch_insert);
967 if (!db || !db_open_database(NULL, db)) {
968 Pmsg2(000, _("Could not open Catalog \"%s\", database \"%s\".\n"),
969 catalog->name(), catalog->db_name);
970 Jmsg(NULL, M_FATAL, 0, _("Could not open Catalog \"%s\", database \"%s\".\n"),
971 catalog->name(), catalog->db_name);
973 Jmsg(NULL, M_FATAL, 0, _("%s"), db_strerror(db));
974 Pmsg1(000, "%s", db_strerror(db));
975 db_close_database(NULL, db);
981 /* Display a message if the db max_connections is too low */
982 if (!db_check_max_connections(NULL, db, director->MaxConcurrentJobs)) {
983 Pmsg1(000, "Warning, settings problem for Catalog=%s\n", catalog->name());
984 Pmsg1(000, "%s", db_strerror(db));
987 /* we are in testing mode, so don't touch anything in the catalog */
988 if (mode == CHECK_CONNECTION) {
989 if (db) db_close_database(NULL, db);
993 /* Loop over all pools, defining/updating them in each database */
995 foreach_res(pool, R_POOL) {
997 * If the Pool has a catalog resource create the pool only
1000 if (!pool->catalog || pool->catalog == catalog) {
1001 create_pool(NULL, db, pool, POOL_OP_UPDATE); /* update request */
1005 /* Once they are created, we can loop over them again, updating
1006 * references (RecyclePool)
1008 foreach_res(pool, R_POOL) {
1010 * If the Pool has a catalog resource update the pool only
1013 if (!pool->catalog || pool->catalog == catalog) {
1014 update_pool_references(NULL, db, pool);
1018 /* Ensure basic client record is in DB */
1020 foreach_res(client, R_CLIENT) {
1022 /* Create clients only if they use the current catalog */
1023 if (client->catalog != catalog) {
1024 Dmsg3(500, "Skip client=%s with cat=%s not catalog=%s\n",
1025 client->name(), client->catalog->name(), catalog->name());
1028 Dmsg2(500, "create cat=%s for client=%s\n",
1029 client->catalog->name(), client->name());
1030 memset(&cr, 0, sizeof(cr));
1031 bstrncpy(cr.Name, client->name(), sizeof(cr.Name));
1033 db_create_client_record(NULL, db, &cr);
1036 /* Ensure basic storage record is in DB */
1038 foreach_res(store, R_STORAGE) {
1041 memset(&sr, 0, sizeof(sr));
1042 memset(&mtr, 0, sizeof(mtr));
1043 if (store->media_type) {
1044 bstrncpy(mtr.MediaType, store->media_type, sizeof(mtr.MediaType));
1046 db_create_mediatype_record(NULL, db, &mtr);
1048 mtr.MediaTypeId = 0;
1050 bstrncpy(sr.Name, store->name(), sizeof(sr.Name));
1051 sr.AutoChanger = store->autochanger;
1052 if (!db_create_storage_record(NULL, db, &sr)) {
1053 Jmsg(NULL, M_FATAL, 0, _("Could not create storage record for %s\n"),
1057 store->StorageId = sr.StorageId; /* set storage Id */
1058 if (!sr.created) { /* if not created, update it */
1059 sr.AutoChanger = store->autochanger;
1060 if (!db_update_storage_record(NULL, db, &sr)) {
1061 Jmsg(NULL, M_FATAL, 0, _("Could not update storage record for %s\n"),
1067 /* tls_require implies tls_enable */
1068 if (store->tls_require) {
1070 store->tls_enable = true;
1072 Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
1077 need_tls = store->tls_enable || store->tls_authenticate;
1079 if ((!store->tls_ca_certfile && !store->tls_ca_certdir) && need_tls) {
1080 Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\""
1081 " or \"TLS CA Certificate Dir\" are defined for Storage \"%s\" in %s.\n"),
1082 store->name(), configfile);
1086 /* If everything is well, attempt to initialize our per-resource TLS context */
1087 if (OK && (need_tls || store->tls_require)) {
1088 /* Initialize TLS context:
1089 * Args: CA certfile, CA certdir, Certfile, Keyfile,
1090 * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
1091 store->tls_ctx = new_tls_context(store->tls_ca_certfile,
1092 store->tls_ca_certdir, store->tls_certfile,
1093 store->tls_keyfile, NULL, NULL, NULL, true);
1095 if (!store->tls_ctx) {
1096 Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for Storage \"%s\" in %s.\n"),
1097 store->name(), configfile);
1103 /* Loop over all counters, defining them in each database */
1104 /* Set default value in all counters */
1106 foreach_res(counter, R_COUNTER) {
1107 /* Write to catalog? */
1108 if (!counter->created && counter->Catalog == catalog) {
1110 bstrncpy(cr.Counter, counter->name(), sizeof(cr.Counter));
1111 cr.MinValue = counter->MinValue;
1112 cr.MaxValue = counter->MaxValue;
1113 cr.CurrentValue = counter->MinValue;
1114 if (counter->WrapCounter) {
1115 bstrncpy(cr.WrapCounter, counter->WrapCounter->name(), sizeof(cr.WrapCounter));
1117 cr.WrapCounter[0] = 0; /* empty string */
1119 if (db_create_counter_record(NULL, db, &cr)) {
1120 counter->CurrentValue = cr.CurrentValue;
1121 counter->created = true;
1122 Dmsg2(100, "Create counter %s val=%d\n", counter->name(), counter->CurrentValue);
1125 if (!counter->created) {
1126 counter->CurrentValue = counter->MinValue; /* default value */
1129 /* cleanup old job records */
1130 if (mode == UPDATE_AND_FIX) {
1131 db_sql_query(db, cleanup_created_job, NULL, NULL);
1132 db_sql_query(db, cleanup_running_job, NULL, NULL);
1135 /* Set SQL engine name in global for debugging */
1136 set_db_engine_name(db_get_engine_name(db));
1137 if (db) db_close_database(NULL, db);
1142 static void cleanup_old_files()
1145 struct dirent *entry, *result;
1147 int my_name_len = strlen(my_name);
1148 int len = strlen(director->working_directory);
1149 POOLMEM *cleanup = get_pool_memory(PM_MESSAGE);
1150 POOLMEM *basename = get_pool_memory(PM_MESSAGE);
1153 const int nmatch = 30;
1154 regmatch_t pmatch[nmatch];
1157 /* Exclude spaces and look for .mail, .tmp or .restore.xx.bsr files */
1158 const char *pat1 = "^[^ ]+\\.(restore\\.[^ ]+\\.bsr|mail|tmp)$";
1160 /* Setup working directory prefix */
1161 pm_strcpy(basename, director->working_directory);
1162 if (len > 0 && !IsPathSeparator(director->working_directory[len-1])) {
1163 pm_strcat(basename, "/");
1166 /* Compile regex expressions */
1167 rc = regcomp(&preg1, pat1, REG_EXTENDED);
1169 regerror(rc, &preg1, prbuf, sizeof(prbuf));
1170 Pmsg2(000, _("Could not compile regex pattern \"%s\" ERR=%s\n"),
1175 name_max = pathconf(".", _PC_NAME_MAX);
1176 if (name_max < 1024) {
1180 if (!(dp = opendir(director->working_directory))) {
1182 Pmsg2(000, "Failed to open working dir %s for cleanup: ERR=%s\n",
1183 director->working_directory, be.bstrerror());
1188 entry = (struct dirent *)malloc(sizeof(struct dirent) + name_max + 1000);
1190 if ((readdir_r(dp, entry, &result) != 0) || (result == NULL)) {
1193 /* Exclude any name with ., .., not my_name or containing a space */
1194 if (strcmp(result->d_name, ".") == 0 || strcmp(result->d_name, "..") == 0 ||
1195 strncmp(result->d_name, my_name, my_name_len) != 0) {
1196 Dmsg1(500, "Skipped: %s\n", result->d_name);
1200 /* Unlink files that match regexes */
1201 if (regexec(&preg1, result->d_name, nmatch, pmatch, 0) == 0) {
1202 pm_strcpy(cleanup, basename);
1203 pm_strcat(cleanup, result->d_name);
1204 Dmsg1(100, "Unlink: %s\n", cleanup);
1211 /* Be careful to free up the correct resources */
1215 free_pool_memory(cleanup);
1216 free_pool_memory(basename);