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 */
266 /* Create pid must come after we are a daemon -- so we have our final pid */
267 create_pid_file(director->pid_directory, "bacula-dir", get_first_port_host_order(director->DIRaddrs));
268 read_state_file(director->working_directory, "bacula-dir", get_first_port_host_order(director->DIRaddrs));
271 load_dir_plugins(director->plugin_directory);
273 drop(uid, gid); /* reduce privileges if requested */
275 /* If we are in testing mode, we don't try to fix the catalog */
276 cat_op mode=(test_config)?CHECK_CONNECTION:UPDATE_AND_FIX;
278 if (!check_catalog(mode)) {
279 Jmsg((JCR *)NULL, M_ERROR_TERM, 0, _("Please correct configuration file: %s\n"), configfile);
286 my_name_is(0, NULL, director->name()); /* set user defined name */
288 /* Plug database interface for library routines */
289 p_sql_query = (sql_query)dir_sql_query;
290 p_sql_escape = (sql_escape)db_escape_string;
292 FDConnectTimeout = (int)director->FDConnectTimeout;
293 SDConnectTimeout = (int)director->SDConnectTimeout;
295 #if !defined(HAVE_WIN32)
296 signal(SIGHUP, reload_config);
299 init_console_msg(working_directory);
302 python_args.progname = director->name();
303 python_args.scriptdir = director->scripts_directory;
304 python_args.modulename = "DirStartUp";
305 python_args.configfile = configfile;
306 python_args.workingdir = director->working_directory;
307 python_args.job_getattr = job_getattr;
308 python_args.job_setattr = job_setattr;
310 init_python_interpreter(&python_args);
311 #endif /* HAVE_PYTHON */
313 set_jcr_in_tsd(INVALID_JCR);
314 set_thread_concurrency(director->MaxConcurrentJobs * 2 +
315 4 /* UA */ + 4 /* sched+watchdog+jobsvr+misc */);
317 Dmsg0(200, "Start UA server\n");
318 start_UA_server(director->DIRaddrs);
320 start_watchdog(); /* start network watchdog thread */
322 init_jcr_subsystem(); /* start JCR watchdogs etc. */
324 init_job_server(director->MaxConcurrentJobs);
326 dbg_jcr_add_hook(_dbg_print_db); /* used to debug B_DB connexion after fatal signal */
328 // init_device_resources();
330 Dmsg0(200, "wait for next job\n");
331 /* Main loop -- call scheduler to get next job to run */
332 while ( (jcr = wait_for_next_job(runjob)) ) {
333 run_job(jcr); /* run job */
334 free_jcr(jcr); /* release jcr */
335 set_jcr_in_tsd(INVALID_JCR);
336 if (runjob) { /* command line, run a single job? */
337 break; /* yes, terminate */
347 * This allows the message handler to operate on the database
348 * by using a pointer to this function. The pointer is
349 * needed because the other daemons do not have access
350 * to the database. If the pointer is
351 * not defined (other daemons), then writing the database
354 static void dir_sql_query(JCR *jcr, const char *cmd)
356 if (!jcr || !jcr->db) {
359 db_sql_query(jcr->db, cmd, NULL, NULL);
362 /* Cleanup and then exit */
363 void terminate_dird(int sig)
365 static bool already_here = false;
367 if (already_here) { /* avoid recursive temination problems */
368 bmicrosleep(2, 0); /* yield */
372 debug_level = 0; /* turn off debug */
374 generate_daemon_event(NULL, "Exit");
376 write_state_file(director->working_directory, "bacula-dir", get_first_port_host_order(director->DIRaddrs));
377 delete_pid_file(director->pid_directory, "bacula-dir", get_first_port_host_order(director->DIRaddrs));
383 if (configfile != NULL) {
386 if (debug_level > 5) {
387 print_memory_pool_stats();
390 config->free_resources();
395 term_msg(); /* terminate message handler */
397 close_memory_pool(); /* release free memory in pool */
403 struct RELOAD_TABLE {
408 static const int max_reloads = 32;
409 static RELOAD_TABLE reload_table[max_reloads];
411 static void init_reload(void)
413 for (int i=0; i < max_reloads; i++) {
414 reload_table[i].job_count = 0;
415 reload_table[i].res_table = NULL;
419 static void free_saved_resources(int table)
421 int num = r_last - r_first + 1;
422 RES **res_tab = reload_table[table].res_table;
424 Dmsg1(100, "res_tab for table %d already released.\n", table);
427 Dmsg1(100, "Freeing resources for table %d\n", table);
428 for (int j=0; j<num; j++) {
429 free_resource(res_tab[j], r_first + j);
432 reload_table[table].job_count = 0;
433 reload_table[table].res_table = NULL;
437 * Called here at the end of every job that was
438 * hooked decrementing the active job_count. When
439 * it goes to zero, no one is using the associated
440 * resource table, so free it.
442 static void reload_job_end_cb(JCR *jcr, void *ctx)
444 int reload_id = (int)((long int)ctx);
445 Dmsg3(100, "reload job_end JobId=%d table=%d cnt=%d\n", jcr->JobId,
446 reload_id, reload_table[reload_id].job_count);
449 if (--reload_table[reload_id].job_count <= 0) {
450 free_saved_resources(reload_id);
456 static int find_free_reload_table_entry()
459 for (int i=0; i < max_reloads; i++) {
460 if (reload_table[i].res_table == NULL) {
469 * If we get here, we have received a SIGHUP, which means to
470 * reread our configuration file.
472 * The algorithm used is as follows: we count how many jobs are
473 * running and mark the running jobs to make a callback on
474 * exiting. The old config is saved with the reload table
475 * id in a reload table. The new config file is read. Now, as
476 * each job exits, it calls back to the reload_job_end_cb(), which
477 * decrements the count of open jobs for the given reload table.
478 * When the count goes to zero, we release those resources.
479 * This allows us to have pointers into the resource table (from
480 * jobs), and once they exit and all the pointers are released, we
481 * release the old table. Note, if no new jobs are running since the
482 * last reload, then the old resources will be immediately release.
483 * A console is considered a job because it may have pointers to
484 * resources, but a SYSTEM job is not since it *should* not have any
485 * permanent pointers to jobs.
488 void reload_config(int sig)
490 static bool already_here = false;
491 #if !defined(HAVE_WIN32)
495 int njobs = 0; /* number of running jobs */
500 abort(); /* Oops, recursion -> die */
504 #if !defined(HAVE_WIN32)
506 sigaddset(&set, SIGHUP);
507 sigprocmask(SIG_BLOCK, &set, NULL);
513 table = find_free_reload_table_entry();
515 Jmsg(NULL, M_ERROR, 0, _("Too many open reload requests. Request ignored.\n"));
519 Dmsg1(100, "Reload_config njobs=%d\n", njobs);
520 reload_table[table].res_table = config->save_resources();
521 Dmsg1(100, "Saved old config in table %d\n", table);
523 ok = parse_dir_config(config, configfile, M_ERROR);
525 Dmsg0(100, "Reloaded config file\n");
526 if (!ok || !check_resources() || !check_catalog(UPDATE_CATALOG)) {
527 rtable = find_free_reload_table_entry(); /* save new, bad table */
529 Jmsg(NULL, M_ERROR, 0, _("Please correct configuration file: %s\n"), configfile);
530 Jmsg(NULL, M_ERROR_TERM, 0, _("Out of reload table entries. Giving up.\n"));
532 Jmsg(NULL, M_ERROR, 0, _("Please correct configuration file: %s\n"), configfile);
533 Jmsg(NULL, M_ERROR, 0, _("Resetting previous configuration.\n"));
535 reload_table[rtable].res_table = config->save_resources();
536 /* Now restore old resoure values */
537 int num = r_last - r_first + 1;
538 RES **res_tab = reload_table[table].res_table;
539 for (int i=0; i<num; i++) {
540 res_head[i] = res_tab[i];
542 table = rtable; /* release new, bad, saved table below */
544 invalidate_schedules();
546 * Hook all active jobs so that they release this table
549 if (jcr->get_JobType() != JT_SYSTEM) {
550 reload_table[table].job_count++;
551 job_end_push(jcr, reload_job_end_cb, (void *)((long int)table));
559 set_working_directory(director->working_directory);
560 FDConnectTimeout = director->FDConnectTimeout;
561 SDConnectTimeout = director->SDConnectTimeout;
562 Dmsg0(10, "Director's configuration file reread.\n");
564 /* Now release saved resources, if no jobs using the resources */
566 free_saved_resources(table);
572 #if !defined(HAVE_WIN32)
573 sigprocmask(SIG_UNBLOCK, &set, NULL);
574 signal(SIGHUP, reload_config);
576 already_here = false;
580 * Make a quick check to see that we have all the
583 * **** FIXME **** this routine could be a lot more
584 * intelligent and comprehensive.
586 static bool check_resources()
594 job = (JOB *)GetNextRes(R_JOB, NULL);
595 director = (DIRRES *)GetNextRes(R_DIRECTOR, NULL);
597 Jmsg(NULL, M_FATAL, 0, _("No Director resource defined in %s\n"
598 "Without that I don't know who I am :-(\n"), configfile);
601 set_working_directory(director->working_directory);
602 if (!director->messages) { /* If message resource not specified */
603 director->messages = (MSGS *)GetNextRes(R_MSGS, NULL);
604 if (!director->messages) {
605 Jmsg(NULL, M_FATAL, 0, _("No Messages resource defined in %s\n"), configfile);
609 if (GetNextRes(R_DIRECTOR, (RES *)director) != NULL) {
610 Jmsg(NULL, M_FATAL, 0, _("Only one Director resource permitted in %s\n"),
614 /* tls_require implies tls_enable */
615 if (director->tls_require) {
617 director->tls_enable = true;
619 Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
624 need_tls = director->tls_enable || director->tls_authenticate;
626 if (!director->tls_certfile && need_tls) {
627 Jmsg(NULL, M_FATAL, 0, _("\"TLS Certificate\" file not defined for Director \"%s\" in %s.\n"),
628 director->name(), configfile);
632 if (!director->tls_keyfile && need_tls) {
633 Jmsg(NULL, M_FATAL, 0, _("\"TLS Key\" file not defined for Director \"%s\" in %s.\n"),
634 director->name(), configfile);
638 if ((!director->tls_ca_certfile && !director->tls_ca_certdir) &&
639 need_tls && director->tls_verify_peer) {
640 Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\" or \"TLS CA"
641 " Certificate Dir\" are defined for Director \"%s\" in %s."
642 " At least one CA certificate store is required"
643 " when using \"TLS Verify Peer\".\n"),
644 director->name(), configfile);
648 /* If everything is well, attempt to initialize our per-resource TLS context */
649 if (OK && (need_tls || director->tls_require)) {
650 /* Initialize TLS context:
651 * Args: CA certfile, CA certdir, Certfile, Keyfile,
652 * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
653 director->tls_ctx = new_tls_context(director->tls_ca_certfile,
654 director->tls_ca_certdir, director->tls_certfile,
655 director->tls_keyfile, NULL, NULL, director->tls_dhfile,
656 director->tls_verify_peer);
658 if (!director->tls_ctx) {
659 Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for Director \"%s\" in %s.\n"),
660 director->name(), configfile);
667 Jmsg(NULL, M_FATAL, 0, _("No Job records defined in %s\n"), configfile);
670 foreach_res(job, R_JOB) {
674 /* Handle Storage alists specifically */
675 JOB *jobdefs = job->jobdefs;
676 if (jobdefs->storage && !job->storage) {
678 job->storage = New(alist(10, not_owned_by_alist));
679 foreach_alist(st, jobdefs->storage) {
680 job->storage->append(st);
683 /* Handle RunScripts alists specifically */
684 if (jobdefs->RunScripts) {
687 if (!job->RunScripts) {
688 job->RunScripts = New(alist(10, not_owned_by_alist));
691 foreach_alist(rs, jobdefs->RunScripts) {
692 elt = copy_runscript(rs);
693 job->RunScripts->append(elt); /* we have to free it */
697 /* Transfer default items from JobDefs Resource */
698 for (i=0; job_items[i].name; i++) {
699 char **def_svalue, **svalue; /* string value */
700 uint32_t *def_ivalue, *ivalue; /* integer value */
701 bool *def_bvalue, *bvalue; /* bool value */
702 int64_t *def_lvalue, *lvalue; /* 64 bit values */
705 Dmsg4(1400, "Job \"%s\", field \"%s\" bit=%d def=%d\n",
706 job->name(), job_items[i].name,
707 bit_is_set(i, job->hdr.item_present),
708 bit_is_set(i, job->jobdefs->hdr.item_present));
710 if (!bit_is_set(i, job->hdr.item_present) &&
711 bit_is_set(i, job->jobdefs->hdr.item_present)) {
712 Dmsg2(400, "Job \"%s\", field \"%s\": getting default.\n",
713 job->name(), job_items[i].name);
714 offset = (char *)(job_items[i].value) - (char *)&res_all;
716 * Handle strings and directory strings
718 if (job_items[i].handler == store_str ||
719 job_items[i].handler == store_dir) {
720 def_svalue = (char **)((char *)(job->jobdefs) + offset);
721 Dmsg5(400, "Job \"%s\", field \"%s\" def_svalue=%s item %d offset=%u\n",
722 job->name(), job_items[i].name, *def_svalue, i, offset);
723 svalue = (char **)((char *)job + offset);
725 Pmsg1(000, _("Hey something is wrong. p=0x%lu\n"), *svalue);
727 *svalue = bstrdup(*def_svalue);
728 set_bit(i, job->hdr.item_present);
732 } else if (job_items[i].handler == store_res) {
733 def_svalue = (char **)((char *)(job->jobdefs) + offset);
734 Dmsg4(400, "Job \"%s\", field \"%s\" item %d offset=%u\n",
735 job->name(), job_items[i].name, i, offset);
736 svalue = (char **)((char *)job + offset);
738 Pmsg1(000, _("Hey something is wrong. p=0x%lu\n"), *svalue);
740 *svalue = *def_svalue;
741 set_bit(i, job->hdr.item_present);
743 * Handle alist resources
745 } else if (job_items[i].handler == store_alist_res) {
746 if (bit_is_set(i, job->jobdefs->hdr.item_present)) {
747 set_bit(i, job->hdr.item_present);
750 * Handle integer fields
751 * Note, our store_bit does not handle bitmaped fields
753 } else if (job_items[i].handler == store_bit ||
754 job_items[i].handler == store_pint32 ||
755 job_items[i].handler == store_jobtype ||
756 job_items[i].handler == store_level ||
757 job_items[i].handler == store_int32 ||
758 job_items[i].handler == store_migtype ||
759 job_items[i].handler == store_replace) {
760 def_ivalue = (uint32_t *)((char *)(job->jobdefs) + offset);
761 Dmsg5(400, "Job \"%s\", field \"%s\" def_ivalue=%d item %d offset=%u\n",
762 job->name(), job_items[i].name, *def_ivalue, i, offset);
763 ivalue = (uint32_t *)((char *)job + offset);
764 *ivalue = *def_ivalue;
765 set_bit(i, job->hdr.item_present);
767 * Handle 64 bit integer fields
769 } else if (job_items[i].handler == store_time ||
770 job_items[i].handler == store_size ||
771 job_items[i].handler == store_int64) {
772 def_lvalue = (int64_t *)((char *)(job->jobdefs) + offset);
773 Dmsg5(400, "Job \"%s\", field \"%s\" def_lvalue=%" lld " item %d offset=%u\n",
774 job->name(), job_items[i].name, *def_lvalue, i, offset);
775 lvalue = (int64_t *)((char *)job + offset);
776 *lvalue = *def_lvalue;
777 set_bit(i, job->hdr.item_present);
781 } else if (job_items[i].handler == store_bool) {
782 def_bvalue = (bool *)((char *)(job->jobdefs) + offset);
783 Dmsg5(400, "Job \"%s\", field \"%s\" def_bvalue=%d item %d offset=%u\n",
784 job->name(), job_items[i].name, *def_bvalue, i, offset);
785 bvalue = (bool *)((char *)job + offset);
786 *bvalue = *def_bvalue;
787 set_bit(i, job->hdr.item_present);
793 * Ensure that all required items are present
795 for (i=0; job_items[i].name; i++) {
796 if (job_items[i].flags & ITEM_REQUIRED) {
797 if (!bit_is_set(i, job->hdr.item_present)) {
798 Jmsg(NULL, M_ERROR_TERM, 0, _("\"%s\" directive in Job \"%s\" resource is required, but not found.\n"),
799 job_items[i].name, job->name());
803 /* If this triggers, take a look at lib/parse_conf.h */
804 if (i >= MAX_RES_ITEMS) {
805 Emsg0(M_ERROR_TERM, 0, _("Too many items in Job resource\n"));
808 if (!job->storage && !job->pool->storage) {
809 Jmsg(NULL, M_FATAL, 0, _("No storage specified in Job \"%s\" nor in Pool.\n"),
813 } /* End loop over Job res */
816 /* Loop over Consoles */
818 foreach_res(cons, R_CONSOLE) {
819 /* tls_require implies tls_enable */
820 if (cons->tls_require) {
822 cons->tls_enable = true;
824 Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
830 need_tls = cons->tls_enable || cons->tls_authenticate;
832 if (!cons->tls_certfile && need_tls) {
833 Jmsg(NULL, M_FATAL, 0, _("\"TLS Certificate\" file not defined for Console \"%s\" in %s.\n"),
834 cons->name(), configfile);
838 if (!cons->tls_keyfile && need_tls) {
839 Jmsg(NULL, M_FATAL, 0, _("\"TLS Key\" file not defined for Console \"%s\" in %s.\n"),
840 cons->name(), configfile);
844 if ((!cons->tls_ca_certfile && !cons->tls_ca_certdir)
845 && need_tls && cons->tls_verify_peer) {
846 Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\" or \"TLS CA"
847 " Certificate Dir\" are defined for Console \"%s\" in %s."
848 " At least one CA certificate store is required"
849 " when using \"TLS Verify Peer\".\n"),
850 cons->name(), configfile);
853 /* If everything is well, attempt to initialize our per-resource TLS context */
854 if (OK && (need_tls || cons->tls_require)) {
855 /* Initialize TLS context:
856 * Args: CA certfile, CA certdir, Certfile, Keyfile,
857 * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
858 cons->tls_ctx = new_tls_context(cons->tls_ca_certfile,
859 cons->tls_ca_certdir, cons->tls_certfile,
860 cons->tls_keyfile, NULL, NULL, cons->tls_dhfile, cons->tls_verify_peer);
862 if (!cons->tls_ctx) {
863 Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for File daemon \"%s\" in %s.\n"),
864 cons->name(), configfile);
871 /* Loop over Clients */
873 foreach_res(client, R_CLIENT) {
874 /* tls_require implies tls_enable */
875 if (client->tls_require) {
877 client->tls_enable = true;
879 Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
884 need_tls = client->tls_enable || client->tls_authenticate;
885 if ((!client->tls_ca_certfile && !client->tls_ca_certdir) && need_tls) {
886 Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\""
887 " or \"TLS CA Certificate Dir\" are defined for File daemon \"%s\" in %s.\n"),
888 client->name(), configfile);
892 /* If everything is well, attempt to initialize our per-resource TLS context */
893 if (OK && (need_tls || client->tls_require)) {
894 /* Initialize TLS context:
895 * Args: CA certfile, CA certdir, Certfile, Keyfile,
896 * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
897 client->tls_ctx = new_tls_context(client->tls_ca_certfile,
898 client->tls_ca_certdir, client->tls_certfile,
899 client->tls_keyfile, NULL, NULL, NULL,
902 if (!client->tls_ctx) {
903 Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for File daemon \"%s\" in %s.\n"),
904 client->name(), configfile);
912 close_msg(NULL); /* close temp message handler */
913 init_msg(NULL, director->messages); /* open daemon message handler */
920 * - we can check the connection (mode=CHECK_CONNECTION)
921 * - we can synchronize the catalog with the configuration (mode=UPDATE_CATALOG)
922 * - we can synchronize, and fix old job records (mode=UPDATE_AND_FIX)
924 static bool check_catalog(cat_op mode)
929 /* Loop over databases */
931 foreach_res(catalog, R_CATALOG) {
934 * Make sure we can open catalog, otherwise print a warning
935 * message because the server is probably not running.
937 db = db_init(NULL, catalog->db_driver, catalog->db_name, catalog->db_user,
938 catalog->db_password, catalog->db_address,
939 catalog->db_port, catalog->db_socket,
940 catalog->mult_db_connections);
941 if (!db || !db_open_database(NULL, db)) {
942 Pmsg2(000, _("Could not open Catalog \"%s\", database \"%s\".\n"),
943 catalog->name(), catalog->db_name);
944 Jmsg(NULL, M_FATAL, 0, _("Could not open Catalog \"%s\", database \"%s\".\n"),
945 catalog->name(), catalog->db_name);
947 Jmsg(NULL, M_FATAL, 0, _("%s"), db_strerror(db));
948 Pmsg1(000, "%s", db_strerror(db));
949 db_close_database(NULL, db);
955 /* we are in testing mode, so don't touch anything in the catalog */
956 if (mode == CHECK_CONNECTION) {
957 db_close_database(NULL, db);
961 /* Loop over all pools, defining/updating them in each database */
963 foreach_res(pool, R_POOL) {
965 * If the Pool has a catalog resource create the pool only
968 if (!pool->catalog || pool->catalog == catalog) {
969 create_pool(NULL, db, pool, POOL_OP_UPDATE); /* update request */
973 /* Once they are created, we can loop over them again, updating
974 * references (RecyclePool)
976 foreach_res(pool, R_POOL) {
978 * If the Pool has a catalog resource update the pool only
981 if (!pool->catalog || pool->catalog == catalog) {
982 update_pool_references(NULL, db, pool);
986 /* Ensure basic client record is in DB */
988 foreach_res(client, R_CLIENT) {
990 memset(&cr, 0, sizeof(cr));
991 bstrncpy(cr.Name, client->name(), sizeof(cr.Name));
992 db_create_client_record(NULL, db, &cr);
995 /* Ensure basic storage record is in DB */
997 foreach_res(store, R_STORAGE) {
1000 memset(&sr, 0, sizeof(sr));
1001 memset(&mr, 0, sizeof(mr));
1002 if (store->media_type) {
1003 bstrncpy(mr.MediaType, store->media_type, sizeof(mr.MediaType));
1005 db_create_mediatype_record(NULL, db, &mr);
1009 bstrncpy(sr.Name, store->name(), sizeof(sr.Name));
1010 sr.AutoChanger = store->autochanger;
1011 db_create_storage_record(NULL, db, &sr);
1012 store->StorageId = sr.StorageId; /* set storage Id */
1013 if (!sr.created) { /* if not created, update it */
1014 sr.AutoChanger = store->autochanger;
1015 db_update_storage_record(NULL, db, &sr);
1018 /* tls_require implies tls_enable */
1019 if (store->tls_require) {
1021 store->tls_enable = true;
1023 Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
1028 need_tls = store->tls_enable || store->tls_authenticate;
1030 if ((!store->tls_ca_certfile && !store->tls_ca_certdir) && need_tls) {
1031 Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\""
1032 " or \"TLS CA Certificate Dir\" are defined for Storage \"%s\" in %s.\n"),
1033 store->name(), configfile);
1037 /* If everything is well, attempt to initialize our per-resource TLS context */
1038 if (OK && (need_tls || store->tls_require)) {
1039 /* Initialize TLS context:
1040 * Args: CA certfile, CA certdir, Certfile, Keyfile,
1041 * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
1042 store->tls_ctx = new_tls_context(store->tls_ca_certfile,
1043 store->tls_ca_certdir, store->tls_certfile,
1044 store->tls_keyfile, NULL, NULL, NULL, true);
1046 if (!store->tls_ctx) {
1047 Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for Storage \"%s\" in %s.\n"),
1048 store->name(), configfile);
1054 /* Loop over all counters, defining them in each database */
1055 /* Set default value in all counters */
1057 foreach_res(counter, R_COUNTER) {
1058 /* Write to catalog? */
1059 if (!counter->created && counter->Catalog == catalog) {
1061 bstrncpy(cr.Counter, counter->name(), sizeof(cr.Counter));
1062 cr.MinValue = counter->MinValue;
1063 cr.MaxValue = counter->MaxValue;
1064 cr.CurrentValue = counter->MinValue;
1065 if (counter->WrapCounter) {
1066 bstrncpy(cr.WrapCounter, counter->WrapCounter->name(), sizeof(cr.WrapCounter));
1068 cr.WrapCounter[0] = 0; /* empty string */
1070 if (db_create_counter_record(NULL, db, &cr)) {
1071 counter->CurrentValue = cr.CurrentValue;
1072 counter->created = true;
1073 Dmsg2(100, "Create counter %s val=%d\n", counter->name(), counter->CurrentValue);
1076 if (!counter->created) {
1077 counter->CurrentValue = counter->MinValue; /* default value */
1080 /* cleanup old job records */
1081 if (mode == UPDATE_AND_FIX) {
1082 db_sql_query(db, cleanup_created_job, NULL, NULL);
1083 db_sql_query(db, cleanup_running_job, NULL, NULL);
1084 db_sql_query(db, "CREATE INDEX basefiles_jobid_idx ON BaseFiles ( JobId )" , NULL, NULL);
1087 db_close_database(NULL, db);
1089 /* Set type in global for debugging */
1090 set_db_type(db_get_type());