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 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 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 bool no_signals = false;
127 bool 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(10, "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);
233 init_stack_dump(); /* grab new pid */
236 /* Create pid must come after we are a daemon -- so we have our final pid */
237 create_pid_file(director->pid_directory, "bacula-dir", get_first_port_host_order(director->DIRaddrs));
238 read_state_file(director->working_directory, "bacula-dir", get_first_port_host_order(director->DIRaddrs));
240 drop(uid, gid); /* reduce privileges if requested */
242 if (!check_catalog()) {
243 Jmsg((JCR *)NULL, M_ERROR_TERM, 0, _("Please correct configuration file: %s\n"), configfile);
250 my_name_is(0, NULL, director->name()); /* set user defined name */
252 /* Plug database interface for library routines */
253 p_sql_query = (sql_query)dir_sql_query;
254 p_sql_escape = (sql_escape)db_escape_string;
256 FDConnectTimeout = (int)director->FDConnectTimeout;
257 SDConnectTimeout = (int)director->SDConnectTimeout;
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 */
299 * This allows the message handler to operate on the database
300 * by using a pointer to this function. The pointer is
301 * needed because the other daemons do not have access
302 * to the database. If the pointer is
303 * not defined (other daemons), then writing the database
306 static void dir_sql_query(JCR *jcr, const char *cmd)
308 if (!jcr || !jcr->db) {
311 db_sql_query(jcr->db, cmd, NULL, NULL);
314 /* Cleanup and then exit */
315 void terminate_dird(int sig)
317 static bool already_here = false;
319 if (already_here) { /* avoid recursive temination problems */
324 generate_daemon_event(NULL, "Exit");
325 write_state_file(director->working_directory, "bacula-dir", get_first_port_host_order(director->DIRaddrs));
326 delete_pid_file(director->pid_directory, "bacula-dir", get_first_port_host_order(director->DIRaddrs));
327 // signal(SIGCHLD, SIG_IGN); /* don't worry about children now */
333 if (configfile != NULL) {
336 if (debug_level > 5) {
337 print_memory_pool_stats();
339 free_config_resources();
341 term_msg(); /* terminate message handler */
343 close_memory_pool(); /* release free memory in pool */
348 struct RELOAD_TABLE {
353 static const int max_reloads = 32;
354 static RELOAD_TABLE reload_table[max_reloads];
356 static void init_reload(void)
358 for (int i=0; i < max_reloads; i++) {
359 reload_table[i].job_count = 0;
360 reload_table[i].res_table = NULL;
364 static void free_saved_resources(int table)
366 int num = r_last - r_first + 1;
367 RES **res_tab = reload_table[table].res_table;
369 Dmsg1(100, "res_tab for table %d already released.\n", table);
372 Dmsg1(100, "Freeing resources for table %d\n", table);
373 for (int j=0; j<num; j++) {
374 free_resource(res_tab[j], r_first + j);
377 reload_table[table].job_count = 0;
378 reload_table[table].res_table = NULL;
382 * Called here at the end of every job that was
383 * hooked decrementing the active job_count. When
384 * it goes to zero, no one is using the associated
385 * resource table, so free it.
387 static void reload_job_end_cb(JCR *jcr, void *ctx)
389 int reload_id = (int)((long int)ctx);
390 Dmsg3(100, "reload job_end JobId=%d table=%d cnt=%d\n", jcr->JobId,
391 reload_id, reload_table[reload_id].job_count);
394 if (--reload_table[reload_id].job_count <= 0) {
395 free_saved_resources(reload_id);
401 static int find_free_reload_table_entry()
404 for (int i=0; i < max_reloads; i++) {
405 if (reload_table[i].res_table == NULL) {
414 * If we get here, we have received a SIGHUP, which means to
415 * reread our configuration file.
417 * The algorithm used is as follows: we count how many jobs are
418 * running and mark the running jobs to make a callback on
419 * exiting. The old config is saved with the reload table
420 * id in a reload table. The new config file is read. Now, as
421 * each job exits, it calls back to the reload_job_end_cb(), which
422 * decrements the count of open jobs for the given reload table.
423 * When the count goes to zero, we release those resources.
424 * This allows us to have pointers into the resource table (from
425 * jobs), and once they exit and all the pointers are released, we
426 * release the old table. Note, if no new jobs are running since the
427 * last reload, then the old resources will be immediately release.
428 * A console is considered a job because it may have pointers to
429 * resources, but a SYSTEM job is not since it *should* not have any
430 * permanent pointers to jobs.
433 void reload_config(int sig)
435 static bool already_here = false;
436 #if !defined(HAVE_WIN32)
440 int njobs = 0; /* number of running jobs */
445 abort(); /* Oops, recursion -> die */
449 #if !defined(HAVE_WIN32)
451 sigaddset(&set, SIGHUP);
452 sigprocmask(SIG_BLOCK, &set, NULL);
458 table = find_free_reload_table_entry();
460 Jmsg(NULL, M_ERROR, 0, _("Too many open reload requests. Request ignored.\n"));
464 Dmsg1(100, "Reload_config njobs=%d\n", njobs);
465 reload_table[table].res_table = save_config_resources();
466 Dmsg1(100, "Saved old config in table %d\n", table);
468 ok = parse_config(configfile, 0, M_ERROR); /* no exit on error */
470 Dmsg0(100, "Reloaded config file\n");
471 if (!ok || !check_resources() || !check_catalog()) {
472 rtable = find_free_reload_table_entry(); /* save new, bad table */
474 Jmsg(NULL, M_ERROR, 0, _("Please correct configuration file: %s\n"), configfile);
475 Jmsg(NULL, M_ERROR_TERM, 0, _("Out of reload table entries. Giving up.\n"));
477 Jmsg(NULL, M_ERROR, 0, _("Please correct configuration file: %s\n"), configfile);
478 Jmsg(NULL, M_ERROR, 0, _("Resetting previous configuration.\n"));
480 reload_table[rtable].res_table = save_config_resources();
481 /* Now restore old resoure values */
482 int num = r_last - r_first + 1;
483 RES **res_tab = reload_table[table].res_table;
484 for (int i=0; i<num; i++) {
485 res_head[i] = res_tab[i];
487 table = rtable; /* release new, bad, saved table below */
489 invalidate_schedules();
491 * Hook all active jobs so that they release this table
494 if (jcr->JobType != JT_SYSTEM) {
495 reload_table[table].job_count++;
496 job_end_push(jcr, reload_job_end_cb, (void *)((long int)table));
504 set_working_directory(director->working_directory);
505 FDConnectTimeout = director->FDConnectTimeout;
506 SDConnectTimeout = director->SDConnectTimeout;
507 Dmsg0(10, "Director's configuration file reread.\n");
509 /* Now release saved resources, if no jobs using the resources */
511 free_saved_resources(table);
517 #if !defined(HAVE_WIN32)
518 sigprocmask(SIG_UNBLOCK, &set, NULL);
519 signal(SIGHUP, reload_config);
521 already_here = false;
525 * Make a quick check to see that we have all the
528 * **** FIXME **** this routine could be a lot more
529 * intelligent and comprehensive.
531 static bool check_resources()
538 job = (JOB *)GetNextRes(R_JOB, NULL);
539 director = (DIRRES *)GetNextRes(R_DIRECTOR, NULL);
541 Jmsg(NULL, M_FATAL, 0, _("No Director resource defined in %s\n"
542 "Without that I don't know who I am :-(\n"), configfile);
545 set_working_directory(director->working_directory);
546 if (!director->messages) { /* If message resource not specified */
547 director->messages = (MSGS *)GetNextRes(R_MSGS, NULL);
548 if (!director->messages) {
549 Jmsg(NULL, M_FATAL, 0, _("No Messages resource defined in %s\n"), configfile);
553 if (GetNextRes(R_DIRECTOR, (RES *)director) != NULL) {
554 Jmsg(NULL, M_FATAL, 0, _("Only one Director resource permitted in %s\n"),
558 /* tls_require implies tls_enable */
559 if (director->tls_require) {
561 director->tls_enable = true;
563 Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
568 if (!director->tls_certfile && director->tls_enable) {
569 Jmsg(NULL, M_FATAL, 0, _("\"TLS Certificate\" file not defined for Director \"%s\" in %s.\n"),
570 director->name(), configfile);
574 if (!director->tls_keyfile && director->tls_enable) {
575 Jmsg(NULL, M_FATAL, 0, _("\"TLS Key\" file not defined for Director \"%s\" in %s.\n"),
576 director->name(), configfile);
580 if ((!director->tls_ca_certfile && !director->tls_ca_certdir) && director->tls_enable && director->tls_verify_peer) {
581 Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\" or \"TLS CA"
582 " Certificate Dir\" are defined for Director \"%s\" in %s."
583 " At least one CA certificate store is required"
584 " when using \"TLS Verify Peer\".\n"),
585 director->name(), configfile);
589 /* If everything is well, attempt to initialize our per-resource TLS context */
590 if (OK && (director->tls_enable || director->tls_require)) {
591 /* Initialize TLS context:
592 * Args: CA certfile, CA certdir, Certfile, Keyfile,
593 * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
594 director->tls_ctx = new_tls_context(director->tls_ca_certfile,
595 director->tls_ca_certdir, director->tls_certfile,
596 director->tls_keyfile, NULL, NULL, director->tls_dhfile,
597 director->tls_verify_peer);
599 if (!director->tls_ctx) {
600 Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for Director \"%s\" in %s.\n"),
601 director->name(), configfile);
608 Jmsg(NULL, M_FATAL, 0, _("No Job records defined in %s\n"), configfile);
611 foreach_res(job, R_JOB) {
615 /* Handle Storage alists specifically */
616 JOB *jobdefs = job->jobdefs;
617 if (jobdefs->storage && !job->storage) {
619 job->storage = New(alist(10, not_owned_by_alist));
620 foreach_alist(st, jobdefs->storage) {
621 job->storage->append(st);
624 /* Handle RunScripts alists specifically */
625 if (jobdefs->RunScripts) {
628 if (!job->RunScripts) {
629 job->RunScripts = New(alist(10, not_owned_by_alist));
632 foreach_alist(rs, jobdefs->RunScripts) {
633 elt = copy_runscript(rs);
634 job->RunScripts->append(elt); /* we have to free it */
638 /* Transfer default items from JobDefs Resource */
639 for (i=0; job_items[i].name; i++) {
640 char **def_svalue, **svalue; /* string value */
641 int *def_ivalue, *ivalue; /* integer value */
642 bool *def_bvalue, *bvalue; /* bool value */
643 int64_t *def_lvalue, *lvalue; /* 64 bit values */
646 Dmsg4(1400, "Job \"%s\", field \"%s\" bit=%d def=%d\n",
647 job->name(), job_items[i].name,
648 bit_is_set(i, job->hdr.item_present),
649 bit_is_set(i, job->jobdefs->hdr.item_present));
651 if (!bit_is_set(i, job->hdr.item_present) &&
652 bit_is_set(i, job->jobdefs->hdr.item_present)) {
653 Dmsg2(400, "Job \"%s\", field \"%s\": getting default.\n",
654 job->name(), job_items[i].name);
655 offset = (char *)(job_items[i].value) - (char *)&res_all;
657 * Handle strings and directory strings
659 if (job_items[i].handler == store_str ||
660 job_items[i].handler == store_dir) {
661 def_svalue = (char **)((char *)(job->jobdefs) + offset);
662 Dmsg5(400, "Job \"%s\", field \"%s\" def_svalue=%s item %d offset=%u\n",
663 job->name(), job_items[i].name, *def_svalue, i, offset);
664 svalue = (char **)((char *)job + offset);
666 Pmsg1(000, _("Hey something is wrong. p=0x%lu\n"), *svalue);
668 *svalue = bstrdup(*def_svalue);
669 set_bit(i, job->hdr.item_present);
673 } else if (job_items[i].handler == store_res) {
674 def_svalue = (char **)((char *)(job->jobdefs) + offset);
675 Dmsg4(400, "Job \"%s\", field \"%s\" item %d offset=%u\n",
676 job->name(), job_items[i].name, i, offset);
677 svalue = (char **)((char *)job + offset);
679 Pmsg1(000, _("Hey something is wrong. p=0x%lu\n"), *svalue);
681 *svalue = *def_svalue;
682 set_bit(i, job->hdr.item_present);
684 * Handle alist resources
686 } else if (job_items[i].handler == store_alist_res) {
687 if (bit_is_set(i, job->jobdefs->hdr.item_present)) {
688 set_bit(i, job->hdr.item_present);
691 * Handle integer fields
692 * Note, our store_bit does not handle bitmaped fields
694 } else if (job_items[i].handler == store_bit ||
695 job_items[i].handler == store_pint ||
696 job_items[i].handler == store_jobtype ||
697 job_items[i].handler == store_level ||
698 job_items[i].handler == store_pint ||
699 job_items[i].handler == store_replace) {
700 def_ivalue = (int *)((char *)(job->jobdefs) + offset);
701 Dmsg5(400, "Job \"%s\", field \"%s\" def_ivalue=%d item %d offset=%u\n",
702 job->name(), job_items[i].name, *def_ivalue, i, offset);
703 ivalue = (int *)((char *)job + offset);
704 *ivalue = *def_ivalue;
705 set_bit(i, job->hdr.item_present);
707 * Handle 64 bit integer fields
709 } else if (job_items[i].handler == store_time ||
710 job_items[i].handler == store_size ||
711 job_items[i].handler == store_int64) {
712 def_lvalue = (int64_t *)((char *)(job->jobdefs) + offset);
713 Dmsg5(400, "Job \"%s\", field \"%s\" def_lvalue=%" lld " item %d offset=%u\n",
714 job->name(), job_items[i].name, *def_lvalue, i, offset);
715 lvalue = (int64_t *)((char *)job + offset);
716 *lvalue = *def_lvalue;
717 set_bit(i, job->hdr.item_present);
721 } else if (job_items[i].handler == store_bool) {
722 def_bvalue = (bool *)((char *)(job->jobdefs) + offset);
723 Dmsg5(400, "Job \"%s\", field \"%s\" def_bvalue=%d item %d offset=%u\n",
724 job->name(), job_items[i].name, *def_bvalue, i, offset);
725 bvalue = (bool *)((char *)job + offset);
726 *bvalue = *def_bvalue;
727 set_bit(i, job->hdr.item_present);
733 * Ensure that all required items are present
735 for (i=0; job_items[i].name; i++) {
736 if (job_items[i].flags & ITEM_REQUIRED) {
737 if (!bit_is_set(i, job->hdr.item_present)) {
738 Jmsg(NULL, M_ERROR_TERM, 0, _("\"%s\" directive in Job \"%s\" resource is required, but not found.\n"),
739 job_items[i].name, job->name());
743 /* If this triggers, take a look at lib/parse_conf.h */
744 if (i >= MAX_RES_ITEMS) {
745 Emsg0(M_ERROR_TERM, 0, _("Too many items in Job resource\n"));
748 if (!job->storage && !job->pool->storage) {
749 Jmsg(NULL, M_FATAL, 0, _("No storage specified in Job \"%s\" nor in Pool.\n"),
753 } /* End loop over Job res */
756 /* Loop over Consoles */
758 foreach_res(cons, R_CONSOLE) {
759 /* tls_require implies tls_enable */
760 if (cons->tls_require) {
762 cons->tls_enable = true;
764 Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
770 if (!cons->tls_certfile && cons->tls_enable) {
771 Jmsg(NULL, M_FATAL, 0, _("\"TLS Certificate\" file not defined for Console \"%s\" in %s.\n"),
772 cons->name(), configfile);
776 if (!cons->tls_keyfile && cons->tls_enable) {
777 Jmsg(NULL, M_FATAL, 0, _("\"TLS Key\" file not defined for Console \"%s\" in %s.\n"),
778 cons->name(), configfile);
782 if ((!cons->tls_ca_certfile && !cons->tls_ca_certdir) && cons->tls_enable && cons->tls_verify_peer) {
783 Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\" or \"TLS CA"
784 " Certificate Dir\" are defined for Console \"%s\" in %s."
785 " At least one CA certificate store is required"
786 " when using \"TLS Verify Peer\".\n"),
787 cons->name(), configfile);
790 /* If everything is well, attempt to initialize our per-resource TLS context */
791 if (OK && (cons->tls_enable || cons->tls_require)) {
792 /* Initialize TLS context:
793 * Args: CA certfile, CA certdir, Certfile, Keyfile,
794 * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
795 cons->tls_ctx = new_tls_context(cons->tls_ca_certfile,
796 cons->tls_ca_certdir, cons->tls_certfile,
797 cons->tls_keyfile, NULL, NULL, cons->tls_dhfile, cons->tls_verify_peer);
799 if (!cons->tls_ctx) {
800 Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for File daemon \"%s\" in %s.\n"),
801 cons->name(), configfile);
808 /* Loop over Clients */
810 foreach_res(client, R_CLIENT) {
811 /* tls_require implies tls_enable */
812 if (client->tls_require) {
814 client->tls_enable = true;
816 Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
822 if ((!client->tls_ca_certfile && !client->tls_ca_certdir) && client->tls_enable) {
823 Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\""
824 " or \"TLS CA Certificate Dir\" are defined for File daemon \"%s\" in %s.\n"),
825 client->name(), configfile);
829 /* If everything is well, attempt to initialize our per-resource TLS context */
830 if (OK && (client->tls_enable || client->tls_require)) {
831 /* Initialize TLS context:
832 * Args: CA certfile, CA certdir, Certfile, Keyfile,
833 * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
834 client->tls_ctx = new_tls_context(client->tls_ca_certfile,
835 client->tls_ca_certdir, client->tls_certfile,
836 client->tls_keyfile, NULL, NULL, NULL,
839 if (!client->tls_ctx) {
840 Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for File daemon \"%s\" in %s.\n"),
841 client->name(), configfile);
849 close_msg(NULL); /* close temp message handler */
850 init_msg(NULL, director->messages); /* open daemon message handler */
855 static bool check_catalog()
859 /* Loop over databases */
861 foreach_res(catalog, R_CATALOG) {
864 * Make sure we can open catalog, otherwise print a warning
865 * message because the server is probably not running.
867 db = db_init_database(NULL, catalog->db_name, catalog->db_user,
868 catalog->db_password, catalog->db_address,
869 catalog->db_port, catalog->db_socket,
870 catalog->mult_db_connections);
871 if (!db || !db_open_database(NULL, db)) {
872 Pmsg2(000, _("Could not open Catalog \"%s\", database \"%s\".\n"),
873 catalog->name(), catalog->db_name);
874 Jmsg(NULL, M_FATAL, 0, _("Could not open Catalog \"%s\", database \"%s\".\n"),
875 catalog->name(), catalog->db_name);
877 Jmsg(NULL, M_FATAL, 0, _("%s"), db_strerror(db));
878 Pmsg1(000, "%s", db_strerror(db));
879 db_close_database(NULL, db);
885 /* Loop over all pools, defining/updating them in each database */
887 foreach_res(pool, R_POOL) {
888 create_pool(NULL, db, pool, POOL_OP_UPDATE); /* update request */
891 /* Loop over all pools for updating RecyclePool */
892 foreach_res(pool, R_POOL) {
893 update_pool_recyclepool(NULL, db, pool);
897 foreach_res(store, R_STORAGE) {
900 if (store->media_type) {
901 bstrncpy(mr.MediaType, store->media_type, sizeof(mr.MediaType));
903 db_create_mediatype_record(NULL, db, &mr);
907 bstrncpy(sr.Name, store->name(), sizeof(sr.Name));
908 sr.AutoChanger = store->autochanger;
909 db_create_storage_record(NULL, db, &sr);
910 store->StorageId = sr.StorageId; /* set storage Id */
911 if (!sr.created) { /* if not created, update it */
912 db_update_storage_record(NULL, db, &sr);
915 /* tls_require implies tls_enable */
916 if (store->tls_require) {
918 store->tls_enable = true;
920 Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
925 if ((!store->tls_ca_certfile && !store->tls_ca_certdir) && store->tls_enable) {
926 Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\""
927 " or \"TLS CA Certificate Dir\" are defined for Storage \"%s\" in %s.\n"),
928 store->name(), configfile);
932 /* If everything is well, attempt to initialize our per-resource TLS context */
933 if (OK && (store->tls_enable || store->tls_require)) {
934 /* Initialize TLS context:
935 * Args: CA certfile, CA certdir, Certfile, Keyfile,
936 * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
937 store->tls_ctx = new_tls_context(store->tls_ca_certfile,
938 store->tls_ca_certdir, store->tls_certfile,
939 store->tls_keyfile, NULL, NULL, NULL, true);
941 if (!store->tls_ctx) {
942 Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for Storage \"%s\" in %s.\n"),
943 store->name(), configfile);
949 /* Loop over all counters, defining them in each database */
950 /* Set default value in all counters */
952 foreach_res(counter, R_COUNTER) {
953 /* Write to catalog? */
954 if (!counter->created && counter->Catalog == catalog) {
956 bstrncpy(cr.Counter, counter->name(), sizeof(cr.Counter));
957 cr.MinValue = counter->MinValue;
958 cr.MaxValue = counter->MaxValue;
959 cr.CurrentValue = counter->MinValue;
960 if (counter->WrapCounter) {
961 bstrncpy(cr.WrapCounter, counter->WrapCounter->name(), sizeof(cr.WrapCounter));
963 cr.WrapCounter[0] = 0; /* empty string */
965 if (db_create_counter_record(NULL, db, &cr)) {
966 counter->CurrentValue = cr.CurrentValue;
967 counter->created = true;
968 Dmsg2(100, "Create counter %s val=%d\n", counter->name(), counter->CurrentValue);
971 if (!counter->created) {
972 counter->CurrentValue = counter->MinValue; /* default value */
975 db_close_database(NULL, db);
977 /* Set type in global for debugging */
978 set_db_type(db_get_type());