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);
231 if (!test_config) { /* we don't need to do this block in test mode */
234 init_stack_dump(); /* grab new pid */
237 /* Create pid must come after we are a daemon -- so we have our final pid */
238 create_pid_file(director->pid_directory, "bacula-dir", get_first_port_host_order(director->DIRaddrs));
239 read_state_file(director->working_directory, "bacula-dir", get_first_port_host_order(director->DIRaddrs));
242 drop(uid, gid); /* reduce privileges if requested */
244 if (!check_catalog()) {
245 Jmsg((JCR *)NULL, M_ERROR_TERM, 0, _("Please correct configuration file: %s\n"), configfile);
252 my_name_is(0, NULL, director->name()); /* set user defined name */
254 /* Plug database interface for library routines */
255 p_sql_query = (sql_query)dir_sql_query;
256 p_sql_escape = (sql_escape)db_escape_string;
258 FDConnectTimeout = (int)director->FDConnectTimeout;
259 SDConnectTimeout = (int)director->SDConnectTimeout;
262 #if !defined(HAVE_WIN32)
263 signal(SIGHUP, reload_config);
266 init_console_msg(working_directory);
268 init_python_interpreter(director->name(), director->scripts_directory,
271 set_thread_concurrency(director->MaxConcurrentJobs * 2 +
272 4 /* UA */ + 4 /* sched+watchdog+jobsvr+misc */);
274 Dmsg0(200, "Start UA server\n");
275 start_UA_server(director->DIRaddrs);
277 start_watchdog(); /* start network watchdog thread */
279 init_jcr_subsystem(); /* start JCR watchdogs etc. */
281 init_job_server(director->MaxConcurrentJobs);
283 // init_device_resources();
285 Dmsg0(200, "wait for next job\n");
286 /* Main loop -- call scheduler to get next job to run */
287 while ( (jcr = wait_for_next_job(runjob)) ) {
288 run_job(jcr); /* run job */
289 free_jcr(jcr); /* release jcr */
290 if (runjob) { /* command line, run a single job? */
291 break; /* yes, terminate */
301 * This allows the message handler to operate on the database
302 * by using a pointer to this function. The pointer is
303 * needed because the other daemons do not have access
304 * to the database. If the pointer is
305 * not defined (other daemons), then writing the database
308 static void dir_sql_query(JCR *jcr, const char *cmd)
310 if (!jcr || !jcr->db) {
313 db_sql_query(jcr->db, cmd, NULL, NULL);
316 /* Cleanup and then exit */
317 void terminate_dird(int sig)
319 static bool already_here = false;
321 if (already_here) { /* avoid recursive temination problems */
326 generate_daemon_event(NULL, "Exit");
327 write_state_file(director->working_directory, "bacula-dir", get_first_port_host_order(director->DIRaddrs));
328 delete_pid_file(director->pid_directory, "bacula-dir", get_first_port_host_order(director->DIRaddrs));
329 // signal(SIGCHLD, SIG_IGN); /* don't worry about children now */
335 if (configfile != NULL) {
338 if (debug_level > 5) {
339 print_memory_pool_stats();
341 free_config_resources();
343 term_msg(); /* terminate message handler */
345 close_memory_pool(); /* release free memory in pool */
350 struct RELOAD_TABLE {
355 static const int max_reloads = 32;
356 static RELOAD_TABLE reload_table[max_reloads];
358 static void init_reload(void)
360 for (int i=0; i < max_reloads; i++) {
361 reload_table[i].job_count = 0;
362 reload_table[i].res_table = NULL;
366 static void free_saved_resources(int table)
368 int num = r_last - r_first + 1;
369 RES **res_tab = reload_table[table].res_table;
371 Dmsg1(100, "res_tab for table %d already released.\n", table);
374 Dmsg1(100, "Freeing resources for table %d\n", table);
375 for (int j=0; j<num; j++) {
376 free_resource(res_tab[j], r_first + j);
379 reload_table[table].job_count = 0;
380 reload_table[table].res_table = NULL;
384 * Called here at the end of every job that was
385 * hooked decrementing the active job_count. When
386 * it goes to zero, no one is using the associated
387 * resource table, so free it.
389 static void reload_job_end_cb(JCR *jcr, void *ctx)
391 int reload_id = (int)((long int)ctx);
392 Dmsg3(100, "reload job_end JobId=%d table=%d cnt=%d\n", jcr->JobId,
393 reload_id, reload_table[reload_id].job_count);
396 if (--reload_table[reload_id].job_count <= 0) {
397 free_saved_resources(reload_id);
403 static int find_free_reload_table_entry()
406 for (int i=0; i < max_reloads; i++) {
407 if (reload_table[i].res_table == NULL) {
416 * If we get here, we have received a SIGHUP, which means to
417 * reread our configuration file.
419 * The algorithm used is as follows: we count how many jobs are
420 * running and mark the running jobs to make a callback on
421 * exiting. The old config is saved with the reload table
422 * id in a reload table. The new config file is read. Now, as
423 * each job exits, it calls back to the reload_job_end_cb(), which
424 * decrements the count of open jobs for the given reload table.
425 * When the count goes to zero, we release those resources.
426 * This allows us to have pointers into the resource table (from
427 * jobs), and once they exit and all the pointers are released, we
428 * release the old table. Note, if no new jobs are running since the
429 * last reload, then the old resources will be immediately release.
430 * A console is considered a job because it may have pointers to
431 * resources, but a SYSTEM job is not since it *should* not have any
432 * permanent pointers to jobs.
435 void reload_config(int sig)
437 static bool already_here = false;
438 #if !defined(HAVE_WIN32)
442 int njobs = 0; /* number of running jobs */
447 abort(); /* Oops, recursion -> die */
451 #if !defined(HAVE_WIN32)
453 sigaddset(&set, SIGHUP);
454 sigprocmask(SIG_BLOCK, &set, NULL);
460 table = find_free_reload_table_entry();
462 Jmsg(NULL, M_ERROR, 0, _("Too many open reload requests. Request ignored.\n"));
466 Dmsg1(100, "Reload_config njobs=%d\n", njobs);
467 reload_table[table].res_table = save_config_resources();
468 Dmsg1(100, "Saved old config in table %d\n", table);
470 ok = parse_config(configfile, 0, M_ERROR); /* no exit on error */
472 Dmsg0(100, "Reloaded config file\n");
473 if (!ok || !check_resources() || !check_catalog()) {
474 rtable = find_free_reload_table_entry(); /* save new, bad table */
476 Jmsg(NULL, M_ERROR, 0, _("Please correct configuration file: %s\n"), configfile);
477 Jmsg(NULL, M_ERROR_TERM, 0, _("Out of reload table entries. Giving up.\n"));
479 Jmsg(NULL, M_ERROR, 0, _("Please correct configuration file: %s\n"), configfile);
480 Jmsg(NULL, M_ERROR, 0, _("Resetting previous configuration.\n"));
482 reload_table[rtable].res_table = save_config_resources();
483 /* Now restore old resoure values */
484 int num = r_last - r_first + 1;
485 RES **res_tab = reload_table[table].res_table;
486 for (int i=0; i<num; i++) {
487 res_head[i] = res_tab[i];
489 table = rtable; /* release new, bad, saved table below */
491 invalidate_schedules();
493 * Hook all active jobs so that they release this table
496 if (jcr->JobType != JT_SYSTEM) {
497 reload_table[table].job_count++;
498 job_end_push(jcr, reload_job_end_cb, (void *)((long int)table));
506 set_working_directory(director->working_directory);
507 FDConnectTimeout = director->FDConnectTimeout;
508 SDConnectTimeout = director->SDConnectTimeout;
509 Dmsg0(10, "Director's configuration file reread.\n");
511 /* Now release saved resources, if no jobs using the resources */
513 free_saved_resources(table);
519 #if !defined(HAVE_WIN32)
520 sigprocmask(SIG_UNBLOCK, &set, NULL);
521 signal(SIGHUP, reload_config);
523 already_here = false;
527 * Make a quick check to see that we have all the
530 * **** FIXME **** this routine could be a lot more
531 * intelligent and comprehensive.
533 static bool check_resources()
540 job = (JOB *)GetNextRes(R_JOB, NULL);
541 director = (DIRRES *)GetNextRes(R_DIRECTOR, NULL);
543 Jmsg(NULL, M_FATAL, 0, _("No Director resource defined in %s\n"
544 "Without that I don't know who I am :-(\n"), configfile);
547 set_working_directory(director->working_directory);
548 if (!director->messages) { /* If message resource not specified */
549 director->messages = (MSGS *)GetNextRes(R_MSGS, NULL);
550 if (!director->messages) {
551 Jmsg(NULL, M_FATAL, 0, _("No Messages resource defined in %s\n"), configfile);
555 if (GetNextRes(R_DIRECTOR, (RES *)director) != NULL) {
556 Jmsg(NULL, M_FATAL, 0, _("Only one Director resource permitted in %s\n"),
560 /* tls_require implies tls_enable */
561 if (director->tls_require) {
563 director->tls_enable = true;
565 Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
570 if (!director->tls_certfile && director->tls_enable) {
571 Jmsg(NULL, M_FATAL, 0, _("\"TLS Certificate\" file not defined for Director \"%s\" in %s.\n"),
572 director->name(), configfile);
576 if (!director->tls_keyfile && director->tls_enable) {
577 Jmsg(NULL, M_FATAL, 0, _("\"TLS Key\" file not defined for Director \"%s\" in %s.\n"),
578 director->name(), configfile);
582 if ((!director->tls_ca_certfile && !director->tls_ca_certdir) && director->tls_enable && director->tls_verify_peer) {
583 Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\" or \"TLS CA"
584 " Certificate Dir\" are defined for Director \"%s\" in %s."
585 " At least one CA certificate store is required"
586 " when using \"TLS Verify Peer\".\n"),
587 director->name(), configfile);
591 /* If everything is well, attempt to initialize our per-resource TLS context */
592 if (OK && (director->tls_enable || director->tls_require)) {
593 /* Initialize TLS context:
594 * Args: CA certfile, CA certdir, Certfile, Keyfile,
595 * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
596 director->tls_ctx = new_tls_context(director->tls_ca_certfile,
597 director->tls_ca_certdir, director->tls_certfile,
598 director->tls_keyfile, NULL, NULL, director->tls_dhfile,
599 director->tls_verify_peer);
601 if (!director->tls_ctx) {
602 Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for Director \"%s\" in %s.\n"),
603 director->name(), configfile);
610 Jmsg(NULL, M_FATAL, 0, _("No Job records defined in %s\n"), configfile);
613 foreach_res(job, R_JOB) {
617 /* Handle Storage alists specifically */
618 JOB *jobdefs = job->jobdefs;
619 if (jobdefs->storage && !job->storage) {
621 job->storage = New(alist(10, not_owned_by_alist));
622 foreach_alist(st, jobdefs->storage) {
623 job->storage->append(st);
626 /* Handle RunScripts alists specifically */
627 if (jobdefs->RunScripts) {
630 if (!job->RunScripts) {
631 job->RunScripts = New(alist(10, not_owned_by_alist));
634 foreach_alist(rs, jobdefs->RunScripts) {
635 elt = copy_runscript(rs);
636 job->RunScripts->append(elt); /* we have to free it */
640 /* Transfer default items from JobDefs Resource */
641 for (i=0; job_items[i].name; i++) {
642 char **def_svalue, **svalue; /* string value */
643 int *def_ivalue, *ivalue; /* integer value */
644 bool *def_bvalue, *bvalue; /* bool value */
645 int64_t *def_lvalue, *lvalue; /* 64 bit values */
648 Dmsg4(1400, "Job \"%s\", field \"%s\" bit=%d def=%d\n",
649 job->name(), job_items[i].name,
650 bit_is_set(i, job->hdr.item_present),
651 bit_is_set(i, job->jobdefs->hdr.item_present));
653 if (!bit_is_set(i, job->hdr.item_present) &&
654 bit_is_set(i, job->jobdefs->hdr.item_present)) {
655 Dmsg2(400, "Job \"%s\", field \"%s\": getting default.\n",
656 job->name(), job_items[i].name);
657 offset = (char *)(job_items[i].value) - (char *)&res_all;
659 * Handle strings and directory strings
661 if (job_items[i].handler == store_str ||
662 job_items[i].handler == store_dir) {
663 def_svalue = (char **)((char *)(job->jobdefs) + offset);
664 Dmsg5(400, "Job \"%s\", field \"%s\" def_svalue=%s item %d offset=%u\n",
665 job->name(), job_items[i].name, *def_svalue, i, offset);
666 svalue = (char **)((char *)job + offset);
668 Pmsg1(000, _("Hey something is wrong. p=0x%lu\n"), *svalue);
670 *svalue = bstrdup(*def_svalue);
671 set_bit(i, job->hdr.item_present);
675 } else if (job_items[i].handler == store_res) {
676 def_svalue = (char **)((char *)(job->jobdefs) + offset);
677 Dmsg4(400, "Job \"%s\", field \"%s\" item %d offset=%u\n",
678 job->name(), job_items[i].name, i, offset);
679 svalue = (char **)((char *)job + offset);
681 Pmsg1(000, _("Hey something is wrong. p=0x%lu\n"), *svalue);
683 *svalue = *def_svalue;
684 set_bit(i, job->hdr.item_present);
686 * Handle alist resources
688 } else if (job_items[i].handler == store_alist_res) {
689 if (bit_is_set(i, job->jobdefs->hdr.item_present)) {
690 set_bit(i, job->hdr.item_present);
693 * Handle integer fields
694 * Note, our store_bit does not handle bitmaped fields
696 } else if (job_items[i].handler == store_bit ||
697 job_items[i].handler == store_pint ||
698 job_items[i].handler == store_jobtype ||
699 job_items[i].handler == store_level ||
700 job_items[i].handler == store_pint ||
701 job_items[i].handler == store_replace) {
702 def_ivalue = (int *)((char *)(job->jobdefs) + offset);
703 Dmsg5(400, "Job \"%s\", field \"%s\" def_ivalue=%d item %d offset=%u\n",
704 job->name(), job_items[i].name, *def_ivalue, i, offset);
705 ivalue = (int *)((char *)job + offset);
706 *ivalue = *def_ivalue;
707 set_bit(i, job->hdr.item_present);
709 * Handle 64 bit integer fields
711 } else if (job_items[i].handler == store_time ||
712 job_items[i].handler == store_size ||
713 job_items[i].handler == store_int64) {
714 def_lvalue = (int64_t *)((char *)(job->jobdefs) + offset);
715 Dmsg5(400, "Job \"%s\", field \"%s\" def_lvalue=%" lld " item %d offset=%u\n",
716 job->name(), job_items[i].name, *def_lvalue, i, offset);
717 lvalue = (int64_t *)((char *)job + offset);
718 *lvalue = *def_lvalue;
719 set_bit(i, job->hdr.item_present);
723 } else if (job_items[i].handler == store_bool) {
724 def_bvalue = (bool *)((char *)(job->jobdefs) + offset);
725 Dmsg5(400, "Job \"%s\", field \"%s\" def_bvalue=%d item %d offset=%u\n",
726 job->name(), job_items[i].name, *def_bvalue, i, offset);
727 bvalue = (bool *)((char *)job + offset);
728 *bvalue = *def_bvalue;
729 set_bit(i, job->hdr.item_present);
735 * Ensure that all required items are present
737 for (i=0; job_items[i].name; i++) {
738 if (job_items[i].flags & ITEM_REQUIRED) {
739 if (!bit_is_set(i, job->hdr.item_present)) {
740 Jmsg(NULL, M_ERROR_TERM, 0, _("\"%s\" directive in Job \"%s\" resource is required, but not found.\n"),
741 job_items[i].name, job->name());
745 /* If this triggers, take a look at lib/parse_conf.h */
746 if (i >= MAX_RES_ITEMS) {
747 Emsg0(M_ERROR_TERM, 0, _("Too many items in Job resource\n"));
750 if (!job->storage && !job->pool->storage) {
751 Jmsg(NULL, M_FATAL, 0, _("No storage specified in Job \"%s\" nor in Pool.\n"),
755 } /* End loop over Job res */
758 /* Loop over Consoles */
760 foreach_res(cons, R_CONSOLE) {
761 /* tls_require implies tls_enable */
762 if (cons->tls_require) {
764 cons->tls_enable = true;
766 Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
772 if (!cons->tls_certfile && cons->tls_enable) {
773 Jmsg(NULL, M_FATAL, 0, _("\"TLS Certificate\" file not defined for Console \"%s\" in %s.\n"),
774 cons->name(), configfile);
778 if (!cons->tls_keyfile && cons->tls_enable) {
779 Jmsg(NULL, M_FATAL, 0, _("\"TLS Key\" file not defined for Console \"%s\" in %s.\n"),
780 cons->name(), configfile);
784 if ((!cons->tls_ca_certfile && !cons->tls_ca_certdir) && cons->tls_enable && cons->tls_verify_peer) {
785 Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\" or \"TLS CA"
786 " Certificate Dir\" are defined for Console \"%s\" in %s."
787 " At least one CA certificate store is required"
788 " when using \"TLS Verify Peer\".\n"),
789 cons->name(), configfile);
792 /* If everything is well, attempt to initialize our per-resource TLS context */
793 if (OK && (cons->tls_enable || cons->tls_require)) {
794 /* Initialize TLS context:
795 * Args: CA certfile, CA certdir, Certfile, Keyfile,
796 * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
797 cons->tls_ctx = new_tls_context(cons->tls_ca_certfile,
798 cons->tls_ca_certdir, cons->tls_certfile,
799 cons->tls_keyfile, NULL, NULL, cons->tls_dhfile, cons->tls_verify_peer);
801 if (!cons->tls_ctx) {
802 Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for File daemon \"%s\" in %s.\n"),
803 cons->name(), configfile);
810 /* Loop over Clients */
812 foreach_res(client, R_CLIENT) {
813 /* tls_require implies tls_enable */
814 if (client->tls_require) {
816 client->tls_enable = true;
818 Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
824 if ((!client->tls_ca_certfile && !client->tls_ca_certdir) && client->tls_enable) {
825 Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\""
826 " or \"TLS CA Certificate Dir\" are defined for File daemon \"%s\" in %s.\n"),
827 client->name(), configfile);
831 /* If everything is well, attempt to initialize our per-resource TLS context */
832 if (OK && (client->tls_enable || client->tls_require)) {
833 /* Initialize TLS context:
834 * Args: CA certfile, CA certdir, Certfile, Keyfile,
835 * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
836 client->tls_ctx = new_tls_context(client->tls_ca_certfile,
837 client->tls_ca_certdir, client->tls_certfile,
838 client->tls_keyfile, NULL, NULL, NULL,
841 if (!client->tls_ctx) {
842 Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for File daemon \"%s\" in %s.\n"),
843 client->name(), configfile);
851 close_msg(NULL); /* close temp message handler */
852 init_msg(NULL, director->messages); /* open daemon message handler */
857 static bool check_catalog()
861 /* Loop over databases */
863 foreach_res(catalog, R_CATALOG) {
866 * Make sure we can open catalog, otherwise print a warning
867 * message because the server is probably not running.
869 db = db_init_database(NULL, catalog->db_name, catalog->db_user,
870 catalog->db_password, catalog->db_address,
871 catalog->db_port, catalog->db_socket,
872 catalog->mult_db_connections);
873 if (!db || !db_open_database(NULL, db)) {
874 Pmsg2(000, _("Could not open Catalog \"%s\", database \"%s\".\n"),
875 catalog->name(), catalog->db_name);
876 Jmsg(NULL, M_FATAL, 0, _("Could not open Catalog \"%s\", database \"%s\".\n"),
877 catalog->name(), catalog->db_name);
879 Jmsg(NULL, M_FATAL, 0, _("%s"), db_strerror(db));
880 Pmsg1(000, "%s", db_strerror(db));
881 db_close_database(NULL, db);
887 /* Loop over all pools, defining/updating them in each database */
889 foreach_res(pool, R_POOL) {
890 create_pool(NULL, db, pool, POOL_OP_UPDATE); /* update request */
893 /* Loop over all pools for updating RecyclePool */
894 foreach_res(pool, R_POOL) {
895 update_pool_recyclepool(NULL, db, pool);
899 foreach_res(store, R_STORAGE) {
902 if (store->media_type) {
903 bstrncpy(mr.MediaType, store->media_type, sizeof(mr.MediaType));
905 db_create_mediatype_record(NULL, db, &mr);
909 bstrncpy(sr.Name, store->name(), sizeof(sr.Name));
910 sr.AutoChanger = store->autochanger;
911 db_create_storage_record(NULL, db, &sr);
912 store->StorageId = sr.StorageId; /* set storage Id */
913 if (!sr.created) { /* if not created, update it */
914 db_update_storage_record(NULL, db, &sr);
917 /* tls_require implies tls_enable */
918 if (store->tls_require) {
920 store->tls_enable = true;
922 Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
927 if ((!store->tls_ca_certfile && !store->tls_ca_certdir) && store->tls_enable) {
928 Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\""
929 " or \"TLS CA Certificate Dir\" are defined for Storage \"%s\" in %s.\n"),
930 store->name(), configfile);
934 /* If everything is well, attempt to initialize our per-resource TLS context */
935 if (OK && (store->tls_enable || store->tls_require)) {
936 /* Initialize TLS context:
937 * Args: CA certfile, CA certdir, Certfile, Keyfile,
938 * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
939 store->tls_ctx = new_tls_context(store->tls_ca_certfile,
940 store->tls_ca_certdir, store->tls_certfile,
941 store->tls_keyfile, NULL, NULL, NULL, true);
943 if (!store->tls_ctx) {
944 Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for Storage \"%s\" in %s.\n"),
945 store->name(), configfile);
951 /* Loop over all counters, defining them in each database */
952 /* Set default value in all counters */
954 foreach_res(counter, R_COUNTER) {
955 /* Write to catalog? */
956 if (!counter->created && counter->Catalog == catalog) {
958 bstrncpy(cr.Counter, counter->name(), sizeof(cr.Counter));
959 cr.MinValue = counter->MinValue;
960 cr.MaxValue = counter->MaxValue;
961 cr.CurrentValue = counter->MinValue;
962 if (counter->WrapCounter) {
963 bstrncpy(cr.WrapCounter, counter->WrapCounter->name(), sizeof(cr.WrapCounter));
965 cr.WrapCounter[0] = 0; /* empty string */
967 if (db_create_counter_record(NULL, db, &cr)) {
968 counter->CurrentValue = cr.CurrentValue;
969 counter->created = true;
970 Dmsg2(100, "Create counter %s val=%d\n", counter->name(), counter->CurrentValue);
973 if (!counter->created) {
974 counter->CurrentValue = counter->MinValue; /* default value */
977 db_close_database(NULL, db);
979 /* Set type in global for debugging */
980 set_db_type(db_get_type());