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