]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/stored/stored.c
01561aa46c8f01ed6d276c422094e2125215d853
[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: %s (%s)\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"), VERSION, BDATE);
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    setlocale(LC_ALL, "");
97    bindtextdomain("bacula", LOCALEDIR);
98    textdomain("bacula");
99
100    init_stack_dump();
101    my_name_is(argc, argv, "bacula-sd");
102    init_msg(NULL, NULL);
103    daemon_start_time = time(NULL);
104
105    /* Sanity checks */
106    if (TAPE_BSIZE % B_DEV_BSIZE != 0 || TAPE_BSIZE / B_DEV_BSIZE == 0) {
107       Emsg2(M_ABORT, 0, _("Tape block size (%d) not multiple of system size (%d)\n"),
108          TAPE_BSIZE, B_DEV_BSIZE);
109    }
110    if (TAPE_BSIZE != (1 << (ffs(TAPE_BSIZE)-1))) {
111       Emsg1(M_ABORT, 0, _("Tape block size (%d) is not a power of 2\n"), TAPE_BSIZE);
112    }
113
114    while ((ch = getopt(argc, argv, "c:d:fg:pstu:v?")) != -1) {
115       switch (ch) {
116       case 'c':                    /* configuration file */
117          if (configfile != NULL) {
118             free(configfile);
119          }
120          configfile = bstrdup(optarg);
121          break;
122
123       case 'd':                    /* debug level */
124          debug_level = atoi(optarg);
125          if (debug_level <= 0) {
126             debug_level = 1;
127          }
128          break;
129
130       case 'f':                    /* run in foreground */
131          foreground = TRUE;
132          break;
133
134       case 'g':                    /* set group id */
135          gid = optarg;
136          break;
137
138       case 'p':                    /* proceed in spite of I/O errors */
139          forge_on = true;
140          break;
141
142       case 's':                    /* no signals */
143          no_signals = TRUE;
144          break;
145
146       case 't':
147          test_config = TRUE;
148          break;
149
150       case 'u':                    /* set uid */
151          uid = optarg;
152          break;
153
154       case 'v':                    /* verbose */
155          verbose++;
156          break;
157
158       case '?':
159       default:
160          usage();
161          break;
162       }
163    }
164    argc -= optind;
165    argv += optind;
166
167    if (argc) {
168       if (configfile != NULL) {
169          free(configfile);
170       }
171       configfile = bstrdup(*argv);
172       argc--;
173       argv++;
174    }
175    if (argc)
176       usage();
177
178    if (!no_signals) {
179       init_signals(terminate_stored);
180    }
181
182    if (configfile == NULL) {
183       configfile = bstrdup(CONFIG_FILE);
184    }
185
186    parse_config(configfile);
187
188    if (init_crypto() != 0) {
189       Jmsg((JCR *)NULL, M_ERROR_TERM, 0, _("Cryptography library initialization failed.\n"));
190    }
191
192    if (!check_resources()) {
193       Jmsg((JCR *)NULL, M_ERROR_TERM, 0, _("Please correct configuration file: %s\n"), configfile);
194    }
195
196    if (test_config) {
197       terminate_stored(0);
198    }
199
200    my_name_is(0, (char **)NULL, me->hdr.name);     /* Set our real name */
201
202    if (!foreground) {
203       daemon_start();                 /* become daemon */
204       init_stack_dump();              /* pick up new pid */
205    }
206
207    create_pid_file(me->pid_directory, "bacula-sd", get_first_port_host_order(me->sdaddrs));
208    read_state_file(me->working_directory, "bacula-sd", get_first_port_host_order(me->sdaddrs));
209
210    drop(uid, gid);
211
212    cleanup_old_files();
213
214
215    /* Ensure that Volume Session Time and Id are both
216     * set and are both non-zero.
217     */
218    VolSessionTime = (long)daemon_start_time;
219    if (VolSessionTime == 0) { /* paranoid */
220       Jmsg0(NULL, M_ABORT, 0, _("Volume Session Time is ZERO!\n"));
221    }
222
223    init_python_interpreter(me->hdr.name, me->scripts_directory, "SDStartUp");
224
225    /* Make sure on Solaris we can run concurrent, watch dog + servers + misc */
226    set_thread_concurrency(me->max_concurrent_jobs * 2 + 4);
227
228     /*
229      * Start the device allocation thread
230      */
231    create_volume_list();              /* do before device_init */
232    if (pthread_create(&thid, NULL, device_initialization, NULL) != 0) {
233       Emsg1(M_ABORT, 0, _("Unable to create thread. ERR=%s\n"), strerror(errno));
234    }
235
236    start_watchdog();                  /* start watchdog thread */
237    init_jcr_subsystem();              /* start JCR watchdogs etc. */
238
239    /* Single server used for Director and File daemon */
240    bnet_thread_server(me->sdaddrs, me->max_concurrent_jobs * 2 + 1,
241                       &dird_workq, handle_connection_request);
242    exit(1);                           /* to keep compiler quiet */
243 }
244
245 /* Return a new Session Id */
246 uint32_t newVolSessionId()
247 {
248    uint32_t Id;
249
250    P(mutex);
251    VolSessionId++;
252    Id = VolSessionId;
253    V(mutex);
254    return Id;
255 }
256
257 /* Check Configuration file for necessary info */
258 static int check_resources()
259 {
260    bool OK = true;
261
262
263    me = (STORES *)GetNextRes(R_STORAGE, NULL);
264    if (!me) {
265       Jmsg1(NULL, M_ERROR, 0, _("No Storage resource defined in %s. Cannot continue.\n"),
266          configfile);
267       OK = false;
268    }
269
270    if (GetNextRes(R_STORAGE, (RES *)me) != NULL) {
271       Jmsg1(NULL, M_ERROR, 0, _("Only one Storage resource permitted in %s\n"),
272          configfile);
273       OK = false;
274    }
275    if (GetNextRes(R_DIRECTOR, NULL) == NULL) {
276       Jmsg1(NULL, M_ERROR, 0, _("No Director resource defined in %s. Cannot continue.\n"),
277          configfile);
278       OK = false;
279    }
280    if (GetNextRes(R_DEVICE, NULL) == NULL){
281       Jmsg1(NULL, M_ERROR, 0, _("No Device resource defined in %s. Cannot continue.\n"),
282            configfile);
283       OK = false;
284    }
285
286    if (!me->messages) {
287       me->messages = (MSGS *)GetNextRes(R_MSGS, NULL);
288       if (!me->messages) {
289          Jmsg1(NULL, M_ERROR, 0, _("No Messages resource defined in %s. Cannot continue.\n"),
290             configfile);
291          OK = false;
292       }
293    }
294
295    if (!me->working_directory) {
296       Jmsg1(NULL, M_ERROR, 0, _("No Working Directory defined in %s. Cannot continue.\n"),
297          configfile);
298       OK = false;
299    }
300
301    DIRRES *director;
302    STORES *store;
303    foreach_res(store, R_STORAGE) { 
304       /* tls_require implies tls_enable */
305       if (store->tls_require) {
306          if (have_tls) {
307             store->tls_enable = true;
308          } else {
309             Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
310             OK = false;
311             continue;
312          }
313       }
314
315       if (!store->tls_certfile && store->tls_enable) {
316          Jmsg(NULL, M_FATAL, 0, _("\"TLS Certificate\" file not defined for Storage \"%s\" in %s.\n"),
317               store->hdr.name, configfile);
318          OK = false;
319       }
320
321       if (!store->tls_keyfile && store->tls_enable) {
322          Jmsg(NULL, M_FATAL, 0, _("\"TLS Key\" file not defined for Storage \"%s\" in %s.\n"),
323               store->hdr.name, configfile);
324          OK = false;
325       }
326
327       if ((!store->tls_ca_certfile && !store->tls_ca_certdir) && store->tls_enable && store->tls_verify_peer) {
328          Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\""
329               " or \"TLS CA Certificate Dir\" are defined for Storage \"%s\" in %s."
330               " At least one CA certificate store is required"
331               " when using \"TLS Verify Peer\".\n"),
332               store->hdr.name, configfile);
333          OK = false;
334       }
335
336       /* If everything is well, attempt to initialize our per-resource TLS context */
337       if (OK && (store->tls_enable || store->tls_require)) {
338          /* Initialize TLS context:
339           * Args: CA certfile, CA certdir, Certfile, Keyfile,
340           * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
341          store->tls_ctx = new_tls_context(store->tls_ca_certfile,
342             store->tls_ca_certdir, store->tls_certfile,
343             store->tls_keyfile, NULL, NULL, store->tls_dhfile,
344             store->tls_verify_peer);
345
346          if (!store->tls_ctx) { 
347             Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for Storage \"%s\" in %s.\n"),
348                  store->hdr.name, configfile);
349             OK = false;
350          }
351       }
352    }
353
354    foreach_res(director, R_DIRECTOR) { 
355       /* tls_require implies tls_enable */
356       if (director->tls_require) {
357          director->tls_enable = true;
358       }
359
360       if (!director->tls_certfile && director->tls_enable) {
361          Jmsg(NULL, M_FATAL, 0, _("\"TLS Certificate\" file not defined for Director \"%s\" in %s.\n"),
362               director->hdr.name, configfile);
363          OK = false;
364       }
365
366       if (!director->tls_keyfile && director->tls_enable) {
367          Jmsg(NULL, M_FATAL, 0, _("\"TLS Key\" file not defined for Director \"%s\" in %s.\n"),
368               director->hdr.name, configfile);
369          OK = false;
370       }
371
372       if ((!director->tls_ca_certfile && !director->tls_ca_certdir) && director->tls_enable && director->tls_verify_peer) {
373          Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\""
374               " or \"TLS CA Certificate Dir\" are defined for Director \"%s\" in %s."
375               " At least one CA certificate store is required"
376               " when using \"TLS Verify Peer\".\n"),
377               director->hdr.name, configfile);
378          OK = false;
379       }
380
381       /* If everything is well, attempt to initialize our per-resource TLS context */
382       if (OK && (director->tls_enable || director->tls_require)) {
383          /* Initialize TLS context:
384           * Args: CA certfile, CA certdir, Certfile, Keyfile,
385           * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
386          director->tls_ctx = new_tls_context(director->tls_ca_certfile,
387             director->tls_ca_certdir, director->tls_certfile,
388             director->tls_keyfile, NULL, NULL, director->tls_dhfile,
389             director->tls_verify_peer);
390
391          if (!director->tls_ctx) { 
392             Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for Director \"%s\" in %s.\n"),
393                  director->hdr.name, configfile);
394             OK = false;
395          }
396       }
397    }
398
399    OK = init_autochangers();
400
401    
402    if (OK) {
403       close_msg(NULL);                   /* close temp message handler */
404       init_msg(NULL, me->messages);      /* open daemon message handler */
405       set_working_directory(me->working_directory);
406    }
407
408    return OK;
409 }
410
411 static void cleanup_old_files()
412 {
413    POOLMEM *cleanup = get_pool_memory(PM_MESSAGE);
414    int len = strlen(me->working_directory);
415    pm_strcpy(cleanup, "/bin/rm -f ");
416    pm_strcat(cleanup, me->working_directory);
417    if (len > 0 && me->working_directory[len-1] != '/') {
418       pm_strcat(cleanup, "/");
419    }
420    pm_strcat(cleanup, my_name);
421    pm_strcat(cleanup, "*.spool");
422    run_program(cleanup, 0, NULL);
423    free_pool_memory(cleanup);
424 }      
425
426
427 /*
428  * Here we attempt to init and open each device. This is done
429  *  once at startup in a separate thread.
430  */
431 extern "C"
432 void *device_initialization(void *arg)
433 {
434    DEVRES *device;
435    DCR *dcr;
436    JCR *jcr;
437    DEVICE *dev;
438
439    LockRes();
440
441    pthread_detach(pthread_self());
442    jcr = new_jcr(sizeof(JCR), stored_free_jcr);
443    jcr->JobType = JT_SYSTEM;
444    /* Initialize FD start condition variable */
445    int errstat = pthread_cond_init(&jcr->job_start_wait, NULL);
446    if (errstat != 0) {
447       Jmsg1(jcr, M_ABORT, 0, _("Unable to init job cond variable: ERR=%s\n"), strerror(errstat));
448    }
449
450    foreach_res(device, R_DEVICE) {
451       Dmsg1(90, "calling init_dev %s\n", device->device_name);
452       device->dev = dev = init_dev(NULL, device);
453       Dmsg1(10, "SD init done %s\n", device->device_name);
454       if (!dev) {
455          Jmsg1(NULL, M_ERROR, 0, _("Could not initialize %s\n"), device->device_name);
456          continue;
457       }
458
459       dcr = new_dcr(jcr, dev);
460       if (dev->is_autochanger()) {
461          /* If autochanger set slot in dev sturcture */
462          get_autochanger_loaded_slot(dcr);
463       }
464
465       if (device->cap_bits & CAP_ALWAYSOPEN) {
466          Dmsg1(20, "calling first_open_device %s\n", dev->print_name());
467          if (!first_open_device(dcr)) {
468             Jmsg1(NULL, M_ERROR, 0, _("Could not open device %s\n"), dev->print_name());
469             Dmsg1(20, "Could not open device %s\n", dev->print_name());
470             free_dcr(dcr);
471             jcr->dcr = NULL;
472             continue;
473          }
474       }
475       if (device->cap_bits & CAP_AUTOMOUNT && dev->is_open()) {
476          switch (read_dev_volume_label(dcr)) {
477          case VOL_OK:
478             memcpy(&dev->VolCatInfo, &dcr->VolCatInfo, sizeof(dev->VolCatInfo));
479             break;
480          default:
481             Jmsg1(NULL, M_WARNING, 0, _("Could not mount device %s\n"), dev->print_name());
482             break;
483          }
484       }
485       free_dcr(dcr);
486       jcr->dcr = NULL;
487    }
488    free_jcr(jcr); 
489    init_done = true;
490    UnlockRes();
491    return NULL;
492 }
493
494
495 /* Clean up and then exit */
496 void terminate_stored(int sig)
497 {
498    static bool in_here = false;
499    DEVRES *device;
500    JCR *jcr;
501
502    if (in_here) {                     /* prevent loops */
503       exit(1);
504    }
505    in_here = true;
506
507    if (sig == SIGTERM) {              /* normal shutdown request? */
508       /*
509        * This is a normal shutdown request. We wiffle through
510        *   all open jobs canceling them and trying to wake
511        *   them up so that they will report back the correct
512        *   volume status.
513        */
514       foreach_jcr(jcr) {
515          BSOCK *fd;
516          if (jcr->JobId == 0) {
517             free_jcr(jcr);
518             continue;                 /* ignore console */
519          }
520          set_jcr_job_status(jcr, JS_Canceled);
521          fd = jcr->file_bsock;
522          if (fd) {
523             fd->timed_out = true;
524             Dmsg1(100, "term_stored killing JobId=%d\n", jcr->JobId);
525             pthread_kill(jcr->my_thread_id, TIMEOUT_SIGNAL);
526             /* ***FIXME*** wiffle through all dcrs */
527             if (jcr->dcr && jcr->dcr->dev && jcr->dcr->dev->dev_blocked) {
528                pthread_cond_broadcast(&jcr->dcr->dev->wait_next_vol);
529                pthread_cond_broadcast(&wait_device_release);
530             }
531             if (jcr->read_dcr && jcr->read_dcr->dev && jcr->read_dcr->dev->dev_blocked) {
532                pthread_cond_broadcast(&jcr->read_dcr->dev->wait_next_vol);
533                pthread_cond_broadcast(&wait_device_release);
534             }
535             bmicrosleep(0, 50000);
536          }
537          free_jcr(jcr);
538       }
539       bmicrosleep(0, 500000);         /* give them 1/2 sec to clean up */
540    }
541
542    write_state_file(me->working_directory, "bacula-sd", get_first_port_host_order(me->sdaddrs));
543    delete_pid_file(me->pid_directory, "bacula-sd", get_first_port_host_order(me->sdaddrs));
544
545    Dmsg1(200, "In terminate_stored() sig=%d\n", sig);
546
547    foreach_res(device, R_DEVICE) {
548       Dmsg1(10, "Term device %s\n", device->device_name);
549       if (device->dev) {
550          free_volume(device->dev);
551          term_dev(device->dev);
552       } else {
553          Dmsg1(10, "No dev structure %s\n", device->device_name);
554       }
555    }
556
557    if (configfile) {
558       free(configfile);
559       configfile = NULL;
560    }
561    free_config_resources();
562
563    if (debug_level > 10) {
564       print_memory_pool_stats();
565    }
566    term_msg();
567    stop_watchdog();
568    cleanup_crypto();
569    free_volume_list();
570    close_memory_pool();
571
572    sm_dump(false);                    /* dump orphaned buffers */
573    exit(sig);
574 }