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