2 Bacula® - The Network Backup Solution
4 Copyright (C) 2000-2007 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 plus additions
11 that are listed in the file LICENSE.
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 John Walker.
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
40 /* Forward referenced subroutines */
41 void terminate_dird(int sig);
42 static bool check_resources();
43 static bool check_catalog();
44 static void dir_sql_query(JCR *jcr, const char *cmd);
46 /* Exported subroutines */
47 extern "C" void reload_config(int sig);
48 extern void invalidate_schedules();
51 /* Imported subroutines */
52 JCR *wait_for_next_job(char *runjob);
53 void term_scheduler();
54 void term_ua_server();
55 void start_UA_server(dlist *addrs);
56 void init_job_server(int max_workers);
57 void term_job_server();
58 void store_jobtype(LEX *lc, RES_ITEM *item, int index, int pass);
59 void store_level(LEX *lc, RES_ITEM *item, int index, int pass);
60 void store_replace(LEX *lc, RES_ITEM *item, int index, int pass);
61 void init_device_resources();
63 static char *runjob = NULL;
64 static int background = 1;
65 static void init_reload(void);
67 /* Globals Exported */
68 DIRRES *director; /* Director resource */
71 char *configfile = NULL;
74 /* Globals Imported */
75 extern int r_first, r_last; /* first and last resources */
76 extern RES_TABLE resources[];
77 extern RES **res_head;
78 extern RES_ITEM job_items[];
81 extern "C" { // work around visual compiler mangling variables
88 #define CONFIG_FILE "bacula-dir.conf" /* default configuration file */
94 "\nVersion: %s (%s)\n\n"
95 "Usage: dird [-f -s] [-c config_file] [-d debug_level] [config_file]\n"
96 " -c <file> set configuration file to file\n"
97 " -dnn set debug level to nn\n"
98 " -f run in foreground (for debugging)\n"
100 " -r <job> run <job> now\n"
102 " -t test - read configuration and exit\n"
104 " -v verbose user messages\n"
105 " -? print this message.\n"
106 "\n"), 2000, VERSION, BDATE);
112 /*********************************************************************
114 * Main Bacula Server program
117 #if defined(HAVE_WIN32)
118 /* For Win32 main() is in src/win32 code ... */
119 #define main BaculaMain
122 int main (int argc, char *argv[])
126 int no_signals = FALSE;
127 int test_config = FALSE;
131 start_heap = sbrk(0);
132 setlocale(LC_ALL, "");
133 bindtextdomain("bacula", LOCALEDIR);
134 textdomain("bacula");
137 my_name_is(argc, argv, "bacula-dir");
138 init_msg(NULL, NULL); /* initialize message handler */
140 daemon_start_time = time(NULL);
142 while ((ch = getopt(argc, argv, "c:d:fg:r:stu:v?")) != -1) {
144 case 'c': /* specify config file */
145 if (configfile != NULL) {
148 configfile = bstrdup(optarg);
151 case 'd': /* set debug level */
152 debug_level = atoi(optarg);
153 if (debug_level <= 0) {
156 Dmsg1(0, "Debug level = %d\n", debug_level);
159 case 'f': /* run in foreground */
163 case 'g': /* set group id */
167 case 'r': /* run job */
168 if (runjob != NULL) {
172 runjob = bstrdup(optarg);
176 case 's': /* turn off signals */
180 case 't': /* test config */
184 case 'u': /* set uid */
188 case 'v': /* verbose */
202 init_signals(terminate_dird);
206 if (configfile != NULL) {
209 configfile = bstrdup(*argv);
217 if (configfile == NULL) {
218 configfile = bstrdup(CONFIG_FILE);
221 parse_config(configfile);
223 if (init_crypto() != 0) {
224 Jmsg((JCR *)NULL, M_ERROR_TERM, 0, _("Cryptography library initialization failed.\n"));
227 if (!check_resources()) {
228 Jmsg((JCR *)NULL, M_ERROR_TERM, 0, _("Please correct configuration file: %s\n"), configfile);
231 drop(uid, gid); /* reduce privileges if requested */
233 if (!check_catalog()) {
234 Jmsg((JCR *)NULL, M_ERROR_TERM, 0, _("Please correct configuration file: %s\n"), configfile);
241 my_name_is(0, NULL, director->name()); /* set user defined name */
243 /* Plug database interface for library routines */
244 p_sql_query = (sql_query)dir_sql_query;
245 p_sql_escape = (sql_escape)db_escape_string;
247 FDConnectTimeout = (int)director->FDConnectTimeout;
248 SDConnectTimeout = (int)director->SDConnectTimeout;
252 init_stack_dump(); /* grab new pid */
255 /* Create pid must come after we are a daemon -- so we have our final pid */
256 create_pid_file(director->pid_directory, "bacula-dir", get_first_port_host_order(director->DIRaddrs));
257 read_state_file(director->working_directory, "bacula-dir", get_first_port_host_order(director->DIRaddrs));
260 #if !defined(HAVE_WIN32)
261 signal(SIGHUP, reload_config);
264 init_console_msg(working_directory);
266 init_python_interpreter(director->name(), director->scripts_directory,
269 set_thread_concurrency(director->MaxConcurrentJobs * 2 +
270 4 /* UA */ + 4 /* sched+watchdog+jobsvr+misc */);
272 Dmsg0(200, "Start UA server\n");
273 start_UA_server(director->DIRaddrs);
275 start_watchdog(); /* start network watchdog thread */
277 init_jcr_subsystem(); /* start JCR watchdogs etc. */
279 init_job_server(director->MaxConcurrentJobs);
281 // init_device_resources();
283 Dmsg0(200, "wait for next job\n");
284 /* Main loop -- call scheduler to get next job to run */
285 while ( (jcr = wait_for_next_job(runjob)) ) {
286 run_job(jcr); /* run job */
287 free_jcr(jcr); /* release jcr */
288 if (runjob) { /* command line, run a single job? */
289 break; /* yes, terminate */
298 static void dir_sql_query(JCR *jcr, const char *cmd)
300 if (!jcr || !jcr->db) {
303 db_sql_query(jcr->db, cmd, NULL, NULL);
306 /* Cleanup and then exit */
307 void terminate_dird(int sig)
309 static bool already_here = false;
311 if (already_here) { /* avoid recursive temination problems */
316 generate_daemon_event(NULL, "Exit");
317 write_state_file(director->working_directory, "bacula-dir", get_first_port_host_order(director->DIRaddrs));
318 delete_pid_file(director->pid_directory, "bacula-dir", get_first_port_host_order(director->DIRaddrs));
319 // signal(SIGCHLD, SIG_IGN); /* don't worry about children now */
325 if (configfile != NULL) {
328 if (debug_level > 5) {
329 print_memory_pool_stats();
331 free_config_resources();
333 term_msg(); /* terminate message handler */
335 close_memory_pool(); /* release free memory in pool */
340 struct RELOAD_TABLE {
345 static const int max_reloads = 32;
346 static RELOAD_TABLE reload_table[max_reloads];
348 static void init_reload(void)
350 for (int i=0; i < max_reloads; i++) {
351 reload_table[i].job_count = 0;
352 reload_table[i].res_table = NULL;
356 static void free_saved_resources(int table)
358 int num = r_last - r_first + 1;
359 RES **res_tab = reload_table[table].res_table;
361 Dmsg1(100, "res_tab for table %d already released.\n", table);
364 Dmsg1(100, "Freeing resources for table %d\n", table);
365 for (int j=0; j<num; j++) {
366 free_resource(res_tab[j], r_first + j);
369 reload_table[table].job_count = 0;
370 reload_table[table].res_table = NULL;
374 * Called here at the end of every job that was
375 * hooked decrementing the active job_count. When
376 * it goes to zero, no one is using the associated
377 * resource table, so free it.
379 static void reload_job_end_cb(JCR *jcr, void *ctx)
381 int reload_id = (int)((long int)ctx);
382 Dmsg3(100, "reload job_end JobId=%d table=%d cnt=%d\n", jcr->JobId,
383 reload_id, reload_table[reload_id].job_count);
386 if (--reload_table[reload_id].job_count <= 0) {
387 free_saved_resources(reload_id);
393 static int find_free_reload_table_entry()
396 for (int i=0; i < max_reloads; i++) {
397 if (reload_table[i].res_table == NULL) {
406 * If we get here, we have received a SIGHUP, which means to
407 * reread our configuration file.
409 * The algorithm used is as follows: we count how many jobs are
410 * running and mark the running jobs to make a callback on
411 * exiting. The old config is saved with the reload table
412 * id in a reload table. The new config file is read. Now, as
413 * each job exits, it calls back to the reload_job_end_cb(), which
414 * decrements the count of open jobs for the given reload table.
415 * When the count goes to zero, we release those resources.
416 * This allows us to have pointers into the resource table (from
417 * jobs), and once they exit and all the pointers are released, we
418 * release the old table. Note, if no new jobs are running since the
419 * last reload, then the old resources will be immediately release.
420 * A console is considered a job because it may have pointers to
421 * resources, but a SYSTEM job is not since it *should* not have any
422 * permanent pointers to jobs.
425 void reload_config(int sig)
427 static bool already_here = false;
428 #if !defined(HAVE_WIN32)
432 int njobs = 0; /* number of running jobs */
437 abort(); /* Oops, recursion -> die */
441 #if !defined(HAVE_WIN32)
443 sigaddset(&set, SIGHUP);
444 sigprocmask(SIG_BLOCK, &set, NULL);
450 table = find_free_reload_table_entry();
452 Jmsg(NULL, M_ERROR, 0, _("Too many open reload requests. Request ignored.\n"));
456 Dmsg1(100, "Reload_config njobs=%d\n", njobs);
457 reload_table[table].res_table = save_config_resources();
458 Dmsg1(100, "Saved old config in table %d\n", table);
460 ok = parse_config(configfile, 0, M_ERROR); /* no exit on error */
462 Dmsg0(100, "Reloaded config file\n");
463 if (!ok || !check_resources()) {
464 rtable = find_free_reload_table_entry(); /* save new, bad table */
466 Jmsg(NULL, M_ERROR, 0, _("Please correct configuration file: %s\n"), configfile);
467 Jmsg(NULL, M_ERROR_TERM, 0, _("Out of reload table entries. Giving up.\n"));
469 Jmsg(NULL, M_ERROR, 0, _("Please correct configuration file: %s\n"), configfile);
470 Jmsg(NULL, M_ERROR, 0, _("Resetting previous configuration.\n"));
472 reload_table[rtable].res_table = save_config_resources();
473 /* Now restore old resoure values */
474 int num = r_last - r_first + 1;
475 RES **res_tab = reload_table[table].res_table;
476 for (int i=0; i<num; i++) {
477 res_head[i] = res_tab[i];
479 table = rtable; /* release new, bad, saved table below */
481 invalidate_schedules();
483 * Hook all active jobs so that they release this table
486 if (jcr->JobType != JT_SYSTEM) {
487 reload_table[table].job_count++;
488 job_end_push(jcr, reload_job_end_cb, (void *)((long int)table));
496 set_working_directory(director->working_directory);
497 FDConnectTimeout = director->FDConnectTimeout;
498 SDConnectTimeout = director->SDConnectTimeout;
499 Dmsg0(0, "Director's configuration file reread.\n");
501 /* Now release saved resources, if no jobs using the resources */
503 free_saved_resources(table);
509 #if !defined(HAVE_WIN32)
510 sigprocmask(SIG_UNBLOCK, &set, NULL);
511 signal(SIGHUP, reload_config);
513 already_here = false;
517 * Make a quick check to see that we have all the
520 * **** FIXME **** this routine could be a lot more
521 * intelligent and comprehensive.
523 static bool check_resources()
530 job = (JOB *)GetNextRes(R_JOB, NULL);
531 director = (DIRRES *)GetNextRes(R_DIRECTOR, NULL);
533 Jmsg(NULL, M_FATAL, 0, _("No Director resource defined in %s\n"
534 "Without that I don't know who I am :-(\n"), configfile);
537 set_working_directory(director->working_directory);
538 if (!director->messages) { /* If message resource not specified */
539 director->messages = (MSGS *)GetNextRes(R_MSGS, NULL);
540 if (!director->messages) {
541 Jmsg(NULL, M_FATAL, 0, _("No Messages resource defined in %s\n"), configfile);
545 if (GetNextRes(R_DIRECTOR, (RES *)director) != NULL) {
546 Jmsg(NULL, M_FATAL, 0, _("Only one Director resource permitted in %s\n"),
550 /* tls_require implies tls_enable */
551 if (director->tls_require) {
553 director->tls_enable = true;
555 Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
560 if (!director->tls_certfile && director->tls_enable) {
561 Jmsg(NULL, M_FATAL, 0, _("\"TLS Certificate\" file not defined for Director \"%s\" in %s.\n"),
562 director->name(), configfile);
566 if (!director->tls_keyfile && director->tls_enable) {
567 Jmsg(NULL, M_FATAL, 0, _("\"TLS Key\" file not defined for Director \"%s\" in %s.\n"),
568 director->name(), configfile);
572 if ((!director->tls_ca_certfile && !director->tls_ca_certdir) && director->tls_enable && director->tls_verify_peer) {
573 Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\" or \"TLS CA"
574 " Certificate Dir\" are defined for Director \"%s\" in %s."
575 " At least one CA certificate store is required"
576 " when using \"TLS Verify Peer\".\n"),
577 director->name(), configfile);
581 /* If everything is well, attempt to initialize our per-resource TLS context */
582 if (OK && (director->tls_enable || director->tls_require)) {
583 /* Initialize TLS context:
584 * Args: CA certfile, CA certdir, Certfile, Keyfile,
585 * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
586 director->tls_ctx = new_tls_context(director->tls_ca_certfile,
587 director->tls_ca_certdir, director->tls_certfile,
588 director->tls_keyfile, NULL, NULL, director->tls_dhfile,
589 director->tls_verify_peer);
591 if (!director->tls_ctx) {
592 Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for Director \"%s\" in %s.\n"),
593 director->name(), configfile);
600 Jmsg(NULL, M_FATAL, 0, _("No Job records defined in %s\n"), configfile);
603 foreach_res(job, R_JOB) {
607 /* Handle Storage alists specifically */
608 JOB *jobdefs = job->jobdefs;
609 if (jobdefs->storage && !job->storage) {
611 job->storage = New(alist(10, not_owned_by_alist));
612 foreach_alist(st, jobdefs->storage) {
613 job->storage->append(st);
616 /* Handle RunScripts alists specifically */
617 if (jobdefs->RunScripts) {
620 if (!job->RunScripts) {
621 job->RunScripts = New(alist(10, not_owned_by_alist));
624 foreach_alist(rs, jobdefs->RunScripts) {
625 elt = copy_runscript(rs);
626 job->RunScripts->append(elt); /* we have to free it */
630 /* Transfer default items from JobDefs Resource */
631 for (i=0; job_items[i].name; i++) {
632 char **def_svalue, **svalue; /* string value */
633 int *def_ivalue, *ivalue; /* integer value */
634 bool *def_bvalue, *bvalue; /* bool value */
635 int64_t *def_lvalue, *lvalue; /* 64 bit values */
638 Dmsg4(1400, "Job \"%s\", field \"%s\" bit=%d def=%d\n",
639 job->name(), job_items[i].name,
640 bit_is_set(i, job->hdr.item_present),
641 bit_is_set(i, job->jobdefs->hdr.item_present));
643 if (!bit_is_set(i, job->hdr.item_present) &&
644 bit_is_set(i, job->jobdefs->hdr.item_present)) {
645 Dmsg2(400, "Job \"%s\", field \"%s\": getting default.\n",
646 job->name(), job_items[i].name);
647 offset = (char *)(job_items[i].value) - (char *)&res_all;
649 * Handle strings and directory strings
651 if (job_items[i].handler == store_str ||
652 job_items[i].handler == store_dir) {
653 def_svalue = (char **)((char *)(job->jobdefs) + offset);
654 Dmsg5(400, "Job \"%s\", field \"%s\" def_svalue=%s item %d offset=%u\n",
655 job->name(), job_items[i].name, *def_svalue, i, offset);
656 svalue = (char **)((char *)job + offset);
658 Pmsg1(000, _("Hey something is wrong. p=0x%lu\n"), *svalue);
660 *svalue = bstrdup(*def_svalue);
661 set_bit(i, job->hdr.item_present);
665 } else if (job_items[i].handler == store_res) {
666 def_svalue = (char **)((char *)(job->jobdefs) + offset);
667 Dmsg4(400, "Job \"%s\", field \"%s\" item %d offset=%u\n",
668 job->name(), job_items[i].name, i, offset);
669 svalue = (char **)((char *)job + offset);
671 Pmsg1(000, _("Hey something is wrong. p=0x%lu\n"), *svalue);
673 *svalue = *def_svalue;
674 set_bit(i, job->hdr.item_present);
676 * Handle alist resources
678 } else if (job_items[i].handler == store_alist_res) {
679 if (bit_is_set(i, job->jobdefs->hdr.item_present)) {
680 set_bit(i, job->hdr.item_present);
683 * Handle integer fields
684 * Note, our store_bit does not handle bitmaped fields
686 } else if (job_items[i].handler == store_bit ||
687 job_items[i].handler == store_pint ||
688 job_items[i].handler == store_jobtype ||
689 job_items[i].handler == store_level ||
690 job_items[i].handler == store_pint ||
691 job_items[i].handler == store_replace) {
692 def_ivalue = (int *)((char *)(job->jobdefs) + offset);
693 Dmsg5(400, "Job \"%s\", field \"%s\" def_ivalue=%d item %d offset=%u\n",
694 job->name(), job_items[i].name, *def_ivalue, i, offset);
695 ivalue = (int *)((char *)job + offset);
696 *ivalue = *def_ivalue;
697 set_bit(i, job->hdr.item_present);
699 * Handle 64 bit integer fields
701 } else if (job_items[i].handler == store_time ||
702 job_items[i].handler == store_size ||
703 job_items[i].handler == store_int64) {
704 def_lvalue = (int64_t *)((char *)(job->jobdefs) + offset);
705 Dmsg5(400, "Job \"%s\", field \"%s\" def_lvalue=%" lld " item %d offset=%u\n",
706 job->name(), job_items[i].name, *def_lvalue, i, offset);
707 lvalue = (int64_t *)((char *)job + offset);
708 *lvalue = *def_lvalue;
709 set_bit(i, job->hdr.item_present);
713 } else if (job_items[i].handler == store_bool) {
714 def_bvalue = (bool *)((char *)(job->jobdefs) + offset);
715 Dmsg5(400, "Job \"%s\", field \"%s\" def_bvalue=%d item %d offset=%u\n",
716 job->name(), job_items[i].name, *def_bvalue, i, offset);
717 bvalue = (bool *)((char *)job + offset);
718 *bvalue = *def_bvalue;
719 set_bit(i, job->hdr.item_present);
725 * Ensure that all required items are present
727 for (i=0; job_items[i].name; i++) {
728 if (job_items[i].flags & ITEM_REQUIRED) {
729 if (!bit_is_set(i, job->hdr.item_present)) {
730 Jmsg(NULL, M_ERROR_TERM, 0, _("\"%s\" directive in Job \"%s\" resource is required, but not found.\n"),
731 job_items[i].name, job->name());
735 /* If this triggers, take a look at lib/parse_conf.h */
736 if (i >= MAX_RES_ITEMS) {
737 Emsg0(M_ERROR_TERM, 0, _("Too many items in Job resource\n"));
740 if (!job->storage && !job->pool->storage) {
741 Jmsg(NULL, M_FATAL, 0, _("No storage specified in Job \"%s\" nor in Pool.\n"),
745 } /* End loop over Job res */
748 /* Loop over Consoles */
750 foreach_res(cons, R_CONSOLE) {
751 /* tls_require implies tls_enable */
752 if (cons->tls_require) {
754 cons->tls_enable = true;
756 Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
762 if (!cons->tls_certfile && cons->tls_enable) {
763 Jmsg(NULL, M_FATAL, 0, _("\"TLS Certificate\" file not defined for Console \"%s\" in %s.\n"),
764 cons->name(), configfile);
768 if (!cons->tls_keyfile && cons->tls_enable) {
769 Jmsg(NULL, M_FATAL, 0, _("\"TLS Key\" file not defined for Console \"%s\" in %s.\n"),
770 cons->name(), configfile);
774 if ((!cons->tls_ca_certfile && !cons->tls_ca_certdir) && cons->tls_enable && cons->tls_verify_peer) {
775 Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\" or \"TLS CA"
776 " Certificate Dir\" are defined for Console \"%s\" in %s."
777 " At least one CA certificate store is required"
778 " when using \"TLS Verify Peer\".\n"),
779 cons->name(), configfile);
782 /* If everything is well, attempt to initialize our per-resource TLS context */
783 if (OK && (cons->tls_enable || cons->tls_require)) {
784 /* Initialize TLS context:
785 * Args: CA certfile, CA certdir, Certfile, Keyfile,
786 * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
787 cons->tls_ctx = new_tls_context(cons->tls_ca_certfile,
788 cons->tls_ca_certdir, cons->tls_certfile,
789 cons->tls_keyfile, NULL, NULL, cons->tls_dhfile, cons->tls_verify_peer);
791 if (!cons->tls_ctx) {
792 Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for File daemon \"%s\" in %s.\n"),
793 cons->name(), configfile);
800 /* Loop over Clients */
802 foreach_res(client, R_CLIENT) {
803 /* tls_require implies tls_enable */
804 if (client->tls_require) {
806 client->tls_enable = true;
808 Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
814 if ((!client->tls_ca_certfile && !client->tls_ca_certdir) && client->tls_enable) {
815 Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\""
816 " or \"TLS CA Certificate Dir\" are defined for File daemon \"%s\" in %s.\n"),
817 client->name(), configfile);
821 /* If everything is well, attempt to initialize our per-resource TLS context */
822 if (OK && (client->tls_enable || client->tls_require)) {
823 /* Initialize TLS context:
824 * Args: CA certfile, CA certdir, Certfile, Keyfile,
825 * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
826 client->tls_ctx = new_tls_context(client->tls_ca_certfile,
827 client->tls_ca_certdir, client->tls_certfile,
828 client->tls_keyfile, NULL, NULL, NULL,
831 if (!client->tls_ctx) {
832 Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for File daemon \"%s\" in %s.\n"),
833 client->name(), configfile);
841 close_msg(NULL); /* close temp message handler */
842 init_msg(NULL, director->messages); /* open daemon message handler */
847 static bool check_catalog()
851 /* Loop over databases */
853 foreach_res(catalog, R_CATALOG) {
856 * Make sure we can open catalog, otherwise print a warning
857 * message because the server is probably not running.
859 db = db_init_database(NULL, catalog->db_name, catalog->db_user,
860 catalog->db_password, catalog->db_address,
861 catalog->db_port, catalog->db_socket,
862 catalog->mult_db_connections);
863 if (!db || !db_open_database(NULL, db)) {
864 Pmsg2(000, _("Could not open Catalog \"%s\", database \"%s\".\n"),
865 catalog->name(), catalog->db_name);
866 Jmsg(NULL, M_FATAL, 0, _("Could not open Catalog \"%s\", database \"%s\".\n"),
867 catalog->name(), catalog->db_name);
869 Jmsg(NULL, M_FATAL, 0, _("%s"), db_strerror(db));
870 Pmsg1(000, "%s", db_strerror(db));
871 db_close_database(NULL, db);
877 /* Loop over all pools, defining/updating them in each database */
879 foreach_res(pool, R_POOL) {
880 create_pool(NULL, db, pool, POOL_OP_UPDATE); /* update request */
883 /* Loop over all pools for updating RecyclePool */
884 foreach_res(pool, R_POOL) {
885 update_pool_recyclepool(NULL, db, pool);
889 foreach_res(store, R_STORAGE) {
892 if (store->media_type) {
893 bstrncpy(mr.MediaType, store->media_type, sizeof(mr.MediaType));
895 db_create_mediatype_record(NULL, db, &mr);
899 bstrncpy(sr.Name, store->name(), sizeof(sr.Name));
900 sr.AutoChanger = store->autochanger;
901 db_create_storage_record(NULL, db, &sr);
902 store->StorageId = sr.StorageId; /* set storage Id */
903 if (!sr.created) { /* if not created, update it */
904 db_update_storage_record(NULL, db, &sr);
907 /* tls_require implies tls_enable */
908 if (store->tls_require) {
910 store->tls_enable = true;
912 Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
917 if ((!store->tls_ca_certfile && !store->tls_ca_certdir) && store->tls_enable) {
918 Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\""
919 " or \"TLS CA Certificate Dir\" are defined for Storage \"%s\" in %s.\n"),
920 store->name(), configfile);
924 /* If everything is well, attempt to initialize our per-resource TLS context */
925 if (OK && (store->tls_enable || store->tls_require)) {
926 /* Initialize TLS context:
927 * Args: CA certfile, CA certdir, Certfile, Keyfile,
928 * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
929 store->tls_ctx = new_tls_context(store->tls_ca_certfile,
930 store->tls_ca_certdir, store->tls_certfile,
931 store->tls_keyfile, NULL, NULL, NULL, true);
933 if (!store->tls_ctx) {
934 Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for Storage \"%s\" in %s.\n"),
935 store->name(), configfile);
941 /* Loop over all counters, defining them in each database */
942 /* Set default value in all counters */
944 foreach_res(counter, R_COUNTER) {
945 /* Write to catalog? */
946 if (!counter->created && counter->Catalog == catalog) {
948 bstrncpy(cr.Counter, counter->name(), sizeof(cr.Counter));
949 cr.MinValue = counter->MinValue;
950 cr.MaxValue = counter->MaxValue;
951 cr.CurrentValue = counter->MinValue;
952 if (counter->WrapCounter) {
953 bstrncpy(cr.WrapCounter, counter->WrapCounter->name(), sizeof(cr.WrapCounter));
955 cr.WrapCounter[0] = 0; /* empty string */
957 if (db_create_counter_record(NULL, db, &cr)) {
958 counter->CurrentValue = cr.CurrentValue;
959 counter->created = true;
960 Dmsg2(100, "Create counter %s val=%d\n", counter->name(), counter->CurrentValue);
963 if (!counter->created) {
964 counter->CurrentValue = counter->MinValue; /* default value */
967 db_close_database(NULL, db);
969 /* Set type in global for debugging */
970 set_db_type(db_get_type());