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