]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/dird/dird.c
Fix #2940 Allow specific Director job code in WriteBootstrap directive
[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_mode, catalog->db_ssl_key,
1146               catalog->db_ssl_cert, catalog->db_ssl_ca,
1147               catalog->db_ssl_capath, catalog->db_ssl_cipher,
1148               catalog->mult_db_connections,
1149               catalog->disable_batch_insert);
1150       if (!db || !db_open_database(NULL, db)) {
1151          Pmsg2(000, _("Could not open Catalog \"%s\", database \"%s\".\n"),
1152               catalog->name(), catalog->db_name);
1153          Jmsg(NULL, M_FATAL, 0, _("Could not open Catalog \"%s\", database \"%s\".\n"),
1154               catalog->name(), catalog->db_name);
1155          if (db) {
1156             Jmsg(NULL, M_FATAL, 0, _("%s"), db_strerror(db));
1157             Pmsg1(000, "%s", db_strerror(db));
1158             db_close_database(NULL, db);
1159          }
1160          OK = false;
1161          continue;
1162       }
1163
1164       /* Display a message if the db max_connections is too low */
1165       if (!db_check_max_connections(NULL, db, director->MaxConcurrentJobs)) {
1166          Pmsg1(000, "Warning, settings problem for Catalog=%s\n", catalog->name());
1167          Pmsg1(000, "%s", db_strerror(db));
1168       }
1169
1170       /* we are in testing mode, so don't touch anything in the catalog */
1171       if (mode == CHECK_CONNECTION) {
1172          if (db) db_close_database(NULL, db);
1173          continue;
1174       }
1175
1176       /* Loop over all pools, defining/updating them in each database */
1177       POOL *pool;
1178       foreach_res(pool, R_POOL) {
1179          /*
1180           * If the Pool has a catalog resource create the pool only
1181           *   in that catalog.
1182           */
1183          if (!pool->catalog || pool->catalog == catalog) {
1184             create_pool(NULL, db, pool, POOL_OP_UPDATE);  /* update request */
1185          }
1186       }
1187
1188       /* Once they are created, we can loop over them again, updating
1189        * references (RecyclePool)
1190        */
1191       foreach_res(pool, R_POOL) {
1192          /*
1193           * If the Pool has a catalog resource update the pool only
1194           *   in that catalog.
1195           */
1196          if (!pool->catalog || pool->catalog == catalog) {
1197             update_pool_references(NULL, db, pool);
1198          }
1199       }
1200
1201       /* Ensure basic client record is in DB */
1202       CLIENT *client;
1203       foreach_res(client, R_CLIENT) {
1204          CLIENT_DBR cr;
1205          /* Create clients only if they use the current catalog */
1206          if (client->catalog != catalog) {
1207             Dmsg3(500, "Skip client=%s with cat=%s not catalog=%s\n",
1208                   client->name(), client->catalog->name(), catalog->name());
1209             continue;
1210          }
1211          Dmsg2(500, "create cat=%s for client=%s\n",
1212                client->catalog->name(), client->name());
1213          memset(&cr, 0, sizeof(cr));
1214          bstrncpy(cr.Name, client->name(), sizeof(cr.Name));
1215
1216          db_create_client_record(NULL, db, &cr);
1217       }
1218
1219       /* Ensure basic storage record is in DB */
1220       foreach_res(store, R_STORAGE) {
1221          STORAGE_DBR sr;
1222          MEDIATYPE_DBR mtr;
1223          memset(&sr, 0, sizeof(sr));
1224          memset(&mtr, 0, sizeof(mtr));
1225          if (store->media_type) {
1226             bstrncpy(mtr.MediaType, store->media_type, sizeof(mtr.MediaType));
1227             mtr.ReadOnly = 0;
1228             db_create_mediatype_record(NULL, db, &mtr);
1229          } else {
1230             mtr.MediaTypeId = 0;
1231          }
1232          bstrncpy(sr.Name, store->name(), sizeof(sr.Name));
1233          sr.AutoChanger = store->autochanger;
1234          if (!db_create_storage_record(NULL, db, &sr)) {
1235             Jmsg(NULL, M_FATAL, 0, _("Could not create storage record for %s\n"),
1236                  store->name());
1237             OK = false;
1238          }
1239          store->StorageId = sr.StorageId;   /* set storage Id */
1240          if (!sr.created) {                 /* if not created, update it */
1241             sr.AutoChanger = store->autochanger;
1242             if (!db_update_storage_record(NULL, db, &sr)) {
1243                Jmsg(NULL, M_FATAL, 0, _("Could not update storage record for %s\n"),
1244                     store->name());
1245                OK = false;
1246             }
1247          }
1248
1249          /* tls_require implies tls_enable */
1250          if (store->tls_require) {
1251             if (have_tls) {
1252                store->tls_enable = true;
1253             } else {
1254                Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
1255                OK = false;
1256             }
1257          }
1258
1259          need_tls = store->tls_enable || store->tls_authenticate;
1260
1261          if ((!store->tls_ca_certfile && !store->tls_ca_certdir) && need_tls) {
1262             Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\""
1263                  " or \"TLS CA Certificate Dir\" are defined for Storage \"%s\" in %s.\n"),
1264                  store->name(), configfile);
1265             OK = false;
1266          }
1267
1268          /* If everything is well, attempt to initialize our per-resource TLS context */
1269          if (OK && (need_tls || store->tls_require)) {
1270            /* Initialize TLS context:
1271             * Args: CA certfile, CA certdir, Certfile, Keyfile,
1272             * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
1273             store->tls_ctx = new_tls_context(store->tls_ca_certfile,
1274                store->tls_ca_certdir, store->tls_certfile,
1275                store->tls_keyfile, NULL, NULL, NULL, true);
1276
1277             if (!store->tls_ctx) {
1278                Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for Storage \"%s\" in %s.\n"),
1279                     store->name(), configfile);
1280                OK = false;
1281             }
1282          }
1283       }
1284
1285       /* Link up all the children for each changer */
1286       foreach_res(store, R_STORAGE) {
1287          char sid[50];
1288          if (store->changer == store) {  /* we are a real Autochanger */
1289             store->ac_group = get_pool_memory(PM_FNAME);
1290             store->ac_group[0] = 0;
1291             pm_strcat(store->ac_group, edit_int64(store->StorageId, sid));
1292             /* Now look for children who point to this storage */
1293             foreach_res(ac_child, R_STORAGE) {
1294                if (ac_child != store && ac_child->changer == store) {
1295                   /* Found a child -- add StorageId */
1296                   pm_strcat(store->ac_group, ",");
1297                   pm_strcat(store->ac_group, edit_int64(ac_child->StorageId, sid));
1298                }
1299             }
1300          }
1301       }
1302
1303       /* Link up all the shared storage devices */
1304       foreach_res(store, R_STORAGE) {
1305          if (store->ac_group) {  /* we are a real Autochanger */
1306             /* Now look for Shared Storage who point to this storage */
1307             foreach_res(ac_child, R_STORAGE) {
1308                if (ac_child->shared_storage == store && ac_child->ac_group &&
1309                    ac_child->shared_storage != ac_child) {
1310                   pm_strcat(store->ac_group, ",");
1311                   pm_strcat(store->ac_group, ac_child->ac_group);
1312                }
1313             }
1314          }
1315       }
1316
1317       /* Loop over all counters, defining them in each database */
1318       /* Set default value in all counters */
1319       COUNTER *counter;
1320       foreach_res(counter, R_COUNTER) {
1321          /* Write to catalog? */
1322          if (!counter->created && counter->Catalog == catalog) {
1323             COUNTER_DBR cr;
1324             bstrncpy(cr.Counter, counter->name(), sizeof(cr.Counter));
1325             cr.MinValue = counter->MinValue;
1326             cr.MaxValue = counter->MaxValue;
1327             cr.CurrentValue = counter->MinValue;
1328             if (counter->WrapCounter) {
1329                bstrncpy(cr.WrapCounter, counter->WrapCounter->name(), sizeof(cr.WrapCounter));
1330             } else {
1331                cr.WrapCounter[0] = 0;  /* empty string */
1332             }
1333             if (db_create_counter_record(NULL, db, &cr)) {
1334                counter->CurrentValue = cr.CurrentValue;
1335                counter->created = true;
1336                Dmsg2(100, "Create counter %s val=%d\n", counter->name(), counter->CurrentValue);
1337             }
1338          }
1339          if (!counter->created) {
1340             counter->CurrentValue = counter->MinValue;  /* default value */
1341          }
1342       }
1343       /* cleanup old job records */
1344       if (mode == UPDATE_AND_FIX) {
1345          db_sql_query(db, cleanup_created_job, NULL, NULL);
1346          db_sql_query(db, cleanup_running_job, NULL, NULL);
1347       }
1348
1349       /* Set SQL engine name in global for debugging */
1350       set_db_engine_name(db_get_engine_name(db));
1351       if (db) db_close_database(NULL, db);
1352    }
1353    return OK;
1354 }
1355
1356 static void cleanup_old_files()
1357 {
1358    DIR* dp;
1359    struct dirent *entry, *result;
1360    int rc, name_max;
1361    int my_name_len = strlen(my_name);
1362    int len = strlen(director->working_directory);
1363    POOLMEM *cleanup = get_pool_memory(PM_MESSAGE);
1364    POOLMEM *basename = get_pool_memory(PM_MESSAGE);
1365    regex_t preg1;
1366    char prbuf[500];
1367    const int nmatch = 30;
1368    regmatch_t pmatch[nmatch];
1369    berrno be;
1370
1371    /* Exclude spaces and look for .mail, .tmp or .restore.xx.bsr files */
1372    const char *pat1 = "^[^ ]+\\.(restore\\.[^ ]+\\.bsr|mail|tmp)$";
1373
1374    /* Setup working directory prefix */
1375    pm_strcpy(basename, director->working_directory);
1376    if (len > 0 && !IsPathSeparator(director->working_directory[len-1])) {
1377       pm_strcat(basename, "/");
1378    }
1379
1380    /* Compile regex expressions */
1381    rc = regcomp(&preg1, pat1, REG_EXTENDED);
1382    if (rc != 0) {
1383       regerror(rc, &preg1, prbuf, sizeof(prbuf));
1384       Pmsg2(000,  _("Could not compile regex pattern \"%s\" ERR=%s\n"),
1385            pat1, prbuf);
1386       goto get_out2;
1387    }
1388
1389    name_max = pathconf(".", _PC_NAME_MAX);
1390    if (name_max < 1024) {
1391       name_max = 1024;
1392    }
1393
1394    if (!(dp = opendir(director->working_directory))) {
1395       berrno be;
1396       Pmsg2(000, "Failed to open working dir %s for cleanup: ERR=%s\n",
1397             director->working_directory, be.bstrerror());
1398       goto get_out1;
1399       return;
1400    }
1401
1402    entry = (struct dirent *)malloc(sizeof(struct dirent) + name_max + 1000);
1403    while (1) {
1404       if ((readdir_r(dp, entry, &result) != 0) || (result == NULL)) {
1405          break;
1406       }
1407       /* Exclude any name with ., .., not my_name or containing a space */
1408       if (strcmp(result->d_name, ".") == 0 || strcmp(result->d_name, "..") == 0 ||
1409           strncmp(result->d_name, my_name, my_name_len) != 0) {
1410          Dmsg1(500, "Skipped: %s\n", result->d_name);
1411          continue;
1412       }
1413
1414       /* Unlink files that match regexes */
1415       if (regexec(&preg1, result->d_name, nmatch, pmatch,  0) == 0) {
1416          pm_strcpy(cleanup, basename);
1417          pm_strcat(cleanup, result->d_name);
1418          Dmsg1(100, "Unlink: %s\n", cleanup);
1419          unlink(cleanup);
1420       }
1421    }
1422
1423    free(entry);
1424    closedir(dp);
1425 /* Be careful to free up the correct resources */
1426 get_out1:
1427    regfree(&preg1);
1428 get_out2:
1429    free_pool_memory(cleanup);
1430    free_pool_memory(basename);
1431 }