2 Bacula® - The Network Backup Solution
4 Copyright (C) 2000-2010 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 three of the GNU Affero 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 Affero General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23 Bacula® is a registered trademark of Kern Sibbald.
24 The licensor of Bacula is the Free Software Foundation Europe
25 (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
26 Switzerland, email:ftf@fsfeurope.org.
30 * Bacula Director daemon -- this is the main program
32 * Kern Sibbald, March MM
41 #undef _POSIX_C_SOURCE
44 #include "lib/pythonlib.h"
46 /* Imported Functions */
47 extern PyObject *job_getattr(PyObject *self, char *attrname);
48 extern int job_setattr(PyObject *self, char *attrname, PyObject *value);
50 #endif /* HAVE_PYTHON */
52 /* Forward referenced subroutines */
53 void terminate_dird(int sig);
54 static bool check_resources();
55 static void dir_sql_query(JCR *jcr, const char *cmd);
56 static void cleanup_old_files();
58 /* Exported subroutines */
59 extern "C" void reload_config(int sig);
60 extern void invalidate_schedules();
61 extern bool parse_dir_config(CONFIG *config, const char *configfile, int exit_code);
63 /* Imported subroutines */
64 JCR *wait_for_next_job(char *runjob);
65 void term_scheduler();
66 void term_ua_server();
67 void start_UA_server(dlist *addrs);
68 void init_job_server(int max_workers);
69 void term_job_server();
70 void store_jobtype(LEX *lc, RES_ITEM *item, int index, int pass);
71 void store_level(LEX *lc, RES_ITEM *item, int index, int pass);
72 void store_replace(LEX *lc, RES_ITEM *item, int index, int pass);
73 void store_migtype(LEX *lc, RES_ITEM *item, int index, int pass);
74 void init_device_resources();
76 static char *runjob = NULL;
77 static bool background = true;
78 static void init_reload(void);
79 static CONFIG *config;
81 /* Globals Exported */
82 DIRRES *director; /* Director resource */
85 char *configfile = NULL;
88 /* Globals Imported */
89 extern RES_ITEM job_items[];
91 extern "C" { // work around visual compiler mangling variables
99 CHECK_CONNECTION, /* Check catalog connection */
100 UPDATE_CATALOG, /* Ensure that catalog is ok with conf */
101 UPDATE_AND_FIX /* Ensure that catalog is ok, and fix old jobs */
103 static bool check_catalog(cat_op mode);
105 #define CONFIG_FILE "bacula-dir.conf" /* default configuration file */
112 "\nVersion: %s (%s)\n\n"
113 "Usage: dird [-f -s] [-c config_file] [-d debug_level] [config_file]\n"
114 " -c <file> set configuration file to file\n"
115 " -d <nn> set debug level to <nn>\n"
116 " -dt print timestamp in debug output\n"
117 " -f run in foreground (for debugging)\n"
119 " -m print kaboom output (for debugging)\n"
120 " -r <job> run <job> now\n"
122 " -t test - read configuration and exit\n"
124 " -v verbose user messages\n"
125 " -? print this message.\n"
126 "\n"), 2000, VERSION, BDATE);
132 /*********************************************************************
134 * Main Bacula Director Server program
137 #if defined(HAVE_WIN32)
138 /* For Win32 main() is in src/win32 code ... */
139 #define main BaculaMain
142 int main (int argc, char *argv[])
146 bool no_signals = false;
147 bool test_config = false;
151 init_python_interpreter_args python_args;
152 #endif /* HAVE_PYTHON */
154 start_heap = sbrk(0);
155 setlocale(LC_ALL, "");
156 bindtextdomain("bacula", LOCALEDIR);
157 textdomain("bacula");
160 my_name_is(argc, argv, "bacula-dir");
161 init_msg(NULL, NULL); /* initialize message handler */
163 daemon_start_time = time(NULL);
165 console_command = run_console_command;
167 while ((ch = getopt(argc, argv, "c:d:fg:mr:stu:v?")) != -1) {
169 case 'c': /* specify config file */
170 if (configfile != NULL) {
173 configfile = bstrdup(optarg);
176 case 'd': /* set debug level */
177 if (*optarg == 't') {
178 dbg_timestamp = true;
180 debug_level = atoi(optarg);
181 if (debug_level <= 0) {
185 Dmsg1(10, "Debug level = %d\n", debug_level);
188 case 'f': /* run in foreground */
192 case 'g': /* set group id */
196 case 'm': /* print kaboom output */
200 case 'r': /* run job */
201 if (runjob != NULL) {
205 runjob = bstrdup(optarg);
209 case 's': /* turn off signals */
213 case 't': /* test config */
217 case 'u': /* set uid */
221 case 'v': /* verbose */
235 init_signals(terminate_dird);
239 if (configfile != NULL) {
242 configfile = bstrdup(*argv);
250 if (configfile == NULL) {
251 configfile = bstrdup(CONFIG_FILE);
254 config = new_config_parser();
255 parse_dir_config(config, configfile, M_ERROR_TERM);
257 if (init_crypto() != 0) {
258 Jmsg((JCR *)NULL, M_ERROR_TERM, 0, _("Cryptography library initialization failed.\n"));
261 if (!check_resources()) {
262 Jmsg((JCR *)NULL, M_ERROR_TERM, 0, _("Please correct configuration file: %s\n"), configfile);
265 if (!test_config) { /* we don't need to do this block in test mode */
268 init_stack_dump(); /* grab new pid */
270 /* Create pid must come after we are a daemon -- so we have our final pid */
271 create_pid_file(director->pid_directory, "bacula-dir",
272 get_first_port_host_order(director->DIRaddrs));
273 read_state_file(director->working_directory, "bacula-dir",
274 get_first_port_host_order(director->DIRaddrs));
277 set_jcr_in_tsd(INVALID_JCR);
278 set_thread_concurrency(director->MaxConcurrentJobs * 2 +
279 4 /* UA */ + 5 /* sched+watchdog+jobsvr+misc */);
280 lmgr_init_thread(); /* initialize the lockmanager stack */
282 load_dir_plugins(director->plugin_directory);
284 drop(uid, gid, false); /* reduce privileges if requested */
288 /* If we are in testing mode, we don't try to fix the catalog */
289 cat_op mode=(test_config)?CHECK_CONNECTION:UPDATE_AND_FIX;
291 if (!check_catalog(mode)) {
292 Jmsg((JCR *)NULL, M_ERROR_TERM, 0, _("Please correct configuration file: %s\n"), configfile);
299 my_name_is(0, NULL, director->name()); /* set user defined name */
301 /* Plug database interface for library routines */
302 p_sql_query = (sql_query_func)dir_sql_query;
303 p_sql_escape = (sql_escape_func)db_escape_string;
305 FDConnectTimeout = (int)director->FDConnectTimeout;
306 SDConnectTimeout = (int)director->SDConnectTimeout;
308 #if !defined(HAVE_WIN32)
309 signal(SIGHUP, reload_config);
312 init_console_msg(working_directory);
315 python_args.progname = director->name();
316 python_args.scriptdir = director->scripts_directory;
317 python_args.modulename = "DirStartUp";
318 python_args.configfile = configfile;
319 python_args.workingdir = director->working_directory;
320 python_args.job_getattr = job_getattr;
321 python_args.job_setattr = job_setattr;
323 init_python_interpreter(&python_args);
324 #endif /* HAVE_PYTHON */
326 Dmsg0(200, "Start UA server\n");
327 start_UA_server(director->DIRaddrs);
329 start_watchdog(); /* start network watchdog thread */
331 init_jcr_subsystem(); /* start JCR watchdogs etc. */
333 init_job_server(director->MaxConcurrentJobs);
335 dbg_jcr_add_hook(db_debug_print); /* used to debug B_DB connexion after fatal signal */
337 // init_device_resources();
339 Dmsg0(200, "wait for next job\n");
340 /* Main loop -- call scheduler to get next job to run */
341 while ( (jcr = wait_for_next_job(runjob)) ) {
342 run_job(jcr); /* run job */
343 free_jcr(jcr); /* release jcr */
344 set_jcr_in_tsd(INVALID_JCR);
345 if (runjob) { /* command line, run a single job? */
346 break; /* yes, terminate */
356 * This allows the message handler to operate on the database
357 * by using a pointer to this function. The pointer is
358 * needed because the other daemons do not have access
359 * to the database. If the pointer is
360 * not defined (other daemons), then writing the database
363 static void dir_sql_query(JCR *jcr, const char *cmd)
365 if (!jcr || !jcr->db) {
368 db_sql_query(jcr->db, cmd, NULL, NULL);
371 /* Cleanup and then exit */
372 void terminate_dird(int sig)
374 static bool already_here = false;
376 if (already_here) { /* avoid recursive temination problems */
377 bmicrosleep(2, 0); /* yield */
381 debug_level = 0; /* turn off debug */
383 generate_daemon_event(NULL, "Exit");
385 write_state_file(director->working_directory, "bacula-dir", get_first_port_host_order(director->DIRaddrs));
386 delete_pid_file(director->pid_directory, "bacula-dir", get_first_port_host_order(director->DIRaddrs));
392 if (configfile != NULL) {
395 if (debug_level > 5) {
396 print_memory_pool_stats();
399 config->free_resources();
404 term_msg(); /* terminate message handler */
406 close_memory_pool(); /* release free memory in pool */
412 struct RELOAD_TABLE {
417 static const int max_reloads = 32;
418 static RELOAD_TABLE reload_table[max_reloads];
420 static void init_reload(void)
422 for (int i=0; i < max_reloads; i++) {
423 reload_table[i].job_count = 0;
424 reload_table[i].res_table = NULL;
428 static void free_saved_resources(int table)
430 int num = r_last - r_first + 1;
431 RES **res_tab = reload_table[table].res_table;
433 Dmsg1(100, "res_tab for table %d already released.\n", table);
436 Dmsg1(100, "Freeing resources for table %d\n", table);
437 for (int j=0; j<num; j++) {
438 free_resource(res_tab[j], r_first + j);
441 reload_table[table].job_count = 0;
442 reload_table[table].res_table = NULL;
446 * Called here at the end of every job that was
447 * hooked decrementing the active job_count. When
448 * it goes to zero, no one is using the associated
449 * resource table, so free it.
451 static void reload_job_end_cb(JCR *jcr, void *ctx)
453 int reload_id = (int)((intptr_t)ctx);
454 Dmsg3(100, "reload job_end JobId=%d table=%d cnt=%d\n", jcr->JobId,
455 reload_id, reload_table[reload_id].job_count);
458 if (--reload_table[reload_id].job_count <= 0) {
459 free_saved_resources(reload_id);
465 static int find_free_reload_table_entry()
468 for (int i=0; i < max_reloads; i++) {
469 if (reload_table[i].res_table == NULL) {
478 * If we get here, we have received a SIGHUP, which means to
479 * reread our configuration file.
481 * The algorithm used is as follows: we count how many jobs are
482 * running and mark the running jobs to make a callback on
483 * exiting. The old config is saved with the reload table
484 * id in a reload table. The new config file is read. Now, as
485 * each job exits, it calls back to the reload_job_end_cb(), which
486 * decrements the count of open jobs for the given reload table.
487 * When the count goes to zero, we release those resources.
488 * This allows us to have pointers into the resource table (from
489 * jobs), and once they exit and all the pointers are released, we
490 * release the old table. Note, if no new jobs are running since the
491 * last reload, then the old resources will be immediately release.
492 * A console is considered a job because it may have pointers to
493 * resources, but a SYSTEM job is not since it *should* not have any
494 * permanent pointers to jobs.
497 void reload_config(int sig)
499 static bool already_here = false;
500 #if !defined(HAVE_WIN32)
504 int njobs = 0; /* number of running jobs */
509 abort(); /* Oops, recursion -> die */
513 #if !defined(HAVE_WIN32)
515 sigaddset(&set, SIGHUP);
516 sigprocmask(SIG_BLOCK, &set, NULL);
522 table = find_free_reload_table_entry();
524 Jmsg(NULL, M_ERROR, 0, _("Too many open reload requests. Request ignored.\n"));
528 Dmsg1(100, "Reload_config njobs=%d\n", njobs);
529 reload_table[table].res_table = config->save_resources();
530 Dmsg1(100, "Saved old config in table %d\n", table);
532 ok = parse_dir_config(config, configfile, M_ERROR);
534 Dmsg0(100, "Reloaded config file\n");
535 if (!ok || !check_resources() || !check_catalog(UPDATE_CATALOG)) {
536 rtable = find_free_reload_table_entry(); /* save new, bad table */
538 Jmsg(NULL, M_ERROR, 0, _("Please correct configuration file: %s\n"), configfile);
539 Jmsg(NULL, M_ERROR_TERM, 0, _("Out of reload table entries. Giving up.\n"));
541 Jmsg(NULL, M_ERROR, 0, _("Please correct configuration file: %s\n"), configfile);
542 Jmsg(NULL, M_ERROR, 0, _("Resetting previous configuration.\n"));
544 reload_table[rtable].res_table = config->save_resources();
545 /* Now restore old resoure values */
546 int num = r_last - r_first + 1;
547 RES **res_tab = reload_table[table].res_table;
548 for (int i=0; i<num; i++) {
549 res_head[i] = res_tab[i];
551 table = rtable; /* release new, bad, saved table below */
553 invalidate_schedules();
555 * Hook all active jobs so that they release this table
558 if (jcr->getJobType() != JT_SYSTEM) {
559 reload_table[table].job_count++;
560 job_end_push(jcr, reload_job_end_cb, (void *)((long int)table));
568 set_working_directory(director->working_directory);
569 FDConnectTimeout = director->FDConnectTimeout;
570 SDConnectTimeout = director->SDConnectTimeout;
571 Dmsg0(10, "Director's configuration file reread.\n");
573 /* Now release saved resources, if no jobs using the resources */
575 free_saved_resources(table);
581 #if !defined(HAVE_WIN32)
582 sigprocmask(SIG_UNBLOCK, &set, NULL);
583 signal(SIGHUP, reload_config);
585 already_here = false;
589 * Make a quick check to see that we have all the
592 * **** FIXME **** this routine could be a lot more
593 * intelligent and comprehensive.
595 static bool check_resources()
603 job = (JOB *)GetNextRes(R_JOB, NULL);
604 director = (DIRRES *)GetNextRes(R_DIRECTOR, NULL);
606 Jmsg(NULL, M_FATAL, 0, _("No Director resource defined in %s\n"
607 "Without that I don't know who I am :-(\n"), configfile);
610 set_working_directory(director->working_directory);
611 if (!director->messages) { /* If message resource not specified */
612 director->messages = (MSGS *)GetNextRes(R_MSGS, NULL);
613 if (!director->messages) {
614 Jmsg(NULL, M_FATAL, 0, _("No Messages resource defined in %s\n"), configfile);
618 if (GetNextRes(R_DIRECTOR, (RES *)director) != NULL) {
619 Jmsg(NULL, M_FATAL, 0, _("Only one Director resource permitted in %s\n"),
623 /* tls_require implies tls_enable */
624 if (director->tls_require) {
626 director->tls_enable = true;
628 Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
633 need_tls = director->tls_enable || director->tls_authenticate;
635 if (!director->tls_certfile && need_tls) {
636 Jmsg(NULL, M_FATAL, 0, _("\"TLS Certificate\" file not defined for Director \"%s\" in %s.\n"),
637 director->name(), configfile);
641 if (!director->tls_keyfile && need_tls) {
642 Jmsg(NULL, M_FATAL, 0, _("\"TLS Key\" file not defined for Director \"%s\" in %s.\n"),
643 director->name(), configfile);
647 if ((!director->tls_ca_certfile && !director->tls_ca_certdir) &&
648 need_tls && director->tls_verify_peer) {
649 Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\" or \"TLS CA"
650 " Certificate Dir\" are defined for Director \"%s\" in %s."
651 " At least one CA certificate store is required"
652 " when using \"TLS Verify Peer\".\n"),
653 director->name(), configfile);
657 /* If everything is well, attempt to initialize our per-resource TLS context */
658 if (OK && (need_tls || director->tls_require)) {
659 /* Initialize TLS context:
660 * Args: CA certfile, CA certdir, Certfile, Keyfile,
661 * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
662 director->tls_ctx = new_tls_context(director->tls_ca_certfile,
663 director->tls_ca_certdir, director->tls_certfile,
664 director->tls_keyfile, NULL, NULL, director->tls_dhfile,
665 director->tls_verify_peer);
667 if (!director->tls_ctx) {
668 Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for Director \"%s\" in %s.\n"),
669 director->name(), configfile);
676 Jmsg(NULL, M_FATAL, 0, _("No Job records defined in %s\n"), configfile);
679 foreach_res(job, R_JOB) {
683 /* Handle Storage alists specifically */
684 JOB *jobdefs = job->jobdefs;
685 if (jobdefs->storage && !job->storage) {
687 job->storage = New(alist(10, not_owned_by_alist));
688 foreach_alist(st, jobdefs->storage) {
689 job->storage->append(st);
692 /* Handle RunScripts alists specifically */
693 if (jobdefs->RunScripts) {
696 if (!job->RunScripts) {
697 job->RunScripts = New(alist(10, not_owned_by_alist));
700 foreach_alist(rs, jobdefs->RunScripts) {
701 elt = copy_runscript(rs);
702 job->RunScripts->append(elt); /* we have to free it */
706 /* Transfer default items from JobDefs Resource */
707 for (i=0; job_items[i].name; i++) {
708 char **def_svalue, **svalue; /* string value */
709 uint32_t *def_ivalue, *ivalue; /* integer value */
710 bool *def_bvalue, *bvalue; /* bool value */
711 int64_t *def_lvalue, *lvalue; /* 64 bit values */
714 Dmsg4(1400, "Job \"%s\", field \"%s\" bit=%d def=%d\n",
715 job->name(), job_items[i].name,
716 bit_is_set(i, job->hdr.item_present),
717 bit_is_set(i, job->jobdefs->hdr.item_present));
719 if (!bit_is_set(i, job->hdr.item_present) &&
720 bit_is_set(i, job->jobdefs->hdr.item_present)) {
721 Dmsg2(400, "Job \"%s\", field \"%s\": getting default.\n",
722 job->name(), job_items[i].name);
723 offset = (char *)(job_items[i].value) - (char *)&res_all;
725 * Handle strings and directory strings
727 if (job_items[i].handler == store_str ||
728 job_items[i].handler == store_dir) {
729 def_svalue = (char **)((char *)(job->jobdefs) + offset);
730 Dmsg5(400, "Job \"%s\", field \"%s\" def_svalue=%s item %d offset=%u\n",
731 job->name(), job_items[i].name, *def_svalue, i, offset);
732 svalue = (char **)((char *)job + offset);
734 Pmsg1(000, _("Hey something is wrong. p=0x%lu\n"), *svalue);
736 *svalue = bstrdup(*def_svalue);
737 set_bit(i, job->hdr.item_present);
741 } else if (job_items[i].handler == store_res) {
742 def_svalue = (char **)((char *)(job->jobdefs) + offset);
743 Dmsg4(400, "Job \"%s\", field \"%s\" item %d offset=%u\n",
744 job->name(), job_items[i].name, i, offset);
745 svalue = (char **)((char *)job + offset);
747 Pmsg1(000, _("Hey something is wrong. p=0x%lu\n"), *svalue);
749 *svalue = *def_svalue;
750 set_bit(i, job->hdr.item_present);
752 * Handle alist resources
754 } else if (job_items[i].handler == store_alist_res) {
755 if (bit_is_set(i, job->jobdefs->hdr.item_present)) {
756 set_bit(i, job->hdr.item_present);
759 * Handle integer fields
760 * Note, our store_bit does not handle bitmaped fields
762 } else if (job_items[i].handler == store_bit ||
763 job_items[i].handler == store_pint32 ||
764 job_items[i].handler == store_jobtype ||
765 job_items[i].handler == store_level ||
766 job_items[i].handler == store_int32 ||
767 job_items[i].handler == store_size32 ||
768 job_items[i].handler == store_migtype ||
769 job_items[i].handler == store_replace) {
770 def_ivalue = (uint32_t *)((char *)(job->jobdefs) + offset);
771 Dmsg5(400, "Job \"%s\", field \"%s\" def_ivalue=%d item %d offset=%u\n",
772 job->name(), job_items[i].name, *def_ivalue, i, offset);
773 ivalue = (uint32_t *)((char *)job + offset);
774 *ivalue = *def_ivalue;
775 set_bit(i, job->hdr.item_present);
777 * Handle 64 bit integer fields
779 } else if (job_items[i].handler == store_time ||
780 job_items[i].handler == store_size64 ||
781 job_items[i].handler == store_int64) {
782 def_lvalue = (int64_t *)((char *)(job->jobdefs) + offset);
783 Dmsg5(400, "Job \"%s\", field \"%s\" def_lvalue=%" lld " item %d offset=%u\n",
784 job->name(), job_items[i].name, *def_lvalue, i, offset);
785 lvalue = (int64_t *)((char *)job + offset);
786 *lvalue = *def_lvalue;
787 set_bit(i, job->hdr.item_present);
791 } else if (job_items[i].handler == store_bool) {
792 def_bvalue = (bool *)((char *)(job->jobdefs) + offset);
793 Dmsg5(400, "Job \"%s\", field \"%s\" def_bvalue=%d item %d offset=%u\n",
794 job->name(), job_items[i].name, *def_bvalue, i, offset);
795 bvalue = (bool *)((char *)job + offset);
796 *bvalue = *def_bvalue;
797 set_bit(i, job->hdr.item_present);
803 * Ensure that all required items are present
805 for (i=0; job_items[i].name; i++) {
806 if (job_items[i].flags & ITEM_REQUIRED) {
807 if (!bit_is_set(i, job->hdr.item_present)) {
808 Jmsg(NULL, M_ERROR_TERM, 0, _("\"%s\" directive in Job \"%s\" resource is required, but not found.\n"),
809 job_items[i].name, job->name());
813 /* If this triggers, take a look at lib/parse_conf.h */
814 if (i >= MAX_RES_ITEMS) {
815 Emsg0(M_ERROR_TERM, 0, _("Too many items in Job resource\n"));
818 if (!job->storage && !job->pool->storage) {
819 Jmsg(NULL, M_FATAL, 0, _("No storage specified in Job \"%s\" nor in Pool.\n"),
823 } /* End loop over Job res */
826 /* Loop over Consoles */
828 foreach_res(cons, R_CONSOLE) {
829 /* tls_require implies tls_enable */
830 if (cons->tls_require) {
832 cons->tls_enable = true;
834 Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
840 need_tls = cons->tls_enable || cons->tls_authenticate;
842 if (!cons->tls_certfile && need_tls) {
843 Jmsg(NULL, M_FATAL, 0, _("\"TLS Certificate\" file not defined for Console \"%s\" in %s.\n"),
844 cons->name(), configfile);
848 if (!cons->tls_keyfile && need_tls) {
849 Jmsg(NULL, M_FATAL, 0, _("\"TLS Key\" file not defined for Console \"%s\" in %s.\n"),
850 cons->name(), configfile);
854 if ((!cons->tls_ca_certfile && !cons->tls_ca_certdir)
855 && need_tls && cons->tls_verify_peer) {
856 Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\" or \"TLS CA"
857 " Certificate Dir\" are defined for Console \"%s\" in %s."
858 " At least one CA certificate store is required"
859 " when using \"TLS Verify Peer\".\n"),
860 cons->name(), configfile);
863 /* If everything is well, attempt to initialize our per-resource TLS context */
864 if (OK && (need_tls || cons->tls_require)) {
865 /* Initialize TLS context:
866 * Args: CA certfile, CA certdir, Certfile, Keyfile,
867 * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
868 cons->tls_ctx = new_tls_context(cons->tls_ca_certfile,
869 cons->tls_ca_certdir, cons->tls_certfile,
870 cons->tls_keyfile, NULL, NULL, cons->tls_dhfile, cons->tls_verify_peer);
872 if (!cons->tls_ctx) {
873 Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for File daemon \"%s\" in %s.\n"),
874 cons->name(), configfile);
881 /* Loop over Clients */
883 foreach_res(client, R_CLIENT) {
884 /* tls_require implies tls_enable */
885 if (client->tls_require) {
887 client->tls_enable = true;
889 Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
894 need_tls = client->tls_enable || client->tls_authenticate;
895 if ((!client->tls_ca_certfile && !client->tls_ca_certdir) && need_tls) {
896 Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\""
897 " or \"TLS CA Certificate Dir\" are defined for File daemon \"%s\" in %s.\n"),
898 client->name(), configfile);
902 /* If everything is well, attempt to initialize our per-resource TLS context */
903 if (OK && (need_tls || client->tls_require)) {
904 /* Initialize TLS context:
905 * Args: CA certfile, CA certdir, Certfile, Keyfile,
906 * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
907 client->tls_ctx = new_tls_context(client->tls_ca_certfile,
908 client->tls_ca_certdir, client->tls_certfile,
909 client->tls_keyfile, NULL, NULL, NULL,
912 if (!client->tls_ctx) {
913 Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for File daemon \"%s\" in %s.\n"),
914 client->name(), configfile);
922 close_msg(NULL); /* close temp message handler */
923 init_msg(NULL, director->messages); /* open daemon message handler */
930 * - we can check the connection (mode=CHECK_CONNECTION)
931 * - we can synchronize the catalog with the configuration (mode=UPDATE_CATALOG)
932 * - we can synchronize, and fix old job records (mode=UPDATE_AND_FIX)
934 static bool check_catalog(cat_op mode)
939 /* Loop over databases */
941 foreach_res(catalog, R_CATALOG) {
944 * Make sure we can open catalog, otherwise print a warning
945 * message because the server is probably not running.
947 db = db_init_database(NULL, catalog->db_driver, catalog->db_name, catalog->db_user,
948 catalog->db_password, catalog->db_address,
949 catalog->db_port, catalog->db_socket,
950 catalog->mult_db_connections,
951 catalog->disable_batch_insert);
952 if (!db || !db_open_database(NULL, db)) {
953 Pmsg2(000, _("Could not open Catalog \"%s\", database \"%s\".\n"),
954 catalog->name(), catalog->db_name);
955 Jmsg(NULL, M_FATAL, 0, _("Could not open Catalog \"%s\", database \"%s\".\n"),
956 catalog->name(), catalog->db_name);
958 Jmsg(NULL, M_FATAL, 0, _("%s"), db_strerror(db));
959 Pmsg1(000, "%s", db_strerror(db));
960 db_close_database(NULL, db);
966 /* Display a message if the db max_connections is too low */
967 if (!db_check_max_connections(NULL, db, director->MaxConcurrentJobs)) {
968 Pmsg1(000, "Warning, settings problem for Catalog=%s\n", catalog->name());
969 Pmsg1(000, "%s", db_strerror(db));
972 /* we are in testing mode, so don't touch anything in the catalog */
973 if (mode == CHECK_CONNECTION) {
974 db_close_database(NULL, db);
978 /* Loop over all pools, defining/updating them in each database */
980 foreach_res(pool, R_POOL) {
982 * If the Pool has a catalog resource create the pool only
985 if (!pool->catalog || pool->catalog == catalog) {
986 create_pool(NULL, db, pool, POOL_OP_UPDATE); /* update request */
990 /* Once they are created, we can loop over them again, updating
991 * references (RecyclePool)
993 foreach_res(pool, R_POOL) {
995 * If the Pool has a catalog resource update the pool only
998 if (!pool->catalog || pool->catalog == catalog) {
999 update_pool_references(NULL, db, pool);
1003 /* Ensure basic client record is in DB */
1005 foreach_res(client, R_CLIENT) {
1007 /* Create clients only if they use the current catalog */
1008 if (client->catalog != catalog) {
1009 Dmsg3(500, "Skip client=%s with cat=%s not catalog=%s\n",
1010 client->name(), client->catalog->name(), catalog->name());
1013 Dmsg2(500, "create cat=%s for client=%s\n",
1014 client->catalog->name(), client->name());
1015 memset(&cr, 0, sizeof(cr));
1016 bstrncpy(cr.Name, client->name(), sizeof(cr.Name));
1017 db_create_client_record(NULL, db, &cr);
1020 /* Ensure basic storage record is in DB */
1022 foreach_res(store, R_STORAGE) {
1025 memset(&sr, 0, sizeof(sr));
1026 memset(&mr, 0, sizeof(mr));
1027 if (store->media_type) {
1028 bstrncpy(mr.MediaType, store->media_type, sizeof(mr.MediaType));
1030 db_create_mediatype_record(NULL, db, &mr);
1034 bstrncpy(sr.Name, store->name(), sizeof(sr.Name));
1035 sr.AutoChanger = store->autochanger;
1036 if (!db_create_storage_record(NULL, db, &sr)) {
1037 Jmsg(NULL, M_FATAL, 0, _("Could not create storage record for %s\n"),
1041 store->StorageId = sr.StorageId; /* set storage Id */
1042 if (!sr.created) { /* if not created, update it */
1043 sr.AutoChanger = store->autochanger;
1044 if (!db_update_storage_record(NULL, db, &sr)) {
1045 Jmsg(NULL, M_FATAL, 0, _("Could not update storage record for %s\n"),
1051 /* tls_require implies tls_enable */
1052 if (store->tls_require) {
1054 store->tls_enable = true;
1056 Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
1061 need_tls = store->tls_enable || store->tls_authenticate;
1063 if ((!store->tls_ca_certfile && !store->tls_ca_certdir) && need_tls) {
1064 Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\""
1065 " or \"TLS CA Certificate Dir\" are defined for Storage \"%s\" in %s.\n"),
1066 store->name(), configfile);
1070 /* If everything is well, attempt to initialize our per-resource TLS context */
1071 if (OK && (need_tls || store->tls_require)) {
1072 /* Initialize TLS context:
1073 * Args: CA certfile, CA certdir, Certfile, Keyfile,
1074 * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
1075 store->tls_ctx = new_tls_context(store->tls_ca_certfile,
1076 store->tls_ca_certdir, store->tls_certfile,
1077 store->tls_keyfile, NULL, NULL, NULL, true);
1079 if (!store->tls_ctx) {
1080 Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for Storage \"%s\" in %s.\n"),
1081 store->name(), configfile);
1087 /* Loop over all counters, defining them in each database */
1088 /* Set default value in all counters */
1090 foreach_res(counter, R_COUNTER) {
1091 /* Write to catalog? */
1092 if (!counter->created && counter->Catalog == catalog) {
1094 bstrncpy(cr.Counter, counter->name(), sizeof(cr.Counter));
1095 cr.MinValue = counter->MinValue;
1096 cr.MaxValue = counter->MaxValue;
1097 cr.CurrentValue = counter->MinValue;
1098 if (counter->WrapCounter) {
1099 bstrncpy(cr.WrapCounter, counter->WrapCounter->name(), sizeof(cr.WrapCounter));
1101 cr.WrapCounter[0] = 0; /* empty string */
1103 if (db_create_counter_record(NULL, db, &cr)) {
1104 counter->CurrentValue = cr.CurrentValue;
1105 counter->created = true;
1106 Dmsg2(100, "Create counter %s val=%d\n", counter->name(), counter->CurrentValue);
1109 if (!counter->created) {
1110 counter->CurrentValue = counter->MinValue; /* default value */
1113 /* cleanup old job records */
1114 if (mode == UPDATE_AND_FIX) {
1115 db_sql_query(db, cleanup_created_job, NULL, NULL);
1116 db_sql_query(db, cleanup_running_job, NULL, NULL);
1119 /* Set type in global for debugging */
1120 set_db_type(db_get_type(db));
1122 db_close_database(NULL, db);
1127 static void copy_base_name(POOLMEM *cleanup)
1129 int len = strlen(director->working_directory);
1130 #if defined(HAVE_WIN32)
1131 pm_strcpy(cleanup, "del /q ");
1133 pm_strcpy(cleanup, "/bin/rm -f ");
1135 pm_strcat(cleanup, director->working_directory);
1136 if (len > 0 && !IsPathSeparator(director->working_directory[len-1])) {
1137 pm_strcat(cleanup, "/");
1139 pm_strcat(cleanup, my_name);
1142 static void cleanup_old_files()
1144 POOLMEM *cleanup = get_pool_memory(PM_MESSAGE);
1145 POOLMEM *results = get_pool_memory(PM_MESSAGE);
1146 copy_base_name(cleanup);
1147 pm_strcat(cleanup, "*.restore.*.bsr");
1148 run_program(cleanup, 0, results);
1149 copy_base_name(cleanup);
1150 pm_strcat(cleanup, "*.mail");
1151 run_program(cleanup, 0, results);
1152 free_pool_memory(cleanup);
1153 free_pool_memory(results);