2 Bacula® - The Network Backup Solution
4 Copyright (C) 2000-2009 Free Software Foundation Europe e.V.
6 The main author of Bacula is Kern Sibbald, with contributions from
7 many others, a complete list can be found in the file AUTHORS.
8 This program is Free Software; you can redistribute it and/or
9 modify it under the terms of version two of the GNU General Public
10 License as published by the Free Software Foundation and included
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23 Bacula® is a registered trademark of Kern Sibbald.
24 The licensor of Bacula is the Free Software Foundation Europe
25 (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
26 Switzerland, email:ftf@fsfeurope.org.
30 * Bacula Director daemon -- this is the main program
32 * Kern Sibbald, March MM
42 #undef _POSIX_C_SOURCE
45 #include "lib/pythonlib.h"
47 /* Imported Functions */
48 extern PyObject *job_getattr(PyObject *self, char *attrname);
49 extern int job_setattr(PyObject *self, char *attrname, PyObject *value);
51 #endif /* HAVE_PYTHON */
53 /* Forward referenced subroutines */
54 void terminate_dird(int sig);
55 static bool check_resources();
56 static void dir_sql_query(JCR *jcr, const char *cmd);
58 /* Exported subroutines */
59 extern "C" void reload_config(int sig);
60 extern void invalidate_schedules();
61 extern bool parse_dir_config(CONFIG *config, const char *configfile, int exit_code);
63 /* Imported subroutines */
64 JCR *wait_for_next_job(char *runjob);
65 void term_scheduler();
66 void term_ua_server();
67 void start_UA_server(dlist *addrs);
68 void init_job_server(int max_workers);
69 void term_job_server();
70 void store_jobtype(LEX *lc, RES_ITEM *item, int index, int pass);
71 void store_level(LEX *lc, RES_ITEM *item, int index, int pass);
72 void store_replace(LEX *lc, RES_ITEM *item, int index, int pass);
73 void store_migtype(LEX *lc, RES_ITEM *item, int index, int pass);
74 void init_device_resources();
76 static char *runjob = NULL;
77 static int background = 1;
78 static void init_reload(void);
79 static CONFIG *config;
81 /* Globals Exported */
82 DIRRES *director; /* Director resource */
85 char *configfile = NULL;
88 /* Globals Imported */
89 extern RES_ITEM job_items[];
91 extern "C" { // work around visual compiler mangling variables
99 CHECK_CONNECTION, /* Check catalog connection */
100 UPDATE_CATALOG, /* Ensure that catalog is ok with conf */
101 UPDATE_AND_FIX /* Ensure that catalog is ok, and fix old jobs */
103 static bool check_catalog(cat_op mode);
105 #define CONFIG_FILE "bacula-dir.conf" /* default configuration file */
112 "\nVersion: %s (%s)\n\n"
113 "Usage: dird [-f -s] [-c config_file] [-d debug_level] [config_file]\n"
114 " -c <file> set configuration file to file\n"
115 " -d <nn> set debug level to <nn>\n"
116 " -dt print timestamp in debug output\n"
117 " -f run in foreground (for debugging)\n"
119 " -r <job> run <job> now\n"
121 " -t test - read configuration and exit\n"
123 " -v verbose user messages\n"
124 " -? print this message.\n"
125 "\n"), 2000, VERSION, BDATE);
131 /*********************************************************************
133 * Main Bacula Server program
136 #if defined(HAVE_WIN32)
137 /* For Win32 main() is in src/win32 code ... */
138 #define main BaculaMain
141 int main (int argc, char *argv[])
145 bool no_signals = false;
146 bool test_config = false;
150 init_python_interpreter_args python_args;
151 #endif /* HAVE_PYTHON */
153 start_heap = sbrk(0);
154 setlocale(LC_ALL, "");
155 bindtextdomain("bacula", LOCALEDIR);
156 textdomain("bacula");
159 my_name_is(argc, argv, "bacula-dir");
160 init_msg(NULL, NULL); /* initialize message handler */
162 daemon_start_time = time(NULL);
164 console_command = run_console_command;
166 while ((ch = getopt(argc, argv, "c:d:fg:r:stu:v?")) != -1) {
168 case 'c': /* specify config file */
169 if (configfile != NULL) {
172 configfile = bstrdup(optarg);
175 case 'd': /* set debug level */
176 if (*optarg == 't') {
177 dbg_timestamp = true;
179 debug_level = atoi(optarg);
180 if (debug_level <= 0) {
184 Dmsg1(10, "Debug level = %d\n", debug_level);
187 case 'f': /* run in foreground */
191 case 'g': /* set group id */
195 case 'r': /* run job */
196 if (runjob != NULL) {
200 runjob = bstrdup(optarg);
204 case 's': /* turn off signals */
208 case 't': /* test config */
212 case 'u': /* set uid */
216 case 'v': /* verbose */
230 init_signals(terminate_dird);
234 if (configfile != NULL) {
237 configfile = bstrdup(*argv);
245 if (configfile == NULL) {
246 configfile = bstrdup(CONFIG_FILE);
249 config = new_config_parser();
250 parse_dir_config(config, configfile, M_ERROR_TERM);
252 if (init_crypto() != 0) {
253 Jmsg((JCR *)NULL, M_ERROR_TERM, 0, _("Cryptography library initialization failed.\n"));
256 if (!check_resources()) {
257 Jmsg((JCR *)NULL, M_ERROR_TERM, 0, _("Please correct configuration file: %s\n"), configfile);
260 if (!test_config) { /* we don't need to do this block in test mode */
263 init_stack_dump(); /* grab new pid */
265 /* Create pid must come after we are a daemon -- so we have our final pid */
266 create_pid_file(director->pid_directory, "bacula-dir",
267 get_first_port_host_order(director->DIRaddrs));
268 read_state_file(director->working_directory, "bacula-dir",
269 get_first_port_host_order(director->DIRaddrs));
272 set_jcr_in_tsd(INVALID_JCR);
273 set_thread_concurrency(director->MaxConcurrentJobs * 2 +
274 4 /* UA */ + 5 /* sched+watchdog+jobsvr+misc */);
275 lmgr_init_thread(); /* initialize the lockmanager stack */
277 load_dir_plugins(director->plugin_directory);
279 drop(uid, gid, false); /* reduce privileges if requested */
281 /* If we are in testing mode, we don't try to fix the catalog */
282 cat_op mode=(test_config)?CHECK_CONNECTION:UPDATE_AND_FIX;
284 if (!check_catalog(mode)) {
285 Jmsg((JCR *)NULL, M_ERROR_TERM, 0, _("Please correct configuration file: %s\n"), configfile);
292 my_name_is(0, NULL, director->name()); /* set user defined name */
294 /* Plug database interface for library routines */
295 p_sql_query = (sql_query)dir_sql_query;
296 p_sql_escape = (sql_escape)db_escape_string;
298 FDConnectTimeout = (int)director->FDConnectTimeout;
299 SDConnectTimeout = (int)director->SDConnectTimeout;
301 #if !defined(HAVE_WIN32)
302 signal(SIGHUP, reload_config);
305 init_console_msg(working_directory);
308 python_args.progname = director->name();
309 python_args.scriptdir = director->scripts_directory;
310 python_args.modulename = "DirStartUp";
311 python_args.configfile = configfile;
312 python_args.workingdir = director->working_directory;
313 python_args.job_getattr = job_getattr;
314 python_args.job_setattr = job_setattr;
316 init_python_interpreter(&python_args);
317 #endif /* HAVE_PYTHON */
319 Dmsg0(200, "Start UA server\n");
320 start_UA_server(director->DIRaddrs);
322 start_watchdog(); /* start network watchdog thread */
324 init_jcr_subsystem(); /* start JCR watchdogs etc. */
326 init_job_server(director->MaxConcurrentJobs);
328 dbg_jcr_add_hook(_dbg_print_db); /* used to debug B_DB connexion after fatal signal */
330 // init_device_resources();
332 Dmsg0(200, "wait for next job\n");
333 /* Main loop -- call scheduler to get next job to run */
334 while ( (jcr = wait_for_next_job(runjob)) ) {
335 run_job(jcr); /* run job */
336 free_jcr(jcr); /* release jcr */
337 set_jcr_in_tsd(INVALID_JCR);
338 if (runjob) { /* command line, run a single job? */
339 break; /* yes, terminate */
349 * This allows the message handler to operate on the database
350 * by using a pointer to this function. The pointer is
351 * needed because the other daemons do not have access
352 * to the database. If the pointer is
353 * not defined (other daemons), then writing the database
356 static void dir_sql_query(JCR *jcr, const char *cmd)
358 if (!jcr || !jcr->db) {
361 db_sql_query(jcr->db, cmd, NULL, NULL);
364 /* Cleanup and then exit */
365 void terminate_dird(int sig)
367 static bool already_here = false;
369 if (already_here) { /* avoid recursive temination problems */
370 bmicrosleep(2, 0); /* yield */
374 debug_level = 0; /* turn off debug */
376 generate_daemon_event(NULL, "Exit");
378 write_state_file(director->working_directory, "bacula-dir", get_first_port_host_order(director->DIRaddrs));
379 delete_pid_file(director->pid_directory, "bacula-dir", get_first_port_host_order(director->DIRaddrs));
385 if (configfile != NULL) {
388 if (debug_level > 5) {
389 print_memory_pool_stats();
392 config->free_resources();
397 term_msg(); /* terminate message handler */
399 close_memory_pool(); /* release free memory in pool */
405 struct RELOAD_TABLE {
410 static const int max_reloads = 32;
411 static RELOAD_TABLE reload_table[max_reloads];
413 static void init_reload(void)
415 for (int i=0; i < max_reloads; i++) {
416 reload_table[i].job_count = 0;
417 reload_table[i].res_table = NULL;
421 static void free_saved_resources(int table)
423 int num = r_last - r_first + 1;
424 RES **res_tab = reload_table[table].res_table;
426 Dmsg1(100, "res_tab for table %d already released.\n", table);
429 Dmsg1(100, "Freeing resources for table %d\n", table);
430 for (int j=0; j<num; j++) {
431 free_resource(res_tab[j], r_first + j);
434 reload_table[table].job_count = 0;
435 reload_table[table].res_table = NULL;
439 * Called here at the end of every job that was
440 * hooked decrementing the active job_count. When
441 * it goes to zero, no one is using the associated
442 * resource table, so free it.
444 static void reload_job_end_cb(JCR *jcr, void *ctx)
446 int reload_id = (int)((long int)ctx);
447 Dmsg3(100, "reload job_end JobId=%d table=%d cnt=%d\n", jcr->JobId,
448 reload_id, reload_table[reload_id].job_count);
451 if (--reload_table[reload_id].job_count <= 0) {
452 free_saved_resources(reload_id);
458 static int find_free_reload_table_entry()
461 for (int i=0; i < max_reloads; i++) {
462 if (reload_table[i].res_table == NULL) {
471 * If we get here, we have received a SIGHUP, which means to
472 * reread our configuration file.
474 * The algorithm used is as follows: we count how many jobs are
475 * running and mark the running jobs to make a callback on
476 * exiting. The old config is saved with the reload table
477 * id in a reload table. The new config file is read. Now, as
478 * each job exits, it calls back to the reload_job_end_cb(), which
479 * decrements the count of open jobs for the given reload table.
480 * When the count goes to zero, we release those resources.
481 * This allows us to have pointers into the resource table (from
482 * jobs), and once they exit and all the pointers are released, we
483 * release the old table. Note, if no new jobs are running since the
484 * last reload, then the old resources will be immediately release.
485 * A console is considered a job because it may have pointers to
486 * resources, but a SYSTEM job is not since it *should* not have any
487 * permanent pointers to jobs.
490 void reload_config(int sig)
492 static bool already_here = false;
493 #if !defined(HAVE_WIN32)
497 int njobs = 0; /* number of running jobs */
502 abort(); /* Oops, recursion -> die */
506 #if !defined(HAVE_WIN32)
508 sigaddset(&set, SIGHUP);
509 sigprocmask(SIG_BLOCK, &set, NULL);
515 table = find_free_reload_table_entry();
517 Jmsg(NULL, M_ERROR, 0, _("Too many open reload requests. Request ignored.\n"));
521 Dmsg1(100, "Reload_config njobs=%d\n", njobs);
522 reload_table[table].res_table = config->save_resources();
523 Dmsg1(100, "Saved old config in table %d\n", table);
525 ok = parse_dir_config(config, configfile, M_ERROR);
527 Dmsg0(100, "Reloaded config file\n");
528 if (!ok || !check_resources() || !check_catalog(UPDATE_CATALOG)) {
529 rtable = find_free_reload_table_entry(); /* save new, bad table */
531 Jmsg(NULL, M_ERROR, 0, _("Please correct configuration file: %s\n"), configfile);
532 Jmsg(NULL, M_ERROR_TERM, 0, _("Out of reload table entries. Giving up.\n"));
534 Jmsg(NULL, M_ERROR, 0, _("Please correct configuration file: %s\n"), configfile);
535 Jmsg(NULL, M_ERROR, 0, _("Resetting previous configuration.\n"));
537 reload_table[rtable].res_table = config->save_resources();
538 /* Now restore old resoure values */
539 int num = r_last - r_first + 1;
540 RES **res_tab = reload_table[table].res_table;
541 for (int i=0; i<num; i++) {
542 res_head[i] = res_tab[i];
544 table = rtable; /* release new, bad, saved table below */
546 invalidate_schedules();
548 * Hook all active jobs so that they release this table
551 if (jcr->get_JobType() != JT_SYSTEM) {
552 reload_table[table].job_count++;
553 job_end_push(jcr, reload_job_end_cb, (void *)((long int)table));
561 set_working_directory(director->working_directory);
562 FDConnectTimeout = director->FDConnectTimeout;
563 SDConnectTimeout = director->SDConnectTimeout;
564 Dmsg0(10, "Director's configuration file reread.\n");
566 /* Now release saved resources, if no jobs using the resources */
568 free_saved_resources(table);
574 #if !defined(HAVE_WIN32)
575 sigprocmask(SIG_UNBLOCK, &set, NULL);
576 signal(SIGHUP, reload_config);
578 already_here = false;
582 * Make a quick check to see that we have all the
585 * **** FIXME **** this routine could be a lot more
586 * intelligent and comprehensive.
588 static bool check_resources()
596 job = (JOB *)GetNextRes(R_JOB, NULL);
597 director = (DIRRES *)GetNextRes(R_DIRECTOR, NULL);
599 Jmsg(NULL, M_FATAL, 0, _("No Director resource defined in %s\n"
600 "Without that I don't know who I am :-(\n"), configfile);
603 set_working_directory(director->working_directory);
604 if (!director->messages) { /* If message resource not specified */
605 director->messages = (MSGS *)GetNextRes(R_MSGS, NULL);
606 if (!director->messages) {
607 Jmsg(NULL, M_FATAL, 0, _("No Messages resource defined in %s\n"), configfile);
611 if (GetNextRes(R_DIRECTOR, (RES *)director) != NULL) {
612 Jmsg(NULL, M_FATAL, 0, _("Only one Director resource permitted in %s\n"),
616 /* tls_require implies tls_enable */
617 if (director->tls_require) {
619 director->tls_enable = true;
621 Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
626 need_tls = director->tls_enable || director->tls_authenticate;
628 if (!director->tls_certfile && need_tls) {
629 Jmsg(NULL, M_FATAL, 0, _("\"TLS Certificate\" file not defined for Director \"%s\" in %s.\n"),
630 director->name(), configfile);
634 if (!director->tls_keyfile && need_tls) {
635 Jmsg(NULL, M_FATAL, 0, _("\"TLS Key\" file not defined for Director \"%s\" in %s.\n"),
636 director->name(), configfile);
640 if ((!director->tls_ca_certfile && !director->tls_ca_certdir) &&
641 need_tls && director->tls_verify_peer) {
642 Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\" or \"TLS CA"
643 " Certificate Dir\" are defined for Director \"%s\" in %s."
644 " At least one CA certificate store is required"
645 " when using \"TLS Verify Peer\".\n"),
646 director->name(), configfile);
650 /* If everything is well, attempt to initialize our per-resource TLS context */
651 if (OK && (need_tls || director->tls_require)) {
652 /* Initialize TLS context:
653 * Args: CA certfile, CA certdir, Certfile, Keyfile,
654 * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
655 director->tls_ctx = new_tls_context(director->tls_ca_certfile,
656 director->tls_ca_certdir, director->tls_certfile,
657 director->tls_keyfile, NULL, NULL, director->tls_dhfile,
658 director->tls_verify_peer);
660 if (!director->tls_ctx) {
661 Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for Director \"%s\" in %s.\n"),
662 director->name(), configfile);
669 Jmsg(NULL, M_FATAL, 0, _("No Job records defined in %s\n"), configfile);
672 foreach_res(job, R_JOB) {
676 /* Handle Storage alists specifically */
677 JOB *jobdefs = job->jobdefs;
678 if (jobdefs->storage && !job->storage) {
680 job->storage = New(alist(10, not_owned_by_alist));
681 foreach_alist(st, jobdefs->storage) {
682 job->storage->append(st);
685 /* Handle RunScripts alists specifically */
686 if (jobdefs->RunScripts) {
689 if (!job->RunScripts) {
690 job->RunScripts = New(alist(10, not_owned_by_alist));
693 foreach_alist(rs, jobdefs->RunScripts) {
694 elt = copy_runscript(rs);
695 job->RunScripts->append(elt); /* we have to free it */
699 /* Transfer default items from JobDefs Resource */
700 for (i=0; job_items[i].name; i++) {
701 char **def_svalue, **svalue; /* string value */
702 uint32_t *def_ivalue, *ivalue; /* integer value */
703 bool *def_bvalue, *bvalue; /* bool value */
704 int64_t *def_lvalue, *lvalue; /* 64 bit values */
707 Dmsg4(1400, "Job \"%s\", field \"%s\" bit=%d def=%d\n",
708 job->name(), job_items[i].name,
709 bit_is_set(i, job->hdr.item_present),
710 bit_is_set(i, job->jobdefs->hdr.item_present));
712 if (!bit_is_set(i, job->hdr.item_present) &&
713 bit_is_set(i, job->jobdefs->hdr.item_present)) {
714 Dmsg2(400, "Job \"%s\", field \"%s\": getting default.\n",
715 job->name(), job_items[i].name);
716 offset = (char *)(job_items[i].value) - (char *)&res_all;
718 * Handle strings and directory strings
720 if (job_items[i].handler == store_str ||
721 job_items[i].handler == store_dir) {
722 def_svalue = (char **)((char *)(job->jobdefs) + offset);
723 Dmsg5(400, "Job \"%s\", field \"%s\" def_svalue=%s item %d offset=%u\n",
724 job->name(), job_items[i].name, *def_svalue, i, offset);
725 svalue = (char **)((char *)job + offset);
727 Pmsg1(000, _("Hey something is wrong. p=0x%lu\n"), *svalue);
729 *svalue = bstrdup(*def_svalue);
730 set_bit(i, job->hdr.item_present);
734 } else if (job_items[i].handler == store_res) {
735 def_svalue = (char **)((char *)(job->jobdefs) + offset);
736 Dmsg4(400, "Job \"%s\", field \"%s\" item %d offset=%u\n",
737 job->name(), job_items[i].name, i, offset);
738 svalue = (char **)((char *)job + offset);
740 Pmsg1(000, _("Hey something is wrong. p=0x%lu\n"), *svalue);
742 *svalue = *def_svalue;
743 set_bit(i, job->hdr.item_present);
745 * Handle alist resources
747 } else if (job_items[i].handler == store_alist_res) {
748 if (bit_is_set(i, job->jobdefs->hdr.item_present)) {
749 set_bit(i, job->hdr.item_present);
752 * Handle integer fields
753 * Note, our store_bit does not handle bitmaped fields
755 } else if (job_items[i].handler == store_bit ||
756 job_items[i].handler == store_pint32 ||
757 job_items[i].handler == store_jobtype ||
758 job_items[i].handler == store_level ||
759 job_items[i].handler == store_int32 ||
760 job_items[i].handler == store_size32 ||
761 job_items[i].handler == store_migtype ||
762 job_items[i].handler == store_replace) {
763 def_ivalue = (uint32_t *)((char *)(job->jobdefs) + offset);
764 Dmsg5(400, "Job \"%s\", field \"%s\" def_ivalue=%d item %d offset=%u\n",
765 job->name(), job_items[i].name, *def_ivalue, i, offset);
766 ivalue = (uint32_t *)((char *)job + offset);
767 *ivalue = *def_ivalue;
768 set_bit(i, job->hdr.item_present);
770 * Handle 64 bit integer fields
772 } else if (job_items[i].handler == store_time ||
773 job_items[i].handler == store_size64 ||
774 job_items[i].handler == store_int64) {
775 def_lvalue = (int64_t *)((char *)(job->jobdefs) + offset);
776 Dmsg5(400, "Job \"%s\", field \"%s\" def_lvalue=%" lld " item %d offset=%u\n",
777 job->name(), job_items[i].name, *def_lvalue, i, offset);
778 lvalue = (int64_t *)((char *)job + offset);
779 *lvalue = *def_lvalue;
780 set_bit(i, job->hdr.item_present);
784 } else if (job_items[i].handler == store_bool) {
785 def_bvalue = (bool *)((char *)(job->jobdefs) + offset);
786 Dmsg5(400, "Job \"%s\", field \"%s\" def_bvalue=%d item %d offset=%u\n",
787 job->name(), job_items[i].name, *def_bvalue, i, offset);
788 bvalue = (bool *)((char *)job + offset);
789 *bvalue = *def_bvalue;
790 set_bit(i, job->hdr.item_present);
796 * Ensure that all required items are present
798 for (i=0; job_items[i].name; i++) {
799 if (job_items[i].flags & ITEM_REQUIRED) {
800 if (!bit_is_set(i, job->hdr.item_present)) {
801 Jmsg(NULL, M_ERROR_TERM, 0, _("\"%s\" directive in Job \"%s\" resource is required, but not found.\n"),
802 job_items[i].name, job->name());
806 /* If this triggers, take a look at lib/parse_conf.h */
807 if (i >= MAX_RES_ITEMS) {
808 Emsg0(M_ERROR_TERM, 0, _("Too many items in Job resource\n"));
811 if (!job->storage && !job->pool->storage) {
812 Jmsg(NULL, M_FATAL, 0, _("No storage specified in Job \"%s\" nor in Pool.\n"),
816 } /* End loop over Job res */
819 /* Loop over Consoles */
821 foreach_res(cons, R_CONSOLE) {
822 /* tls_require implies tls_enable */
823 if (cons->tls_require) {
825 cons->tls_enable = true;
827 Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
833 need_tls = cons->tls_enable || cons->tls_authenticate;
835 if (!cons->tls_certfile && need_tls) {
836 Jmsg(NULL, M_FATAL, 0, _("\"TLS Certificate\" file not defined for Console \"%s\" in %s.\n"),
837 cons->name(), configfile);
841 if (!cons->tls_keyfile && need_tls) {
842 Jmsg(NULL, M_FATAL, 0, _("\"TLS Key\" file not defined for Console \"%s\" in %s.\n"),
843 cons->name(), configfile);
847 if ((!cons->tls_ca_certfile && !cons->tls_ca_certdir)
848 && need_tls && cons->tls_verify_peer) {
849 Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\" or \"TLS CA"
850 " Certificate Dir\" are defined for Console \"%s\" in %s."
851 " At least one CA certificate store is required"
852 " when using \"TLS Verify Peer\".\n"),
853 cons->name(), configfile);
856 /* If everything is well, attempt to initialize our per-resource TLS context */
857 if (OK && (need_tls || cons->tls_require)) {
858 /* Initialize TLS context:
859 * Args: CA certfile, CA certdir, Certfile, Keyfile,
860 * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
861 cons->tls_ctx = new_tls_context(cons->tls_ca_certfile,
862 cons->tls_ca_certdir, cons->tls_certfile,
863 cons->tls_keyfile, NULL, NULL, cons->tls_dhfile, cons->tls_verify_peer);
865 if (!cons->tls_ctx) {
866 Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for File daemon \"%s\" in %s.\n"),
867 cons->name(), configfile);
874 /* Loop over Clients */
876 foreach_res(client, R_CLIENT) {
877 /* tls_require implies tls_enable */
878 if (client->tls_require) {
880 client->tls_enable = true;
882 Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
887 need_tls = client->tls_enable || client->tls_authenticate;
888 if ((!client->tls_ca_certfile && !client->tls_ca_certdir) && need_tls) {
889 Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\""
890 " or \"TLS CA Certificate Dir\" are defined for File daemon \"%s\" in %s.\n"),
891 client->name(), configfile);
895 /* If everything is well, attempt to initialize our per-resource TLS context */
896 if (OK && (need_tls || client->tls_require)) {
897 /* Initialize TLS context:
898 * Args: CA certfile, CA certdir, Certfile, Keyfile,
899 * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
900 client->tls_ctx = new_tls_context(client->tls_ca_certfile,
901 client->tls_ca_certdir, client->tls_certfile,
902 client->tls_keyfile, NULL, NULL, NULL,
905 if (!client->tls_ctx) {
906 Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for File daemon \"%s\" in %s.\n"),
907 client->name(), configfile);
915 close_msg(NULL); /* close temp message handler */
916 init_msg(NULL, director->messages); /* open daemon message handler */
923 * - we can check the connection (mode=CHECK_CONNECTION)
924 * - we can synchronize the catalog with the configuration (mode=UPDATE_CATALOG)
925 * - we can synchronize, and fix old job records (mode=UPDATE_AND_FIX)
927 static bool check_catalog(cat_op mode)
932 /* Loop over databases */
934 foreach_res(catalog, R_CATALOG) {
937 * Make sure we can open catalog, otherwise print a warning
938 * message because the server is probably not running.
940 db = db_init(NULL, catalog->db_driver, catalog->db_name, catalog->db_user,
941 catalog->db_password, catalog->db_address,
942 catalog->db_port, catalog->db_socket,
943 catalog->mult_db_connections);
944 if (!db || !db_open_database(NULL, db)) {
945 Pmsg2(000, _("Could not open Catalog \"%s\", database \"%s\".\n"),
946 catalog->name(), catalog->db_name);
947 Jmsg(NULL, M_FATAL, 0, _("Could not open Catalog \"%s\", database \"%s\".\n"),
948 catalog->name(), catalog->db_name);
950 Jmsg(NULL, M_FATAL, 0, _("%s"), db_strerror(db));
951 Pmsg1(000, "%s", db_strerror(db));
952 db_close_database(NULL, db);
958 /* we are in testing mode, so don't touch anything in the catalog */
959 if (mode == CHECK_CONNECTION) {
960 db_close_database(NULL, db);
964 /* Loop over all pools, defining/updating them in each database */
966 foreach_res(pool, R_POOL) {
968 * If the Pool has a catalog resource create the pool only
971 if (!pool->catalog || pool->catalog == catalog) {
972 create_pool(NULL, db, pool, POOL_OP_UPDATE); /* update request */
976 /* Once they are created, we can loop over them again, updating
977 * references (RecyclePool)
979 foreach_res(pool, R_POOL) {
981 * If the Pool has a catalog resource update the pool only
984 if (!pool->catalog || pool->catalog == catalog) {
985 update_pool_references(NULL, db, pool);
989 /* Ensure basic client record is in DB */
991 foreach_res(client, R_CLIENT) {
993 memset(&cr, 0, sizeof(cr));
994 bstrncpy(cr.Name, client->name(), sizeof(cr.Name));
995 db_create_client_record(NULL, db, &cr);
998 /* Ensure basic storage record is in DB */
1000 foreach_res(store, R_STORAGE) {
1003 memset(&sr, 0, sizeof(sr));
1004 memset(&mr, 0, sizeof(mr));
1005 if (store->media_type) {
1006 bstrncpy(mr.MediaType, store->media_type, sizeof(mr.MediaType));
1008 db_create_mediatype_record(NULL, db, &mr);
1012 bstrncpy(sr.Name, store->name(), sizeof(sr.Name));
1013 sr.AutoChanger = store->autochanger;
1014 db_create_storage_record(NULL, db, &sr);
1015 store->StorageId = sr.StorageId; /* set storage Id */
1016 if (!sr.created) { /* if not created, update it */
1017 sr.AutoChanger = store->autochanger;
1018 db_update_storage_record(NULL, db, &sr);
1021 /* tls_require implies tls_enable */
1022 if (store->tls_require) {
1024 store->tls_enable = true;
1026 Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
1031 need_tls = store->tls_enable || store->tls_authenticate;
1033 if ((!store->tls_ca_certfile && !store->tls_ca_certdir) && need_tls) {
1034 Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\""
1035 " or \"TLS CA Certificate Dir\" are defined for Storage \"%s\" in %s.\n"),
1036 store->name(), configfile);
1040 /* If everything is well, attempt to initialize our per-resource TLS context */
1041 if (OK && (need_tls || store->tls_require)) {
1042 /* Initialize TLS context:
1043 * Args: CA certfile, CA certdir, Certfile, Keyfile,
1044 * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
1045 store->tls_ctx = new_tls_context(store->tls_ca_certfile,
1046 store->tls_ca_certdir, store->tls_certfile,
1047 store->tls_keyfile, NULL, NULL, NULL, true);
1049 if (!store->tls_ctx) {
1050 Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for Storage \"%s\" in %s.\n"),
1051 store->name(), configfile);
1057 /* Loop over all counters, defining them in each database */
1058 /* Set default value in all counters */
1060 foreach_res(counter, R_COUNTER) {
1061 /* Write to catalog? */
1062 if (!counter->created && counter->Catalog == catalog) {
1064 bstrncpy(cr.Counter, counter->name(), sizeof(cr.Counter));
1065 cr.MinValue = counter->MinValue;
1066 cr.MaxValue = counter->MaxValue;
1067 cr.CurrentValue = counter->MinValue;
1068 if (counter->WrapCounter) {
1069 bstrncpy(cr.WrapCounter, counter->WrapCounter->name(), sizeof(cr.WrapCounter));
1071 cr.WrapCounter[0] = 0; /* empty string */
1073 if (db_create_counter_record(NULL, db, &cr)) {
1074 counter->CurrentValue = cr.CurrentValue;
1075 counter->created = true;
1076 Dmsg2(100, "Create counter %s val=%d\n", counter->name(), counter->CurrentValue);
1079 if (!counter->created) {
1080 counter->CurrentValue = counter->MinValue; /* default value */
1083 /* cleanup old job records */
1084 if (mode == UPDATE_AND_FIX) {
1085 db_sql_query(db, cleanup_created_job, NULL, NULL);
1086 db_sql_query(db, cleanup_running_job, NULL, NULL);
1089 db_close_database(NULL, db);
1091 /* Set type in global for debugging */
1092 set_db_type(db_get_type());