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