]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/dird/dird.c
Big backport from Enterprise
[bacula/bacula] / bacula / src / dird / dird.c
1 /*
2    Bacula(R) - The Network Backup Solution
3
4    Copyright (C) 2000-2017 Kern Sibbald
5
6    The original author of Bacula is Kern Sibbald, with contributions
7    from many others, a complete list can be found in the file AUTHORS.
8
9    You may use this file and others of this release according to the
10    license defined in the LICENSE file, which includes the Affero General
11    Public License, v3.0 ("AGPLv3") and some additional permissions and
12    terms pursuant to its AGPLv3 Section 7.
13
14    This notice must be preserved when any source code is
15    conveyed and/or propagated.
16
17    Bacula(R) is a registered trademark of Kern Sibbald.
18 */
19 /*
20  *   Bacula Director daemon -- this is the main program
21  *
22  *     Kern Sibbald, March MM
23  */
24
25 #include "bacula.h"
26 #include "dird.h"
27 #ifndef HAVE_REGEX_H
28 #include "lib/bregex.h"
29 #else
30 #include <regex.h>
31 #endif
32 #ifdef HAVE_DIRENT_H
33 #include <dirent.h>
34 #define NAMELEN(dirent) (strlen((dirent)->d_name))
35 #endif
36 #ifndef HAVE_READDIR_R
37 int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result);
38 #endif
39
40 /* Forward referenced subroutines */
41 void terminate_dird(int sig);
42 static bool check_resources();
43 static void cleanup_old_files();
44 static void resize_reload(int nb);
45
46 /* Exported subroutines */
47 extern "C" void reload_config(int sig);
48 extern void invalidate_schedules();
49 extern bool parse_dir_config(CONFIG *config, const char *configfile, int exit_code);
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 store_migtype(LEX *lc, RES_ITEM *item, int index, int pass);
62 void init_device_resources();
63
64
65 static char *runjob = NULL;
66 static bool foreground = false;
67 static void init_reload(void);
68 static CONFIG *config;
69 static bool test_config = false;
70
71 /* Globals Exported */
72 DIRRES *director;                     /* Director resource */
73 int FDConnectTimeout;
74 int SDConnectTimeout;
75 char *configfile = NULL;
76 void *start_heap;
77 utime_t last_reload_time = 0;
78
79
80 /* Globals Imported */
81 extern dlist client_globals;
82 extern dlist store_globals;
83 extern dlist job_globals;
84 extern dlist sched_globals;
85 extern dlist *daemon_msg_queue;
86 extern pthread_mutex_t daemon_msg_queue_mutex;
87 extern RES_ITEM job_items[];
88 #if defined(_MSC_VER)
89 extern "C" { // work around visual compiler mangling variables
90    extern URES res_all;
91 }
92 #else
93 extern URES res_all;
94 #endif
95
96 typedef enum {
97    CHECK_CONNECTION,  /* Check catalog connection */
98    UPDATE_CATALOG,    /* Ensure that catalog is ok with conf */
99    UPDATE_AND_FIX     /* Ensure that catalog is ok, and fix old jobs */
100 } cat_op;
101 static bool check_catalog(cat_op mode);
102
103 #define CONFIG_FILE "bacula-dir.conf" /* default configuration file */
104
105 static bool dir_sql_query(JCR *jcr, const char *cmd) 
106
107    if (jcr && jcr->db && jcr->db->is_connected()) {
108       return db_sql_query(jcr->db, cmd, NULL, NULL);
109    } 
110    return false; 
111
112
113 static bool dir_sql_escape(JCR *jcr, BDB *mdb, char *snew, char *sold, int len) 
114
115    if (jcr && jcr->db && jcr->db->is_connected()) { 
116       db_escape_string(jcr, mdb, snew, sold, len);
117       return true;
118    } 
119    return false; 
120
121
122 static void usage()
123 {
124    fprintf(stderr, _(
125       PROG_COPYRIGHT
126       "\n%sVersion: %s (%s)\n\n"
127       "Usage: bacula-dir [-f -s] [-c config_file] [-d debug_level] [config_file]\n"
128       "     -c <file>        set configuration file to file\n"
129       "     -d <nn>[,<tags>] set debug level to <nn>, debug tags to <tags>\n"
130       "     -dt              print timestamp in debug output\n"
131       "     -T               set trace on\n"
132       "     -f               run in foreground (for debugging)\n"
133       "     -g               groupid\n"
134       "     -m               print kaboom output (for debugging)\n"
135       "     -r <job>         run <job> now\n"
136       "     -s               no signals\n"
137       "     -t               test - read configuration and exit\n"
138       "     -u               userid\n"
139       "     -v               verbose user messages\n"
140       "     -?               print this message.\n"
141       "\n"), 2000, "", VERSION, BDATE);
142
143    exit(1);
144 }
145
146 /*
147  * !!! WARNING !!! Use this function only when bacula is stopped.
148  * ie, after a fatal signal and before exiting the program
149  * Print information about a JCR
150  */
151 static void dir_debug_print(JCR *jcr, FILE *fp)
152 {
153    fprintf(fp, "\twstore=%p rstore=%p wjcr=%p client=%p reschedule_count=%d SD_msg_chan_started=%d\n",
154            jcr->wstore, jcr->rstore, jcr->wjcr, jcr->client, jcr->reschedule_count, (int)jcr->SD_msg_chan_started);
155 }
156
157 /*********************************************************************
158  *
159  *         Main Bacula Director Server program
160  *
161  */
162 #if defined(HAVE_WIN32)
163 /* For Win32 main() is in src/win32 code ... */
164 #define main BaculaMain
165 #endif
166
167 /* DELETE ME when bugs in MA1512, MA1632 MA1639 are fixed */
168 extern void (*MA1512_reload_job_end_cb)(JCR *,void *);
169 static void reload_job_end_cb(JCR *jcr, void *ctx);
170
171 int main (int argc, char *argv[])
172 {
173    int ch;
174    JCR *jcr;
175    bool no_signals = false;
176    char *uid = NULL;
177    char *gid = NULL;
178    MQUEUE_ITEM *item = NULL;
179
180    /* DELETE ME when bugs in MA1512, MA1632 MA1639 are fixed */
181    MA1512_reload_job_end_cb = reload_job_end_cb;
182
183    start_heap = sbrk(0);
184    setlocale(LC_ALL, "");
185    bindtextdomain("bacula", LOCALEDIR);
186    textdomain("bacula");
187
188    init_stack_dump();
189    my_name_is(argc, argv, "bacula-dir");
190    init_msg(NULL, NULL);              /* initialize message handler */
191    init_reload();
192    daemon_start_time = time(NULL);
193    /* Setup daemon message queue */
194    daemon_msg_queue = New(dlist(item, &item->link));
195    console_command = run_console_command;
196
197    while ((ch = getopt(argc, argv, "c:d:fg:mr:stu:v?T")) != -1) {
198       switch (ch) {
199       case 'c':                    /* specify config file */
200          if (configfile != NULL) {
201             free(configfile);
202          }
203          configfile = bstrdup(optarg);
204          break;
205
206       case 'd':                    /* set debug level */
207          if (*optarg == 't') {
208             dbg_timestamp = true;
209          } else {
210             char *p;
211             /* We probably find a tag list -d 10,sql,bvfs */
212             if ((p = strchr(optarg, ',')) != NULL) {
213                *p = 0;
214             }
215             debug_level = atoi(optarg);
216             if (debug_level <= 0) {
217                debug_level = 1;
218             }
219             if (p) {
220                debug_parse_tags(p+1, &debug_level_tags);
221             }
222          }
223          Dmsg1(10, "Debug level = %lld\n", debug_level);
224          break;
225
226       case 'T':
227          set_trace(true);
228          break;
229
230       case 'f':                    /* run in foreground */
231          foreground = true;
232          break;
233
234       case 'g':                    /* set group id */
235          gid = optarg;
236          break;
237
238       case 'm':                    /* print kaboom output */
239          prt_kaboom = true;
240          break;
241
242       case 'r':                    /* run job */
243          if (runjob != NULL) {
244             free(runjob);
245          }
246          if (optarg) {
247             runjob = bstrdup(optarg);
248          }
249          break;
250
251       case 's':                    /* turn off signals */
252          no_signals = true;
253          break;
254
255       case 't':                    /* test config */
256          test_config = true;
257          break;
258
259       case 'u':                    /* set uid */
260          uid = optarg;
261          break;
262
263       case 'v':                    /* verbose */
264          verbose++;
265          break;
266
267       case '?':
268       default:
269          usage();
270
271       }
272    }
273    argc -= optind;
274    argv += optind;
275
276    if (argc) {
277       if (configfile != NULL) {
278          free(configfile);
279       }
280       configfile = bstrdup(*argv);
281       argc--;
282       argv++;
283    }
284    if (argc) {
285       usage();
286    }
287
288    if (!foreground && !test_config) {
289       daemon_start();
290       init_stack_dump();              /* grab new pid */
291    }
292
293    if (!no_signals) {
294       init_signals(terminate_dird);
295    }
296
297    if (configfile == NULL) {
298       configfile = bstrdup(CONFIG_FILE);
299    }
300
301    config = New(CONFIG());
302    parse_dir_config(config, configfile, M_ERROR_TERM);
303
304    if (init_crypto() != 0) {
305       Jmsg((JCR *)NULL, M_ERROR_TERM, 0, _("Cryptography library initialization failed.\n"));
306    }
307
308    if (!check_resources()) {
309       Jmsg((JCR *)NULL, M_ERROR_TERM, 0, _("Please correct configuration file: %s\n"), configfile);
310    }
311
312    if (!test_config) {
313       /* Create pid must come after we are a daemon -- so we have our final pid */
314       create_pid_file(director->pid_directory, "bacula-dir",
315                       get_first_port_host_order(director->DIRaddrs));
316       read_state_file(director->working_directory, "bacula-dir",
317                       get_first_port_host_order(director->DIRaddrs));
318    }
319
320    set_jcr_in_tsd(INVALID_JCR);
321    set_thread_concurrency(director->MaxConcurrentJobs * 2 +
322                           4 /* UA */ + 5 /* sched+watchdog+jobsvr+misc */);
323    lmgr_init_thread(); /* initialize the lockmanager stack */
324
325    load_dir_plugins(director->plugin_directory);
326
327    drop(uid, gid, false);                    /* reduce privileges if requested */
328
329    /* If we are in testing mode, we don't try to fix the catalog */
330    cat_op mode=(test_config)?CHECK_CONNECTION:UPDATE_AND_FIX;
331
332    if (!check_catalog(mode)) {
333       Jmsg((JCR *)NULL, M_ERROR_TERM, 0, _("Please correct configuration file: %s\n"), configfile);
334    }
335
336    if (test_config) {
337       terminate_dird(0);
338    }
339
340    my_name_is(0, NULL, director->name());    /* set user defined name */
341
342    cleanup_old_files();
343
344    /* Plug database interface for library routines */
345    p_sql_query = (sql_query_call)dir_sql_query;
346    p_sql_escape = (sql_escape_call)dir_sql_escape;
347
348    FDConnectTimeout = (int)director->FDConnectTimeout;
349    SDConnectTimeout = (int)director->SDConnectTimeout;
350
351    resize_reload(director->MaxReload);
352
353 #if !defined(HAVE_WIN32)
354    signal(SIGHUP, reload_config);
355 #endif
356
357    init_console_msg(working_directory);
358
359    Dmsg0(200, "Start UA server\n");
360    start_UA_server(director->DIRaddrs);
361
362    start_watchdog();                  /* start network watchdog thread */
363
364    init_jcr_subsystem();              /* start JCR watchdogs etc. */
365
366    init_job_server(director->MaxConcurrentJobs);
367
368    dbg_jcr_add_hook(dir_debug_print); /* used to director variables */
369    dbg_jcr_add_hook(bdb_debug_print);     /* used to debug B_DB connexion after fatal signal */
370
371 //   init_device_resources();
372
373    Dmsg0(200, "wait for next job\n");
374    /* Main loop -- call scheduler to get next job to run */
375    while ( (jcr = wait_for_next_job(runjob)) ) {
376       run_job(jcr);                   /* run job */
377       free_jcr(jcr);                  /* release jcr */
378       set_jcr_in_tsd(INVALID_JCR);
379       if (runjob) {                   /* command line, run a single job? */
380          break;                       /* yes, terminate */
381       }
382    }
383
384    terminate_dird(0);
385
386    return 0;
387 }
388
389 struct RELOAD_TABLE {
390    int job_count;
391    RES_HEAD **res_head;
392 };
393
394 static int max_reloads = 32;
395 static RELOAD_TABLE *reload_table=NULL;
396
397 static void resize_reload(int nb)
398 {
399    if (nb <= max_reloads) {
400       return;
401    }
402
403    reload_table = (RELOAD_TABLE*)realloc(reload_table, nb * sizeof(RELOAD_TABLE));
404    for (int i=max_reloads; i < nb ; i++) {
405       reload_table[i].job_count = 0;
406       reload_table[i].res_head = NULL;
407    }
408    max_reloads = nb;
409 }
410
411 static void init_reload(void)
412 {
413    reload_table = (RELOAD_TABLE*)malloc(max_reloads * sizeof(RELOAD_TABLE));
414    for (int i=0; i < max_reloads; i++) {
415       reload_table[i].job_count = 0;
416       reload_table[i].res_head = NULL;
417    }
418 }
419
420 /*
421  * This subroutine frees a saved resource table.
422  *  It was saved when a new table was created with "reload"
423  */
424 static void free_saved_resources(int table)
425 {
426    RES *next, *res;
427    int num = r_last - r_first + 1;
428    RES_HEAD **res_tab = reload_table[table].res_head;
429
430    if (res_tab == NULL) {
431       Dmsg1(100, "res_tab for table %d already released.\n", table);
432       return;
433    }
434    Dmsg1(100, "Freeing resources for table %d\n", table);
435    for (int j=0; j<num; j++) {
436       if (res_tab[j]) {
437          next = res_tab[j]->first;
438          for ( ; next; ) {
439             res = next;
440             next = res->res_next;
441             free_resource(res, r_first + j);
442          }
443          free(res_tab[j]->res_list);
444          free(res_tab[j]);
445          res_tab[j] = NULL;
446       }
447    }
448    free(res_tab);
449    reload_table[table].job_count = 0;
450    reload_table[table].res_head = NULL;
451 }
452
453 /*
454  * Called here at the end of every job that was
455  * hooked decrementing the active job_count. When
456  * it goes to zero, no one is using the associated
457  * resource table, so free it.
458  */
459 static void reload_job_end_cb(JCR *jcr, void *ctx)
460 {
461    int reload_id = (int)((intptr_t)ctx);
462    Dmsg3(100, "reload job_end JobId=%d table=%d cnt=%d\n", jcr->JobId,
463       reload_id, reload_table[reload_id].job_count);
464    lock_jobs();
465    LockRes();
466    if (--reload_table[reload_id].job_count <= 0) {
467       free_saved_resources(reload_id);
468    }
469    UnlockRes();
470    unlock_jobs();
471 }
472
473 static int find_free_reload_table_entry()
474 {
475    int table = -1;
476    for (int i=0; i < max_reloads; i++) {
477       if (reload_table[i].res_head == NULL) {
478          table = i;
479          break;
480       }
481    }
482    return table;
483 }
484
485 static pthread_mutex_t reload_mutex = PTHREAD_MUTEX_INITIALIZER;
486
487 /*
488  * If we get here, we have received a SIGHUP, which means to
489  *    reread our configuration file.
490  *
491  * The algorithm used is as follows: we count how many jobs are
492  *   running and mark the running jobs to make a callback on
493  *   exiting. The old config is saved with the reload table
494  *   id in a reload table. The new config file is read. Now, as
495  *   each job exits, it calls back to the reload_job_end_cb(), which
496  *   decrements the count of open jobs for the given reload table.
497  *   When the count goes to zero, we release those resources.
498  *   This allows us to have pointers into the resource table (from
499  *   jobs), and once they exit and all the pointers are released, we
500  *   release the old table. Note, if no new jobs are running since the
501  *   last reload, then the old resources will be immediately release.
502  *   A console is considered a job because it may have pointers to
503  *   resources, but a SYSTEM job is not since it *should* not have any
504  *   permanent pointers to jobs.
505  */
506 extern "C"
507 void reload_config(int sig)
508 {
509    static bool already_here = false;
510 #if !defined(HAVE_WIN32)
511    sigset_t set;
512 #endif
513    JCR *jcr;
514    int njobs = 0;                     /* number of running jobs */
515    int table, rtable;
516    bool ok=false;
517    int tries=0;
518
519    /* Wait to do the reload */
520    do {
521       P(reload_mutex);
522       if (already_here) {
523          V(reload_mutex);
524          if (tries++ > 10) {
525             Jmsg(NULL, M_INFO, 0, _("Already doing a reload request, "
526                                     "request ignored.\n"));
527             return;
528          }
529          Dmsg0(10, "Already doing a reload request, waiting a bit\n");
530          bmicrosleep(1, 0);
531       } else {
532          already_here = true;
533          V(reload_mutex);
534          ok = true;
535       }
536    } while (!ok);
537
538 #if !defined(HAVE_WIN32)
539    sigemptyset(&set);
540    sigaddset(&set, SIGHUP);
541    sigprocmask(SIG_BLOCK, &set, NULL);
542 #endif
543
544    lock_jobs();
545    LockRes();
546
547    table = find_free_reload_table_entry();
548    if (table < 0) {
549       Jmsg(NULL, M_ERROR, 0, _("Too many open reload requests. "
550                                "Request ignored.\n"));
551       goto bail_out;
552    }
553
554    Dmsg1(100, "Reload_config njobs=%d\n", njobs);
555    /* Save current res_head */
556    reload_table[table].res_head = res_head;
557    Dmsg1(100, "Saved old config in table %d\n", table);
558
559    /* Create a new res_head and parse into it */
560    ok = parse_dir_config(config, configfile, M_ERROR);
561
562    Dmsg0(100, "Reloaded config file\n");
563    if (!ok || !check_resources() || !check_catalog(UPDATE_CATALOG)) {
564       /*
565        * We got an error, save broken point, restore old one,
566        *  then release everything from broken pointer.
567        */
568       rtable = find_free_reload_table_entry();    /* save new, bad table */
569       if (rtable < 0) {
570          Jmsg(NULL, M_ERROR, 0, _("Please correct configuration file: %s\n"), configfile);
571          Jmsg(NULL, M_ERROR_TERM, 0, _("Out of reload table entries. Giving up.\n"));
572       } else {
573          Jmsg(NULL, M_ERROR, 0, _("Please correct configuration file: %s\n"), configfile);
574          Jmsg(NULL, M_ERROR, 0, _("Resetting previous configuration.\n"));
575       }
576       /* Save broken res_head pointer */
577       reload_table[rtable].res_head = res_head;
578
579       /* Now restore old resource pointer */
580       res_head = reload_table[table].res_head;
581       table = rtable;           /* release new, bad, saved table below */
582    } else {
583       invalidate_schedules();
584       /*
585        * Hook all active jobs so that they release this table
586        */
587       foreach_jcr(jcr) {
588          if (jcr->getJobType() != JT_SYSTEM) {
589             reload_table[table].job_count++;
590             job_end_push(jcr, reload_job_end_cb, (void *)((long int)table));
591             njobs++;
592          }
593       }
594       endeach_jcr(jcr);
595       /*
596        * Now walk through globals tables and plug them into the
597        * new resources.
598        */
599       CLIENT_GLOBALS *cg;
600       foreach_dlist(cg, &client_globals) {
601          CLIENT *client;
602          client = GetClientResWithName(cg->name);
603          if (!client) {
604             Jmsg(NULL, M_INFO, 0, _("Client=%s not found. Assuming it was removed!!!\n"), cg->name);
605          } else {
606             client->globals = cg;      /* Set globals pointer */
607          }
608       }
609       STORE_GLOBALS *sg;
610       foreach_dlist(sg, &store_globals) {
611          STORE *store;
612          store = GetStoreResWithName(sg->name);
613          if (!store) {
614             Jmsg(NULL, M_INFO, 0, _("Storage=%s not found. Assuming it was removed!!!\n"), sg->name);
615          } else {
616             store->globals = sg;       /* set globals pointer */
617             Dmsg2(200, "Reload found numConcurrent=%ld for Store %s\n",
618                sg->NumConcurrentJobs, sg->name);
619          }
620       }
621       JOB_GLOBALS *jg;
622       foreach_dlist(jg, &job_globals) {
623          JOB *job;
624          job = GetJobResWithName(jg->name);
625          if (!job) {
626             Jmsg(NULL, M_INFO, 0, _("Job=%s not found. Assuming it was removed!!!\n"), jg->name);
627          } else {
628             job->globals = jg;         /* Set globals pointer */
629          }
630       }
631       SCHED_GLOBALS *schg;
632       foreach_dlist(schg, &sched_globals) {
633          SCHED *sched;
634          sched = GetSchedResWithName(schg->name);
635          if (!sched) {
636             Jmsg(NULL, M_INFO, 0, _("Schedule=%s not found. Assuming it was removed!!!\n"), schg->name);
637          } else {
638             sched->globals = schg;     /* Set globals pointer */
639          }
640       }
641    }
642
643    /* Reset other globals */
644    set_working_directory(director->working_directory);
645    FDConnectTimeout = director->FDConnectTimeout;
646    SDConnectTimeout = director->SDConnectTimeout;
647    Dmsg0(10, "Director's configuration file reread.\n");
648
649    /* Now release saved resources, if no jobs using the resources */
650    if (njobs == 0) {
651       free_saved_resources(table);
652    }
653
654 bail_out:
655    UnlockRes();
656    unlock_jobs();
657 #if !defined(HAVE_WIN32)
658    sigprocmask(SIG_UNBLOCK, &set, NULL);
659    signal(SIGHUP, reload_config);
660 #endif
661    already_here = false;
662 }
663
664 /* Cleanup and then exit */
665 void terminate_dird(int sig)
666 {
667    static bool already_here = false;
668
669    if (already_here) {                /* avoid recursive temination problems */
670       bmicrosleep(2, 0);              /* yield */
671       exit(1);
672    }
673    already_here = true;
674    debug_level = 0;                   /* turn off debug */
675    stop_watchdog();
676    generate_daemon_event(NULL, "Exit");
677    unload_plugins();
678    if (!test_config) {
679       write_state_file(director->working_directory, "bacula-dir", get_first_port_host_order(director->DIRaddrs));
680       delete_pid_file(director->pid_directory, "bacula-dir", get_first_port_host_order(director->DIRaddrs));
681    }
682    term_scheduler();
683    term_job_server();
684    if (runjob) {
685       free(runjob);
686    }
687    if (configfile != NULL) {
688       free(configfile);
689    }
690    if (chk_dbglvl(5)) {
691       print_memory_pool_stats();
692    }
693    if (config) {
694       delete config;
695       config = NULL;
696    }
697    term_ua_server();
698    term_msg();                        /* terminate message handler */
699    cleanup_crypto();
700
701    P(daemon_msg_queue_mutex);
702    daemon_msg_queue->destroy();
703    free(daemon_msg_queue);
704    V(daemon_msg_queue_mutex);
705
706    if (reload_table) {
707       free(reload_table);
708    }
709    free(res_head);
710    res_head = NULL;
711    /*
712     * Now walk through resource globals tables and release them
713     */
714    CLIENT_GLOBALS *cg;
715    foreach_dlist(cg, &client_globals) {
716       free(cg->name);
717       if (cg->SetIPaddress) {
718          free(cg->SetIPaddress);
719       }
720       free(cg);
721    }
722    STORE_GLOBALS *sg;
723    foreach_dlist(sg, &store_globals) {
724       free(sg->name);
725       free(sg);
726    }
727    JOB_GLOBALS *jg;
728    foreach_dlist(jg, &job_globals) {
729       free(jg->name);
730       free(jg);
731    }
732    close_memory_pool();               /* release free memory in pool */
733    lmgr_cleanup_main();
734    sm_dump(false);
735    exit(sig);
736 }
737
738 /*
739  * Make a quick check to see that we have all the
740  * resources needed.
741  *
742  *  **** FIXME **** this routine could be a lot more
743  *   intelligent and comprehensive.
744  */
745 static bool check_resources()
746 {
747    bool OK = true;
748    JOB *job;
749    bool need_tls;
750
751    LockRes();
752
753    job = (JOB *)GetNextRes(R_JOB, NULL);
754    director = (DIRRES *)GetNextRes(R_DIRECTOR, NULL);
755    if (!director) {
756       Jmsg(NULL, M_FATAL, 0, _("No Director resource defined in %s\n"
757 "Without that I don't know who I am :-(\n"), configfile);
758       OK = false;
759    } else {
760       set_working_directory(director->working_directory);
761       if (!director->messages) {       /* If message resource not specified */
762          director->messages = (MSGS *)GetNextRes(R_MSGS, NULL);
763          if (!director->messages) {
764             Jmsg(NULL, M_FATAL, 0, _("No Messages resource defined in %s\n"), configfile);
765             OK = false;
766          }
767       }
768       if (GetNextRes(R_DIRECTOR, (RES *)director) != NULL) {
769          Jmsg(NULL, M_FATAL, 0, _("Only one Director resource permitted in %s\n"),
770             configfile);
771          OK = false;
772       }
773       /* tls_require implies tls_enable */
774       if (director->tls_require) {
775          if (have_tls) {
776             director->tls_enable = true;
777          } else {
778             Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
779             OK = false;
780          }
781       }
782
783       need_tls = director->tls_enable || director->tls_authenticate;
784
785       if (!director->tls_certfile && need_tls) {
786          Jmsg(NULL, M_FATAL, 0, _("\"TLS Certificate\" file not defined for Director \"%s\" in %s.\n"),
787             director->name(), configfile);
788          OK = false;
789       }
790
791       if (!director->tls_keyfile && need_tls) {
792          Jmsg(NULL, M_FATAL, 0, _("\"TLS Key\" file not defined for Director \"%s\" in %s.\n"),
793             director->name(), configfile);
794          OK = false;
795       }
796
797       if ((!director->tls_ca_certfile && !director->tls_ca_certdir) &&
798            need_tls && director->tls_verify_peer) {
799          Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\" or \"TLS CA"
800               " Certificate Dir\" are defined for Director \"%s\" in %s."
801               " At least one CA certificate store is required"
802               " when using \"TLS Verify Peer\".\n"),
803               director->name(), configfile);
804          OK = false;
805       }
806
807       /* If everything is well, attempt to initialize our per-resource TLS context */
808       if (OK && (need_tls || director->tls_require)) {
809          /* Initialize TLS context:
810           * Args: CA certfile, CA certdir, Certfile, Keyfile,
811           * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
812          director->tls_ctx = new_tls_context(director->tls_ca_certfile,
813             director->tls_ca_certdir, director->tls_certfile,
814             director->tls_keyfile, NULL, NULL, director->tls_dhfile,
815             director->tls_verify_peer);
816
817          if (!director->tls_ctx) {
818             Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for Director \"%s\" in %s.\n"),
819                  director->name(), configfile);
820             OK = false;
821          }
822       }
823    }
824
825    if (!job) {
826       Jmsg(NULL, M_FATAL, 0, _("No Job records defined in %s\n"), configfile);
827       OK = false;
828    }
829    foreach_res(job, R_JOB) {
830       int i;
831
832       if (job->jobdefs) {
833          JOB *jobdefs = job->jobdefs;
834          /* Handle RunScripts alists specifically */
835          if (jobdefs->RunScripts) {
836             RUNSCRIPT *rs, *elt;
837
838             if (!job->RunScripts) {
839                job->RunScripts = New(alist(10, not_owned_by_alist));
840             }
841
842             foreach_alist(rs, jobdefs->RunScripts) {
843                elt = copy_runscript(rs);
844                job->RunScripts->append(elt); /* we have to free it */
845             }
846          }
847
848          /* Transfer default items from JobDefs Resource */
849          for (i=0; job_items[i].name; i++) {
850             char **def_svalue, **svalue;  /* string value */
851             uint32_t *def_ivalue, *ivalue;     /* integer value */
852             bool *def_bvalue, *bvalue;    /* bool value */
853             int64_t *def_lvalue, *lvalue; /* 64 bit values */
854             alist **def_avalue, **avalue; /* alist values */
855             uint32_t offset;
856
857             Dmsg4(1400, "Job \"%s\", field \"%s\" bit=%d def=%d\n",
858                 job->name(), job_items[i].name,
859                 bit_is_set(i, job->hdr.item_present),
860                 bit_is_set(i, job->jobdefs->hdr.item_present));
861
862             if (!bit_is_set(i, job->hdr.item_present) &&
863                  bit_is_set(i, job->jobdefs->hdr.item_present)) {
864                Dmsg2(400, "Job \"%s\", field \"%s\": getting default.\n",
865                  job->name(), job_items[i].name);
866                offset = (char *)(job_items[i].value) - (char *)&res_all;
867                /*
868                 * Handle strings and directory strings
869                 */
870                if (job_items[i].handler == store_str ||
871                    job_items[i].handler == store_dir) {
872                   def_svalue = (char **)((char *)(job->jobdefs) + offset);
873                   Dmsg5(400, "Job \"%s\", field \"%s\" def_svalue=%s item %d offset=%u\n",
874                        job->name(), job_items[i].name, *def_svalue, i, offset);
875                   svalue = (char **)((char *)job + offset);
876                   if (*svalue) {
877                      Pmsg1(000, _("Hey something is wrong. p=0x%lu\n"), *svalue);
878                   }
879                   *svalue = bstrdup(*def_svalue);
880                   set_bit(i, job->hdr.item_present);
881                /*
882                 * Handle resources
883                 */
884                } else if (job_items[i].handler == store_res) {
885                   def_svalue = (char **)((char *)(job->jobdefs) + offset);
886                   Dmsg4(400, "Job \"%s\", field \"%s\" item %d offset=%u\n",
887                        job->name(), job_items[i].name, i, offset);
888                   svalue = (char **)((char *)job + offset);
889                   if (*svalue) {
890                      Pmsg1(000, _("Hey something is wrong. p=0x%lu\n"), *svalue);
891                   }
892                   *svalue = *def_svalue;
893                   set_bit(i, job->hdr.item_present);
894                /*
895                 * Handle alist resources
896                 */
897                } else if (job_items[i].handler == store_alist_res) {
898                   void *elt;
899
900                   def_avalue = (alist **)((char *)(job->jobdefs) + offset);
901                   avalue = (alist **)((char *)job + offset);
902
903                   *avalue = New(alist(10, not_owned_by_alist));
904
905                   foreach_alist(elt, (*def_avalue)) {
906                      (*avalue)->append(elt);
907                   }
908                   set_bit(i, job->hdr.item_present);
909                /*
910                 * Handle integer fields
911                 *    Note, our store_bit does not handle bitmaped fields
912                 */
913                } else if (job_items[i].handler == store_bit     ||
914                           job_items[i].handler == store_pint32  ||
915                           job_items[i].handler == store_jobtype ||
916                           job_items[i].handler == store_level   ||
917                           job_items[i].handler == store_int32   ||
918                           job_items[i].handler == store_size32  ||
919                           job_items[i].handler == store_migtype ||
920                           job_items[i].handler == store_replace) {
921                   def_ivalue = (uint32_t *)((char *)(job->jobdefs) + offset);
922                   Dmsg5(400, "Job \"%s\", field \"%s\" def_ivalue=%d item %d offset=%u\n",
923                        job->name(), job_items[i].name, *def_ivalue, i, offset);
924                   ivalue = (uint32_t *)((char *)job + offset);
925                   *ivalue = *def_ivalue;
926                   set_bit(i, job->hdr.item_present);
927                /*
928                 * Handle 64 bit integer fields
929                 */
930                } else if (job_items[i].handler == store_time   ||
931                           job_items[i].handler == store_size64 ||
932                           job_items[i].handler == store_speed  ||
933                           job_items[i].handler == store_int64) {
934                   def_lvalue = (int64_t *)((char *)(job->jobdefs) + offset);
935                   Dmsg5(400, "Job \"%s\", field \"%s\" def_lvalue=%" lld " item %d offset=%u\n",
936                        job->name(), job_items[i].name, *def_lvalue, i, offset);
937                   lvalue = (int64_t *)((char *)job + offset);
938                   *lvalue = *def_lvalue;
939                   set_bit(i, job->hdr.item_present);
940                /*
941                 * Handle bool fields
942                 */
943                } else if (job_items[i].handler == store_bool) {
944                   def_bvalue = (bool *)((char *)(job->jobdefs) + offset);
945                   Dmsg5(400, "Job \"%s\", field \"%s\" def_bvalue=%d item %d offset=%u\n",
946                        job->name(), job_items[i].name, *def_bvalue, i, offset);
947                   bvalue = (bool *)((char *)job + offset);
948                   *bvalue = *def_bvalue;
949                   set_bit(i, job->hdr.item_present);
950                }
951             }
952          }
953       }
954       /*
955        * Ensure that all required items are present
956        */
957       for (i=0; job_items[i].name; i++) {
958          if (job_items[i].flags & ITEM_REQUIRED) {
959                if (!bit_is_set(i, job->hdr.item_present)) {
960                   Jmsg(NULL, M_ERROR_TERM, 0, _("\"%s\" directive in Job \"%s\" resource is required, but not found.\n"),
961                     job_items[i].name, job->name());
962                   OK = false;
963                 }
964          }
965          /* If this triggers, take a look at lib/parse_conf.h */
966          if (i >= MAX_RES_ITEMS) {
967             Emsg0(M_ERROR_TERM, 0, _("Too many items in Job resource\n"));
968          }
969       }
970       if (!job->storage && !job->pool->storage) {
971          Jmsg(NULL, M_FATAL, 0, _("No storage specified in Job \"%s\" nor in Pool.\n"),
972             job->name());
973          OK = false;
974       }
975
976       /* Make sure the job doesn't use the Scratch Pool to start with */
977       const char *name;
978       if (!check_pool(job->JobType, job->JobLevel,
979                       job->pool, job->next_pool, &name)) { 
980          Jmsg(NULL, M_FATAL, 0,
981               _("%s \"Scratch\" not valid in Job \"%s\".\n"),
982               name, job->name());
983          OK = false;
984       }
985    } /* End loop over Job res */
986
987
988    /* Loop over Consoles */
989    CONRES *cons;
990    foreach_res(cons, R_CONSOLE) {
991       /* tls_require implies tls_enable */
992       if (cons->tls_require) {
993          if (have_tls) {
994             cons->tls_enable = true;
995          } else {
996             Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
997             OK = false;
998             continue;
999          }
1000       }
1001
1002       need_tls = cons->tls_enable || cons->tls_authenticate;
1003
1004       if (!cons->tls_certfile && need_tls) {
1005          Jmsg(NULL, M_FATAL, 0, _("\"TLS Certificate\" file not defined for Console \"%s\" in %s.\n"),
1006             cons->name(), configfile);
1007          OK = false;
1008       }
1009
1010       if (!cons->tls_keyfile && need_tls) {
1011          Jmsg(NULL, M_FATAL, 0, _("\"TLS Key\" file not defined for Console \"%s\" in %s.\n"),
1012             cons->name(), configfile);
1013          OK = false;
1014       }
1015
1016       if ((!cons->tls_ca_certfile && !cons->tls_ca_certdir)
1017             && need_tls && cons->tls_verify_peer) {
1018          Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\" or \"TLS CA"
1019             " Certificate Dir\" are defined for Console \"%s\" in %s."
1020             " At least one CA certificate store is required"
1021             " when using \"TLS Verify Peer\".\n"),
1022             cons->name(), configfile);
1023          OK = false;
1024       }
1025       /* If everything is well, attempt to initialize our per-resource TLS context */
1026       if (OK && (need_tls || cons->tls_require)) {
1027          /* Initialize TLS context:
1028           * Args: CA certfile, CA certdir, Certfile, Keyfile,
1029           * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
1030          cons->tls_ctx = new_tls_context(cons->tls_ca_certfile,
1031             cons->tls_ca_certdir, cons->tls_certfile,
1032             cons->tls_keyfile, NULL, NULL, cons->tls_dhfile, cons->tls_verify_peer);
1033
1034          if (!cons->tls_ctx) {
1035             Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for File daemon \"%s\" in %s.\n"),
1036                cons->name(), configfile);
1037             OK = false;
1038          }
1039       }
1040
1041    }
1042
1043    /* Loop over Clients */
1044    CLIENT *client;
1045    foreach_res(client, R_CLIENT) {
1046       /* tls_require implies tls_enable */
1047       if (client->tls_require) {
1048          if (have_tls) {
1049             client->tls_enable = true;
1050          } else {
1051             Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
1052             OK = false;
1053             continue;
1054          }
1055       }
1056       need_tls = client->tls_enable || client->tls_authenticate;
1057       if ((!client->tls_ca_certfile && !client->tls_ca_certdir) && need_tls) {
1058          Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\""
1059             " or \"TLS CA Certificate Dir\" are defined for File daemon \"%s\" in %s.\n"),
1060             client->name(), configfile);
1061          OK = false;
1062       }
1063
1064       /* If everything is well, attempt to initialize our per-resource TLS context */
1065       if (OK && (need_tls || client->tls_require)) {
1066          /* Initialize TLS context:
1067           * Args: CA certfile, CA certdir, Certfile, Keyfile,
1068           * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
1069          client->tls_ctx = new_tls_context(client->tls_ca_certfile,
1070             client->tls_ca_certdir, client->tls_certfile,
1071             client->tls_keyfile, NULL, NULL, NULL,
1072             true);
1073
1074          if (!client->tls_ctx) {
1075             Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for File daemon \"%s\" in %s.\n"),
1076                client->name(), configfile);
1077             OK = false;
1078          }
1079       }
1080    }
1081
1082    /* Loop over all pools, check PoolType */
1083    POOL *pool;
1084    foreach_res(pool, R_POOL) {
1085       if (!pool->pool_type) {
1086          /* This case is checked by the parse engine, we should not */
1087          Jmsg(NULL, M_FATAL, 0, _("PoolType required in Pool resource \"%s\".\n"), pool->hdr.name);
1088          OK = false;
1089          continue;
1090       }
1091       if ((strcasecmp(pool->pool_type, NT_("backup"))  != 0) &&
1092           (strcasecmp(pool->pool_type, NT_("copy"))    != 0) &&
1093           (strcasecmp(pool->pool_type, NT_("cloned"))  != 0) &&
1094           (strcasecmp(pool->pool_type, NT_("archive")) != 0) &&
1095           (strcasecmp(pool->pool_type, NT_("migration")) != 0) &&
1096           (strcasecmp(pool->pool_type, NT_("scratch")) != 0))
1097       {
1098          Jmsg(NULL, M_FATAL, 0, _("Invalid PoolType \"%s\" in Pool resource \"%s\".\n"), pool->pool_type, pool->hdr.name);
1099          OK = false;
1100       }
1101
1102       if (pool->NextPool && strcmp(pool->NextPool->name(), "Scratch") == 0) {
1103          Jmsg(NULL, M_FATAL, 0,
1104               _("NextPool \"Scratch\" not valid in Pool \"%s\".\n"),
1105               pool->name());
1106          OK = false;
1107       }
1108    }
1109
1110    UnlockRes();
1111    if (OK) {
1112       close_msg(NULL);                /* close temp message handler */
1113       init_msg(NULL, director->messages); /* open daemon message handler */
1114       last_reload_time = time(NULL);
1115    }
1116    return OK;
1117 }
1118
1119 /*
1120  * In this routine,
1121  *  - we can check the connection (mode=CHECK_CONNECTION)
1122  *  - we can synchronize the catalog with the configuration (mode=UPDATE_CATALOG)
1123  *  - we can synchronize, and fix old job records (mode=UPDATE_AND_FIX)
1124  *  - we hook up the Autochange children with the parent, and
1125  *    we hook the shared autochangers together.
1126  */
1127 static bool check_catalog(cat_op mode)
1128 {
1129    bool OK = true;
1130    bool need_tls;
1131    STORE *store, *ac_child;
1132
1133    /* Loop over databases */
1134    CAT *catalog;
1135    foreach_res(catalog, R_CATALOG) {
1136       BDB *db;
1137       /*
1138        * Make sure we can open catalog, otherwise print a warning
1139        * message because the server is probably not running.
1140        */
1141       db = db_init_database(NULL, catalog->db_driver, catalog->db_name, 
1142               catalog->db_user,
1143               catalog->db_password, catalog->db_address,
1144               catalog->db_port, catalog->db_socket,
1145               catalog->db_ssl_key, catalog->db_ssl_cert, catalog->db_ssl_ca,
1146               catalog->db_ssl_capath, catalog->db_ssl_cipher,
1147               catalog->mult_db_connections,
1148               catalog->disable_batch_insert);
1149       if (!db || !db_open_database(NULL, db)) {
1150          Pmsg2(000, _("Could not open Catalog \"%s\", database \"%s\".\n"),
1151               catalog->name(), catalog->db_name);
1152          Jmsg(NULL, M_FATAL, 0, _("Could not open Catalog \"%s\", database \"%s\".\n"),
1153               catalog->name(), catalog->db_name);
1154          if (db) {
1155             Jmsg(NULL, M_FATAL, 0, _("%s"), db_strerror(db));
1156             Pmsg1(000, "%s", db_strerror(db));
1157             db_close_database(NULL, db);
1158          }
1159          OK = false;
1160          continue;
1161       }
1162
1163       /* Display a message if the db max_connections is too low */
1164       if (!db_check_max_connections(NULL, db, director->MaxConcurrentJobs)) {
1165          Pmsg1(000, "Warning, settings problem for Catalog=%s\n", catalog->name());
1166          Pmsg1(000, "%s", db_strerror(db));
1167       }
1168
1169       /* we are in testing mode, so don't touch anything in the catalog */
1170       if (mode == CHECK_CONNECTION) {
1171          if (db) db_close_database(NULL, db);
1172          continue;
1173       }
1174
1175       /* Loop over all pools, defining/updating them in each database */
1176       POOL *pool;
1177       foreach_res(pool, R_POOL) {
1178          /*
1179           * If the Pool has a catalog resource create the pool only
1180           *   in that catalog.
1181           */
1182          if (!pool->catalog || pool->catalog == catalog) {
1183             create_pool(NULL, db, pool, POOL_OP_UPDATE);  /* update request */
1184          }
1185       }
1186
1187       /* Once they are created, we can loop over them again, updating
1188        * references (RecyclePool)
1189        */
1190       foreach_res(pool, R_POOL) {
1191          /*
1192           * If the Pool has a catalog resource update the pool only
1193           *   in that catalog.
1194           */
1195          if (!pool->catalog || pool->catalog == catalog) {
1196             update_pool_references(NULL, db, pool);
1197          }
1198       }
1199
1200       /* Ensure basic client record is in DB */
1201       CLIENT *client;
1202       foreach_res(client, R_CLIENT) {
1203          CLIENT_DBR cr;
1204          /* Create clients only if they use the current catalog */
1205          if (client->catalog != catalog) {
1206             Dmsg3(500, "Skip client=%s with cat=%s not catalog=%s\n",
1207                   client->name(), client->catalog->name(), catalog->name());
1208             continue;
1209          }
1210          Dmsg2(500, "create cat=%s for client=%s\n",
1211                client->catalog->name(), client->name());
1212          memset(&cr, 0, sizeof(cr));
1213          bstrncpy(cr.Name, client->name(), sizeof(cr.Name));
1214
1215          db_create_client_record(NULL, db, &cr);
1216       }
1217
1218       /* Ensure basic storage record is in DB */
1219       foreach_res(store, R_STORAGE) {
1220          STORAGE_DBR sr;
1221          MEDIATYPE_DBR mtr;
1222          memset(&sr, 0, sizeof(sr));
1223          memset(&mtr, 0, sizeof(mtr));
1224          if (store->media_type) {
1225             bstrncpy(mtr.MediaType, store->media_type, sizeof(mtr.MediaType));
1226             mtr.ReadOnly = 0;
1227             db_create_mediatype_record(NULL, db, &mtr);
1228          } else {
1229             mtr.MediaTypeId = 0;
1230          }
1231          bstrncpy(sr.Name, store->name(), sizeof(sr.Name));
1232          sr.AutoChanger = store->autochanger;
1233          if (!db_create_storage_record(NULL, db, &sr)) {
1234             Jmsg(NULL, M_FATAL, 0, _("Could not create storage record for %s\n"),
1235                  store->name());
1236             OK = false;
1237          }
1238          store->StorageId = sr.StorageId;   /* set storage Id */
1239          if (!sr.created) {                 /* if not created, update it */
1240             sr.AutoChanger = store->autochanger;
1241             if (!db_update_storage_record(NULL, db, &sr)) {
1242                Jmsg(NULL, M_FATAL, 0, _("Could not update storage record for %s\n"),
1243                     store->name());
1244                OK = false;
1245             }
1246          }
1247
1248          /* tls_require implies tls_enable */
1249          if (store->tls_require) {
1250             if (have_tls) {
1251                store->tls_enable = true;
1252             } else {
1253                Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
1254                OK = false;
1255             }
1256          }
1257
1258          need_tls = store->tls_enable || store->tls_authenticate;
1259
1260          if ((!store->tls_ca_certfile && !store->tls_ca_certdir) && need_tls) {
1261             Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\""
1262                  " or \"TLS CA Certificate Dir\" are defined for Storage \"%s\" in %s.\n"),
1263                  store->name(), configfile);
1264             OK = false;
1265          }
1266
1267          /* If everything is well, attempt to initialize our per-resource TLS context */
1268          if (OK && (need_tls || store->tls_require)) {
1269            /* Initialize TLS context:
1270             * Args: CA certfile, CA certdir, Certfile, Keyfile,
1271             * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
1272             store->tls_ctx = new_tls_context(store->tls_ca_certfile,
1273                store->tls_ca_certdir, store->tls_certfile,
1274                store->tls_keyfile, NULL, NULL, NULL, true);
1275
1276             if (!store->tls_ctx) {
1277                Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for Storage \"%s\" in %s.\n"),
1278                     store->name(), configfile);
1279                OK = false;
1280             }
1281          }
1282       }
1283
1284       /* Link up all the children for each changer */
1285       foreach_res(store, R_STORAGE) {
1286          char sid[50];
1287          if (store->changer == store) {  /* we are a real Autochanger */
1288             store->ac_group = get_pool_memory(PM_FNAME);
1289             store->ac_group[0] = 0;
1290             pm_strcat(store->ac_group, edit_int64(store->StorageId, sid));
1291             /* Now look for children who point to this storage */
1292             foreach_res(ac_child, R_STORAGE) {
1293                if (ac_child != store && ac_child->changer == store) {
1294                   /* Found a child -- add StorageId */
1295                   pm_strcat(store->ac_group, ",");
1296                   pm_strcat(store->ac_group, edit_int64(ac_child->StorageId, sid));
1297                }
1298             }
1299          }
1300       }
1301
1302       /* Link up all the shared storage devices */
1303       foreach_res(store, R_STORAGE) {
1304          if (store->ac_group) {  /* we are a real Autochanger */
1305             /* Now look for Shared Storage who point to this storage */
1306             foreach_res(ac_child, R_STORAGE) {
1307                if (ac_child->shared_storage == store && ac_child->ac_group &&
1308                    ac_child->shared_storage != ac_child) {
1309                   pm_strcat(store->ac_group, ",");
1310                   pm_strcat(store->ac_group, ac_child->ac_group);
1311                }
1312             }
1313          }
1314       }
1315
1316       /* Loop over all counters, defining them in each database */
1317       /* Set default value in all counters */
1318       COUNTER *counter;
1319       foreach_res(counter, R_COUNTER) {
1320          /* Write to catalog? */
1321          if (!counter->created && counter->Catalog == catalog) {
1322             COUNTER_DBR cr;
1323             bstrncpy(cr.Counter, counter->name(), sizeof(cr.Counter));
1324             cr.MinValue = counter->MinValue;
1325             cr.MaxValue = counter->MaxValue;
1326             cr.CurrentValue = counter->MinValue;
1327             if (counter->WrapCounter) {
1328                bstrncpy(cr.WrapCounter, counter->WrapCounter->name(), sizeof(cr.WrapCounter));
1329             } else {
1330                cr.WrapCounter[0] = 0;  /* empty string */
1331             }
1332             if (db_create_counter_record(NULL, db, &cr)) {
1333                counter->CurrentValue = cr.CurrentValue;
1334                counter->created = true;
1335                Dmsg2(100, "Create counter %s val=%d\n", counter->name(), counter->CurrentValue);
1336             }
1337          }
1338          if (!counter->created) {
1339             counter->CurrentValue = counter->MinValue;  /* default value */
1340          }
1341       }
1342       /* cleanup old job records */
1343       if (mode == UPDATE_AND_FIX) {
1344          db_sql_query(db, cleanup_created_job, NULL, NULL);
1345          db_sql_query(db, cleanup_running_job, NULL, NULL);
1346       }
1347
1348       /* Set SQL engine name in global for debugging */
1349       set_db_engine_name(db_get_engine_name(db));
1350       if (db) db_close_database(NULL, db);
1351    }
1352    return OK;
1353 }
1354
1355 static void cleanup_old_files()
1356 {
1357    DIR* dp;
1358    struct dirent *entry, *result;
1359    int rc, name_max;
1360    int my_name_len = strlen(my_name);
1361    int len = strlen(director->working_directory);
1362    POOLMEM *cleanup = get_pool_memory(PM_MESSAGE);
1363    POOLMEM *basename = get_pool_memory(PM_MESSAGE);
1364    regex_t preg1;
1365    char prbuf[500];
1366    const int nmatch = 30;
1367    regmatch_t pmatch[nmatch];
1368    berrno be;
1369
1370    /* Exclude spaces and look for .mail, .tmp or .restore.xx.bsr files */
1371    const char *pat1 = "^[^ ]+\\.(restore\\.[^ ]+\\.bsr|mail|tmp)$";
1372
1373    /* Setup working directory prefix */
1374    pm_strcpy(basename, director->working_directory);
1375    if (len > 0 && !IsPathSeparator(director->working_directory[len-1])) {
1376       pm_strcat(basename, "/");
1377    }
1378
1379    /* Compile regex expressions */
1380    rc = regcomp(&preg1, pat1, REG_EXTENDED);
1381    if (rc != 0) {
1382       regerror(rc, &preg1, prbuf, sizeof(prbuf));
1383       Pmsg2(000,  _("Could not compile regex pattern \"%s\" ERR=%s\n"),
1384            pat1, prbuf);
1385       goto get_out2;
1386    }
1387
1388    name_max = pathconf(".", _PC_NAME_MAX);
1389    if (name_max < 1024) {
1390       name_max = 1024;
1391    }
1392
1393    if (!(dp = opendir(director->working_directory))) {
1394       berrno be;
1395       Pmsg2(000, "Failed to open working dir %s for cleanup: ERR=%s\n",
1396             director->working_directory, be.bstrerror());
1397       goto get_out1;
1398       return;
1399    }
1400
1401    entry = (struct dirent *)malloc(sizeof(struct dirent) + name_max + 1000);
1402    while (1) {
1403       if ((readdir_r(dp, entry, &result) != 0) || (result == NULL)) {
1404          break;
1405       }
1406       /* Exclude any name with ., .., not my_name or containing a space */
1407       if (strcmp(result->d_name, ".") == 0 || strcmp(result->d_name, "..") == 0 ||
1408           strncmp(result->d_name, my_name, my_name_len) != 0) {
1409          Dmsg1(500, "Skipped: %s\n", result->d_name);
1410          continue;
1411       }
1412
1413       /* Unlink files that match regexes */
1414       if (regexec(&preg1, result->d_name, nmatch, pmatch,  0) == 0) {
1415          pm_strcpy(cleanup, basename);
1416          pm_strcat(cleanup, result->d_name);
1417          Dmsg1(100, "Unlink: %s\n", cleanup);
1418          unlink(cleanup);
1419       }
1420    }
1421
1422    free(entry);
1423    closedir(dp);
1424 /* Be careful to free up the correct resources */
1425 get_out1:
1426    regfree(&preg1);
1427 get_out2:
1428    free_pool_memory(cleanup);
1429    free_pool_memory(basename);
1430 }