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