]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/stored/stored.c
Replace explicit checks for "/" with calls to IsPathSeparator, strchr with first_path...
[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 && !IsPathSeparator(me->working_directory[len-1])) {
428       pm_strcat(cleanup, "/");
429    }
430    pm_strcat(cleanup, my_name);
431    pm_strcat(cleanup, "*.spool");
432    run_program(cleanup, 0, NULL);
433    free_pool_memory(cleanup);
434 }
435
436
437 /*
438  * Here we attempt to init and open each device. This is done
439  *  once at startup in a separate thread.
440  */
441 extern "C"
442 void *device_initialization(void *arg)
443 {
444    DEVRES *device;
445    DCR *dcr;
446    JCR *jcr;
447    DEVICE *dev;
448
449    LockRes();
450
451    pthread_detach(pthread_self());
452    jcr = new_jcr(sizeof(JCR), stored_free_jcr);
453    jcr->JobType = JT_SYSTEM;
454    /* Initialize FD start condition variable */
455    int errstat = pthread_cond_init(&jcr->job_start_wait, NULL);
456    if (errstat != 0) {
457       Jmsg1(jcr, M_ABORT, 0, _("Unable to init job cond variable: ERR=%s\n"), strerror(errstat));
458    }
459
460    foreach_res(device, R_DEVICE) {
461       Dmsg1(90, "calling init_dev %s\n", device->device_name);
462       dev = init_dev(NULL, device);
463       Dmsg1(10, "SD init done %s\n", device->device_name);
464       if (!dev) {
465          Jmsg1(NULL, M_ERROR, 0, _("Could not initialize %s\n"), device->device_name);
466          continue;
467       }
468
469       jcr->dcr = dcr = new_dcr(jcr, dev);
470       if (dev->is_autochanger()) {
471          /* If autochanger set slot in dev sturcture */
472          get_autochanger_loaded_slot(dcr);
473       }
474
475       if (device->cap_bits & CAP_ALWAYSOPEN) {
476          Dmsg1(20, "calling first_open_device %s\n", dev->print_name());
477          if (!first_open_device(dcr)) {
478             Jmsg1(NULL, M_ERROR, 0, _("Could not open device %s\n"), dev->print_name());
479             Dmsg1(20, "Could not open device %s\n", dev->print_name());
480             free_dcr(dcr);
481             jcr->dcr = NULL;
482             continue;
483          }
484       }
485       if (device->cap_bits & CAP_AUTOMOUNT && dev->is_open()) {
486          switch (read_dev_volume_label(dcr)) {
487          case VOL_OK:
488             memcpy(&dev->VolCatInfo, &dcr->VolCatInfo, sizeof(dev->VolCatInfo));
489             break;
490          default:
491             Jmsg1(NULL, M_WARNING, 0, _("Could not mount device %s\n"), dev->print_name());
492             break;
493          }
494       }
495       free_dcr(dcr);
496       jcr->dcr = NULL;
497    }
498    free_jcr(jcr); 
499    init_done = true;
500    UnlockRes();
501    return NULL;
502 }
503
504
505 /* Clean up and then exit */
506 void terminate_stored(int sig)
507 {
508    static bool in_here = false;
509    DEVRES *device;
510    JCR *jcr;
511
512    if (in_here) {                     /* prevent loops */
513       exit(1);
514    }
515    in_here = true;
516
517    if (sig == SIGTERM) {              /* normal shutdown request? */
518       /*
519        * This is a normal shutdown request. We wiffle through
520        *   all open jobs canceling them and trying to wake
521        *   them up so that they will report back the correct
522        *   volume status.
523        */
524       foreach_jcr(jcr) {
525          BSOCK *fd;
526          if (jcr->JobId == 0) {
527             free_jcr(jcr);
528             continue;                 /* ignore console */
529          }
530          set_jcr_job_status(jcr, JS_Canceled);
531          fd = jcr->file_bsock;
532          if (fd) {
533             fd->timed_out = true;
534             Dmsg1(100, "term_stored killing JobId=%d\n", jcr->JobId);
535             pthread_kill(jcr->my_thread_id, TIMEOUT_SIGNAL);
536             /* ***FIXME*** wiffle through all dcrs */
537             if (jcr->dcr && jcr->dcr->dev && jcr->dcr->dev->dev_blocked) {
538                pthread_cond_broadcast(&jcr->dcr->dev->wait_next_vol);
539                pthread_cond_broadcast(&wait_device_release);
540             }
541             if (jcr->read_dcr && jcr->read_dcr->dev && jcr->read_dcr->dev->dev_blocked) {
542                pthread_cond_broadcast(&jcr->read_dcr->dev->wait_next_vol);
543                pthread_cond_broadcast(&wait_device_release);
544             }
545             bmicrosleep(0, 50000);
546          }
547          free_jcr(jcr);
548       }
549       bmicrosleep(0, 500000);         /* give them 1/2 sec to clean up */
550    }
551
552    write_state_file(me->working_directory, "bacula-sd", get_first_port_host_order(me->sdaddrs));
553    delete_pid_file(me->pid_directory, "bacula-sd", get_first_port_host_order(me->sdaddrs));
554
555    Dmsg1(200, "In terminate_stored() sig=%d\n", sig);
556
557    foreach_res(device, R_DEVICE) {
558       Dmsg1(10, "Term device %s\n", device->device_name);
559       if (device->dev) {
560          free_volume(device->dev);
561          device->dev->term();
562          device->dev = NULL;
563       } else {
564          Dmsg1(10, "No dev structure %s\n", device->device_name);
565       }
566    }
567
568    if (configfile) {
569       free(configfile);
570       configfile = NULL;
571    }
572    free_config_resources();
573
574    if (debug_level > 10) {
575       print_memory_pool_stats();
576    }
577    term_reservations_lock();
578    term_msg();
579    stop_watchdog();
580    cleanup_crypto();
581    free_volume_list();
582    close_memory_pool();
583
584    sm_dump(false);                    /* dump orphaned buffers */
585    exit(sig);
586 }