]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/stored/stored.c
508b0abe454f018c486f6e1f4f2072cd16eca81a
[bacula/bacula] / bacula / src / stored / stored.c
1 /*
2  * Second generation Storage daemon.
3  *
4  * It accepts a number of simple commands from the File daemon
5  * and acts on them. When a request to append data is made,
6  * it opens a data channel and accepts data from the
7  * File daemon.
8  *
9  *   Version $Id$
10  *
11  */
12 /*
13    Copyright (C) 2000-2005 Kern Sibbald
14
15    This program is free software; you can redistribute it and/or
16    modify it under the terms of the GNU General Public License
17    version 2 as amended with additional clauses defined in the
18    file LICENSE in the main source directory.
19
20    This program is distributed in the hope that it will be useful,
21    but WITHOUT ANY WARRANTY; without even the implied warranty of
22    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
23    the file LICENSE for additional details.
24
25  */
26
27 #include "bacula.h"
28 #include "stored.h"
29
30 /* Imported functions */
31
32
33 /* Forward referenced functions */
34 void terminate_stored(int sig);
35 static int check_resources();
36 static void cleanup_old_files();
37
38 extern "C" void *device_initialization(void *arg);
39
40 #define CONFIG_FILE "bacula-sd.conf"  /* Default config file */
41
42 /* Global variables exported */
43 char OK_msg[]   = "3000 OK\n";
44 char TERM_msg[] = "3999 Terminate\n";
45 STORES *me = NULL;                    /* our Global resource */
46 bool forge_on = false;                /* proceed inspite of I/O errors */
47 pthread_mutex_t device_release_mutex = PTHREAD_MUTEX_INITIALIZER;
48 pthread_cond_t wait_device_release = PTHREAD_COND_INITIALIZER;
49
50
51 static uint32_t VolSessionId = 0;
52 uint32_t VolSessionTime;
53 char *configfile = NULL;
54 bool init_done = false;
55
56 /* Global static variables */
57 static int foreground = 0;
58 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
59 static workq_t dird_workq;            /* queue for processing connections */
60
61
62 static void usage()
63 {
64    fprintf(stderr, _(
65 "Copyright (C) 2000-2005 Kern Sibbald.\n"
66 "\nVersion: " VERSION " (" BDATE ")\n\n"
67 "Usage: stored [options] [-c config_file] [config_file]\n"
68 "        -c <file>   use <file> as configuration file\n"
69 "        -dnn        set debug level to nn\n"
70 "        -f          run in foreground (for debugging)\n"
71 "        -g <group>  set groupid to group\n"
72 "        -p          proceed despite I/O errors\n"
73 "        -s          no signals (for debugging)\n"
74 "        -t          test - read config and exit\n"
75 "        -u <user>   userid to <user>\n"
76 "        -v          verbose user messages\n"
77 "        -?          print this message.\n"
78 "\n"));
79    exit(1);
80 }
81
82 /*********************************************************************
83  *
84  *  Main Bacula Unix Storage Daemon
85  *
86  */
87 int main (int argc, char *argv[])
88 {
89    int ch;
90    int no_signals = FALSE;
91    int test_config = FALSE;
92    pthread_t thid;
93    char *uid = NULL;
94    char *gid = NULL;
95
96    init_stack_dump();
97    my_name_is(argc, argv, "bacula-sd");
98    textdomain("bacula");
99    init_msg(NULL, NULL);
100    daemon_start_time = time(NULL);
101
102    /* Sanity checks */
103    if (TAPE_BSIZE % B_DEV_BSIZE != 0 || TAPE_BSIZE / B_DEV_BSIZE == 0) {
104       Emsg2(M_ABORT, 0, "Tape block size (%d) not multiple of system size (%d)\n",
105          TAPE_BSIZE, B_DEV_BSIZE);
106    }
107    if (TAPE_BSIZE != (1 << (ffs(TAPE_BSIZE)-1))) {
108       Emsg1(M_ABORT, 0, "Tape block size (%d) is not a power of 2\n", TAPE_BSIZE);
109    }
110
111    while ((ch = getopt(argc, argv, "c:d:fg:pstu:v?")) != -1) {
112       switch (ch) {
113       case 'c':                    /* configuration file */
114          if (configfile != NULL) {
115             free(configfile);
116          }
117          configfile = bstrdup(optarg);
118          break;
119
120       case 'd':                    /* debug level */
121          debug_level = atoi(optarg);
122          if (debug_level <= 0) {
123             debug_level = 1;
124          }
125          break;
126
127       case 'f':                    /* run in foreground */
128          foreground = TRUE;
129          break;
130
131       case 'g':                    /* set group id */
132          gid = optarg;
133          break;
134
135       case 'p':                    /* proceed in spite of I/O errors */
136          forge_on = true;
137          break;
138
139       case 's':                    /* no signals */
140          no_signals = TRUE;
141          break;
142
143       case 't':
144          test_config = TRUE;
145          break;
146
147       case 'u':                    /* set uid */
148          uid = optarg;
149          break;
150
151       case 'v':                    /* verbose */
152          verbose++;
153          break;
154
155       case '?':
156       default:
157          usage();
158          break;
159       }
160    }
161    argc -= optind;
162    argv += optind;
163
164    if (argc) {
165       if (configfile != NULL) {
166          free(configfile);
167       }
168       configfile = bstrdup(*argv);
169       argc--;
170       argv++;
171    }
172    if (argc)
173       usage();
174
175    if (!no_signals) {
176       init_signals(terminate_stored);
177    }
178
179    if (configfile == NULL) {
180       configfile = bstrdup(CONFIG_FILE);
181    }
182
183    parse_config(configfile);
184
185    if (init_tls() != 0) {
186       Jmsg((JCR *)NULL, M_ERROR_TERM, 0, _("TLS library initialization failed.\n"));
187    }
188
189    if (!check_resources()) {
190       Jmsg((JCR *)NULL, M_ERROR_TERM, 0, _("Please correct configuration file: %s\n"), configfile);
191    }
192
193    if (test_config) {
194       terminate_stored(0);
195    }
196
197    my_name_is(0, (char **)NULL, me->hdr.name);     /* Set our real name */
198
199    if (!foreground) {
200       daemon_start();                 /* become daemon */
201       init_stack_dump();              /* pick up new pid */
202    }
203
204    create_pid_file(me->pid_directory, "bacula-sd", get_first_port_host_order(me->sdaddrs));
205    read_state_file(me->working_directory, "bacula-sd", get_first_port_host_order(me->sdaddrs));
206
207    drop(uid, gid);
208
209    cleanup_old_files();
210
211
212    /* Ensure that Volume Session Time and Id are both
213     * set and are both non-zero.
214     */
215    VolSessionTime = (long)daemon_start_time;
216    if (VolSessionTime == 0) { /* paranoid */
217       Jmsg0(NULL, M_ABORT, 0, _("Volume Session Time is ZERO!\n"));
218    }
219
220    init_python_interpreter(me->hdr.name, me->scripts_directory, "SDStartUp");
221
222    /* Make sure on Solaris we can run concurrent, watch dog + servers + misc */
223    set_thread_concurrency(me->max_concurrent_jobs * 2 + 4);
224
225     /*
226      * Start the device allocation thread
227      */
228    create_volume_list();              /* do before device_init */
229    if (pthread_create(&thid, NULL, device_initialization, NULL) != 0) {
230       Emsg1(M_ABORT, 0, _("Unable to create thread. ERR=%s\n"), strerror(errno));
231    }
232
233    start_watchdog();                  /* start watchdog thread */
234    init_jcr_subsystem();              /* start JCR watchdogs etc. */
235
236    /* Single server used for Director and File daemon */
237    bnet_thread_server(me->sdaddrs, me->max_concurrent_jobs * 2 + 1,
238                       &dird_workq, handle_connection_request);
239    exit(1);                           /* to keep compiler quiet */
240 }
241
242 /* Return a new Session Id */
243 uint32_t newVolSessionId()
244 {
245    uint32_t Id;
246
247    P(mutex);
248    VolSessionId++;
249    Id = VolSessionId;
250    V(mutex);
251    return Id;
252 }
253
254 /* Check Configuration file for necessary info */
255 static int check_resources()
256 {
257    bool OK = true;
258    AUTOCHANGER *changer;
259
260
261    me = (STORES *)GetNextRes(R_STORAGE, NULL);
262    if (!me) {
263       Jmsg1(NULL, M_ERROR, 0, _("No Storage resource defined in %s. Cannot continue.\n"),
264          configfile);
265       OK = false;
266    }
267
268    if (GetNextRes(R_STORAGE, (RES *)me) != NULL) {
269       Jmsg1(NULL, M_ERROR, 0, _("Only one Storage resource permitted in %s\n"),
270          configfile);
271       OK = false;
272    }
273    if (GetNextRes(R_DIRECTOR, NULL) == NULL) {
274       Jmsg1(NULL, M_ERROR, 0, _("No Director resource defined in %s. Cannot continue.\n"),
275          configfile);
276       OK = false;
277    }
278    if (GetNextRes(R_DEVICE, NULL) == NULL){
279       Jmsg1(NULL, M_ERROR, 0, _("No Device resource defined in %s. Cannot continue.\n"),
280            configfile);
281       OK = false;
282    }
283
284    if (!me->messages) {
285       me->messages = (MSGS *)GetNextRes(R_MSGS, NULL);
286       if (!me->messages) {
287          Jmsg1(NULL, M_ERROR, 0, _("No Messages resource defined in %s. Cannot continue.\n"),
288             configfile);
289          OK = false;
290       }
291    }
292
293    if (!me->working_directory) {
294       Jmsg1(NULL, M_ERROR, 0, _("No Working Directory defined in %s. Cannot continue.\n"),
295          configfile);
296       OK = false;
297    }
298
299    DIRRES *director;
300    STORES *store;
301    foreach_res(store, R_STORAGE) { 
302       /* tls_require implies tls_enable */
303       if (store->tls_require) {
304          if (have_tls) {
305             store->tls_enable = true;
306          } else {
307             Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
308             OK = false;
309             continue;
310          }
311       }
312
313       if (!store->tls_certfile && store->tls_enable) {
314          Jmsg(NULL, M_FATAL, 0, _("\"TLS Certificate\" file not defined for Storage \"%s\" in %s.\n"),
315               store->hdr.name, configfile);
316          OK = false;
317       }
318
319       if (!store->tls_keyfile && store->tls_enable) {
320          Jmsg(NULL, M_FATAL, 0, _("\"TLS Key\" file not defined for Storage \"%s\" in %s.\n"),
321               store->hdr.name, configfile);
322          OK = false;
323       }
324
325       if ((!store->tls_ca_certfile && !store->tls_ca_certdir) && store->tls_enable && store->tls_verify_peer) {
326          Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\""
327               " or \"TLS CA Certificate Dir\" are defined for Storage \"%s\" in %s."
328               " At least one CA certificate store is required"
329               " when using \"TLS Verify Peer\".\n"),
330               store->hdr.name, configfile);
331          OK = false;
332       }
333
334       /* If everything is well, attempt to initialize our per-resource TLS context */
335       if (OK && (store->tls_enable || store->tls_require)) {
336          /* Initialize TLS context:
337           * Args: CA certfile, CA certdir, Certfile, Keyfile,
338           * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
339          store->tls_ctx = new_tls_context(store->tls_ca_certfile,
340             store->tls_ca_certdir, store->tls_certfile,
341             store->tls_keyfile, NULL, NULL, store->tls_dhfile,
342             store->tls_verify_peer);
343
344          if (!store->tls_ctx) { 
345             Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for Storage \"%s\" in %s.\n"),
346                  store->hdr.name, configfile);
347             OK = false;
348          }
349       }
350    }
351
352    foreach_res(director, R_DIRECTOR) { 
353       /* tls_require implies tls_enable */
354       if (director->tls_require) {
355          director->tls_enable = true;
356       }
357
358       if (!director->tls_certfile && director->tls_enable) {
359          Jmsg(NULL, M_FATAL, 0, _("\"TLS Certificate\" file not defined for Director \"%s\" in %s.\n"),
360               director->hdr.name, configfile);
361          OK = false;
362       }
363
364       if (!director->tls_keyfile && director->tls_enable) {
365          Jmsg(NULL, M_FATAL, 0, _("\"TLS Key\" file not defined for Director \"%s\" in %s.\n"),
366               director->hdr.name, configfile);
367          OK = false;
368       }
369
370       if ((!director->tls_ca_certfile && !director->tls_ca_certdir) && director->tls_enable && director->tls_verify_peer) {
371          Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\""
372               " or \"TLS CA Certificate Dir\" are defined for Director \"%s\" in %s."
373               " At least one CA certificate store is required"
374               " when using \"TLS Verify Peer\".\n"),
375               director->hdr.name, configfile);
376          OK = false;
377       }
378
379       /* If everything is well, attempt to initialize our per-resource TLS context */
380       if (OK && (director->tls_enable || director->tls_require)) {
381          /* Initialize TLS context:
382           * Args: CA certfile, CA certdir, Certfile, Keyfile,
383           * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
384          director->tls_ctx = new_tls_context(director->tls_ca_certfile,
385             director->tls_ca_certdir, director->tls_certfile,
386             director->tls_keyfile, NULL, NULL, director->tls_dhfile,
387             director->tls_verify_peer);
388
389          if (!director->tls_ctx) { 
390             Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for Director \"%s\" in %s.\n"),
391                  director->hdr.name, configfile);
392             OK = false;
393          }
394       }
395    }
396
397    /* Ensure that the media_type for each device is the same */
398    foreach_res(changer, R_AUTOCHANGER) {
399       DEVRES *device;
400       char *media_type = NULL;
401       foreach_alist(device, changer->device) {
402          /*
403           * If the device does not have a changer name or changer command
404           *   defined, used the one from the Autochanger resource 
405           */
406          if (!device->changer_name && changer->changer_name) {
407             device->changer_name = bstrdup(changer->changer_name);
408          }
409          if (!device->changer_command && changer->changer_command) {
410             device->changer_command = bstrdup(changer->changer_command);
411          }
412          if (!device->changer_name) {
413             Jmsg(NULL, M_ERROR, 0, 
414                _("No Changer Name given for device %s. Cannot continue.\n"),
415                device->hdr.name);
416             OK = false;
417          }   
418          if (!device->changer_command) {
419             Jmsg(NULL, M_ERROR, 0, 
420                _("No Changer Command given for device %s. Cannot continue.\n"),
421                device->hdr.name);
422             OK = false;
423          }   
424
425          if (media_type == NULL) {
426             media_type = device->media_type;     /* get Media Type of first device */
427             continue;
428          }     
429          /* Ensure that other devices Media Types are the same */
430          if (strcmp(media_type, device->media_type) != 0) {
431             Jmsg(NULL, M_ERROR, 0, 
432                _("Media Type not the same for all devices in changer %s. Cannot continue.\n"),
433                changer->hdr.name);
434             OK = false;
435             continue;
436          }
437       }
438    }
439    
440    if (OK) {
441       close_msg(NULL);                   /* close temp message handler */
442       init_msg(NULL, me->messages);      /* open daemon message handler */
443       set_working_directory(me->working_directory);
444    }
445
446    return OK;
447 }
448
449 static void cleanup_old_files()
450 {
451    POOLMEM *cleanup = get_pool_memory(PM_MESSAGE);
452    int len = strlen(me->working_directory);
453    pm_strcpy(cleanup, "/bin/rm -f ");
454    pm_strcat(cleanup, me->working_directory);
455    if (len > 0 && me->working_directory[len-1] != '/') {
456       pm_strcat(cleanup, "/");
457    }
458    pm_strcat(cleanup, my_name);
459    pm_strcat(cleanup, "*.spool");
460    run_program(cleanup, 0, NULL);
461    free_pool_memory(cleanup);
462 }      
463
464
465 /*
466  * Here we attempt to init and open each device. This is done
467  *  once at startup in a separate thread.
468  */
469 extern "C"
470 void *device_initialization(void *arg)
471 {
472    DEVRES *device;
473    DCR *dcr;
474    JCR *jcr;
475    DEVICE *dev;
476
477    LockRes();
478
479    pthread_detach(pthread_self());
480    jcr = new_jcr(sizeof(JCR), stored_free_jcr);
481    jcr->JobType = JT_SYSTEM;
482    /* Initialize FD start condition variable */
483    int errstat = pthread_cond_init(&jcr->job_start_wait, NULL);
484    if (errstat != 0) {
485       Jmsg1(jcr, M_ABORT, 0, _("Unable to init job cond variable: ERR=%s\n"), strerror(errstat));
486    }
487
488    foreach_res(device, R_DEVICE) {
489       Dmsg1(90, "calling init_dev %s\n", device->device_name);
490       device->dev = dev = init_dev(NULL, device);
491       Dmsg1(10, "SD init done %s\n", device->device_name);
492       if (!dev) {
493          Jmsg1(NULL, M_ERROR, 0, _("Could not initialize %s\n"), device->device_name);
494          continue;
495       }
496
497       dcr = new_dcr(jcr, dev);
498
499       if (device->cap_bits & CAP_ALWAYSOPEN) {
500          Dmsg1(20, "calling first_open_device %s\n", dev->print_name());
501          if (!first_open_device(dcr)) {
502             Jmsg1(NULL, M_ERROR, 0, _("Could not open device %s\n"), dev->print_name());
503             Dmsg1(20, "Could not open device %s\n", dev->print_name());
504             term_dev(dev);
505             device->dev = NULL;
506             free_dcr(dcr);
507             continue;
508          }
509       }
510       if (device->cap_bits & CAP_AUTOMOUNT && dev->is_open()) {
511          switch (read_dev_volume_label(dcr)) {
512          case VOL_OK:
513             memcpy(&dev->VolCatInfo, &dcr->VolCatInfo, sizeof(dev->VolCatInfo));
514             break;
515          default:
516             Jmsg1(NULL, M_WARNING, 0, _("Could not mount device %s\n"), dev->print_name());
517             break;
518          }
519       }
520       free_dcr(dcr);
521    }
522    free_jcr(jcr); 
523    init_done = true;
524    UnlockRes();
525    return NULL;
526 }
527
528
529 /* Clean up and then exit */
530 void terminate_stored(int sig)
531 {
532    static bool in_here = false;
533    DEVRES *device;
534    JCR *jcr;
535
536    if (in_here) {                     /* prevent loops */
537       exit(1);
538    }
539    in_here = true;
540
541    if (sig == SIGTERM) {              /* normal shutdown request? */
542       /*
543        * This is a normal shutdown request. We wiffle through
544        *   all open jobs canceling them and trying to wake
545        *   them up so that they will report back the correct
546        *   volume status.
547        */
548       foreach_jcr(jcr) {
549          BSOCK *fd;
550          if (jcr->JobId == 0) {
551             free_jcr(jcr);
552             continue;                 /* ignore console */
553          }
554          set_jcr_job_status(jcr, JS_Canceled);
555          fd = jcr->file_bsock;
556          if (fd) {
557             fd->timed_out = true;
558             Dmsg1(100, "term_stored killing JobId=%d\n", jcr->JobId);
559             pthread_kill(jcr->my_thread_id, TIMEOUT_SIGNAL);
560             /* ***FIXME*** wiffle through all dcrs */
561             if (jcr->dcr && jcr->dcr->dev && jcr->dcr->dev->dev_blocked) {
562                pthread_cond_broadcast(&jcr->dcr->dev->wait_next_vol);
563                pthread_cond_broadcast(&wait_device_release);
564             }
565             bmicrosleep(0, 50000);
566          }
567          free_jcr(jcr);
568       }
569       bmicrosleep(0, 500000);         /* give them 1/2 sec to clean up */
570    }
571
572    write_state_file(me->working_directory, "bacula-sd", get_first_port_host_order(me->sdaddrs));
573    delete_pid_file(me->pid_directory, "bacula-sd", get_first_port_host_order(me->sdaddrs));
574
575    Dmsg1(200, "In terminate_stored() sig=%d\n", sig);
576
577    foreach_res(device, R_DEVICE) {
578       Dmsg1(10, "Term device %s\n", device->device_name);
579       if (device->dev) {
580          free_volume(device->dev);
581          term_dev(device->dev);
582       } else {
583          Dmsg1(10, "No dev structure %s\n", device->device_name);
584       }
585    }
586
587    if (configfile) {
588       free(configfile);
589       configfile = NULL;
590    }
591    free_config_resources();
592
593    if (debug_level > 10) {
594       print_memory_pool_stats();
595    }
596    term_msg();
597    stop_watchdog();
598    cleanup_tls();
599    free_volume_list();
600    close_memory_pool();
601
602    sm_dump(false);                    /* dump orphaned buffers */
603    exit(sig);
604 }