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 bool check_catalog();
57 static void dir_sql_query(JCR *jcr, const char *cmd);
59 /* Exported subroutines */
60 extern "C" void reload_config(int sig);
61 extern void invalidate_schedules();
62 extern bool parse_dir_config(CONFIG *config, const char *configfile, int exit_code);
64 /* Imported subroutines */
65 JCR *wait_for_next_job(char *runjob);
66 void term_scheduler();
67 void term_ua_server();
68 void start_UA_server(dlist *addrs);
69 void init_job_server(int max_workers);
70 void term_job_server();
71 void store_jobtype(LEX *lc, RES_ITEM *item, int index, int pass);
72 void store_level(LEX *lc, RES_ITEM *item, int index, int pass);
73 void store_replace(LEX *lc, RES_ITEM *item, int index, int pass);
74 void store_migtype(LEX *lc, RES_ITEM *item, int index, int pass);
75 void init_device_resources();
77 static char *runjob = NULL;
78 static int background = 1;
79 static void init_reload(void);
80 static CONFIG *config;
82 /* Globals Exported */
83 DIRRES *director; /* Director resource */
86 char *configfile = NULL;
89 /* Globals Imported */
90 extern RES_ITEM job_items[];
92 extern "C" { // work around visual compiler mangling variables
99 #define CONFIG_FILE "bacula-dir.conf" /* default configuration file */
105 "\nVersion: %s (%s)\n\n"
106 "Usage: dird [-f -s] [-c config_file] [-d debug_level] [config_file]\n"
107 " -c <file> set configuration file to file\n"
108 " -d <nn> set debug level to <nn>\n"
109 " -dt print timestamp in debug output\n"
110 " -f run in foreground (for debugging)\n"
112 " -r <job> run <job> now\n"
114 " -t test - read configuration and exit\n"
116 " -v verbose user messages\n"
117 " -? print this message.\n"
118 "\n"), 2000, VERSION, BDATE);
124 /*********************************************************************
126 * Main Bacula Server program
129 #if defined(HAVE_WIN32)
130 /* For Win32 main() is in src/win32 code ... */
131 #define main BaculaMain
134 int main (int argc, char *argv[])
138 bool no_signals = false;
139 bool test_config = false;
143 init_python_interpreter_args python_args;
144 #endif /* HAVE_PYTHON */
146 start_heap = sbrk(0);
147 setlocale(LC_ALL, "");
148 bindtextdomain("bacula", LOCALEDIR);
149 textdomain("bacula");
152 my_name_is(argc, argv, "bacula-dir");
153 init_msg(NULL, NULL); /* initialize message handler */
155 daemon_start_time = time(NULL);
157 console_command = run_console_command;
159 while ((ch = getopt(argc, argv, "c:d:fg:r:stu:v?")) != -1) {
161 case 'c': /* specify config file */
162 if (configfile != NULL) {
165 configfile = bstrdup(optarg);
168 case 'd': /* set debug level */
169 if (*optarg == 't') {
170 dbg_timestamp = true;
172 debug_level = atoi(optarg);
173 if (debug_level <= 0) {
177 Dmsg1(10, "Debug level = %d\n", debug_level);
180 case 'f': /* run in foreground */
184 case 'g': /* set group id */
188 case 'r': /* run job */
189 if (runjob != NULL) {
193 runjob = bstrdup(optarg);
197 case 's': /* turn off signals */
201 case 't': /* test config */
205 case 'u': /* set uid */
209 case 'v': /* verbose */
223 init_signals(terminate_dird);
227 if (configfile != NULL) {
230 configfile = bstrdup(*argv);
238 if (configfile == NULL) {
239 configfile = bstrdup(CONFIG_FILE);
242 config = new_config_parser();
243 parse_dir_config(config, configfile, M_ERROR_TERM);
245 if (init_crypto() != 0) {
246 Jmsg((JCR *)NULL, M_ERROR_TERM, 0, _("Cryptography library initialization failed.\n"));
249 if (!check_resources()) {
250 Jmsg((JCR *)NULL, M_ERROR_TERM, 0, _("Please correct configuration file: %s\n"), configfile);
253 if (!test_config) { /* we don't need to do this block in test mode */
256 init_stack_dump(); /* grab new pid */
259 /* Create pid must come after we are a daemon -- so we have our final pid */
260 create_pid_file(director->pid_directory, "bacula-dir", get_first_port_host_order(director->DIRaddrs));
261 read_state_file(director->working_directory, "bacula-dir", get_first_port_host_order(director->DIRaddrs));
264 load_dir_plugins(director->plugin_directory);
266 drop(uid, gid); /* reduce privileges if requested */
268 if (!check_catalog()) {
269 Jmsg((JCR *)NULL, M_ERROR_TERM, 0, _("Please correct configuration file: %s\n"), configfile);
276 my_name_is(0, NULL, director->name()); /* set user defined name */
278 /* Plug database interface for library routines */
279 p_sql_query = (sql_query)dir_sql_query;
280 p_sql_escape = (sql_escape)db_escape_string;
282 FDConnectTimeout = (int)director->FDConnectTimeout;
283 SDConnectTimeout = (int)director->SDConnectTimeout;
285 #if !defined(HAVE_WIN32)
286 signal(SIGHUP, reload_config);
289 init_console_msg(working_directory);
292 python_args.progname = director->name();
293 python_args.scriptdir = director->scripts_directory;
294 python_args.modulename = "DirStartUp";
295 python_args.configfile = configfile;
296 python_args.workingdir = director->working_directory;
297 python_args.job_getattr = job_getattr;
298 python_args.job_setattr = job_setattr;
300 init_python_interpreter(&python_args);
301 #endif /* HAVE_PYTHON */
303 set_jcr_in_tsd(INVALID_JCR);
304 set_thread_concurrency(director->MaxConcurrentJobs * 2 +
305 4 /* UA */ + 4 /* sched+watchdog+jobsvr+misc */);
307 Dmsg0(200, "Start UA server\n");
308 start_UA_server(director->DIRaddrs);
310 start_watchdog(); /* start network watchdog thread */
312 init_jcr_subsystem(); /* start JCR watchdogs etc. */
314 init_job_server(director->MaxConcurrentJobs);
316 dbg_jcr_add_hook(_dbg_print_db); /* used to debug B_DB connexion after fatal signal */
318 // init_device_resources();
320 Dmsg0(200, "wait for next job\n");
321 /* Main loop -- call scheduler to get next job to run */
322 while ( (jcr = wait_for_next_job(runjob)) ) {
323 run_job(jcr); /* run job */
324 free_jcr(jcr); /* release jcr */
325 set_jcr_in_tsd(INVALID_JCR);
326 if (runjob) { /* command line, run a single job? */
327 break; /* yes, terminate */
337 * This allows the message handler to operate on the database
338 * by using a pointer to this function. The pointer is
339 * needed because the other daemons do not have access
340 * to the database. If the pointer is
341 * not defined (other daemons), then writing the database
344 static void dir_sql_query(JCR *jcr, const char *cmd)
346 if (!jcr || !jcr->db) {
349 db_sql_query(jcr->db, cmd, NULL, NULL);
352 /* Cleanup and then exit */
353 void terminate_dird(int sig)
355 static bool already_here = false;
357 if (already_here) { /* avoid recursive temination problems */
358 bmicrosleep(2, 0); /* yield */
362 debug_level = 0; /* turn off debug */
364 generate_daemon_event(NULL, "Exit");
366 write_state_file(director->working_directory, "bacula-dir", get_first_port_host_order(director->DIRaddrs));
367 delete_pid_file(director->pid_directory, "bacula-dir", get_first_port_host_order(director->DIRaddrs));
373 if (configfile != NULL) {
376 if (debug_level > 5) {
377 print_memory_pool_stats();
380 config->free_resources();
385 term_msg(); /* terminate message handler */
387 close_memory_pool(); /* release free memory in pool */
393 struct RELOAD_TABLE {
398 static const int max_reloads = 32;
399 static RELOAD_TABLE reload_table[max_reloads];
401 static void init_reload(void)
403 for (int i=0; i < max_reloads; i++) {
404 reload_table[i].job_count = 0;
405 reload_table[i].res_table = NULL;
409 static void free_saved_resources(int table)
411 int num = r_last - r_first + 1;
412 RES **res_tab = reload_table[table].res_table;
414 Dmsg1(100, "res_tab for table %d already released.\n", table);
417 Dmsg1(100, "Freeing resources for table %d\n", table);
418 for (int j=0; j<num; j++) {
419 free_resource(res_tab[j], r_first + j);
422 reload_table[table].job_count = 0;
423 reload_table[table].res_table = NULL;
427 * Called here at the end of every job that was
428 * hooked decrementing the active job_count. When
429 * it goes to zero, no one is using the associated
430 * resource table, so free it.
432 static void reload_job_end_cb(JCR *jcr, void *ctx)
434 int reload_id = (int)((long int)ctx);
435 Dmsg3(100, "reload job_end JobId=%d table=%d cnt=%d\n", jcr->JobId,
436 reload_id, reload_table[reload_id].job_count);
439 if (--reload_table[reload_id].job_count <= 0) {
440 free_saved_resources(reload_id);
446 static int find_free_reload_table_entry()
449 for (int i=0; i < max_reloads; i++) {
450 if (reload_table[i].res_table == NULL) {
459 * If we get here, we have received a SIGHUP, which means to
460 * reread our configuration file.
462 * The algorithm used is as follows: we count how many jobs are
463 * running and mark the running jobs to make a callback on
464 * exiting. The old config is saved with the reload table
465 * id in a reload table. The new config file is read. Now, as
466 * each job exits, it calls back to the reload_job_end_cb(), which
467 * decrements the count of open jobs for the given reload table.
468 * When the count goes to zero, we release those resources.
469 * This allows us to have pointers into the resource table (from
470 * jobs), and once they exit and all the pointers are released, we
471 * release the old table. Note, if no new jobs are running since the
472 * last reload, then the old resources will be immediately release.
473 * A console is considered a job because it may have pointers to
474 * resources, but a SYSTEM job is not since it *should* not have any
475 * permanent pointers to jobs.
478 void reload_config(int sig)
480 static bool already_here = false;
481 #if !defined(HAVE_WIN32)
485 int njobs = 0; /* number of running jobs */
490 abort(); /* Oops, recursion -> die */
494 #if !defined(HAVE_WIN32)
496 sigaddset(&set, SIGHUP);
497 sigprocmask(SIG_BLOCK, &set, NULL);
503 table = find_free_reload_table_entry();
505 Jmsg(NULL, M_ERROR, 0, _("Too many open reload requests. Request ignored.\n"));
509 Dmsg1(100, "Reload_config njobs=%d\n", njobs);
510 reload_table[table].res_table = config->save_resources();
511 Dmsg1(100, "Saved old config in table %d\n", table);
513 ok = parse_dir_config(config, configfile, M_ERROR);
515 Dmsg0(100, "Reloaded config file\n");
516 if (!ok || !check_resources() || !check_catalog()) {
517 rtable = find_free_reload_table_entry(); /* save new, bad table */
519 Jmsg(NULL, M_ERROR, 0, _("Please correct configuration file: %s\n"), configfile);
520 Jmsg(NULL, M_ERROR_TERM, 0, _("Out of reload table entries. Giving up.\n"));
522 Jmsg(NULL, M_ERROR, 0, _("Please correct configuration file: %s\n"), configfile);
523 Jmsg(NULL, M_ERROR, 0, _("Resetting previous configuration.\n"));
525 reload_table[rtable].res_table = config->save_resources();
526 /* Now restore old resoure values */
527 int num = r_last - r_first + 1;
528 RES **res_tab = reload_table[table].res_table;
529 for (int i=0; i<num; i++) {
530 res_head[i] = res_tab[i];
532 table = rtable; /* release new, bad, saved table below */
534 invalidate_schedules();
536 * Hook all active jobs so that they release this table
539 if (jcr->get_JobType() != JT_SYSTEM) {
540 reload_table[table].job_count++;
541 job_end_push(jcr, reload_job_end_cb, (void *)((long int)table));
549 set_working_directory(director->working_directory);
550 FDConnectTimeout = director->FDConnectTimeout;
551 SDConnectTimeout = director->SDConnectTimeout;
552 Dmsg0(10, "Director's configuration file reread.\n");
554 /* Now release saved resources, if no jobs using the resources */
556 free_saved_resources(table);
562 #if !defined(HAVE_WIN32)
563 sigprocmask(SIG_UNBLOCK, &set, NULL);
564 signal(SIGHUP, reload_config);
566 already_here = false;
570 * Make a quick check to see that we have all the
573 * **** FIXME **** this routine could be a lot more
574 * intelligent and comprehensive.
576 static bool check_resources()
584 job = (JOB *)GetNextRes(R_JOB, NULL);
585 director = (DIRRES *)GetNextRes(R_DIRECTOR, NULL);
587 Jmsg(NULL, M_FATAL, 0, _("No Director resource defined in %s\n"
588 "Without that I don't know who I am :-(\n"), configfile);
591 set_working_directory(director->working_directory);
592 if (!director->messages) { /* If message resource not specified */
593 director->messages = (MSGS *)GetNextRes(R_MSGS, NULL);
594 if (!director->messages) {
595 Jmsg(NULL, M_FATAL, 0, _("No Messages resource defined in %s\n"), configfile);
599 if (GetNextRes(R_DIRECTOR, (RES *)director) != NULL) {
600 Jmsg(NULL, M_FATAL, 0, _("Only one Director resource permitted in %s\n"),
604 /* tls_require implies tls_enable */
605 if (director->tls_require) {
607 director->tls_enable = true;
609 Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
614 need_tls = director->tls_enable || director->tls_authenticate;
616 if (!director->tls_certfile && need_tls) {
617 Jmsg(NULL, M_FATAL, 0, _("\"TLS Certificate\" file not defined for Director \"%s\" in %s.\n"),
618 director->name(), configfile);
622 if (!director->tls_keyfile && need_tls) {
623 Jmsg(NULL, M_FATAL, 0, _("\"TLS Key\" file not defined for Director \"%s\" in %s.\n"),
624 director->name(), configfile);
628 if ((!director->tls_ca_certfile && !director->tls_ca_certdir) &&
629 need_tls && director->tls_verify_peer) {
630 Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\" or \"TLS CA"
631 " Certificate Dir\" are defined for Director \"%s\" in %s."
632 " At least one CA certificate store is required"
633 " when using \"TLS Verify Peer\".\n"),
634 director->name(), configfile);
638 /* If everything is well, attempt to initialize our per-resource TLS context */
639 if (OK && (need_tls || director->tls_require)) {
640 /* Initialize TLS context:
641 * Args: CA certfile, CA certdir, Certfile, Keyfile,
642 * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
643 director->tls_ctx = new_tls_context(director->tls_ca_certfile,
644 director->tls_ca_certdir, director->tls_certfile,
645 director->tls_keyfile, NULL, NULL, director->tls_dhfile,
646 director->tls_verify_peer);
648 if (!director->tls_ctx) {
649 Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for Director \"%s\" in %s.\n"),
650 director->name(), configfile);
657 Jmsg(NULL, M_FATAL, 0, _("No Job records defined in %s\n"), configfile);
660 foreach_res(job, R_JOB) {
664 /* Handle Storage alists specifically */
665 JOB *jobdefs = job->jobdefs;
666 if (jobdefs->storage && !job->storage) {
668 job->storage = New(alist(10, not_owned_by_alist));
669 foreach_alist(st, jobdefs->storage) {
670 job->storage->append(st);
673 /* Handle RunScripts alists specifically */
674 if (jobdefs->RunScripts) {
677 if (!job->RunScripts) {
678 job->RunScripts = New(alist(10, not_owned_by_alist));
681 foreach_alist(rs, jobdefs->RunScripts) {
682 elt = copy_runscript(rs);
683 job->RunScripts->append(elt); /* we have to free it */
687 /* Transfer default items from JobDefs Resource */
688 for (i=0; job_items[i].name; i++) {
689 char **def_svalue, **svalue; /* string value */
690 uint32_t *def_ivalue, *ivalue; /* integer value */
691 bool *def_bvalue, *bvalue; /* bool value */
692 int64_t *def_lvalue, *lvalue; /* 64 bit values */
695 Dmsg4(1400, "Job \"%s\", field \"%s\" bit=%d def=%d\n",
696 job->name(), job_items[i].name,
697 bit_is_set(i, job->hdr.item_present),
698 bit_is_set(i, job->jobdefs->hdr.item_present));
700 if (!bit_is_set(i, job->hdr.item_present) &&
701 bit_is_set(i, job->jobdefs->hdr.item_present)) {
702 Dmsg2(400, "Job \"%s\", field \"%s\": getting default.\n",
703 job->name(), job_items[i].name);
704 offset = (char *)(job_items[i].value) - (char *)&res_all;
706 * Handle strings and directory strings
708 if (job_items[i].handler == store_str ||
709 job_items[i].handler == store_dir) {
710 def_svalue = (char **)((char *)(job->jobdefs) + offset);
711 Dmsg5(400, "Job \"%s\", field \"%s\" def_svalue=%s item %d offset=%u\n",
712 job->name(), job_items[i].name, *def_svalue, i, offset);
713 svalue = (char **)((char *)job + offset);
715 Pmsg1(000, _("Hey something is wrong. p=0x%lu\n"), *svalue);
717 *svalue = bstrdup(*def_svalue);
718 set_bit(i, job->hdr.item_present);
722 } else if (job_items[i].handler == store_res) {
723 def_svalue = (char **)((char *)(job->jobdefs) + offset);
724 Dmsg4(400, "Job \"%s\", field \"%s\" item %d offset=%u\n",
725 job->name(), job_items[i].name, i, offset);
726 svalue = (char **)((char *)job + offset);
728 Pmsg1(000, _("Hey something is wrong. p=0x%lu\n"), *svalue);
730 *svalue = *def_svalue;
731 set_bit(i, job->hdr.item_present);
733 * Handle alist resources
735 } else if (job_items[i].handler == store_alist_res) {
736 if (bit_is_set(i, job->jobdefs->hdr.item_present)) {
737 set_bit(i, job->hdr.item_present);
740 * Handle integer fields
741 * Note, our store_bit does not handle bitmaped fields
743 } else if (job_items[i].handler == store_bit ||
744 job_items[i].handler == store_pint32 ||
745 job_items[i].handler == store_jobtype ||
746 job_items[i].handler == store_level ||
747 job_items[i].handler == store_int32 ||
748 job_items[i].handler == store_migtype ||
749 job_items[i].handler == store_replace) {
750 def_ivalue = (uint32_t *)((char *)(job->jobdefs) + offset);
751 Dmsg5(400, "Job \"%s\", field \"%s\" def_ivalue=%d item %d offset=%u\n",
752 job->name(), job_items[i].name, *def_ivalue, i, offset);
753 ivalue = (uint32_t *)((char *)job + offset);
754 *ivalue = *def_ivalue;
755 set_bit(i, job->hdr.item_present);
757 * Handle 64 bit integer fields
759 } else if (job_items[i].handler == store_time ||
760 job_items[i].handler == store_size ||
761 job_items[i].handler == store_int64) {
762 def_lvalue = (int64_t *)((char *)(job->jobdefs) + offset);
763 Dmsg5(400, "Job \"%s\", field \"%s\" def_lvalue=%" lld " item %d offset=%u\n",
764 job->name(), job_items[i].name, *def_lvalue, i, offset);
765 lvalue = (int64_t *)((char *)job + offset);
766 *lvalue = *def_lvalue;
767 set_bit(i, job->hdr.item_present);
771 } else if (job_items[i].handler == store_bool) {
772 def_bvalue = (bool *)((char *)(job->jobdefs) + offset);
773 Dmsg5(400, "Job \"%s\", field \"%s\" def_bvalue=%d item %d offset=%u\n",
774 job->name(), job_items[i].name, *def_bvalue, i, offset);
775 bvalue = (bool *)((char *)job + offset);
776 *bvalue = *def_bvalue;
777 set_bit(i, job->hdr.item_present);
783 * Ensure that all required items are present
785 for (i=0; job_items[i].name; i++) {
786 if (job_items[i].flags & ITEM_REQUIRED) {
787 if (!bit_is_set(i, job->hdr.item_present)) {
788 Jmsg(NULL, M_ERROR_TERM, 0, _("\"%s\" directive in Job \"%s\" resource is required, but not found.\n"),
789 job_items[i].name, job->name());
793 /* If this triggers, take a look at lib/parse_conf.h */
794 if (i >= MAX_RES_ITEMS) {
795 Emsg0(M_ERROR_TERM, 0, _("Too many items in Job resource\n"));
798 if (!job->storage && !job->pool->storage) {
799 Jmsg(NULL, M_FATAL, 0, _("No storage specified in Job \"%s\" nor in Pool.\n"),
803 } /* End loop over Job res */
806 /* Loop over Consoles */
808 foreach_res(cons, R_CONSOLE) {
809 /* tls_require implies tls_enable */
810 if (cons->tls_require) {
812 cons->tls_enable = true;
814 Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
820 need_tls = cons->tls_enable || cons->tls_authenticate;
822 if (!cons->tls_certfile && need_tls) {
823 Jmsg(NULL, M_FATAL, 0, _("\"TLS Certificate\" file not defined for Console \"%s\" in %s.\n"),
824 cons->name(), configfile);
828 if (!cons->tls_keyfile && need_tls) {
829 Jmsg(NULL, M_FATAL, 0, _("\"TLS Key\" file not defined for Console \"%s\" in %s.\n"),
830 cons->name(), configfile);
834 if ((!cons->tls_ca_certfile && !cons->tls_ca_certdir)
835 && need_tls && cons->tls_verify_peer) {
836 Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\" or \"TLS CA"
837 " Certificate Dir\" are defined for Console \"%s\" in %s."
838 " At least one CA certificate store is required"
839 " when using \"TLS Verify Peer\".\n"),
840 cons->name(), configfile);
843 /* If everything is well, attempt to initialize our per-resource TLS context */
844 if (OK && (need_tls || cons->tls_require)) {
845 /* Initialize TLS context:
846 * Args: CA certfile, CA certdir, Certfile, Keyfile,
847 * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
848 cons->tls_ctx = new_tls_context(cons->tls_ca_certfile,
849 cons->tls_ca_certdir, cons->tls_certfile,
850 cons->tls_keyfile, NULL, NULL, cons->tls_dhfile, cons->tls_verify_peer);
852 if (!cons->tls_ctx) {
853 Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for File daemon \"%s\" in %s.\n"),
854 cons->name(), configfile);
861 /* Loop over Clients */
863 foreach_res(client, R_CLIENT) {
864 /* tls_require implies tls_enable */
865 if (client->tls_require) {
867 client->tls_enable = true;
869 Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
874 need_tls = client->tls_enable || client->tls_authenticate;
875 if ((!client->tls_ca_certfile && !client->tls_ca_certdir) && need_tls) {
876 Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\""
877 " or \"TLS CA Certificate Dir\" are defined for File daemon \"%s\" in %s.\n"),
878 client->name(), configfile);
882 /* If everything is well, attempt to initialize our per-resource TLS context */
883 if (OK && (need_tls || client->tls_require)) {
884 /* Initialize TLS context:
885 * Args: CA certfile, CA certdir, Certfile, Keyfile,
886 * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
887 client->tls_ctx = new_tls_context(client->tls_ca_certfile,
888 client->tls_ca_certdir, client->tls_certfile,
889 client->tls_keyfile, NULL, NULL, NULL,
892 if (!client->tls_ctx) {
893 Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for File daemon \"%s\" in %s.\n"),
894 client->name(), configfile);
902 close_msg(NULL); /* close temp message handler */
903 init_msg(NULL, director->messages); /* open daemon message handler */
908 static bool check_catalog()
913 /* Loop over databases */
915 foreach_res(catalog, R_CATALOG) {
918 * Make sure we can open catalog, otherwise print a warning
919 * message because the server is probably not running.
921 db = db_init(NULL, catalog->db_driver, catalog->db_name, catalog->db_user,
922 catalog->db_password, catalog->db_address,
923 catalog->db_port, catalog->db_socket,
924 catalog->mult_db_connections);
925 if (!db || !db_open_database(NULL, db)) {
926 Pmsg2(000, _("Could not open Catalog \"%s\", database \"%s\".\n"),
927 catalog->name(), catalog->db_name);
928 Jmsg(NULL, M_FATAL, 0, _("Could not open Catalog \"%s\", database \"%s\".\n"),
929 catalog->name(), catalog->db_name);
931 Jmsg(NULL, M_FATAL, 0, _("%s"), db_strerror(db));
932 Pmsg1(000, "%s", db_strerror(db));
933 db_close_database(NULL, db);
939 /* Loop over all pools, defining/updating them in each database */
941 foreach_res(pool, R_POOL) {
943 * If the Pool has a catalog resource create the pool only
946 if (!pool->catalog || pool->catalog == catalog) {
947 create_pool(NULL, db, pool, POOL_OP_UPDATE); /* update request */
951 /* Once they are created, we can loop over them again, updating
952 * references (RecyclePool)
954 foreach_res(pool, R_POOL) {
956 * If the Pool has a catalog resource update the pool only
959 if (!pool->catalog || pool->catalog == catalog) {
960 update_pool_references(NULL, db, pool);
965 foreach_res(store, R_STORAGE) {
968 if (store->media_type) {
969 bstrncpy(mr.MediaType, store->media_type, sizeof(mr.MediaType));
971 db_create_mediatype_record(NULL, db, &mr);
975 bstrncpy(sr.Name, store->name(), sizeof(sr.Name));
976 sr.AutoChanger = store->autochanger;
977 db_create_storage_record(NULL, db, &sr);
978 store->StorageId = sr.StorageId; /* set storage Id */
979 if (!sr.created) { /* if not created, update it */
980 sr.AutoChanger = store->autochanger;
981 db_update_storage_record(NULL, db, &sr);
984 /* tls_require implies tls_enable */
985 if (store->tls_require) {
987 store->tls_enable = true;
989 Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
994 need_tls = store->tls_enable || store->tls_authenticate;
996 if ((!store->tls_ca_certfile && !store->tls_ca_certdir) && need_tls) {
997 Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\""
998 " or \"TLS CA Certificate Dir\" are defined for Storage \"%s\" in %s.\n"),
999 store->name(), configfile);
1003 /* If everything is well, attempt to initialize our per-resource TLS context */
1004 if (OK && (need_tls || store->tls_require)) {
1005 /* Initialize TLS context:
1006 * Args: CA certfile, CA certdir, Certfile, Keyfile,
1007 * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
1008 store->tls_ctx = new_tls_context(store->tls_ca_certfile,
1009 store->tls_ca_certdir, store->tls_certfile,
1010 store->tls_keyfile, NULL, NULL, NULL, true);
1012 if (!store->tls_ctx) {
1013 Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for Storage \"%s\" in %s.\n"),
1014 store->name(), configfile);
1020 /* Loop over all counters, defining them in each database */
1021 /* Set default value in all counters */
1023 foreach_res(counter, R_COUNTER) {
1024 /* Write to catalog? */
1025 if (!counter->created && counter->Catalog == catalog) {
1027 bstrncpy(cr.Counter, counter->name(), sizeof(cr.Counter));
1028 cr.MinValue = counter->MinValue;
1029 cr.MaxValue = counter->MaxValue;
1030 cr.CurrentValue = counter->MinValue;
1031 if (counter->WrapCounter) {
1032 bstrncpy(cr.WrapCounter, counter->WrapCounter->name(), sizeof(cr.WrapCounter));
1034 cr.WrapCounter[0] = 0; /* empty string */
1036 if (db_create_counter_record(NULL, db, &cr)) {
1037 counter->CurrentValue = cr.CurrentValue;
1038 counter->created = true;
1039 Dmsg2(100, "Create counter %s val=%d\n", counter->name(), counter->CurrentValue);
1042 if (!counter->created) {
1043 counter->CurrentValue = counter->MinValue; /* default value */
1046 db_close_database(NULL, db);
1048 /* Set type in global for debugging */
1049 set_db_type(db_get_type());