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;
73 /* Globals Imported */
74 extern int r_first, r_last; /* first and last resources */
75 extern RES_TABLE resources[];
76 extern RES **res_head;
77 extern RES_ITEM job_items[];
80 extern "C" { // work around visual compiler mangling variables
87 #define CONFIG_FILE "bacula-dir.conf" /* default configuration file */
93 "\nVersion: %s (%s)\n\n"
94 "Usage: dird [-f -s] [-c config_file] [-d debug_level] [config_file]\n"
95 " -c <file> set configuration file to file\n"
96 " -dnn set debug level to nn\n"
97 " -f run in foreground (for debugging)\n"
99 " -r <job> run <job> now\n"
101 " -t test - read configuration and exit\n"
103 " -v verbose user messages\n"
104 " -? print this message.\n"
105 "\n"), 2000, VERSION, BDATE);
111 /*********************************************************************
113 * Main Bacula Server program
116 #if defined(HAVE_WIN32)
117 /* For Win32 main() is in src/win32 code ... */
118 #define main BaculaMain
121 int main (int argc, char *argv[])
125 int no_signals = FALSE;
126 int test_config = FALSE;
130 setlocale(LC_ALL, "");
131 bindtextdomain("bacula", LOCALEDIR);
132 textdomain("bacula");
135 my_name_is(argc, argv, "bacula-dir");
136 init_msg(NULL, NULL); /* initialize message handler */
138 daemon_start_time = time(NULL);
140 while ((ch = getopt(argc, argv, "c:d:fg:r:stu:v?")) != -1) {
142 case 'c': /* specify config file */
143 if (configfile != NULL) {
146 configfile = bstrdup(optarg);
149 case 'd': /* set debug level */
150 debug_level = atoi(optarg);
151 if (debug_level <= 0) {
154 Dmsg1(0, "Debug level = %d\n", debug_level);
157 case 'f': /* run in foreground */
161 case 'g': /* set group id */
165 case 'r': /* run job */
166 if (runjob != NULL) {
170 runjob = bstrdup(optarg);
174 case 's': /* turn off signals */
178 case 't': /* test config */
182 case 'u': /* set uid */
186 case 'v': /* verbose */
200 init_signals(terminate_dird);
204 if (configfile != NULL) {
207 configfile = bstrdup(*argv);
215 if (configfile == NULL) {
216 configfile = bstrdup(CONFIG_FILE);
219 parse_config(configfile);
221 if (init_crypto() != 0) {
222 Jmsg((JCR *)NULL, M_ERROR_TERM, 0, _("Cryptography library initialization failed.\n"));
225 if (!check_resources()) {
226 Jmsg((JCR *)NULL, M_ERROR_TERM, 0, _("Please correct configuration file: %s\n"), configfile);
229 drop(uid, gid); /* reduce privileges if requested */
231 if (!check_catalog()) {
232 Jmsg((JCR *)NULL, M_ERROR_TERM, 0, _("Please correct configuration file: %s\n"), configfile);
239 my_name_is(0, NULL, director->name()); /* set user defined name */
241 /* Plug database interface for library routines */
242 p_sql_query = (sql_query)dir_sql_query;
243 p_sql_escape = (sql_escape)db_escape_string;
245 FDConnectTimeout = (int)director->FDConnectTimeout;
246 SDConnectTimeout = (int)director->SDConnectTimeout;
250 init_stack_dump(); /* grab new pid */
253 /* Create pid must come after we are a daemon -- so we have our final pid */
254 create_pid_file(director->pid_directory, "bacula-dir", get_first_port_host_order(director->DIRaddrs));
255 read_state_file(director->working_directory, "bacula-dir", get_first_port_host_order(director->DIRaddrs));
258 #if !defined(HAVE_WIN32)
259 signal(SIGHUP, reload_config);
262 init_console_msg(working_directory);
264 init_python_interpreter(director->name(), director->scripts_directory,
267 set_thread_concurrency(director->MaxConcurrentJobs * 2 +
268 4 /* UA */ + 4 /* sched+watchdog+jobsvr+misc */);
270 Dmsg0(200, "Start UA server\n");
271 start_UA_server(director->DIRaddrs);
273 start_watchdog(); /* start network watchdog thread */
275 init_jcr_subsystem(); /* start JCR watchdogs etc. */
277 init_job_server(director->MaxConcurrentJobs);
279 // init_device_resources();
281 Dmsg0(200, "wait for next job\n");
282 /* Main loop -- call scheduler to get next job to run */
283 while ( (jcr = wait_for_next_job(runjob)) ) {
284 run_job(jcr); /* run job */
285 free_jcr(jcr); /* release jcr */
286 if (runjob) { /* command line, run a single job? */
287 break; /* yes, terminate */
296 static void dir_sql_query(JCR *jcr, const char *cmd)
298 if (!jcr || !jcr->db) {
301 db_sql_query(jcr->db, cmd, NULL, NULL);
304 /* Cleanup and then exit */
305 void terminate_dird(int sig)
307 static bool already_here = false;
309 if (already_here) { /* avoid recursive temination problems */
314 generate_daemon_event(NULL, "Exit");
315 write_state_file(director->working_directory, "bacula-dir", get_first_port_host_order(director->DIRaddrs));
316 delete_pid_file(director->pid_directory, "bacula-dir", get_first_port_host_order(director->DIRaddrs));
317 // signal(SIGCHLD, SIG_IGN); /* don't worry about children now */
323 if (configfile != NULL) {
326 if (debug_level > 5) {
327 print_memory_pool_stats();
329 free_config_resources();
331 term_msg(); /* terminate message handler */
333 close_memory_pool(); /* release free memory in pool */
338 struct RELOAD_TABLE {
343 static const int max_reloads = 32;
344 static RELOAD_TABLE reload_table[max_reloads];
346 static void init_reload(void)
348 for (int i=0; i < max_reloads; i++) {
349 reload_table[i].job_count = 0;
350 reload_table[i].res_table = NULL;
354 static void free_saved_resources(int table)
356 int num = r_last - r_first + 1;
357 RES **res_tab = reload_table[table].res_table;
359 Dmsg1(100, "res_tab for table %d already released.\n", table);
362 Dmsg1(100, "Freeing resources for table %d\n", table);
363 for (int j=0; j<num; j++) {
364 free_resource(res_tab[j], r_first + j);
367 reload_table[table].job_count = 0;
368 reload_table[table].res_table = NULL;
372 * Called here at the end of every job that was
373 * hooked decrementing the active job_count. When
374 * it goes to zero, no one is using the associated
375 * resource table, so free it.
377 static void reload_job_end_cb(JCR *jcr, void *ctx)
379 int reload_id = (int)((long int)ctx);
380 Dmsg3(100, "reload job_end JobId=%d table=%d cnt=%d\n", jcr->JobId,
381 reload_id, reload_table[reload_id].job_count);
384 if (--reload_table[reload_id].job_count <= 0) {
385 free_saved_resources(reload_id);
391 static int find_free_reload_table_entry()
394 for (int i=0; i < max_reloads; i++) {
395 if (reload_table[i].res_table == NULL) {
404 * If we get here, we have received a SIGHUP, which means to
405 * reread our configuration file.
407 * The algorithm used is as follows: we count how many jobs are
408 * running and mark the running jobs to make a callback on
409 * exiting. The old config is saved with the reload table
410 * id in a reload table. The new config file is read. Now, as
411 * each job exits, it calls back to the reload_job_end_cb(), which
412 * decrements the count of open jobs for the given reload table.
413 * When the count goes to zero, we release those resources.
414 * This allows us to have pointers into the resource table (from
415 * jobs), and once they exit and all the pointers are released, we
416 * release the old table. Note, if no new jobs are running since the
417 * last reload, then the old resources will be immediately release.
418 * A console is considered a job because it may have pointers to
419 * resources, but a SYSTEM job is not since it *should* not have any
420 * permanent pointers to jobs.
423 void reload_config(int sig)
425 static bool already_here = false;
426 #if !defined(HAVE_WIN32)
430 int njobs = 0; /* number of running jobs */
435 abort(); /* Oops, recursion -> die */
439 #if !defined(HAVE_WIN32)
441 sigaddset(&set, SIGHUP);
442 sigprocmask(SIG_BLOCK, &set, NULL);
448 table = find_free_reload_table_entry();
450 Jmsg(NULL, M_ERROR, 0, _("Too many open reload requests. Request ignored.\n"));
454 Dmsg1(100, "Reload_config njobs=%d\n", njobs);
455 reload_table[table].res_table = save_config_resources();
456 Dmsg1(100, "Saved old config in table %d\n", table);
458 ok = parse_config(configfile, 0, M_ERROR); /* no exit on error */
460 Dmsg0(100, "Reloaded config file\n");
461 if (!ok || !check_resources()) {
462 rtable = find_free_reload_table_entry(); /* save new, bad table */
464 Jmsg(NULL, M_ERROR, 0, _("Please correct configuration file: %s\n"), configfile);
465 Jmsg(NULL, M_ERROR_TERM, 0, _("Out of reload table entries. Giving up.\n"));
467 Jmsg(NULL, M_ERROR, 0, _("Please correct configuration file: %s\n"), configfile);
468 Jmsg(NULL, M_ERROR, 0, _("Resetting previous configuration.\n"));
470 reload_table[rtable].res_table = save_config_resources();
471 /* Now restore old resoure values */
472 int num = r_last - r_first + 1;
473 RES **res_tab = reload_table[table].res_table;
474 for (int i=0; i<num; i++) {
475 res_head[i] = res_tab[i];
477 table = rtable; /* release new, bad, saved table below */
479 invalidate_schedules();
481 * Hook all active jobs so that they release this table
484 if (jcr->JobType != JT_SYSTEM) {
485 reload_table[table].job_count++;
486 job_end_push(jcr, reload_job_end_cb, (void *)((long int)table));
494 set_working_directory(director->working_directory);
495 FDConnectTimeout = director->FDConnectTimeout;
496 SDConnectTimeout = director->SDConnectTimeout;
497 Dmsg0(0, "Director's configuration file reread.\n");
499 /* Now release saved resources, if no jobs using the resources */
501 free_saved_resources(table);
507 #if !defined(HAVE_WIN32)
508 sigprocmask(SIG_UNBLOCK, &set, NULL);
509 signal(SIGHUP, reload_config);
511 already_here = false;
515 * Make a quick check to see that we have all the
518 * **** FIXME **** this routine could be a lot more
519 * intelligent and comprehensive.
521 static bool check_resources()
528 job = (JOB *)GetNextRes(R_JOB, NULL);
529 director = (DIRRES *)GetNextRes(R_DIRECTOR, NULL);
531 Jmsg(NULL, M_FATAL, 0, _("No Director resource defined in %s\n"
532 "Without that I don't know who I am :-(\n"), configfile);
535 set_working_directory(director->working_directory);
536 if (!director->messages) { /* If message resource not specified */
537 director->messages = (MSGS *)GetNextRes(R_MSGS, NULL);
538 if (!director->messages) {
539 Jmsg(NULL, M_FATAL, 0, _("No Messages resource defined in %s\n"), configfile);
543 if (GetNextRes(R_DIRECTOR, (RES *)director) != NULL) {
544 Jmsg(NULL, M_FATAL, 0, _("Only one Director resource permitted in %s\n"),
548 /* tls_require implies tls_enable */
549 if (director->tls_require) {
551 director->tls_enable = true;
553 Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
558 if (!director->tls_certfile && director->tls_enable) {
559 Jmsg(NULL, M_FATAL, 0, _("\"TLS Certificate\" file not defined for Director \"%s\" in %s.\n"),
560 director->name(), configfile);
564 if (!director->tls_keyfile && director->tls_enable) {
565 Jmsg(NULL, M_FATAL, 0, _("\"TLS Key\" file not defined for Director \"%s\" in %s.\n"),
566 director->name(), configfile);
570 if ((!director->tls_ca_certfile && !director->tls_ca_certdir) && director->tls_enable && director->tls_verify_peer) {
571 Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\" or \"TLS CA"
572 " Certificate Dir\" are defined for Director \"%s\" in %s."
573 " At least one CA certificate store is required"
574 " when using \"TLS Verify Peer\".\n"),
575 director->name(), configfile);
579 /* If everything is well, attempt to initialize our per-resource TLS context */
580 if (OK && (director->tls_enable || director->tls_require)) {
581 /* Initialize TLS context:
582 * Args: CA certfile, CA certdir, Certfile, Keyfile,
583 * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
584 director->tls_ctx = new_tls_context(director->tls_ca_certfile,
585 director->tls_ca_certdir, director->tls_certfile,
586 director->tls_keyfile, NULL, NULL, director->tls_dhfile,
587 director->tls_verify_peer);
589 if (!director->tls_ctx) {
590 Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for Director \"%s\" in %s.\n"),
591 director->name(), configfile);
598 Jmsg(NULL, M_FATAL, 0, _("No Job records defined in %s\n"), configfile);
601 foreach_res(job, R_JOB) {
605 /* Handle Storage alists specifically */
606 JOB *jobdefs = job->jobdefs;
607 if (jobdefs->storage && !job->storage) {
609 job->storage = New(alist(10, not_owned_by_alist));
610 foreach_alist(st, jobdefs->storage) {
611 job->storage->append(st);
614 /* Handle RunScripts alists specifically */
615 if (jobdefs->RunScripts) {
618 if (!job->RunScripts) {
619 job->RunScripts = New(alist(10, not_owned_by_alist));
622 foreach_alist(rs, jobdefs->RunScripts) {
623 elt = copy_runscript(rs);
624 job->RunScripts->append(elt); /* we have to free it */
628 /* Transfer default items from JobDefs Resource */
629 for (i=0; job_items[i].name; i++) {
630 char **def_svalue, **svalue; /* string value */
631 int *def_ivalue, *ivalue; /* integer value */
632 bool *def_bvalue, *bvalue; /* bool value */
633 int64_t *def_lvalue, *lvalue; /* 64 bit values */
636 Dmsg4(1400, "Job \"%s\", field \"%s\" bit=%d def=%d\n",
637 job->name(), job_items[i].name,
638 bit_is_set(i, job->hdr.item_present),
639 bit_is_set(i, job->jobdefs->hdr.item_present));
641 if (!bit_is_set(i, job->hdr.item_present) &&
642 bit_is_set(i, job->jobdefs->hdr.item_present)) {
643 Dmsg2(400, "Job \"%s\", field \"%s\": getting default.\n",
644 job->name(), job_items[i].name);
645 offset = (char *)(job_items[i].value) - (char *)&res_all;
647 * Handle strings and directory strings
649 if (job_items[i].handler == store_str ||
650 job_items[i].handler == store_dir) {
651 def_svalue = (char **)((char *)(job->jobdefs) + offset);
652 Dmsg5(400, "Job \"%s\", field \"%s\" def_svalue=%s item %d offset=%u\n",
653 job->name(), job_items[i].name, *def_svalue, i, offset);
654 svalue = (char **)((char *)job + offset);
656 Pmsg1(000, _("Hey something is wrong. p=0x%lu\n"), *svalue);
658 *svalue = bstrdup(*def_svalue);
659 set_bit(i, job->hdr.item_present);
663 } else if (job_items[i].handler == store_res) {
664 def_svalue = (char **)((char *)(job->jobdefs) + offset);
665 Dmsg4(400, "Job \"%s\", field \"%s\" item %d offset=%u\n",
666 job->name(), job_items[i].name, i, offset);
667 svalue = (char **)((char *)job + offset);
669 Pmsg1(000, _("Hey something is wrong. p=0x%lu\n"), *svalue);
671 *svalue = *def_svalue;
672 set_bit(i, job->hdr.item_present);
674 * Handle alist resources
676 } else if (job_items[i].handler == store_alist_res) {
677 if (bit_is_set(i, job->jobdefs->hdr.item_present)) {
678 set_bit(i, job->hdr.item_present);
681 * Handle integer fields
682 * Note, our store_bit does not handle bitmaped fields
684 } else if (job_items[i].handler == store_bit ||
685 job_items[i].handler == store_pint ||
686 job_items[i].handler == store_jobtype ||
687 job_items[i].handler == store_level ||
688 job_items[i].handler == store_pint ||
689 job_items[i].handler == store_replace) {
690 def_ivalue = (int *)((char *)(job->jobdefs) + offset);
691 Dmsg5(400, "Job \"%s\", field \"%s\" def_ivalue=%d item %d offset=%u\n",
692 job->name(), job_items[i].name, *def_ivalue, i, offset);
693 ivalue = (int *)((char *)job + offset);
694 *ivalue = *def_ivalue;
695 set_bit(i, job->hdr.item_present);
697 * Handle 64 bit integer fields
699 } else if (job_items[i].handler == store_time ||
700 job_items[i].handler == store_size ||
701 job_items[i].handler == store_int64) {
702 def_lvalue = (int64_t *)((char *)(job->jobdefs) + offset);
703 Dmsg5(400, "Job \"%s\", field \"%s\" def_lvalue=%" lld " item %d offset=%u\n",
704 job->name(), job_items[i].name, *def_lvalue, i, offset);
705 lvalue = (int64_t *)((char *)job + offset);
706 *lvalue = *def_lvalue;
707 set_bit(i, job->hdr.item_present);
711 } else if (job_items[i].handler == store_bool) {
712 def_bvalue = (bool *)((char *)(job->jobdefs) + offset);
713 Dmsg5(400, "Job \"%s\", field \"%s\" def_bvalue=%d item %d offset=%u\n",
714 job->name(), job_items[i].name, *def_bvalue, i, offset);
715 bvalue = (bool *)((char *)job + offset);
716 *bvalue = *def_bvalue;
717 set_bit(i, job->hdr.item_present);
723 * Ensure that all required items are present
725 for (i=0; job_items[i].name; i++) {
726 if (job_items[i].flags & ITEM_REQUIRED) {
727 if (!bit_is_set(i, job->hdr.item_present)) {
728 Jmsg(NULL, M_ERROR_TERM, 0, _("\"%s\" directive in Job \"%s\" resource is required, but not found.\n"),
729 job_items[i].name, job->name());
733 /* If this triggers, take a look at lib/parse_conf.h */
734 if (i >= MAX_RES_ITEMS) {
735 Emsg0(M_ERROR_TERM, 0, _("Too many items in Job resource\n"));
738 if (!job->storage && !job->pool->storage) {
739 Jmsg(NULL, M_FATAL, 0, _("No storage specified in Job \"%s\" nor in Pool.\n"),
743 } /* End loop over Job res */
746 /* Loop over Consoles */
748 foreach_res(cons, R_CONSOLE) {
749 /* tls_require implies tls_enable */
750 if (cons->tls_require) {
752 cons->tls_enable = true;
754 Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
760 if (!cons->tls_certfile && cons->tls_enable) {
761 Jmsg(NULL, M_FATAL, 0, _("\"TLS Certificate\" file not defined for Console \"%s\" in %s.\n"),
762 cons->name(), configfile);
766 if (!cons->tls_keyfile && cons->tls_enable) {
767 Jmsg(NULL, M_FATAL, 0, _("\"TLS Key\" file not defined for Console \"%s\" in %s.\n"),
768 cons->name(), configfile);
772 if ((!cons->tls_ca_certfile && !cons->tls_ca_certdir) && cons->tls_enable && cons->tls_verify_peer) {
773 Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\" or \"TLS CA"
774 " Certificate Dir\" are defined for Console \"%s\" in %s."
775 " At least one CA certificate store is required"
776 " when using \"TLS Verify Peer\".\n"),
777 cons->name(), configfile);
780 /* If everything is well, attempt to initialize our per-resource TLS context */
781 if (OK && (cons->tls_enable || cons->tls_require)) {
782 /* Initialize TLS context:
783 * Args: CA certfile, CA certdir, Certfile, Keyfile,
784 * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
785 cons->tls_ctx = new_tls_context(cons->tls_ca_certfile,
786 cons->tls_ca_certdir, cons->tls_certfile,
787 cons->tls_keyfile, NULL, NULL, cons->tls_dhfile, cons->tls_verify_peer);
789 if (!cons->tls_ctx) {
790 Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for File daemon \"%s\" in %s.\n"),
791 cons->name(), configfile);
798 /* Loop over Clients */
800 foreach_res(client, R_CLIENT) {
801 /* tls_require implies tls_enable */
802 if (client->tls_require) {
804 client->tls_enable = true;
806 Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
812 if ((!client->tls_ca_certfile && !client->tls_ca_certdir) && client->tls_enable) {
813 Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\""
814 " or \"TLS CA Certificate Dir\" are defined for File daemon \"%s\" in %s.\n"),
815 client->name(), configfile);
819 /* If everything is well, attempt to initialize our per-resource TLS context */
820 if (OK && (client->tls_enable || client->tls_require)) {
821 /* Initialize TLS context:
822 * Args: CA certfile, CA certdir, Certfile, Keyfile,
823 * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
824 client->tls_ctx = new_tls_context(client->tls_ca_certfile,
825 client->tls_ca_certdir, client->tls_certfile,
826 client->tls_keyfile, NULL, NULL, NULL,
829 if (!client->tls_ctx) {
830 Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for File daemon \"%s\" in %s.\n"),
831 client->name(), configfile);
839 close_msg(NULL); /* close temp message handler */
840 init_msg(NULL, director->messages); /* open daemon message handler */
845 static bool check_catalog()
849 /* Loop over databases */
851 foreach_res(catalog, R_CATALOG) {
854 * Make sure we can open catalog, otherwise print a warning
855 * message because the server is probably not running.
857 db = db_init_database(NULL, catalog->db_name, catalog->db_user,
858 catalog->db_password, catalog->db_address,
859 catalog->db_port, catalog->db_socket,
860 catalog->mult_db_connections);
861 if (!db || !db_open_database(NULL, db)) {
862 Pmsg2(000, _("Could not open Catalog \"%s\", database \"%s\".\n"),
863 catalog->name(), catalog->db_name);
864 Jmsg(NULL, M_FATAL, 0, _("Could not open Catalog \"%s\", database \"%s\".\n"),
865 catalog->name(), catalog->db_name);
867 Jmsg(NULL, M_FATAL, 0, _("%s"), db_strerror(db));
868 Pmsg1(000, "%s", db_strerror(db));
874 /* Loop over all pools, defining/updating them in each database */
876 foreach_res(pool, R_POOL) {
877 create_pool(NULL, db, pool, POOL_OP_UPDATE); /* update request */
880 /* Loop over all pools for updating RecyclePool */
881 foreach_res(pool, R_POOL) {
882 update_pool_recyclepool(NULL, db, pool);
886 foreach_res(store, R_STORAGE) {
889 if (store->media_type) {
890 bstrncpy(mr.MediaType, store->media_type, sizeof(mr.MediaType));
892 db_create_mediatype_record(NULL, db, &mr);
896 bstrncpy(sr.Name, store->name(), sizeof(sr.Name));
897 sr.AutoChanger = store->autochanger;
898 db_create_storage_record(NULL, db, &sr);
899 store->StorageId = sr.StorageId; /* set storage Id */
900 if (!sr.created) { /* if not created, update it */
901 db_update_storage_record(NULL, db, &sr);
904 /* tls_require implies tls_enable */
905 if (store->tls_require) {
907 store->tls_enable = true;
909 Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
914 if ((!store->tls_ca_certfile && !store->tls_ca_certdir) && store->tls_enable) {
915 Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\""
916 " or \"TLS CA Certificate Dir\" are defined for Storage \"%s\" in %s.\n"),
917 store->name(), configfile);
921 /* If everything is well, attempt to initialize our per-resource TLS context */
922 if (OK && (store->tls_enable || store->tls_require)) {
923 /* Initialize TLS context:
924 * Args: CA certfile, CA certdir, Certfile, Keyfile,
925 * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
926 store->tls_ctx = new_tls_context(store->tls_ca_certfile,
927 store->tls_ca_certdir, store->tls_certfile,
928 store->tls_keyfile, NULL, NULL, NULL, true);
930 if (!store->tls_ctx) {
931 Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for Storage \"%s\" in %s.\n"),
932 store->name(), configfile);
938 /* Loop over all counters, defining them in each database */
939 /* Set default value in all counters */
941 foreach_res(counter, R_COUNTER) {
942 /* Write to catalog? */
943 if (!counter->created && counter->Catalog == catalog) {
945 bstrncpy(cr.Counter, counter->name(), sizeof(cr.Counter));
946 cr.MinValue = counter->MinValue;
947 cr.MaxValue = counter->MaxValue;
948 cr.CurrentValue = counter->MinValue;
949 if (counter->WrapCounter) {
950 bstrncpy(cr.WrapCounter, counter->WrapCounter->name(), sizeof(cr.WrapCounter));
952 cr.WrapCounter[0] = 0; /* empty string */
954 if (db_create_counter_record(NULL, db, &cr)) {
955 counter->CurrentValue = cr.CurrentValue;
956 counter->created = true;
957 Dmsg2(100, "Create counter %s val=%d\n", counter->name(), counter->CurrentValue);
960 if (!counter->created) {
961 counter->CurrentValue = counter->MinValue; /* default value */
964 db_close_database(NULL, db);
966 /* Set type in global for debugging */
967 set_db_type(db_get_type());