]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/stored/stored.c
a8d9dfc19dc09a709d032b4ce6117a2c8ac53b66
[bacula/bacula] / bacula / src / stored / stored.c
1 /*
2    Bacula(R) - The Network Backup Solution
3
4    Copyright (C) 2000-2016 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  * Second generation Storage daemon.
21  *
22  *  Written by Kern Sibbald, MM
23  *
24  * It accepts a number of simple commands from the File daemon
25  * and acts on them. When a request to append data is made,
26  * it opens a data channel and accepts data from the
27  * File daemon.
28  *
29  */
30
31 #include "bacula.h"
32 #include "stored.h"
33
34 /* TODO: fix problem with bls, bextract
35  * that use findlib and already declare
36  * filed plugins
37  */
38 #include "sd_plugins.h"
39
40 /* Imported functions */
41 extern bool parse_sd_config(CONFIG *config, const char *configfile, int exit_code);
42
43 /* Forward referenced functions */
44 void terminate_stored(int sig);
45 static int check_resources();
46 static void cleanup_old_files();
47
48 extern "C" void *device_initialization(void *arg);
49
50 #define CONFIG_FILE "bacula-sd.conf"  /* Default config file */
51
52 /* Global variables exported */
53 char OK_msg[]   = "3000 OK\n";
54 char TERM_msg[] = "3999 Terminate\n";
55 STORES *me = NULL;                    /* our Global resource */
56
57 bool forge_on = false;                /* proceed inspite of I/O errors */
58 pthread_mutex_t device_release_mutex = PTHREAD_MUTEX_INITIALIZER;
59 pthread_cond_t wait_device_release = PTHREAD_COND_INITIALIZER;
60 void *start_heap;
61 static bool test_config = false;
62
63
64 static uint32_t VolSessionId = 0;
65 uint32_t VolSessionTime;
66 char *configfile = NULL;
67 bool init_done = false;
68 static pthread_t server_tid;
69 static bool server_tid_valid = false;
70
71 /* Global static variables */
72 static bool foreground = 0;
73 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
74 static workq_t dird_workq;            /* queue for processing connections */
75 static CONFIG *config;
76
77
78 static void usage()
79 {
80    fprintf(stderr, _(
81       PROG_COPYRIGHT
82       "\n%sVersion: %s (%s)\n\n"
83       "Usage: bacula-sd [options] [-c config_file] [config_file]\n"
84       "     -c <file>         use <file> as configuration file\n"
85       "     -d <nn>[,<tags>]  set debug level to <nn>, debug tags to <tags>\n"
86       "     -dt               print timestamp in debug output\n"
87       "     -T                set trace on\n"
88       "     -f                run in foreground (for debugging)\n"
89       "     -g <group>        set groupid to group\n"
90       "     -m                print kaboom output (for debugging)\n"
91       "     -p                proceed despite I/O errors\n"
92       "     -s                no signals (for debugging)\n"
93       "     -t                test - read config and exit\n"
94       "     -u <user>         userid to <user>\n"
95       "     -v                verbose user messages\n"
96       "     -?                print this message.\n"
97       "\n"), 2000, "", VERSION, BDATE);
98    exit(1);
99 }
100
101 /*********************************************************************
102  *
103  *  Main Bacula Unix Storage Daemon
104  *
105  */
106 #if defined(HAVE_WIN32)
107 #define main BaculaMain
108 #endif
109
110 int main (int argc, char *argv[])
111 {
112    int ch;
113    bool no_signals = false;
114    pthread_t thid;
115    char *uid = NULL;
116    char *gid = NULL;
117
118    start_heap = sbrk(0);
119    setlocale(LC_ALL, "");
120    bindtextdomain("bacula", LOCALEDIR);
121    textdomain("bacula");
122
123    init_stack_dump();
124    my_name_is(argc, argv, "bacula-sd");
125    init_msg(NULL, NULL);
126    daemon_start_time = time(NULL);
127
128    /* Sanity checks */
129    if (TAPE_BSIZE % B_DEV_BSIZE != 0 || TAPE_BSIZE / B_DEV_BSIZE == 0) {
130       Emsg2(M_ABORT, 0, _("Tape block size (%d) not multiple of system size (%d)\n"),
131          TAPE_BSIZE, B_DEV_BSIZE);
132    }
133    if (TAPE_BSIZE != (1 << (ffs(TAPE_BSIZE)-1))) {
134       Emsg1(M_ABORT, 0, _("Tape block size (%d) is not a power of 2\n"), TAPE_BSIZE);
135    }
136
137    while ((ch = getopt(argc, argv, "c:d:fg:mpstu:v?T")) != -1) {
138       switch (ch) {
139       case 'c':                    /* configuration file */
140          if (configfile != NULL) {
141             free(configfile);
142          }
143          configfile = bstrdup(optarg);
144          break;
145
146       case 'd':                    /* debug level */
147          if (*optarg == 't') {
148             dbg_timestamp = true;
149          } else {
150             char *p;
151             /* We probably find a tag list -d 10,sql,bvfs */
152             if ((p = strchr(optarg, ',')) != NULL) {
153                *p = 0;
154             }
155             debug_level = atoi(optarg);
156             if (debug_level <= 0) {
157                debug_level = 1;
158             }
159             if (p) {
160                debug_parse_tags(p+1, &debug_level_tags);
161             }
162          }
163          break;
164
165       case 'T':
166          set_trace(true);
167          break;
168
169       case 'f':                    /* run in foreground */
170          foreground = true;
171          break;
172
173       case 'g':                    /* set group id */
174          gid = optarg;
175          break;
176
177       case 'm':                    /* print kaboom output */
178          prt_kaboom = true;
179          break;
180
181       case 'p':                    /* proceed in spite of I/O errors */
182          forge_on = true;
183          break;
184
185       case 's':                    /* no signals */
186          no_signals = true;
187          break;
188
189       case 't':
190          test_config = true;
191          break;
192
193       case 'u':                    /* set uid */
194          uid = optarg;
195          break;
196
197       case 'v':                    /* verbose */
198          verbose++;
199          break;
200
201       case '?':
202       default:
203          usage();
204          break;
205       }
206    }
207    argc -= optind;
208    argv += optind;
209
210    if (argc) {
211       if (configfile != NULL) {
212          free(configfile);
213       }
214       configfile = bstrdup(*argv);
215       argc--;
216       argv++;
217    }
218    if (argc)
219       usage();
220
221    if (!foreground) {
222       daemon_start();                 /* become daemon */
223       init_stack_dump();              /* pick up new pid */
224    }
225
226    if (!no_signals) {
227       init_signals(terminate_stored);
228    }
229
230    if (configfile == NULL) {
231       configfile = bstrdup(CONFIG_FILE);
232    }
233
234    config = new_config_parser();
235    parse_sd_config(config, configfile, M_ERROR_TERM);
236
237    if (init_crypto() != 0) {
238       Jmsg((JCR *)NULL, M_ERROR_TERM, 0, _("Cryptography library initialization failed.\n"));
239    }
240
241    if (!check_resources()) {
242       Jmsg((JCR *)NULL, M_ERROR_TERM, 0, _("Please correct configuration file: %s\n"), configfile);
243    }
244
245    init_reservations_lock();
246
247    if (test_config) {
248       terminate_stored(0);
249    }
250
251    my_name_is(0, (char **)NULL, me->hdr.name);     /* Set our real name */
252
253
254    create_pid_file(me->pid_directory, "bacula-sd",
255                    get_first_port_host_order(me->sdaddrs));
256    read_state_file(me->working_directory, "bacula-sd",
257                    get_first_port_host_order(me->sdaddrs));
258
259    set_jcr_in_tsd(INVALID_JCR);
260    /* Make sure on Solaris we can run concurrent, watch dog + servers + misc */
261    set_thread_concurrency(me->max_concurrent_jobs * 2 + 4);
262    lmgr_init_thread(); /* initialize the lockmanager stack */
263
264    load_sd_plugins(me->plugin_directory);
265
266    drop(uid, gid, false);
267
268    cleanup_old_files();
269
270    /* Ensure that Volume Session Time and Id are both
271     * set and are both non-zero.
272     */
273    VolSessionTime = (uint32_t)daemon_start_time;
274    if (VolSessionTime == 0) { /* paranoid */
275       Jmsg0(NULL, M_ABORT, 0, _("Volume Session Time is ZERO!\n"));
276    }
277
278    /*
279     * Start the device allocation thread
280     */
281    create_volume_lists();             /* do before device_init */
282    if (pthread_create(&thid, NULL, device_initialization, NULL) != 0) {
283       berrno be;
284       Emsg1(M_ABORT, 0, _("Unable to create thread. ERR=%s\n"), be.bstrerror());
285    }
286
287    start_watchdog();                  /* start watchdog thread */
288    init_jcr_subsystem();              /* start JCR watchdogs etc. */
289
290    /* Single server used for Director and File daemon */
291    server_tid = pthread_self();
292    server_tid_valid = true;
293    bnet_thread_server(me->sdaddrs, me->max_concurrent_jobs * 2 + 1,
294                       &dird_workq, handle_connection_request);
295    exit(1);                           /* to keep compiler quiet */
296 }
297
298 /* Return a new Session Id */
299 uint32_t newVolSessionId()
300 {
301    uint32_t Id;
302
303    P(mutex);
304    VolSessionId++;
305    Id = VolSessionId;
306    V(mutex);
307    return Id;
308 }
309
310 /* Check Configuration file for necessary info */
311 static int check_resources()
312 {
313    bool OK = true;
314    bool tls_needed;
315
316    me = (STORES *)GetNextRes(R_STORAGE, NULL);
317    if (!me) {
318       Jmsg1(NULL, M_ERROR, 0, _("No Storage resource defined in %s. Cannot continue.\n"),
319          configfile);
320       OK = false;
321    }
322
323    if (GetNextRes(R_STORAGE, (RES *)me) != NULL) {
324       Jmsg1(NULL, M_ERROR, 0, _("Only one Storage resource permitted in %s\n"),
325          configfile);
326       OK = false;
327    }
328    if (GetNextRes(R_DIRECTOR, NULL) == NULL) {
329       Jmsg1(NULL, M_ERROR, 0, _("No Director resource defined in %s. Cannot continue.\n"),
330          configfile);
331       OK = false;
332    }
333    if (GetNextRes(R_DEVICE, NULL) == NULL){
334       Jmsg1(NULL, M_ERROR, 0, _("No Device resource defined in %s. Cannot continue.\n"),
335            configfile);
336       OK = false;
337    }
338
339    if (!me->messages) {
340       me->messages = (MSGS *)GetNextRes(R_MSGS, NULL);
341       if (!me->messages) {
342          Jmsg1(NULL, M_ERROR, 0, _("No Messages resource defined in %s. Cannot continue.\n"),
343             configfile);
344          OK = false;
345       }
346    }
347
348    if (!me->working_directory) {
349       Jmsg1(NULL, M_ERROR, 0, _("No Working Directory defined in %s. Cannot continue.\n"),
350          configfile);
351       OK = false;
352    }
353
354    DIRRES *director;
355    STORES *store;
356    foreach_res(store, R_STORAGE) {
357       /* tls_require implies tls_enable */
358       if (store->tls_require) {
359          if (have_tls) {
360             store->tls_enable = true;
361          } else {
362             Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
363             OK = false;
364             continue;
365          }
366       }
367
368       tls_needed = store->tls_enable || store->tls_authenticate;
369
370       if (!store->tls_certfile && tls_needed) {
371          Jmsg(NULL, M_FATAL, 0, _("\"TLS Certificate\" file not defined for Storage \"%s\" in %s.\n"),
372               store->hdr.name, configfile);
373          OK = false;
374       }
375
376       if (!store->tls_keyfile && tls_needed) {
377          Jmsg(NULL, M_FATAL, 0, _("\"TLS Key\" file not defined for Storage \"%s\" in %s.\n"),
378               store->hdr.name, configfile);
379          OK = false;
380       }
381
382       if ((!store->tls_ca_certfile && !store->tls_ca_certdir) && tls_needed && store->tls_verify_peer) {
383          Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\""
384               " or \"TLS CA Certificate Dir\" are defined for Storage \"%s\" in %s."
385               " At least one CA certificate store is required"
386               " when using \"TLS Verify Peer\".\n"),
387               store->hdr.name, configfile);
388          OK = false;
389       }
390
391       /* If everything is well, attempt to initialize our per-resource TLS context */
392       if (OK && (tls_needed || store->tls_require)) {
393          /* Initialize TLS context:
394           * Args: CA certfile, CA certdir, Certfile, Keyfile,
395           * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
396          store->tls_ctx = new_tls_context(store->tls_ca_certfile,
397             store->tls_ca_certdir, store->tls_certfile,
398             store->tls_keyfile, NULL, NULL, store->tls_dhfile,
399             store->tls_verify_peer);
400
401          if (!store->tls_ctx) {
402             Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for Storage \"%s\" in %s.\n"),
403                  store->hdr.name, configfile);
404             OK = false;
405          }
406       }
407    }
408
409    foreach_res(director, R_DIRECTOR) {
410       /* tls_require implies tls_enable */
411       if (director->tls_require) {
412          director->tls_enable = true;
413       }
414
415       tls_needed = director->tls_enable || director->tls_authenticate;
416
417       if (!director->tls_certfile && tls_needed) {
418          Jmsg(NULL, M_FATAL, 0, _("\"TLS Certificate\" file not defined for Director \"%s\" in %s.\n"),
419               director->hdr.name, configfile);
420          OK = false;
421       }
422
423       if (!director->tls_keyfile && tls_needed) {
424          Jmsg(NULL, M_FATAL, 0, _("\"TLS Key\" file not defined for Director \"%s\" in %s.\n"),
425               director->hdr.name, configfile);
426          OK = false;
427       }
428
429       if ((!director->tls_ca_certfile && !director->tls_ca_certdir) && tls_needed && director->tls_verify_peer) {
430          Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\""
431               " or \"TLS CA Certificate Dir\" are defined for Director \"%s\" in %s."
432               " At least one CA certificate store is required"
433               " when using \"TLS Verify Peer\".\n"),
434               director->hdr.name, configfile);
435          OK = false;
436       }
437
438       /* If everything is well, attempt to initialize our per-resource TLS context */
439       if (OK && (tls_needed || director->tls_require)) {
440          /* Initialize TLS context:
441           * Args: CA certfile, CA certdir, Certfile, Keyfile,
442           * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
443          director->tls_ctx = new_tls_context(director->tls_ca_certfile,
444             director->tls_ca_certdir, director->tls_certfile,
445             director->tls_keyfile, NULL, NULL, director->tls_dhfile,
446             director->tls_verify_peer);
447
448          if (!director->tls_ctx) {
449             Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for Director \"%s\" in %s.\n"),
450                  director->hdr.name, configfile);
451             OK = false;
452          }
453       }
454    }
455
456    OK = init_autochangers();
457
458
459    if (OK) {
460       close_msg(NULL);                   /* close temp message handler */
461       init_msg(NULL, me->messages);      /* open daemon message handler */
462       set_working_directory(me->working_directory);
463    }
464
465    return OK;
466 }
467
468 /*
469  * Remove old .spool files written by me from the working directory.
470  */
471 static void cleanup_old_files()
472 {
473    DIR* dp;
474    struct dirent *entry, *result;
475    int rc, name_max;
476    int my_name_len = strlen(my_name);
477    int len = strlen(me->working_directory);
478    POOLMEM *cleanup = get_pool_memory(PM_MESSAGE);
479    POOLMEM *basename = get_pool_memory(PM_MESSAGE);
480    regex_t preg1;
481    char prbuf[500];
482    const int nmatch = 30;
483    regmatch_t pmatch[nmatch];
484    berrno be;
485
486    /* Look for .spool files but don't allow spaces */
487    const char *pat1 = "^[^ ]+\\.spool$";
488
489    /* Setup working directory prefix */
490    pm_strcpy(basename, me->working_directory);
491    if (len > 0 && !IsPathSeparator(me->working_directory[len-1])) {
492       pm_strcat(basename, "/");
493    }
494
495    /* Compile regex expressions */
496    rc = regcomp(&preg1, pat1, REG_EXTENDED);
497    if (rc != 0) {
498       regerror(rc, &preg1, prbuf, sizeof(prbuf));
499       Pmsg2(000,  _("Could not compile regex pattern \"%s\" ERR=%s\n"),
500            pat1, prbuf);
501       goto get_out2;
502    }
503
504    name_max = pathconf(".", _PC_NAME_MAX);
505    if (name_max < 1024) {
506       name_max = 1024;
507    }
508
509    if (!(dp = opendir(me->working_directory))) {
510       berrno be;
511       Pmsg2(000, "Failed to open working dir %s for cleanup: ERR=%s\n",
512             me->working_directory, be.bstrerror());
513       goto get_out1;
514    }
515
516    entry = (struct dirent *)malloc(sizeof(struct dirent) + name_max + 1000);
517    while (1) {
518       if ((readdir_r(dp, entry, &result) != 0) || (result == NULL)) {
519          break;
520       }
521       /* Exclude any name with ., .., not my_name or containing a space */
522       if (strcmp(result->d_name, ".") == 0 || strcmp(result->d_name, "..") == 0 ||
523           strncmp(result->d_name, my_name, my_name_len) != 0) {
524          Dmsg1(500, "Skipped: %s\n", result->d_name);
525          continue;
526       }
527
528       /* Unlink files that match regex */
529       if (regexec(&preg1, result->d_name, nmatch, pmatch,  0) == 0) {
530          pm_strcpy(cleanup, basename);
531          pm_strcat(cleanup, result->d_name);
532          Dmsg1(500, "Unlink: %s\n", cleanup);
533          unlink(cleanup);
534       }
535    }
536    free(entry);
537    closedir(dp);
538
539 get_out1:
540    regfree(&preg1);
541 get_out2:
542    free_pool_memory(cleanup);
543    free_pool_memory(basename);
544 }
545
546 /*
547  * Here we attempt to init and open each device. This is done
548  *  once at startup in a separate thread.
549  */
550 extern "C"
551 void *device_initialization(void *arg)
552 {
553    DEVRES *device;
554    DCR *dcr;
555    JCR *jcr;
556    DEVICE *dev;
557
558    LockRes();
559
560    pthread_detach(pthread_self());
561    jcr = new_jcr(sizeof(JCR), stored_free_jcr);
562    new_plugins(jcr);  /* instantiate plugins */
563    jcr->setJobType(JT_SYSTEM);
564    /* Initialize FD start condition variable */
565    int errstat = pthread_cond_init(&jcr->job_start_wait, NULL);
566    if (errstat != 0) {
567       berrno be;
568       Jmsg1(jcr, M_ABORT, 0, _("Unable to init job cond variable: ERR=%s\n"), be.bstrerror(errstat));
569    }
570
571    foreach_res(device, R_DEVICE) {
572       Dmsg1(90, "calling init_dev %s\n", device->device_name);
573       dev = init_dev(NULL, device);
574       Dmsg1(10, "SD init done %s\n", device->device_name);
575       if (!dev) {
576          Jmsg1(NULL, M_ERROR, 0, _("Could not initialize %s\n"), device->device_name);
577          continue;
578       }
579
580       jcr->dcr = dcr = new_dcr(jcr, NULL, dev);
581       generate_plugin_event(jcr, bsdEventDeviceInit, dcr);
582
583       if (device->cap_bits & CAP_ALWAYSOPEN) {
584          if (dev->is_autochanger()) {
585             /* If autochanger set slot in dev sturcture */
586             get_autochanger_loaded_slot(dcr);
587          }
588          Dmsg1(20, "calling first_open_device %s\n", dev->print_name());
589          if (generate_plugin_event(jcr, bsdEventDeviceOpen, dcr) != bRC_OK) {
590             Jmsg(jcr, M_FATAL, 0, _("generate_plugin_event(bsdEventDeviceOpen) Failed\n"));
591             continue;
592          }
593
594          if (!first_open_device(dcr)) {
595             Jmsg1(NULL, M_ERROR, 0, _("Could not open device %s\n"), dev->print_name());
596             Dmsg1(20, "Could not open device %s\n", dev->print_name());
597             generate_plugin_event(jcr, bsdEventDeviceClose, dcr);
598             free_dcr(dcr);
599             jcr->dcr = NULL;
600             continue;
601          }
602       } else {
603          /* If not always open, we don't know what is in the drive */
604          dev->clear_slot();
605       }
606       if (device->cap_bits & CAP_AUTOMOUNT && dev->is_open()) {
607          switch (read_dev_volume_label(dcr)) {
608          case VOL_OK:
609             memcpy(&dev->VolCatInfo, &dcr->VolCatInfo, sizeof(dev->VolCatInfo));
610             volume_unused(dcr);             /* mark volume "released" */
611             break;
612          default:
613             Jmsg1(NULL, M_WARNING, 0, _("Could not mount device %s\n"), dev->print_name());
614             break;
615          }
616       }
617
618       free_dcr(dcr);
619       jcr->dcr = NULL;
620    }
621
622
623 #ifdef xxx
624    if (jcr->dcr) {
625       Pmsg1(000, "free_dcr=%p\n", jcr->dcr);
626       free_dcr(jcr->dcr);
627       jcr->dcr = NULL;
628    }
629 #endif
630    free_plugins(jcr);
631    free_jcr(jcr);
632    init_done = true;
633    UnlockRes();
634    return NULL;
635 }
636
637
638 /* Clean up and then exit */
639 void terminate_stored(int sig)
640 {
641    static bool in_here = false;
642    DEVRES *device;
643    JCR *jcr;
644
645    if (in_here) {                     /* prevent loops */
646       bmicrosleep(2, 0);              /* yield */
647       exit(1);
648    }
649    in_here = true;
650    debug_level = 0;                   /* turn off any debug */
651    stop_watchdog();
652
653    if (sig == SIGTERM || sig == SIGINT) { /* normal shutdown request? or ^C */
654       /*
655        * This is a normal shutdown request. We wiffle through
656        *   all open jobs canceling them and trying to wake
657        *   them up so that they will report back the correct
658        *   volume status.
659        */
660       foreach_jcr(jcr) {
661          BSOCK *fd;
662          if (jcr->JobId == 0) {
663             free_jcr(jcr);
664             continue;                 /* ignore console */
665          }
666          if (jcr->dcr) {
667             /* Make sure no device remains locked */
668             generate_plugin_event(jcr, bsdEventDeviceClose, jcr->dcr);
669          }
670          jcr->setJobStatus(JS_Canceled);
671          fd = jcr->file_bsock;
672          if (fd) {
673             fd->set_timed_out();
674             jcr->my_thread_send_signal(TIMEOUT_SIGNAL);
675             Dmsg1(100, "term_stored killing JobId=%d\n", jcr->JobId);
676             /* ***FIXME*** wiffle through all dcrs */
677             if (jcr->dcr && jcr->dcr->dev && jcr->dcr->dev->blocked()) {
678                pthread_cond_broadcast(&jcr->dcr->dev->wait_next_vol);
679                Dmsg1(100, "JobId=%u broadcast wait_device_release\n", (uint32_t)jcr->JobId);
680                pthread_cond_broadcast(&wait_device_release);
681             }
682             if (jcr->read_dcr && jcr->read_dcr->dev && jcr->read_dcr->dev->blocked()) {
683                pthread_cond_broadcast(&jcr->read_dcr->dev->wait_next_vol);
684                pthread_cond_broadcast(&wait_device_release);
685             }
686             bmicrosleep(0, 50000);
687          }
688          free_jcr(jcr);
689       }
690       bmicrosleep(0, 500000);         /* give them 1/2 sec to clean up */
691    }
692
693    if (!test_config) {
694       write_state_file(me->working_directory,
695                        "bacula-sd", get_first_port_host_order(me->sdaddrs));
696       delete_pid_file(me->pid_directory,
697                       "bacula-sd", get_first_port_host_order(me->sdaddrs));
698    }
699
700    Dmsg1(200, "In terminate_stored() sig=%d\n", sig);
701
702    unload_plugins();
703    free_volume_lists();
704
705    foreach_res(device, R_DEVICE) {
706       Dmsg1(10, "Term device %s\n", device->device_name);
707       if (device->dev) {
708          device->dev->clear_volhdr();
709          device->dev->term();
710          device->dev = NULL;
711       } else {
712          Dmsg1(10, "No dev structure %s\n", device->device_name);
713       }
714    }
715    if (server_tid_valid) {
716       bnet_stop_thread_server(server_tid);
717    }
718
719    if (configfile) {
720       free(configfile);
721       configfile = NULL;
722    }
723    if (config) {
724       config->free_resources();
725       free(config);
726       config = NULL;
727    }
728
729    if (chk_dbglvl(10)) {
730       print_memory_pool_stats();
731    }
732    term_msg();
733    cleanup_crypto();
734    term_reservations_lock();
735    close_memory_pool();
736    lmgr_cleanup_main();
737
738    sm_dump(false);                    /* dump orphaned buffers */
739    exit(sig);
740 }