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
41 #undef _POSIX_C_SOURCE
44 #include "lib/pythonlib.h"
46 /* Imported Functions */
47 extern PyObject *job_getattr(PyObject *self, char *attrname);
48 extern int job_setattr(PyObject *self, char *attrname, PyObject *value);
50 #endif /* HAVE_PYTHON */
52 /* Forward referenced subroutines */
53 void terminate_dird(int sig);
54 static bool check_resources();
55 static void dir_sql_query(JCR *jcr, const char *cmd);
57 /* Exported subroutines */
58 extern "C" void reload_config(int sig);
59 extern void invalidate_schedules();
60 extern bool parse_dir_config(CONFIG *config, const char *configfile, int exit_code);
62 /* Imported subroutines */
63 JCR *wait_for_next_job(char *runjob);
64 void term_scheduler();
65 void term_ua_server();
66 void start_UA_server(dlist *addrs);
67 void init_job_server(int max_workers);
68 void term_job_server();
69 void store_jobtype(LEX *lc, RES_ITEM *item, int index, int pass);
70 void store_level(LEX *lc, RES_ITEM *item, int index, int pass);
71 void store_replace(LEX *lc, RES_ITEM *item, int index, int pass);
72 void store_migtype(LEX *lc, RES_ITEM *item, int index, int pass);
73 void init_device_resources();
75 static char *runjob = NULL;
76 static bool background = true;
77 static void init_reload(void);
78 static CONFIG *config;
80 /* Globals Exported */
81 DIRRES *director; /* Director resource */
84 char *configfile = NULL;
87 /* Globals Imported */
88 extern RES_ITEM job_items[];
90 extern "C" { // work around visual compiler mangling variables
98 CHECK_CONNECTION, /* Check catalog connection */
99 UPDATE_CATALOG, /* Ensure that catalog is ok with conf */
100 UPDATE_AND_FIX /* Ensure that catalog is ok, and fix old jobs */
102 static bool check_catalog(cat_op mode);
104 #define CONFIG_FILE "bacula-dir.conf" /* default configuration file */
111 "\nVersion: %s (%s)\n\n"
112 "Usage: dird [-f -s] [-c config_file] [-d debug_level] [config_file]\n"
113 " -c <file> set configuration file to file\n"
114 " -d <nn> set debug level to <nn>\n"
115 " -dt print timestamp in debug output\n"
116 " -f run in foreground (for debugging)\n"
118 " -m print kaboom output (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 Director 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:mr: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 'm': /* print kaboom output */
199 case 'r': /* run job */
200 if (runjob != NULL) {
204 runjob = bstrdup(optarg);
208 case 's': /* turn off signals */
212 case 't': /* test config */
216 case 'u': /* set uid */
220 case 'v': /* verbose */
234 init_signals(terminate_dird);
238 if (configfile != NULL) {
241 configfile = bstrdup(*argv);
249 if (configfile == NULL) {
250 configfile = bstrdup(CONFIG_FILE);
253 config = new_config_parser();
254 parse_dir_config(config, configfile, M_ERROR_TERM);
256 if (init_crypto() != 0) {
257 Jmsg((JCR *)NULL, M_ERROR_TERM, 0, _("Cryptography library initialization failed.\n"));
260 if (!check_resources()) {
261 Jmsg((JCR *)NULL, M_ERROR_TERM, 0, _("Please correct configuration file: %s\n"), configfile);
264 if (!test_config) { /* we don't need to do this block in test mode */
267 init_stack_dump(); /* grab new pid */
269 /* Create pid must come after we are a daemon -- so we have our final pid */
270 create_pid_file(director->pid_directory, "bacula-dir",
271 get_first_port_host_order(director->DIRaddrs));
272 read_state_file(director->working_directory, "bacula-dir",
273 get_first_port_host_order(director->DIRaddrs));
276 set_jcr_in_tsd(INVALID_JCR);
277 set_thread_concurrency(director->MaxConcurrentJobs * 2 +
278 4 /* UA */ + 5 /* sched+watchdog+jobsvr+misc */);
279 lmgr_init_thread(); /* initialize the lockmanager stack */
281 load_dir_plugins(director->plugin_directory);
283 drop(uid, gid, false); /* reduce privileges if requested */
285 /* If we are in testing mode, we don't try to fix the catalog */
286 cat_op mode=(test_config)?CHECK_CONNECTION:UPDATE_AND_FIX;
288 if (!check_catalog(mode)) {
289 Jmsg((JCR *)NULL, M_ERROR_TERM, 0, _("Please correct configuration file: %s\n"), configfile);
296 my_name_is(0, NULL, director->name()); /* set user defined name */
298 /* Plug database interface for library routines */
299 p_sql_query = (sql_query)dir_sql_query;
300 p_sql_escape = (sql_escape)db_escape_string;
302 FDConnectTimeout = (int)director->FDConnectTimeout;
303 SDConnectTimeout = (int)director->SDConnectTimeout;
305 #if !defined(HAVE_WIN32)
306 signal(SIGHUP, reload_config);
309 init_console_msg(working_directory);
312 python_args.progname = director->name();
313 python_args.scriptdir = director->scripts_directory;
314 python_args.modulename = "DirStartUp";
315 python_args.configfile = configfile;
316 python_args.workingdir = director->working_directory;
317 python_args.job_getattr = job_getattr;
318 python_args.job_setattr = job_setattr;
320 init_python_interpreter(&python_args);
321 #endif /* HAVE_PYTHON */
323 Dmsg0(200, "Start UA server\n");
324 start_UA_server(director->DIRaddrs);
326 start_watchdog(); /* start network watchdog thread */
328 init_jcr_subsystem(); /* start JCR watchdogs etc. */
330 init_job_server(director->MaxConcurrentJobs);
332 dbg_jcr_add_hook(db_debug_print); /* used to debug B_DB connexion after fatal signal */
334 // init_device_resources();
336 Dmsg0(200, "wait for next job\n");
337 /* Main loop -- call scheduler to get next job to run */
338 while ( (jcr = wait_for_next_job(runjob)) ) {
339 run_job(jcr); /* run job */
340 free_jcr(jcr); /* release jcr */
341 set_jcr_in_tsd(INVALID_JCR);
342 if (runjob) { /* command line, run a single job? */
343 break; /* yes, terminate */
353 * This allows the message handler to operate on the database
354 * by using a pointer to this function. The pointer is
355 * needed because the other daemons do not have access
356 * to the database. If the pointer is
357 * not defined (other daemons), then writing the database
360 static void dir_sql_query(JCR *jcr, const char *cmd)
362 if (!jcr || !jcr->db) {
365 db_sql_query(jcr->db, cmd, NULL, NULL);
368 /* Cleanup and then exit */
369 void terminate_dird(int sig)
371 static bool already_here = false;
373 if (already_here) { /* avoid recursive temination problems */
374 bmicrosleep(2, 0); /* yield */
378 debug_level = 0; /* turn off debug */
380 generate_daemon_event(NULL, "Exit");
382 write_state_file(director->working_directory, "bacula-dir", get_first_port_host_order(director->DIRaddrs));
383 delete_pid_file(director->pid_directory, "bacula-dir", get_first_port_host_order(director->DIRaddrs));
389 if (configfile != NULL) {
392 if (debug_level > 5) {
393 print_memory_pool_stats();
396 config->free_resources();
401 term_msg(); /* terminate message handler */
403 close_memory_pool(); /* release free memory in pool */
409 struct RELOAD_TABLE {
414 static const int max_reloads = 32;
415 static RELOAD_TABLE reload_table[max_reloads];
417 static void init_reload(void)
419 for (int i=0; i < max_reloads; i++) {
420 reload_table[i].job_count = 0;
421 reload_table[i].res_table = NULL;
425 static void free_saved_resources(int table)
427 int num = r_last - r_first + 1;
428 RES **res_tab = reload_table[table].res_table;
430 Dmsg1(100, "res_tab for table %d already released.\n", table);
433 Dmsg1(100, "Freeing resources for table %d\n", table);
434 for (int j=0; j<num; j++) {
435 free_resource(res_tab[j], r_first + j);
438 reload_table[table].job_count = 0;
439 reload_table[table].res_table = NULL;
443 * Called here at the end of every job that was
444 * hooked decrementing the active job_count. When
445 * it goes to zero, no one is using the associated
446 * resource table, so free it.
448 static void reload_job_end_cb(JCR *jcr, void *ctx)
450 int reload_id = (int)((long int)ctx);
451 Dmsg3(100, "reload job_end JobId=%d table=%d cnt=%d\n", jcr->JobId,
452 reload_id, reload_table[reload_id].job_count);
455 if (--reload_table[reload_id].job_count <= 0) {
456 free_saved_resources(reload_id);
462 static int find_free_reload_table_entry()
465 for (int i=0; i < max_reloads; i++) {
466 if (reload_table[i].res_table == NULL) {
475 * If we get here, we have received a SIGHUP, which means to
476 * reread our configuration file.
478 * The algorithm used is as follows: we count how many jobs are
479 * running and mark the running jobs to make a callback on
480 * exiting. The old config is saved with the reload table
481 * id in a reload table. The new config file is read. Now, as
482 * each job exits, it calls back to the reload_job_end_cb(), which
483 * decrements the count of open jobs for the given reload table.
484 * When the count goes to zero, we release those resources.
485 * This allows us to have pointers into the resource table (from
486 * jobs), and once they exit and all the pointers are released, we
487 * release the old table. Note, if no new jobs are running since the
488 * last reload, then the old resources will be immediately release.
489 * A console is considered a job because it may have pointers to
490 * resources, but a SYSTEM job is not since it *should* not have any
491 * permanent pointers to jobs.
494 void reload_config(int sig)
496 static bool already_here = false;
497 #if !defined(HAVE_WIN32)
501 int njobs = 0; /* number of running jobs */
506 abort(); /* Oops, recursion -> die */
510 #if !defined(HAVE_WIN32)
512 sigaddset(&set, SIGHUP);
513 sigprocmask(SIG_BLOCK, &set, NULL);
519 table = find_free_reload_table_entry();
521 Jmsg(NULL, M_ERROR, 0, _("Too many open reload requests. Request ignored.\n"));
525 Dmsg1(100, "Reload_config njobs=%d\n", njobs);
526 reload_table[table].res_table = config->save_resources();
527 Dmsg1(100, "Saved old config in table %d\n", table);
529 ok = parse_dir_config(config, configfile, M_ERROR);
531 Dmsg0(100, "Reloaded config file\n");
532 if (!ok || !check_resources() || !check_catalog(UPDATE_CATALOG)) {
533 rtable = find_free_reload_table_entry(); /* save new, bad table */
535 Jmsg(NULL, M_ERROR, 0, _("Please correct configuration file: %s\n"), configfile);
536 Jmsg(NULL, M_ERROR_TERM, 0, _("Out of reload table entries. Giving up.\n"));
538 Jmsg(NULL, M_ERROR, 0, _("Please correct configuration file: %s\n"), configfile);
539 Jmsg(NULL, M_ERROR, 0, _("Resetting previous configuration.\n"));
541 reload_table[rtable].res_table = config->save_resources();
542 /* Now restore old resoure values */
543 int num = r_last - r_first + 1;
544 RES **res_tab = reload_table[table].res_table;
545 for (int i=0; i<num; i++) {
546 res_head[i] = res_tab[i];
548 table = rtable; /* release new, bad, saved table below */
550 invalidate_schedules();
552 * Hook all active jobs so that they release this table
555 if (jcr->getJobType() != JT_SYSTEM) {
556 reload_table[table].job_count++;
557 job_end_push(jcr, reload_job_end_cb, (void *)((long int)table));
565 set_working_directory(director->working_directory);
566 FDConnectTimeout = director->FDConnectTimeout;
567 SDConnectTimeout = director->SDConnectTimeout;
568 Dmsg0(10, "Director's configuration file reread.\n");
570 /* Now release saved resources, if no jobs using the resources */
572 free_saved_resources(table);
578 #if !defined(HAVE_WIN32)
579 sigprocmask(SIG_UNBLOCK, &set, NULL);
580 signal(SIGHUP, reload_config);
582 already_here = false;
586 * Make a quick check to see that we have all the
589 * **** FIXME **** this routine could be a lot more
590 * intelligent and comprehensive.
592 static bool check_resources()
600 job = (JOB *)GetNextRes(R_JOB, NULL);
601 director = (DIRRES *)GetNextRes(R_DIRECTOR, NULL);
603 Jmsg(NULL, M_FATAL, 0, _("No Director resource defined in %s\n"
604 "Without that I don't know who I am :-(\n"), configfile);
607 set_working_directory(director->working_directory);
608 if (!director->messages) { /* If message resource not specified */
609 director->messages = (MSGS *)GetNextRes(R_MSGS, NULL);
610 if (!director->messages) {
611 Jmsg(NULL, M_FATAL, 0, _("No Messages resource defined in %s\n"), configfile);
615 if (GetNextRes(R_DIRECTOR, (RES *)director) != NULL) {
616 Jmsg(NULL, M_FATAL, 0, _("Only one Director resource permitted in %s\n"),
620 /* tls_require implies tls_enable */
621 if (director->tls_require) {
623 director->tls_enable = true;
625 Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
630 need_tls = director->tls_enable || director->tls_authenticate;
632 if (!director->tls_certfile && need_tls) {
633 Jmsg(NULL, M_FATAL, 0, _("\"TLS Certificate\" file not defined for Director \"%s\" in %s.\n"),
634 director->name(), configfile);
638 if (!director->tls_keyfile && need_tls) {
639 Jmsg(NULL, M_FATAL, 0, _("\"TLS Key\" file not defined for Director \"%s\" in %s.\n"),
640 director->name(), configfile);
644 if ((!director->tls_ca_certfile && !director->tls_ca_certdir) &&
645 need_tls && director->tls_verify_peer) {
646 Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\" or \"TLS CA"
647 " Certificate Dir\" are defined for Director \"%s\" in %s."
648 " At least one CA certificate store is required"
649 " when using \"TLS Verify Peer\".\n"),
650 director->name(), configfile);
654 /* If everything is well, attempt to initialize our per-resource TLS context */
655 if (OK && (need_tls || director->tls_require)) {
656 /* Initialize TLS context:
657 * Args: CA certfile, CA certdir, Certfile, Keyfile,
658 * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
659 director->tls_ctx = new_tls_context(director->tls_ca_certfile,
660 director->tls_ca_certdir, director->tls_certfile,
661 director->tls_keyfile, NULL, NULL, director->tls_dhfile,
662 director->tls_verify_peer);
664 if (!director->tls_ctx) {
665 Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for Director \"%s\" in %s.\n"),
666 director->name(), configfile);
673 Jmsg(NULL, M_FATAL, 0, _("No Job records defined in %s\n"), configfile);
676 foreach_res(job, R_JOB) {
680 /* Handle Storage alists specifically */
681 JOB *jobdefs = job->jobdefs;
682 if (jobdefs->storage && !job->storage) {
684 job->storage = New(alist(10, not_owned_by_alist));
685 foreach_alist(st, jobdefs->storage) {
686 job->storage->append(st);
689 /* Handle RunScripts alists specifically */
690 if (jobdefs->RunScripts) {
693 if (!job->RunScripts) {
694 job->RunScripts = New(alist(10, not_owned_by_alist));
697 foreach_alist(rs, jobdefs->RunScripts) {
698 elt = copy_runscript(rs);
699 job->RunScripts->append(elt); /* we have to free it */
703 /* Transfer default items from JobDefs Resource */
704 for (i=0; job_items[i].name; i++) {
705 char **def_svalue, **svalue; /* string value */
706 uint32_t *def_ivalue, *ivalue; /* integer value */
707 bool *def_bvalue, *bvalue; /* bool value */
708 int64_t *def_lvalue, *lvalue; /* 64 bit values */
711 Dmsg4(1400, "Job \"%s\", field \"%s\" bit=%d def=%d\n",
712 job->name(), job_items[i].name,
713 bit_is_set(i, job->hdr.item_present),
714 bit_is_set(i, job->jobdefs->hdr.item_present));
716 if (!bit_is_set(i, job->hdr.item_present) &&
717 bit_is_set(i, job->jobdefs->hdr.item_present)) {
718 Dmsg2(400, "Job \"%s\", field \"%s\": getting default.\n",
719 job->name(), job_items[i].name);
720 offset = (char *)(job_items[i].value) - (char *)&res_all;
722 * Handle strings and directory strings
724 if (job_items[i].handler == store_str ||
725 job_items[i].handler == store_dir) {
726 def_svalue = (char **)((char *)(job->jobdefs) + offset);
727 Dmsg5(400, "Job \"%s\", field \"%s\" def_svalue=%s item %d offset=%u\n",
728 job->name(), job_items[i].name, *def_svalue, i, offset);
729 svalue = (char **)((char *)job + offset);
731 Pmsg1(000, _("Hey something is wrong. p=0x%lu\n"), *svalue);
733 *svalue = bstrdup(*def_svalue);
734 set_bit(i, job->hdr.item_present);
738 } else if (job_items[i].handler == store_res) {
739 def_svalue = (char **)((char *)(job->jobdefs) + offset);
740 Dmsg4(400, "Job \"%s\", field \"%s\" item %d offset=%u\n",
741 job->name(), job_items[i].name, i, offset);
742 svalue = (char **)((char *)job + offset);
744 Pmsg1(000, _("Hey something is wrong. p=0x%lu\n"), *svalue);
746 *svalue = *def_svalue;
747 set_bit(i, job->hdr.item_present);
749 * Handle alist resources
751 } else if (job_items[i].handler == store_alist_res) {
752 if (bit_is_set(i, job->jobdefs->hdr.item_present)) {
753 set_bit(i, job->hdr.item_present);
756 * Handle integer fields
757 * Note, our store_bit does not handle bitmaped fields
759 } else if (job_items[i].handler == store_bit ||
760 job_items[i].handler == store_pint32 ||
761 job_items[i].handler == store_jobtype ||
762 job_items[i].handler == store_level ||
763 job_items[i].handler == store_int32 ||
764 job_items[i].handler == store_size32 ||
765 job_items[i].handler == store_migtype ||
766 job_items[i].handler == store_replace) {
767 def_ivalue = (uint32_t *)((char *)(job->jobdefs) + offset);
768 Dmsg5(400, "Job \"%s\", field \"%s\" def_ivalue=%d item %d offset=%u\n",
769 job->name(), job_items[i].name, *def_ivalue, i, offset);
770 ivalue = (uint32_t *)((char *)job + offset);
771 *ivalue = *def_ivalue;
772 set_bit(i, job->hdr.item_present);
774 * Handle 64 bit integer fields
776 } else if (job_items[i].handler == store_time ||
777 job_items[i].handler == store_size64 ||
778 job_items[i].handler == store_int64) {
779 def_lvalue = (int64_t *)((char *)(job->jobdefs) + offset);
780 Dmsg5(400, "Job \"%s\", field \"%s\" def_lvalue=%" lld " item %d offset=%u\n",
781 job->name(), job_items[i].name, *def_lvalue, i, offset);
782 lvalue = (int64_t *)((char *)job + offset);
783 *lvalue = *def_lvalue;
784 set_bit(i, job->hdr.item_present);
788 } else if (job_items[i].handler == store_bool) {
789 def_bvalue = (bool *)((char *)(job->jobdefs) + offset);
790 Dmsg5(400, "Job \"%s\", field \"%s\" def_bvalue=%d item %d offset=%u\n",
791 job->name(), job_items[i].name, *def_bvalue, i, offset);
792 bvalue = (bool *)((char *)job + offset);
793 *bvalue = *def_bvalue;
794 set_bit(i, job->hdr.item_present);
800 * Ensure that all required items are present
802 for (i=0; job_items[i].name; i++) {
803 if (job_items[i].flags & ITEM_REQUIRED) {
804 if (!bit_is_set(i, job->hdr.item_present)) {
805 Jmsg(NULL, M_ERROR_TERM, 0, _("\"%s\" directive in Job \"%s\" resource is required, but not found.\n"),
806 job_items[i].name, job->name());
810 /* If this triggers, take a look at lib/parse_conf.h */
811 if (i >= MAX_RES_ITEMS) {
812 Emsg0(M_ERROR_TERM, 0, _("Too many items in Job resource\n"));
815 if (!job->storage && !job->pool->storage) {
816 Jmsg(NULL, M_FATAL, 0, _("No storage specified in Job \"%s\" nor in Pool.\n"),
820 } /* End loop over Job res */
823 /* Loop over Consoles */
825 foreach_res(cons, R_CONSOLE) {
826 /* tls_require implies tls_enable */
827 if (cons->tls_require) {
829 cons->tls_enable = true;
831 Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
837 need_tls = cons->tls_enable || cons->tls_authenticate;
839 if (!cons->tls_certfile && need_tls) {
840 Jmsg(NULL, M_FATAL, 0, _("\"TLS Certificate\" file not defined for Console \"%s\" in %s.\n"),
841 cons->name(), configfile);
845 if (!cons->tls_keyfile && need_tls) {
846 Jmsg(NULL, M_FATAL, 0, _("\"TLS Key\" file not defined for Console \"%s\" in %s.\n"),
847 cons->name(), configfile);
851 if ((!cons->tls_ca_certfile && !cons->tls_ca_certdir)
852 && need_tls && cons->tls_verify_peer) {
853 Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\" or \"TLS CA"
854 " Certificate Dir\" are defined for Console \"%s\" in %s."
855 " At least one CA certificate store is required"
856 " when using \"TLS Verify Peer\".\n"),
857 cons->name(), configfile);
860 /* If everything is well, attempt to initialize our per-resource TLS context */
861 if (OK && (need_tls || cons->tls_require)) {
862 /* Initialize TLS context:
863 * Args: CA certfile, CA certdir, Certfile, Keyfile,
864 * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
865 cons->tls_ctx = new_tls_context(cons->tls_ca_certfile,
866 cons->tls_ca_certdir, cons->tls_certfile,
867 cons->tls_keyfile, NULL, NULL, cons->tls_dhfile, cons->tls_verify_peer);
869 if (!cons->tls_ctx) {
870 Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for File daemon \"%s\" in %s.\n"),
871 cons->name(), configfile);
878 /* Loop over Clients */
880 foreach_res(client, R_CLIENT) {
881 /* tls_require implies tls_enable */
882 if (client->tls_require) {
884 client->tls_enable = true;
886 Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
891 need_tls = client->tls_enable || client->tls_authenticate;
892 if ((!client->tls_ca_certfile && !client->tls_ca_certdir) && need_tls) {
893 Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\""
894 " or \"TLS CA Certificate Dir\" are defined for File daemon \"%s\" in %s.\n"),
895 client->name(), configfile);
899 /* If everything is well, attempt to initialize our per-resource TLS context */
900 if (OK && (need_tls || client->tls_require)) {
901 /* Initialize TLS context:
902 * Args: CA certfile, CA certdir, Certfile, Keyfile,
903 * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
904 client->tls_ctx = new_tls_context(client->tls_ca_certfile,
905 client->tls_ca_certdir, client->tls_certfile,
906 client->tls_keyfile, NULL, NULL, NULL,
909 if (!client->tls_ctx) {
910 Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for File daemon \"%s\" in %s.\n"),
911 client->name(), configfile);
919 close_msg(NULL); /* close temp message handler */
920 init_msg(NULL, director->messages); /* open daemon message handler */
927 * - we can check the connection (mode=CHECK_CONNECTION)
928 * - we can synchronize the catalog with the configuration (mode=UPDATE_CATALOG)
929 * - we can synchronize, and fix old job records (mode=UPDATE_AND_FIX)
931 static bool check_catalog(cat_op mode)
936 /* Loop over databases */
938 foreach_res(catalog, R_CATALOG) {
941 * Make sure we can open catalog, otherwise print a warning
942 * message because the server is probably not running.
944 db = db_init(NULL, catalog->db_driver, catalog->db_name, catalog->db_user,
945 catalog->db_password, catalog->db_address,
946 catalog->db_port, catalog->db_socket,
947 catalog->mult_db_connections);
948 if (!db || !db_open_database(NULL, db)) {
949 Pmsg2(000, _("Could not open Catalog \"%s\", database \"%s\".\n"),
950 catalog->name(), catalog->db_name);
951 Jmsg(NULL, M_FATAL, 0, _("Could not open Catalog \"%s\", database \"%s\".\n"),
952 catalog->name(), catalog->db_name);
954 Jmsg(NULL, M_FATAL, 0, _("%s"), db_strerror(db));
955 Pmsg1(000, "%s", db_strerror(db));
956 db_close_database(NULL, db);
962 /* Display a message if the db max_connections is too low */
963 if (!db_check_max_connections(NULL, db, director->MaxConcurrentJobs+1)) {
964 Pmsg1(000, "Warning, settings problem for Catalog=%s\n", catalog->name());
965 Pmsg1(000, "%s", db_strerror(db));
968 /* we are in testing mode, so don't touch anything in the catalog */
969 if (mode == CHECK_CONNECTION) {
970 db_close_database(NULL, db);
974 /* Loop over all pools, defining/updating them in each database */
976 foreach_res(pool, R_POOL) {
978 * If the Pool has a catalog resource create the pool only
981 if (!pool->catalog || pool->catalog == catalog) {
982 create_pool(NULL, db, pool, POOL_OP_UPDATE); /* update request */
986 /* Once they are created, we can loop over them again, updating
987 * references (RecyclePool)
989 foreach_res(pool, R_POOL) {
991 * If the Pool has a catalog resource update the pool only
994 if (!pool->catalog || pool->catalog == catalog) {
995 update_pool_references(NULL, db, pool);
999 /* Ensure basic client record is in DB */
1001 foreach_res(client, R_CLIENT) {
1003 memset(&cr, 0, sizeof(cr));
1004 bstrncpy(cr.Name, client->name(), sizeof(cr.Name));
1005 db_create_client_record(NULL, db, &cr);
1008 /* Ensure basic storage record is in DB */
1010 foreach_res(store, R_STORAGE) {
1013 memset(&sr, 0, sizeof(sr));
1014 memset(&mr, 0, sizeof(mr));
1015 if (store->media_type) {
1016 bstrncpy(mr.MediaType, store->media_type, sizeof(mr.MediaType));
1018 db_create_mediatype_record(NULL, db, &mr);
1022 bstrncpy(sr.Name, store->name(), sizeof(sr.Name));
1023 sr.AutoChanger = store->autochanger;
1024 db_create_storage_record(NULL, db, &sr);
1025 store->StorageId = sr.StorageId; /* set storage Id */
1026 if (!sr.created) { /* if not created, update it */
1027 sr.AutoChanger = store->autochanger;
1028 db_update_storage_record(NULL, db, &sr);
1031 /* tls_require implies tls_enable */
1032 if (store->tls_require) {
1034 store->tls_enable = true;
1036 Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
1041 need_tls = store->tls_enable || store->tls_authenticate;
1043 if ((!store->tls_ca_certfile && !store->tls_ca_certdir) && need_tls) {
1044 Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\""
1045 " or \"TLS CA Certificate Dir\" are defined for Storage \"%s\" in %s.\n"),
1046 store->name(), configfile);
1050 /* If everything is well, attempt to initialize our per-resource TLS context */
1051 if (OK && (need_tls || store->tls_require)) {
1052 /* Initialize TLS context:
1053 * Args: CA certfile, CA certdir, Certfile, Keyfile,
1054 * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
1055 store->tls_ctx = new_tls_context(store->tls_ca_certfile,
1056 store->tls_ca_certdir, store->tls_certfile,
1057 store->tls_keyfile, NULL, NULL, NULL, true);
1059 if (!store->tls_ctx) {
1060 Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for Storage \"%s\" in %s.\n"),
1061 store->name(), configfile);
1067 /* Loop over all counters, defining them in each database */
1068 /* Set default value in all counters */
1070 foreach_res(counter, R_COUNTER) {
1071 /* Write to catalog? */
1072 if (!counter->created && counter->Catalog == catalog) {
1074 bstrncpy(cr.Counter, counter->name(), sizeof(cr.Counter));
1075 cr.MinValue = counter->MinValue;
1076 cr.MaxValue = counter->MaxValue;
1077 cr.CurrentValue = counter->MinValue;
1078 if (counter->WrapCounter) {
1079 bstrncpy(cr.WrapCounter, counter->WrapCounter->name(), sizeof(cr.WrapCounter));
1081 cr.WrapCounter[0] = 0; /* empty string */
1083 if (db_create_counter_record(NULL, db, &cr)) {
1084 counter->CurrentValue = cr.CurrentValue;
1085 counter->created = true;
1086 Dmsg2(100, "Create counter %s val=%d\n", counter->name(), counter->CurrentValue);
1089 if (!counter->created) {
1090 counter->CurrentValue = counter->MinValue; /* default value */
1093 /* cleanup old job records */
1094 if (mode == UPDATE_AND_FIX) {
1095 db_sql_query(db, cleanup_created_job, NULL, NULL);
1096 db_sql_query(db, cleanup_running_job, NULL, NULL);
1099 db_close_database(NULL, db);
1101 /* Set type in global for debugging */
1102 set_db_type(db_get_type());