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