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, false); /* 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_size32 ||
759 job_items[i].handler == store_migtype ||
760 job_items[i].handler == store_replace) {
761 def_ivalue = (uint32_t *)((char *)(job->jobdefs) + offset);
762 Dmsg5(400, "Job \"%s\", field \"%s\" def_ivalue=%d item %d offset=%u\n",
763 job->name(), job_items[i].name, *def_ivalue, i, offset);
764 ivalue = (uint32_t *)((char *)job + offset);
765 *ivalue = *def_ivalue;
766 set_bit(i, job->hdr.item_present);
768 * Handle 64 bit integer fields
770 } else if (job_items[i].handler == store_time ||
771 job_items[i].handler == store_size64 ||
772 job_items[i].handler == store_int64) {
773 def_lvalue = (int64_t *)((char *)(job->jobdefs) + offset);
774 Dmsg5(400, "Job \"%s\", field \"%s\" def_lvalue=%" lld " item %d offset=%u\n",
775 job->name(), job_items[i].name, *def_lvalue, i, offset);
776 lvalue = (int64_t *)((char *)job + offset);
777 *lvalue = *def_lvalue;
778 set_bit(i, job->hdr.item_present);
782 } else if (job_items[i].handler == store_bool) {
783 def_bvalue = (bool *)((char *)(job->jobdefs) + offset);
784 Dmsg5(400, "Job \"%s\", field \"%s\" def_bvalue=%d item %d offset=%u\n",
785 job->name(), job_items[i].name, *def_bvalue, i, offset);
786 bvalue = (bool *)((char *)job + offset);
787 *bvalue = *def_bvalue;
788 set_bit(i, job->hdr.item_present);
794 * Ensure that all required items are present
796 for (i=0; job_items[i].name; i++) {
797 if (job_items[i].flags & ITEM_REQUIRED) {
798 if (!bit_is_set(i, job->hdr.item_present)) {
799 Jmsg(NULL, M_ERROR_TERM, 0, _("\"%s\" directive in Job \"%s\" resource is required, but not found.\n"),
800 job_items[i].name, job->name());
804 /* If this triggers, take a look at lib/parse_conf.h */
805 if (i >= MAX_RES_ITEMS) {
806 Emsg0(M_ERROR_TERM, 0, _("Too many items in Job resource\n"));
809 if (!job->storage && !job->pool->storage) {
810 Jmsg(NULL, M_FATAL, 0, _("No storage specified in Job \"%s\" nor in Pool.\n"),
814 } /* End loop over Job res */
817 /* Loop over Consoles */
819 foreach_res(cons, R_CONSOLE) {
820 /* tls_require implies tls_enable */
821 if (cons->tls_require) {
823 cons->tls_enable = true;
825 Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
831 need_tls = cons->tls_enable || cons->tls_authenticate;
833 if (!cons->tls_certfile && need_tls) {
834 Jmsg(NULL, M_FATAL, 0, _("\"TLS Certificate\" file not defined for Console \"%s\" in %s.\n"),
835 cons->name(), configfile);
839 if (!cons->tls_keyfile && need_tls) {
840 Jmsg(NULL, M_FATAL, 0, _("\"TLS Key\" file not defined for Console \"%s\" in %s.\n"),
841 cons->name(), configfile);
845 if ((!cons->tls_ca_certfile && !cons->tls_ca_certdir)
846 && need_tls && cons->tls_verify_peer) {
847 Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\" or \"TLS CA"
848 " Certificate Dir\" are defined for Console \"%s\" in %s."
849 " At least one CA certificate store is required"
850 " when using \"TLS Verify Peer\".\n"),
851 cons->name(), configfile);
854 /* If everything is well, attempt to initialize our per-resource TLS context */
855 if (OK && (need_tls || cons->tls_require)) {
856 /* Initialize TLS context:
857 * Args: CA certfile, CA certdir, Certfile, Keyfile,
858 * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
859 cons->tls_ctx = new_tls_context(cons->tls_ca_certfile,
860 cons->tls_ca_certdir, cons->tls_certfile,
861 cons->tls_keyfile, NULL, NULL, cons->tls_dhfile, cons->tls_verify_peer);
863 if (!cons->tls_ctx) {
864 Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for File daemon \"%s\" in %s.\n"),
865 cons->name(), configfile);
872 /* Loop over Clients */
874 foreach_res(client, R_CLIENT) {
875 /* tls_require implies tls_enable */
876 if (client->tls_require) {
878 client->tls_enable = true;
880 Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
885 need_tls = client->tls_enable || client->tls_authenticate;
886 if ((!client->tls_ca_certfile && !client->tls_ca_certdir) && need_tls) {
887 Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\""
888 " or \"TLS CA Certificate Dir\" are defined for File daemon \"%s\" in %s.\n"),
889 client->name(), configfile);
893 /* If everything is well, attempt to initialize our per-resource TLS context */
894 if (OK && (need_tls || client->tls_require)) {
895 /* Initialize TLS context:
896 * Args: CA certfile, CA certdir, Certfile, Keyfile,
897 * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
898 client->tls_ctx = new_tls_context(client->tls_ca_certfile,
899 client->tls_ca_certdir, client->tls_certfile,
900 client->tls_keyfile, NULL, NULL, NULL,
903 if (!client->tls_ctx) {
904 Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for File daemon \"%s\" in %s.\n"),
905 client->name(), configfile);
913 close_msg(NULL); /* close temp message handler */
914 init_msg(NULL, director->messages); /* open daemon message handler */
921 * - we can check the connection (mode=CHECK_CONNECTION)
922 * - we can synchronize the catalog with the configuration (mode=UPDATE_CATALOG)
923 * - we can synchronize, and fix old job records (mode=UPDATE_AND_FIX)
925 static bool check_catalog(cat_op mode)
930 /* Loop over databases */
932 foreach_res(catalog, R_CATALOG) {
935 * Make sure we can open catalog, otherwise print a warning
936 * message because the server is probably not running.
938 db = db_init(NULL, catalog->db_driver, catalog->db_name, catalog->db_user,
939 catalog->db_password, catalog->db_address,
940 catalog->db_port, catalog->db_socket,
941 catalog->mult_db_connections);
942 if (!db || !db_open_database(NULL, db)) {
943 Pmsg2(000, _("Could not open Catalog \"%s\", database \"%s\".\n"),
944 catalog->name(), catalog->db_name);
945 Jmsg(NULL, M_FATAL, 0, _("Could not open Catalog \"%s\", database \"%s\".\n"),
946 catalog->name(), catalog->db_name);
948 Jmsg(NULL, M_FATAL, 0, _("%s"), db_strerror(db));
949 Pmsg1(000, "%s", db_strerror(db));
950 db_close_database(NULL, db);
956 /* we are in testing mode, so don't touch anything in the catalog */
957 if (mode == CHECK_CONNECTION) {
958 db_close_database(NULL, db);
962 /* Loop over all pools, defining/updating them in each database */
964 foreach_res(pool, R_POOL) {
966 * If the Pool has a catalog resource create the pool only
969 if (!pool->catalog || pool->catalog == catalog) {
970 create_pool(NULL, db, pool, POOL_OP_UPDATE); /* update request */
974 /* Once they are created, we can loop over them again, updating
975 * references (RecyclePool)
977 foreach_res(pool, R_POOL) {
979 * If the Pool has a catalog resource update the pool only
982 if (!pool->catalog || pool->catalog == catalog) {
983 update_pool_references(NULL, db, pool);
987 /* Ensure basic client record is in DB */
989 foreach_res(client, R_CLIENT) {
991 memset(&cr, 0, sizeof(cr));
992 bstrncpy(cr.Name, client->name(), sizeof(cr.Name));
993 db_create_client_record(NULL, db, &cr);
996 /* Ensure basic storage record is in DB */
998 foreach_res(store, R_STORAGE) {
1001 memset(&sr, 0, sizeof(sr));
1002 memset(&mr, 0, sizeof(mr));
1003 if (store->media_type) {
1004 bstrncpy(mr.MediaType, store->media_type, sizeof(mr.MediaType));
1006 db_create_mediatype_record(NULL, db, &mr);
1010 bstrncpy(sr.Name, store->name(), sizeof(sr.Name));
1011 sr.AutoChanger = store->autochanger;
1012 db_create_storage_record(NULL, db, &sr);
1013 store->StorageId = sr.StorageId; /* set storage Id */
1014 if (!sr.created) { /* if not created, update it */
1015 sr.AutoChanger = store->autochanger;
1016 db_update_storage_record(NULL, db, &sr);
1019 /* tls_require implies tls_enable */
1020 if (store->tls_require) {
1022 store->tls_enable = true;
1024 Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
1029 need_tls = store->tls_enable || store->tls_authenticate;
1031 if ((!store->tls_ca_certfile && !store->tls_ca_certdir) && need_tls) {
1032 Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\""
1033 " or \"TLS CA Certificate Dir\" are defined for Storage \"%s\" in %s.\n"),
1034 store->name(), configfile);
1038 /* If everything is well, attempt to initialize our per-resource TLS context */
1039 if (OK && (need_tls || store->tls_require)) {
1040 /* Initialize TLS context:
1041 * Args: CA certfile, CA certdir, Certfile, Keyfile,
1042 * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
1043 store->tls_ctx = new_tls_context(store->tls_ca_certfile,
1044 store->tls_ca_certdir, store->tls_certfile,
1045 store->tls_keyfile, NULL, NULL, NULL, true);
1047 if (!store->tls_ctx) {
1048 Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for Storage \"%s\" in %s.\n"),
1049 store->name(), configfile);
1055 /* Loop over all counters, defining them in each database */
1056 /* Set default value in all counters */
1058 foreach_res(counter, R_COUNTER) {
1059 /* Write to catalog? */
1060 if (!counter->created && counter->Catalog == catalog) {
1062 bstrncpy(cr.Counter, counter->name(), sizeof(cr.Counter));
1063 cr.MinValue = counter->MinValue;
1064 cr.MaxValue = counter->MaxValue;
1065 cr.CurrentValue = counter->MinValue;
1066 if (counter->WrapCounter) {
1067 bstrncpy(cr.WrapCounter, counter->WrapCounter->name(), sizeof(cr.WrapCounter));
1069 cr.WrapCounter[0] = 0; /* empty string */
1071 if (db_create_counter_record(NULL, db, &cr)) {
1072 counter->CurrentValue = cr.CurrentValue;
1073 counter->created = true;
1074 Dmsg2(100, "Create counter %s val=%d\n", counter->name(), counter->CurrentValue);
1077 if (!counter->created) {
1078 counter->CurrentValue = counter->MinValue; /* default value */
1081 /* cleanup old job records */
1082 if (mode == UPDATE_AND_FIX) {
1083 db_sql_query(db, cleanup_created_job, NULL, NULL);
1084 db_sql_query(db, cleanup_running_job, NULL, NULL);
1085 db_sql_query(db, "CREATE INDEX basefiles_jobid_idx ON BaseFiles ( JobId )" , NULL, NULL);
1088 db_close_database(NULL, db);
1090 /* Set type in global for debugging */
1091 set_db_type(db_get_type());