]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/dird/dird.c
- Tweak catalog make scripts.
[bacula/bacula] / bacula / src / dird / dird.c
1 /*
2  *
3  *   Bacula Director daemon -- this is the main program
4  *
5  *     Kern Sibbald, March MM
6  *
7  *   Version $Id$
8  */
9 /*
10    Copyright (C) 2000-2006 Kern Sibbald
11
12    This program is free software; you can redistribute it and/or
13    modify it under the terms of the GNU General Public License
14    version 2 as amended with additional clauses defined in the
15    file LICENSE in the main source directory.
16
17    This program is distributed in the hope that it will be useful,
18    but WITHOUT ANY WARRANTY; without even the implied warranty of
19    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
20    the file LICENSE for additional details.
21
22  */
23
24 #include "bacula.h"
25 #include "dird.h"
26
27 /* Forward referenced subroutines */
28 static void terminate_dird(int sig);
29 static int check_resources();
30 static void dir_sql_query(JCR *jcr, const char *cmd);
31   
32 /* Exported subroutines */
33 extern "C" void reload_config(int sig);
34 extern void invalidate_schedules();
35
36
37 /* Imported subroutines */
38 JCR *wait_for_next_job(char *runjob);
39 void term_scheduler();
40 void term_ua_server();
41 void start_UA_server(dlist *addrs);
42 void init_job_server(int max_workers);
43 void term_job_server();
44 void store_jobtype(LEX *lc, RES_ITEM *item, int index, int pass);
45 void store_level(LEX *lc, RES_ITEM *item, int index, int pass);
46 void store_replace(LEX *lc, RES_ITEM *item, int index, int pass);
47 void init_device_resources();
48
49 static char *runjob = NULL;
50 static int background = 1;
51 static void init_reload(void);
52
53 /* Globals Exported */
54 DIRRES *director;                     /* Director resource */
55 int FDConnectTimeout;
56 int SDConnectTimeout;
57 char *configfile = NULL;
58
59 /* Globals Imported */
60 extern int r_first, r_last;           /* first and last resources */
61 extern RES_TABLE resources[];
62 extern RES **res_head;
63 extern RES_ITEM job_items[];
64
65 #if defined(_MSC_VER)
66 extern "C" { // work around visual compiler mangling variables
67     extern URES res_all;
68 }
69 #else
70 extern URES res_all;
71 #endif
72
73 #define CONFIG_FILE "./bacula-dir.conf" /* default configuration file */
74
75 static void usage()
76 {
77    fprintf(stderr, _(
78 "Copyright (C) 2000-2005 Kern Sibbald.\n"
79 "\nVersion: %s (%s)\n\n"
80 "Usage: dird [-f -s] [-c config_file] [-d debug_level] [config_file]\n"
81 "       -c <file>   set configuration file to file\n"
82 "       -dnn        set debug level to nn\n"
83 "       -f          run in foreground (for debugging)\n"
84 "       -g          groupid\n"
85 "       -r <job>    run <job> now\n"
86 "       -s          no signals\n"
87 "       -t          test - read configuration and exit\n"
88 "       -u          userid\n"
89 "       -v          verbose user messages\n"
90 "       -?          print this message.\n"
91 "\n"), VERSION, BDATE);
92
93    exit(1);
94 }
95
96
97 /*********************************************************************
98  *
99  *         Main Bacula Server program
100  *
101  */
102 int main (int argc, char *argv[])
103 {
104    int ch;
105    JCR *jcr;
106    int no_signals = FALSE;
107    int test_config = FALSE;
108    char *uid = NULL;
109    char *gid = NULL;
110
111    setlocale(LC_ALL, "");
112    bindtextdomain("bacula", LOCALEDIR);
113    textdomain("bacula");
114
115    init_stack_dump();
116    my_name_is(argc, argv, "bacula-dir");
117    init_msg(NULL, NULL);              /* initialize message handler */
118    init_reload();
119    daemon_start_time = time(NULL);
120
121    while ((ch = getopt(argc, argv, "c:d:fg:r:stu:v?")) != -1) {
122       switch (ch) {
123       case 'c':                    /* specify config file */
124          if (configfile != NULL) {
125             free(configfile);
126          }
127          configfile = bstrdup(optarg);
128          break;
129
130       case 'd':                    /* set debug level */
131          debug_level = atoi(optarg);
132          if (debug_level <= 0) {
133             debug_level = 1;
134          }
135          Dmsg1(0, "Debug level = %d\n", debug_level);
136          break;
137
138       case 'f':                    /* run in foreground */
139          background = FALSE;
140          break;
141
142       case 'g':                    /* set group id */
143          gid = optarg;
144          break;
145
146       case 'r':                    /* run job */
147          if (runjob != NULL) {
148             free(runjob);
149          }
150          if (optarg) {
151             runjob = bstrdup(optarg);
152          }
153          break;
154
155       case 's':                    /* turn off signals */
156          no_signals = TRUE;
157          break;
158
159       case 't':                    /* test config */
160          test_config = TRUE;
161          break;
162
163       case 'u':                    /* set uid */
164          uid = optarg;
165          break;
166
167       case 'v':                    /* verbose */
168          verbose++;
169          break;
170
171       case '?':
172       default:
173          usage();
174
175       }
176    }
177    argc -= optind;
178    argv += optind;
179
180    if (!no_signals) {
181       init_signals(terminate_dird);
182    }
183
184    if (argc) {
185       if (configfile != NULL) {
186          free(configfile);
187       }
188       configfile = bstrdup(*argv);
189       argc--;
190       argv++;
191    }
192    if (argc) {
193       usage();
194    }
195
196    if (configfile == NULL) {
197       configfile = bstrdup(CONFIG_FILE);
198    }
199
200    parse_config(configfile);
201
202    if (init_crypto() != 0) {
203       Jmsg((JCR *)NULL, M_ERROR_TERM, 0, _("Cryptography library initialization failed.\n"));
204    }
205
206    if (!check_resources()) {
207       Jmsg((JCR *)NULL, M_ERROR_TERM, 0, _("Please correct configuration file: %s\n"), configfile);
208    }
209
210    if (test_config) {
211       terminate_dird(0);
212    }
213
214    my_name_is(0, NULL, director->hdr.name);    /* set user defined name */
215
216    /* Plug database interface for library routines */
217    p_sql_query = (sql_query)dir_sql_query;                                   
218
219    FDConnectTimeout = (int)director->FDConnectTimeout;
220    SDConnectTimeout = (int)director->SDConnectTimeout;
221
222    if (background) {
223       daemon_start();
224       init_stack_dump();              /* grab new pid */
225    }
226
227    /* Create pid must come after we are a daemon -- so we have our final pid */
228    create_pid_file(director->pid_directory, "bacula-dir", get_first_port_host_order(director->DIRaddrs));
229    read_state_file(director->working_directory, "bacula-dir", get_first_port_host_order(director->DIRaddrs));
230
231    drop(uid, gid);                    /* reduce priveleges if requested */
232
233    signal(SIGHUP, reload_config);
234
235    init_console_msg(working_directory);
236
237    init_python_interpreter(director->hdr.name, director->scripts_directory, 
238        "DirStartUp");
239
240    set_thread_concurrency(director->MaxConcurrentJobs * 2 +
241       4 /* UA */ + 4 /* sched+watchdog+jobsvr+misc */);
242
243    Dmsg0(200, "Start UA server\n");
244    start_UA_server(director->DIRaddrs);
245
246    start_watchdog();                  /* start network watchdog thread */
247
248    init_jcr_subsystem();              /* start JCR watchdogs etc. */
249
250    init_job_server(director->MaxConcurrentJobs);
251
252    Dmsg0(200, "wait for next job\n");
253    /* Main loop -- call scheduler to get next job to run */
254    while ( (jcr = wait_for_next_job(runjob)) ) {
255       run_job(jcr);                   /* run job */
256       free_jcr(jcr);                  /* release jcr */
257       if (runjob) {                   /* command line, run a single job? */
258          break;                       /* yes, terminate */
259       }
260    }
261
262    terminate_dird(0);
263
264    return 0;
265 }
266
267 static void dir_sql_query(JCR *jcr, const char *cmd)
268 {
269    if (!jcr || !jcr->db) {
270       return;
271    }
272    db_sql_query(jcr->db, cmd, NULL, NULL);
273 }
274
275 /* Cleanup and then exit */
276 static void terminate_dird(int sig)
277 {
278    static bool already_here = false;
279
280    if (already_here) {                /* avoid recursive temination problems */
281       exit(1);
282    }
283    already_here = true;
284    generate_daemon_event(NULL, "Exit");
285    write_state_file(director->working_directory, "bacula-dir", get_first_port_host_order(director->DIRaddrs));
286    delete_pid_file(director->pid_directory, "bacula-dir", get_first_port_host_order(director->DIRaddrs));
287 // signal(SIGCHLD, SIG_IGN);          /* don't worry about children now */
288    term_scheduler();
289    term_job_server();
290    if (runjob) {
291       free(runjob);
292    }
293    if (configfile != NULL) {
294       free(configfile);
295    }
296    if (debug_level > 5) {
297       print_memory_pool_stats();
298    }
299    free_config_resources();
300    term_ua_server();
301    term_msg();                        /* terminate message handler */
302    stop_watchdog();
303    cleanup_crypto();
304    close_memory_pool();               /* release free memory in pool */
305    sm_dump(false);
306    exit(sig);
307 }
308
309 struct RELOAD_TABLE {
310    int job_count;
311    RES **res_table;
312 };
313
314 static const int max_reloads = 32;
315 static RELOAD_TABLE reload_table[max_reloads];
316
317 static void init_reload(void)
318 {
319    for (int i=0; i < max_reloads; i++) {
320       reload_table[i].job_count = 0;
321       reload_table[i].res_table = NULL;
322    }
323 }
324
325 static void free_saved_resources(int table)
326 {
327    int num = r_last - r_first + 1;
328    RES **res_tab = reload_table[table].res_table;
329    if (!res_tab) {
330       Dmsg1(100, "res_tab for table %d already released.\n", table);
331       return;
332    }
333    Dmsg1(100, "Freeing resources for table %d\n", table);
334    for (int j=0; j<num; j++) {
335       free_resource(res_tab[j], r_first + j);
336    }
337    free(res_tab);
338    reload_table[table].job_count = 0;
339    reload_table[table].res_table = NULL;
340 }
341
342 /*
343  * Called here at the end of every job that was
344  * hooked decrementing the active job_count. When
345  * it goes to zero, no one is using the associated
346  * resource table, so free it.
347  */
348 static void reload_job_end_cb(JCR *jcr, void *ctx)
349 {
350    int reload_id = (int)((long int)ctx);
351    Dmsg3(100, "reload job_end JobId=%d table=%d cnt=%d\n", jcr->JobId,
352       reload_id, reload_table[reload_id].job_count);
353    lock_jobs();
354    LockRes();
355    if (--reload_table[reload_id].job_count <= 0) {
356       free_saved_resources(reload_id);
357    }
358    UnlockRes();
359    unlock_jobs();
360 }
361
362 static int find_free_reload_table_entry()
363 {
364    int table = -1;
365    for (int i=0; i < max_reloads; i++) {
366       if (reload_table[i].res_table == NULL) {
367          table = i;
368          break;
369       }
370    }
371    return table;
372 }
373
374 /*
375  * If we get here, we have received a SIGHUP, which means to
376  *    reread our configuration file.
377  *
378  * The algorithm used is as follows: we count how many jobs are
379  *   running and mark the running jobs to make a callback on
380  *   exiting. The old config is saved with the reload table
381  *   id in a reload table. The new config file is read. Now, as
382  *   each job exits, it calls back to the reload_job_end_cb(), which
383  *   decrements the count of open jobs for the given reload table.
384  *   When the count goes to zero, we release those resources.
385  *   This allows us to have pointers into the resource table (from
386  *   jobs), and once they exit and all the pointers are released, we
387  *   release the old table. Note, if no new jobs are running since the
388  *   last reload, then the old resources will be immediately release.
389  *   A console is considered a job because it may have pointers to
390  *   resources, but a SYSTEM job is not since it *should* not have any
391  *   permanent pointers to jobs.
392  */
393 extern "C"
394 void reload_config(int sig)
395 {
396    static bool already_here = false;
397    sigset_t set;
398    JCR *jcr;
399    int njobs = 0;                     /* number of running jobs */
400    int table, rtable;
401    bool ok;       
402
403    if (already_here) {
404       abort();                        /* Oops, recursion -> die */
405    }
406    already_here = true;
407    sigemptyset(&set);
408    sigaddset(&set, SIGHUP);
409    sigprocmask(SIG_BLOCK, &set, NULL);
410
411    lock_jobs();
412    LockRes();
413
414    table = find_free_reload_table_entry();
415    if (table < 0) {
416       Jmsg(NULL, M_ERROR, 0, _("Too many open reload requests. Request ignored.\n"));
417       goto bail_out;
418    }
419
420    Dmsg1(100, "Reload_config njobs=%d\n", njobs);
421    reload_table[table].res_table = save_config_resources();
422    Dmsg1(100, "Saved old config in table %d\n", table);
423
424    ok = parse_config(configfile, 0, M_ERROR);  /* no exit on error */
425
426    Dmsg0(100, "Reloaded config file\n");
427    if (!ok || !check_resources()) {
428       rtable = find_free_reload_table_entry();    /* save new, bad table */
429       if (rtable < 0) {
430          Jmsg(NULL, M_ERROR, 0, _("Please correct configuration file: %s\n"), configfile);
431          Jmsg(NULL, M_ERROR_TERM, 0, _("Out of reload table entries. Giving up.\n"));
432       } else {
433          Jmsg(NULL, M_ERROR, 0, _("Please correct configuration file: %s\n"), configfile);
434          Jmsg(NULL, M_ERROR, 0, _("Resetting previous configuration.\n"));
435       }
436       reload_table[rtable].res_table = save_config_resources();
437       /* Now restore old resoure values */
438       int num = r_last - r_first + 1;
439       RES **res_tab = reload_table[table].res_table;
440       for (int i=0; i<num; i++) {
441          res_head[i] = res_tab[i];
442       }
443       table = rtable;                 /* release new, bad, saved table below */
444    } else {
445       invalidate_schedules();
446       /*
447        * Hook all active jobs so that they release this table
448        */
449       foreach_jcr(jcr) {
450          if (jcr->JobType != JT_SYSTEM) {
451             reload_table[table].job_count++;
452             job_end_push(jcr, reload_job_end_cb, (void *)((long int)table));
453             njobs++;
454          }
455       }
456       endeach_jcr(jcr);
457    }
458
459    /* Reset globals */
460    set_working_directory(director->working_directory);
461    FDConnectTimeout = director->FDConnectTimeout;
462    SDConnectTimeout = director->SDConnectTimeout;
463    Dmsg0(0, "Director's configuration file reread.\n");
464
465    /* Now release saved resources, if no jobs using the resources */
466    if (njobs == 0) {
467       free_saved_resources(table);
468    }
469
470 bail_out:
471    UnlockRes();
472    unlock_jobs();
473    sigprocmask(SIG_UNBLOCK, &set, NULL);
474    signal(SIGHUP, reload_config);
475    already_here = false;
476 }
477
478 /*
479  * Make a quick check to see that we have all the
480  * resources needed.
481  *
482  *  **** FIXME **** this routine could be a lot more
483  *   intelligent and comprehensive.
484  */
485 static int check_resources()
486 {
487    bool OK = true;
488    JOB *job;
489
490    LockRes();
491
492    job = (JOB *)GetNextRes(R_JOB, NULL);
493    director = (DIRRES *)GetNextRes(R_DIRECTOR, NULL);
494    if (!director) {
495       Jmsg(NULL, M_FATAL, 0, _("No Director resource defined in %s\n"
496 "Without that I don't know who I am :-(\n"), configfile);
497       OK = false;
498    } else {
499       set_working_directory(director->working_directory);
500       if (!director->messages) {       /* If message resource not specified */
501          director->messages = (MSGS *)GetNextRes(R_MSGS, NULL);
502          if (!director->messages) {
503             Jmsg(NULL, M_FATAL, 0, _("No Messages resource defined in %s\n"), configfile);
504             OK = false;
505          }
506       }
507       if (GetNextRes(R_DIRECTOR, (RES *)director) != NULL) {
508          Jmsg(NULL, M_FATAL, 0, _("Only one Director resource permitted in %s\n"),
509             configfile);
510          OK = false;
511       }
512       /* tls_require implies tls_enable */
513       if (director->tls_require) {
514          if (have_tls) {
515             director->tls_enable = true;
516          } else {
517             Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
518             OK = false;
519          }
520       }
521
522       if (!director->tls_certfile && director->tls_enable) {
523          Jmsg(NULL, M_FATAL, 0, _("\"TLS Certificate\" file not defined for Director \"%s\" in %s.\n"),
524             director->hdr.name, configfile);
525          OK = false;
526       }
527
528       if (!director->tls_keyfile && director->tls_enable) {
529          Jmsg(NULL, M_FATAL, 0, _("\"TLS Key\" file not defined for Director \"%s\" in %s.\n"),
530             director->hdr.name, configfile);
531          OK = false;
532       }
533
534       if ((!director->tls_ca_certfile && !director->tls_ca_certdir) && director->tls_enable && director->tls_verify_peer) {
535          Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\" or \"TLS CA"
536               " Certificate Dir\" are defined for Director \"%s\" in %s."
537               " At least one CA certificate store is required"
538               " when using \"TLS Verify Peer\".\n"),
539               director->hdr.name, configfile);
540          OK = false;
541       }
542
543       /* If everything is well, attempt to initialize our per-resource TLS context */
544       if (OK && (director->tls_enable || director->tls_require)) {
545          /* Initialize TLS context:
546           * Args: CA certfile, CA certdir, Certfile, Keyfile,
547           * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
548          director->tls_ctx = new_tls_context(director->tls_ca_certfile,
549             director->tls_ca_certdir, director->tls_certfile,
550             director->tls_keyfile, NULL, NULL, director->tls_dhfile,
551             director->tls_verify_peer);
552          
553          if (!director->tls_ctx) {
554             Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for Director \"%s\" in %s.\n"),
555                  director->hdr.name, configfile);
556             OK = false;
557          }
558       }
559    }
560
561    if (!job) {
562       Jmsg(NULL, M_FATAL, 0, _("No Job records defined in %s\n"), configfile);
563       OK = false;
564    }
565    foreach_res(job, R_JOB) {
566       int i;
567
568       if (job->jobdefs) {
569          /* Handle Storage alists specifically */
570          JOB *jobdefs = job->jobdefs;
571          if (jobdefs->storage && !job->storage) {
572             STORE *st;
573             job->storage = New(alist(10, not_owned_by_alist));
574             foreach_alist(st, jobdefs->storage) {
575                job->storage->append(st);
576             }
577          }
578          /* Handle RunScripts alists specifically */
579          if (jobdefs->RunScripts) {
580             RUNSCRIPT *rs, *elt;
581             
582             if (!job->RunScripts) {
583                job->RunScripts = New(alist(10, not_owned_by_alist));
584             }
585            
586             foreach_alist(rs, jobdefs->RunScripts) {
587                elt = copy_runscript(rs);
588                job->RunScripts->append(elt); /* we have to free it */
589             }
590          }
591
592          /* Transfer default items from JobDefs Resource */
593          for (i=0; job_items[i].name; i++) {
594             char **def_svalue, **svalue;  /* string value */
595             int *def_ivalue, *ivalue;     /* integer value */
596             bool *def_bvalue, *bvalue;    /* bool value */
597             int64_t *def_lvalue, *lvalue; /* 64 bit values */
598             uint32_t offset;
599
600             Dmsg4(1400, "Job \"%s\", field \"%s\" bit=%d def=%d\n",
601                 job->hdr.name, job_items[i].name,
602                 bit_is_set(i, job->hdr.item_present),
603                 bit_is_set(i, job->jobdefs->hdr.item_present));
604
605             if (!bit_is_set(i, job->hdr.item_present) &&
606                  bit_is_set(i, job->jobdefs->hdr.item_present)) {
607                Dmsg2(400, "Job \"%s\", field \"%s\": getting default.\n",
608                  job->hdr.name, job_items[i].name);
609                offset = (char *)(job_items[i].value) - (char *)&res_all;
610                /*
611                 * Handle strings and directory strings
612                 */
613                if (job_items[i].handler == store_str ||
614                    job_items[i].handler == store_dir) {
615                   def_svalue = (char **)((char *)(job->jobdefs) + offset);
616                   Dmsg5(400, "Job \"%s\", field \"%s\" def_svalue=%s item %d offset=%u\n",
617                        job->hdr.name, job_items[i].name, *def_svalue, i, offset);
618                   svalue = (char **)((char *)job + offset);
619                   if (*svalue) {
620                      Pmsg1(000, _("Hey something is wrong. p=0x%lu\n"), *svalue);
621                   }
622                   *svalue = bstrdup(*def_svalue);
623                   set_bit(i, job->hdr.item_present);
624                /*
625                 * Handle resources
626                 */
627                } else if (job_items[i].handler == store_res) {
628                   def_svalue = (char **)((char *)(job->jobdefs) + offset);
629                   Dmsg4(400, "Job \"%s\", field \"%s\" item %d offset=%u\n",
630                        job->hdr.name, job_items[i].name, i, offset);
631                   svalue = (char **)((char *)job + offset);
632                   if (*svalue) {
633                      Pmsg1(000, _("Hey something is wrong. p=0x%lu\n"), *svalue);
634                   }
635                   *svalue = *def_svalue;
636                   set_bit(i, job->hdr.item_present);
637                /*
638                 * Handle alist resources
639                 */
640                } else if (job_items[i].handler == store_alist_res) {
641                   if (bit_is_set(i, job->jobdefs->hdr.item_present)) {
642                      set_bit(i, job->hdr.item_present);
643                   }
644                /*
645                 * Handle integer fields
646                 *    Note, our store_bit does not handle bitmaped fields
647                 */
648                } else if (job_items[i].handler == store_bit     ||
649                           job_items[i].handler == store_pint    ||
650                           job_items[i].handler == store_jobtype ||
651                           job_items[i].handler == store_level   ||
652                           job_items[i].handler == store_pint    ||
653                           job_items[i].handler == store_replace) {
654                   def_ivalue = (int *)((char *)(job->jobdefs) + offset);
655                   Dmsg5(400, "Job \"%s\", field \"%s\" def_ivalue=%d item %d offset=%u\n",
656                        job->hdr.name, job_items[i].name, *def_ivalue, i, offset);
657                   ivalue = (int *)((char *)job + offset);
658                   *ivalue = *def_ivalue;
659                   set_bit(i, job->hdr.item_present);
660                /*
661                 * Handle 64 bit integer fields
662                 */
663                } else if (job_items[i].handler == store_time   ||
664                           job_items[i].handler == store_size   ||
665                           job_items[i].handler == store_int64) {
666                   def_lvalue = (int64_t *)((char *)(job->jobdefs) + offset);
667                   Dmsg5(400, "Job \"%s\", field \"%s\" def_lvalue=%" lld " item %d offset=%u\n",
668                        job->hdr.name, job_items[i].name, *def_lvalue, i, offset);
669                   lvalue = (int64_t *)((char *)job + offset);
670                   *lvalue = *def_lvalue;
671                   set_bit(i, job->hdr.item_present);
672                /*
673                 * Handle bool fields
674                 */
675                } else if (job_items[i].handler == store_bool) {
676                   def_bvalue = (bool *)((char *)(job->jobdefs) + offset);
677                   Dmsg5(400, "Job \"%s\", field \"%s\" def_bvalue=%d item %d offset=%u\n",
678                        job->hdr.name, job_items[i].name, *def_bvalue, i, offset);
679                   bvalue = (bool *)((char *)job + offset);
680                   *bvalue = *def_bvalue;
681                   set_bit(i, job->hdr.item_present);
682                }
683             }
684          }
685       }
686       /*
687        * Ensure that all required items are present
688        */
689       for (i=0; job_items[i].name; i++) {
690          if (job_items[i].flags & ITEM_REQUIRED) {
691                if (!bit_is_set(i, job->hdr.item_present)) {
692                   Jmsg(NULL, M_FATAL, 0, _("\"%s\" directive in Job \"%s\" resource is required, but not found.\n"),
693                     job_items[i].name, job->hdr.name);
694                   OK = false;
695                 }
696          }
697          /* If this triggers, take a look at lib/parse_conf.h */
698          if (i >= MAX_RES_ITEMS) {
699             Emsg0(M_ERROR_TERM, 0, _("Too many items in Job resource\n"));
700          }
701       }
702    } /* End loop over Job res */
703
704    /* Loop over databases */
705    CAT *catalog;
706    foreach_res(catalog, R_CATALOG) {
707       B_DB *db;
708       /*
709        * Make sure we can open catalog, otherwise print a warning
710        * message because the server is probably not running.
711        */
712       db = db_init_database(NULL, catalog->db_name, catalog->db_user,
713                          catalog->db_password, catalog->db_address,
714                          catalog->db_port, catalog->db_socket,
715                          catalog->mult_db_connections);
716       if (!db || !db_open_database(NULL, db)) {
717          Jmsg(NULL, M_FATAL, 0, _("Could not open Catalog \"%s\", database \"%s\".\n"),
718               catalog->hdr.name, catalog->db_name);
719          if (db) {
720             Jmsg(NULL, M_FATAL, 0, _("%s"), db_strerror(db));
721          }
722          OK = false;
723          continue;
724       }
725
726       /* Loop over all pools, defining/updating them in each database */
727       POOL *pool;
728       foreach_res(pool, R_POOL) {
729          create_pool(NULL, db, pool, POOL_OP_UPDATE);  /* update request */
730       }
731
732       STORE *store;
733       foreach_res(store, R_STORAGE) {
734          STORAGE_DBR sr;
735          MEDIATYPE_DBR mr;
736          if (store->media_type) {
737             bstrncpy(mr.MediaType, store->media_type, sizeof(mr.MediaType));
738             mr.ReadOnly = 0;
739             db_create_mediatype_record(NULL, db, &mr);
740          } else {
741             mr.MediaTypeId = 0;
742          }
743          bstrncpy(sr.Name, store->name(), sizeof(sr.Name));
744          sr.AutoChanger = store->autochanger;
745          db_create_storage_record(NULL, db, &sr);
746          store->StorageId = sr.StorageId;   /* set storage Id */
747          if (!sr.created) {                 /* if not created, update it */
748             db_update_storage_record(NULL, db, &sr);
749          }
750
751          /* tls_require implies tls_enable */
752          if (store->tls_require) {
753             if (have_tls) {
754                store->tls_enable = true;
755             } else {
756                Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
757                OK = false;
758             }
759          } 
760
761          if ((!store->tls_ca_certfile && !store->tls_ca_certdir) && store->tls_enable) {
762             Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\""
763                  " or \"TLS CA Certificate Dir\" are defined for Storage \"%s\" in %s.\n"),
764                  store->hdr.name, configfile);
765             OK = false;
766          }
767
768          /* If everything is well, attempt to initialize our per-resource TLS context */
769          if (OK && (store->tls_enable || store->tls_require)) {
770            /* Initialize TLS context:
771             * Args: CA certfile, CA certdir, Certfile, Keyfile,
772             * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
773             store->tls_ctx = new_tls_context(store->tls_ca_certfile,
774                store->tls_ca_certdir, store->tls_certfile,
775                store->tls_keyfile, NULL, NULL, NULL, true);
776          
777             if (!store->tls_ctx) {
778                Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for Storage \"%s\" in %s.\n"),
779                     store->hdr.name, configfile);
780                OK = false;
781             }
782          }
783       }
784
785       /* Loop over all counters, defining them in each database */
786       /* Set default value in all counters */
787       COUNTER *counter;
788       foreach_res(counter, R_COUNTER) {
789          /* Write to catalog? */
790          if (!counter->created && counter->Catalog == catalog) {
791             COUNTER_DBR cr;
792             bstrncpy(cr.Counter, counter->hdr.name, sizeof(cr.Counter));
793             cr.MinValue = counter->MinValue;
794             cr.MaxValue = counter->MaxValue;
795             cr.CurrentValue = counter->MinValue;
796             if (counter->WrapCounter) {
797                bstrncpy(cr.WrapCounter, counter->WrapCounter->hdr.name, sizeof(cr.WrapCounter));
798             } else {
799                cr.WrapCounter[0] = 0;  /* empty string */
800             }
801             if (db_create_counter_record(NULL, db, &cr)) {
802                counter->CurrentValue = cr.CurrentValue;
803                counter->created = true;
804                Dmsg2(100, "Create counter %s val=%d\n", counter->hdr.name, counter->CurrentValue);
805             }
806          }
807          if (!counter->created) {
808             counter->CurrentValue = counter->MinValue;  /* default value */
809          }
810       }
811       db_close_database(NULL, db);
812    }
813
814    /* Loop over Consoles */
815    CONRES *cons;
816    foreach_res(cons, R_CONSOLE) {
817       /* tls_require implies tls_enable */
818       if (cons->tls_require) {
819          if (have_tls) {
820             cons->tls_enable = true;
821          } else {
822             Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
823             OK = false;
824             continue;
825          }
826       }
827
828       if (!cons->tls_certfile && cons->tls_enable) {
829          Jmsg(NULL, M_FATAL, 0, _("\"TLS Certificate\" file not defined for Console \"%s\" in %s.\n"),
830             cons->hdr.name, configfile);
831          OK = false;
832       }
833
834       if (!cons->tls_keyfile && cons->tls_enable) {
835          Jmsg(NULL, M_FATAL, 0, _("\"TLS Key\" file not defined for Console \"%s\" in %s.\n"),
836             cons->hdr.name, configfile);
837          OK = false;
838       }
839
840       if ((!cons->tls_ca_certfile && !cons->tls_ca_certdir) && cons->tls_enable && cons->tls_verify_peer) {
841          Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\" or \"TLS CA"
842             " Certificate Dir\" are defined for Console \"%s\" in %s."
843             " At least one CA certificate store is required"
844             " when using \"TLS Verify Peer\".\n"),
845             cons->hdr.name, configfile);
846          OK = false;
847       }
848       /* If everything is well, attempt to initialize our per-resource TLS context */
849       if (OK && (cons->tls_enable || cons->tls_require)) {
850          /* Initialize TLS context:
851           * Args: CA certfile, CA certdir, Certfile, Keyfile,
852           * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
853          cons->tls_ctx = new_tls_context(cons->tls_ca_certfile,
854             cons->tls_ca_certdir, cons->tls_certfile,
855             cons->tls_keyfile, NULL, NULL, cons->tls_dhfile, cons->tls_verify_peer);
856          
857          if (!cons->tls_ctx) {
858             Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for File daemon \"%s\" in %s.\n"),
859                cons->hdr.name, configfile);
860             OK = false;
861          }
862       }
863
864    }
865
866    /* Loop over Clients */
867    CLIENT *client;
868    foreach_res(client, R_CLIENT) {
869       /* tls_require implies tls_enable */
870       if (client->tls_require) {
871          if (have_tls) {
872             client->tls_enable = true;
873          } else {
874             Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
875             OK = false;
876             continue;
877          }
878       }
879
880       if ((!client->tls_ca_certfile && !client->tls_ca_certdir) && client->tls_enable) {
881          Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\""
882             " or \"TLS CA Certificate Dir\" are defined for File daemon \"%s\" in %s.\n"),
883             client->hdr.name, configfile);
884          OK = false;
885       }
886
887       /* If everything is well, attempt to initialize our per-resource TLS context */
888       if (OK && (client->tls_enable || client->tls_require)) {
889          /* Initialize TLS context:
890           * Args: CA certfile, CA certdir, Certfile, Keyfile,
891           * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
892          client->tls_ctx = new_tls_context(client->tls_ca_certfile,
893             client->tls_ca_certdir, client->tls_certfile,
894             client->tls_keyfile, NULL, NULL, NULL,
895             true);
896          
897          if (!client->tls_ctx) {
898             Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for File daemon \"%s\" in %s.\n"),
899                client->hdr.name, configfile);
900             OK = false;
901          }
902       }
903    }
904
905    UnlockRes();
906    if (OK) {
907       close_msg(NULL);                /* close temp message handler */
908       init_msg(NULL, director->messages); /* open daemon message handler */
909    }
910    return OK;
911 }