]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/stored/stored.c
ebl Make SD plugins working
[bacula/bacula] / bacula / src / stored / stored.c
1 /*
2    Bacula® - The Network Backup Solution
3
4    Copyright (C) 2000-2008 Free Software Foundation Europe e.V.
5
6    The main author of Bacula is Kern Sibbald, with contributions from
7    many others, a complete list can be found in the file AUTHORS.
8    This program is Free Software; you can redistribute it and/or
9    modify it under the terms of version two of the GNU General Public
10    License as published by the Free Software Foundation and included
11    in the file LICENSE.
12
13    This program is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16    General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21    02110-1301, USA.
22
23    Bacula® is a registered trademark of Kern Sibbald.
24    The licensor of Bacula is the Free Software Foundation Europe
25    (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
26    Switzerland, email:ftf@fsfeurope.org.
27 */
28 /*
29  * Second generation Storage daemon.
30  *
31  *  Kern Sibbald, MM
32  *
33  * It accepts a number of simple commands from the File daemon
34  * and acts on them. When a request to append data is made,
35  * it opens a data channel and accepts data from the
36  * File daemon.
37  *
38  *   Version $Id$
39  *
40  */
41
42 #include "bacula.h"
43 #include "stored.h"
44
45 /* TODO: fix problem with bls, bextract
46  * that use findlib and already declare
47  * filed plugins 
48  */
49 #include "sd_plugins.h"         
50
51 #ifdef HAVE_PYTHON
52
53 #undef _POSIX_C_SOURCE
54 #include <Python.h>
55
56 #include "lib/pythonlib.h"
57
58 /* Imported Functions */
59 extern PyObject *job_getattr(PyObject *self, char *attrname);
60 extern int job_setattr(PyObject *self, char *attrname, PyObject *value);
61
62 #endif /* HAVE_PYTHON */
63
64 /* Imported functions */
65 extern bool parse_sd_config(CONFIG *config, const char *configfile, int exit_code);
66
67 /* Forward referenced functions */
68 void terminate_stored(int sig);
69 static int check_resources();
70 static void cleanup_old_files();
71
72 extern "C" void *device_initialization(void *arg);
73
74 #define CONFIG_FILE "bacula-sd.conf"  /* Default config file */
75
76 /* Global variables exported */
77 char OK_msg[]   = "3000 OK\n";
78 char TERM_msg[] = "3999 Terminate\n";
79 STORES *me = NULL;                    /* our Global resource */
80 bool forge_on = false;                /* proceed inspite of I/O errors */
81 pthread_mutex_t device_release_mutex = PTHREAD_MUTEX_INITIALIZER;
82 pthread_cond_t wait_device_release = PTHREAD_COND_INITIALIZER;
83 void *start_heap;
84
85
86 static uint32_t VolSessionId = 0;
87 uint32_t VolSessionTime;
88 char *configfile = NULL;
89 bool init_done = false;
90
91 /* Global static variables */
92 static bool foreground = 0;
93 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
94 static workq_t dird_workq;            /* queue for processing connections */
95 static CONFIG *config;
96
97
98 static void usage()
99 {
100    fprintf(stderr, _(
101 PROG_COPYRIGHT
102 "\nVersion: %s (%s)\n\n"
103 "Usage: stored [options] [-c config_file] [config_file]\n"
104 "        -c <file>   use <file> as configuration file\n"
105 "        -d <nn>     set debug level to <nn>\n"
106 "        -dt         print timestamp in debug output\n"
107 "        -f          run in foreground (for debugging)\n"
108 "        -g <group>  set groupid to group\n"
109 "        -p          proceed despite I/O errors\n"
110 "        -s          no signals (for debugging)\n"
111 "        -t          test - read config and exit\n"
112 "        -u <user>   userid to <user>\n"
113 "        -v          verbose user messages\n"
114 "        -?          print this message.\n"
115 "\n"), 2000, VERSION, BDATE);
116    exit(1);
117 }
118
119 /*********************************************************************
120  *
121  *  Main Bacula Unix Storage Daemon
122  *
123  */
124 #if defined(HAVE_WIN32)
125 #define main BaculaMain
126 #endif
127
128 int main (int argc, char *argv[])
129 {
130    int ch;
131    bool no_signals = false;
132    bool test_config = false;
133    pthread_t thid;
134    char *uid = NULL;
135    char *gid = NULL;
136 #ifdef HAVE_PYTHON
137    init_python_interpreter_args python_args;
138 #endif /* HAVE_PYTHON */
139
140    start_heap = sbrk(0);
141    setlocale(LC_ALL, "");
142    bindtextdomain("bacula", LOCALEDIR);
143    textdomain("bacula");
144
145    init_stack_dump();
146    my_name_is(argc, argv, "bacula-sd");
147    init_msg(NULL, NULL);
148    daemon_start_time = time(NULL);
149
150    /* Sanity checks */
151    if (TAPE_BSIZE % B_DEV_BSIZE != 0 || TAPE_BSIZE / B_DEV_BSIZE == 0) {
152       Emsg2(M_ABORT, 0, _("Tape block size (%d) not multiple of system size (%d)\n"),
153          TAPE_BSIZE, B_DEV_BSIZE);
154    }
155    if (TAPE_BSIZE != (1 << (ffs(TAPE_BSIZE)-1))) {
156       Emsg1(M_ABORT, 0, _("Tape block size (%d) is not a power of 2\n"), TAPE_BSIZE);
157    }
158
159    while ((ch = getopt(argc, argv, "c:d:fg:pstu:v?")) != -1) {
160       switch (ch) {
161       case 'c':                    /* configuration file */
162          if (configfile != NULL) {
163             free(configfile);
164          }
165          configfile = bstrdup(optarg);
166          break;
167
168       case 'd':                    /* debug level */
169          if (*optarg == 't') {
170             dbg_timestamp = true;
171          } else {
172             debug_level = atoi(optarg);
173             if (debug_level <= 0) {
174                debug_level = 1;
175             }
176          }
177          break;
178
179       case 'f':                    /* run in foreground */
180          foreground = true;
181          break;
182
183       case 'g':                    /* set group id */
184          gid = optarg;
185          break;
186
187       case 'p':                    /* proceed in spite of I/O errors */
188          forge_on = true;
189          break;
190
191       case 's':                    /* no signals */
192          no_signals = true;
193          break;
194
195       case 't':
196          test_config = true;
197          break;
198
199       case 'u':                    /* set uid */
200          uid = optarg;
201          break;
202
203       case 'v':                    /* verbose */
204          verbose++;
205          break;
206
207       case '?':
208       default:
209          usage();
210          break;
211       }
212    }
213    argc -= optind;
214    argv += optind;
215
216    if (argc) {
217       if (configfile != NULL) {
218          free(configfile);
219       }
220       configfile = bstrdup(*argv);
221       argc--;
222       argv++;
223    }
224    if (argc)
225       usage();
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    if (!foreground) {
255       daemon_start();                 /* become daemon */
256       init_stack_dump();              /* pick up new pid */
257    }
258
259    create_pid_file(me->pid_directory, "bacula-sd", get_first_port_host_order(me->sdaddrs));
260    read_state_file(me->working_directory, "bacula-sd", get_first_port_host_order(me->sdaddrs));
261
262    load_dir_plugins(me->plugin_directory);
263
264    drop(uid, gid);
265
266    cleanup_old_files();
267
268
269    /* Ensure that Volume Session Time and Id are both
270     * set and are both non-zero.
271     */
272    VolSessionTime = (uint32_t)daemon_start_time;
273    if (VolSessionTime == 0) { /* paranoid */
274       Jmsg0(NULL, M_ABORT, 0, _("Volume Session Time is ZERO!\n"));
275    }
276
277 #ifdef HAVE_PYTHON
278    python_args.progname = me->hdr.name;
279    python_args.scriptdir = me->scripts_directory;
280    python_args.modulename = "SDStartUp";
281    python_args.configfile = configfile;
282    python_args.workingdir = me->working_directory;
283    python_args.job_getattr = job_getattr;
284    python_args.job_setattr = job_setattr;
285
286    init_python_interpreter(&python_args);
287 #endif /* HAVE_PYTHON */
288
289    /* Make sure on Solaris we can run concurrent, watch dog + servers + misc */
290    set_thread_concurrency(me->max_concurrent_jobs * 2 + 4);
291
292     /*
293      * Start the device allocation thread
294      */
295    create_volume_lists();             /* do before device_init */
296    if (pthread_create(&thid, NULL, device_initialization, NULL) != 0) {
297       berrno be;
298       Emsg1(M_ABORT, 0, _("Unable to create thread. ERR=%s\n"), be.bstrerror());
299    }
300
301    start_watchdog();                  /* start watchdog thread */
302    init_jcr_subsystem();              /* start JCR watchdogs etc. */
303
304    /* Single server used for Director and File daemon */
305    bnet_thread_server(me->sdaddrs, me->max_concurrent_jobs * 2 + 1,
306                       &dird_workq, handle_connection_request);
307    exit(1);                           /* to keep compiler quiet */
308 }
309
310 /* Return a new Session Id */
311 uint32_t newVolSessionId()
312 {
313    uint32_t Id;
314
315    P(mutex);
316    VolSessionId++;
317    Id = VolSessionId;
318    V(mutex);
319    return Id;
320 }
321
322 /* Check Configuration file for necessary info */
323 static int check_resources()
324 {
325    bool OK = true;
326    bool tls_needed;
327
328
329    me = (STORES *)GetNextRes(R_STORAGE, NULL);
330    if (!me) {
331       Jmsg1(NULL, M_ERROR, 0, _("No Storage resource defined in %s. Cannot continue.\n"),
332          configfile);
333       OK = false;
334    }
335
336    if (GetNextRes(R_STORAGE, (RES *)me) != NULL) {
337       Jmsg1(NULL, M_ERROR, 0, _("Only one Storage resource permitted in %s\n"),
338          configfile);
339       OK = false;
340    }
341    if (GetNextRes(R_DIRECTOR, NULL) == NULL) {
342       Jmsg1(NULL, M_ERROR, 0, _("No Director resource defined in %s. Cannot continue.\n"),
343          configfile);
344       OK = false;
345    }
346    if (GetNextRes(R_DEVICE, NULL) == NULL){
347       Jmsg1(NULL, M_ERROR, 0, _("No Device resource defined in %s. Cannot continue.\n"),
348            configfile);
349       OK = false;
350    }
351
352    if (!me->messages) {
353       me->messages = (MSGS *)GetNextRes(R_MSGS, NULL);
354       if (!me->messages) {
355          Jmsg1(NULL, M_ERROR, 0, _("No Messages resource defined in %s. Cannot continue.\n"),
356             configfile);
357          OK = false;
358       }
359    }
360
361    if (!me->working_directory) {
362       Jmsg1(NULL, M_ERROR, 0, _("No Working Directory defined in %s. Cannot continue.\n"),
363          configfile);
364       OK = false;
365    }
366
367    DIRRES *director;
368    STORES *store;
369    foreach_res(store, R_STORAGE) { 
370       /* tls_require implies tls_enable */
371       if (store->tls_require) {
372          if (have_tls) {
373             store->tls_enable = true;
374          } else {
375             Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
376             OK = false;
377             continue;
378          }
379       }
380
381       tls_needed = store->tls_enable || store->tls_authenticate;
382
383       if (!store->tls_certfile && tls_needed) {
384          Jmsg(NULL, M_FATAL, 0, _("\"TLS Certificate\" file not defined for Storage \"%s\" in %s.\n"),
385               store->hdr.name, configfile);
386          OK = false;
387       }
388
389       if (!store->tls_keyfile && tls_needed) {
390          Jmsg(NULL, M_FATAL, 0, _("\"TLS Key\" file not defined for Storage \"%s\" in %s.\n"),
391               store->hdr.name, configfile);
392          OK = false;
393       }
394
395       if ((!store->tls_ca_certfile && !store->tls_ca_certdir) && tls_needed && store->tls_verify_peer) {
396          Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\""
397               " or \"TLS CA Certificate Dir\" are defined for Storage \"%s\" in %s."
398               " At least one CA certificate store is required"
399               " when using \"TLS Verify Peer\".\n"),
400               store->hdr.name, configfile);
401          OK = false;
402       }
403
404       /* If everything is well, attempt to initialize our per-resource TLS context */
405       if (OK && (tls_needed || store->tls_require)) {
406          /* Initialize TLS context:
407           * Args: CA certfile, CA certdir, Certfile, Keyfile,
408           * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
409          store->tls_ctx = new_tls_context(store->tls_ca_certfile,
410             store->tls_ca_certdir, store->tls_certfile,
411             store->tls_keyfile, NULL, NULL, store->tls_dhfile,
412             store->tls_verify_peer);
413
414          if (!store->tls_ctx) { 
415             Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for Storage \"%s\" in %s.\n"),
416                  store->hdr.name, configfile);
417             OK = false;
418          }
419       }
420    }
421
422    foreach_res(director, R_DIRECTOR) { 
423       /* tls_require implies tls_enable */
424       if (director->tls_require) {
425          director->tls_enable = true;
426       }
427
428       tls_needed = director->tls_enable || director->tls_authenticate;
429
430       if (!director->tls_certfile && tls_needed) {
431          Jmsg(NULL, M_FATAL, 0, _("\"TLS Certificate\" file not defined for Director \"%s\" in %s.\n"),
432               director->hdr.name, configfile);
433          OK = false;
434       }
435
436       if (!director->tls_keyfile && tls_needed) {
437          Jmsg(NULL, M_FATAL, 0, _("\"TLS Key\" file not defined for Director \"%s\" in %s.\n"),
438               director->hdr.name, configfile);
439          OK = false;
440       }
441
442       if ((!director->tls_ca_certfile && !director->tls_ca_certdir) && tls_needed && director->tls_verify_peer) {
443          Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\""
444               " or \"TLS CA Certificate Dir\" are defined for Director \"%s\" in %s."
445               " At least one CA certificate store is required"
446               " when using \"TLS Verify Peer\".\n"),
447               director->hdr.name, configfile);
448          OK = false;
449       }
450
451       /* If everything is well, attempt to initialize our per-resource TLS context */
452       if (OK && (tls_needed || director->tls_require)) {
453          /* Initialize TLS context:
454           * Args: CA certfile, CA certdir, Certfile, Keyfile,
455           * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
456          director->tls_ctx = new_tls_context(director->tls_ca_certfile,
457             director->tls_ca_certdir, director->tls_certfile,
458             director->tls_keyfile, NULL, NULL, director->tls_dhfile,
459             director->tls_verify_peer);
460
461          if (!director->tls_ctx) { 
462             Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for Director \"%s\" in %s.\n"),
463                  director->hdr.name, configfile);
464             OK = false;
465          }
466       }
467    }
468
469    OK = init_autochangers();
470
471    
472    if (OK) {
473       close_msg(NULL);                   /* close temp message handler */
474       init_msg(NULL, me->messages);      /* open daemon message handler */
475       set_working_directory(me->working_directory);
476    }
477
478    return OK;
479 }
480
481 static void cleanup_old_files()
482 {
483    POOLMEM *cleanup = get_pool_memory(PM_MESSAGE);
484    POOLMEM *results = get_pool_memory(PM_MESSAGE);
485    int len = strlen(me->working_directory);
486 #if defined(HAVE_WIN32)
487    pm_strcpy(cleanup, "del /q ");
488 #else
489    pm_strcpy(cleanup, "/bin/rm -f ");
490 #endif
491    pm_strcat(cleanup, me->working_directory);
492    if (len > 0 && !IsPathSeparator(me->working_directory[len-1])) {
493       pm_strcat(cleanup, "/");
494    }
495    pm_strcat(cleanup, my_name);
496    pm_strcat(cleanup, "*.spool");
497    run_program(cleanup, 0, results);
498    free_pool_memory(cleanup);
499    free_pool_memory(results);
500 }
501
502
503 /*
504  * Here we attempt to init and open each device. This is done
505  *  once at startup in a separate thread.
506  */
507 extern "C"
508 void *device_initialization(void *arg)
509 {
510    DEVRES *device;
511    DCR *dcr;
512    JCR *jcr;
513    DEVICE *dev;
514
515    LockRes();
516
517    pthread_detach(pthread_self());
518    jcr = new_jcr(sizeof(JCR), stored_free_jcr);
519    jcr->set_JobType(JT_SYSTEM);
520    /* Initialize FD start condition variable */
521    int errstat = pthread_cond_init(&jcr->job_start_wait, NULL);
522    if (errstat != 0) {
523       berrno be;
524       Jmsg1(jcr, M_ABORT, 0, _("Unable to init job cond variable: ERR=%s\n"), be.bstrerror(errstat));
525    }
526
527    foreach_res(device, R_DEVICE) {
528       Dmsg1(90, "calling init_dev %s\n", device->device_name);
529       dev = init_dev(NULL, device);
530       Dmsg1(10, "SD init done %s\n", device->device_name);
531       if (!dev) {
532          Jmsg1(NULL, M_ERROR, 0, _("Could not initialize %s\n"), device->device_name);
533          continue;
534       }
535
536       jcr->dcr = dcr = new_dcr(jcr, NULL, dev);
537       if (dev->is_autochanger()) {
538          /* If autochanger set slot in dev sturcture */
539          get_autochanger_loaded_slot(dcr);
540       }
541
542       if (device->cap_bits & CAP_ALWAYSOPEN) {
543          Dmsg1(20, "calling first_open_device %s\n", dev->print_name());
544          if (!first_open_device(dcr)) {
545             Jmsg1(NULL, M_ERROR, 0, _("Could not open device %s\n"), dev->print_name());
546             Dmsg1(20, "Could not open device %s\n", dev->print_name());
547             free_dcr(dcr);
548             jcr->dcr = NULL;
549             continue;
550          }
551       }
552       if (device->cap_bits & CAP_AUTOMOUNT && dev->is_open()) {
553          switch (read_dev_volume_label(dcr)) {
554          case VOL_OK:
555             memcpy(&dev->VolCatInfo, &dcr->VolCatInfo, sizeof(dev->VolCatInfo));
556             volume_unused(dcr);             /* mark volume "released" */
557             break;
558          default:
559             Jmsg1(NULL, M_WARNING, 0, _("Could not mount device %s\n"), dev->print_name());
560             break;
561          }
562       }
563       free_dcr(dcr);
564       jcr->dcr = NULL;
565    }
566 #ifdef xxx
567    if (jcr->dcr) {
568       Dmsg1(000, "free_dcr=%p\n", jcr->dcr);
569       free_dcr(jcr->dcr);
570       jcr->dcr = NULL;
571    }
572 #endif
573    free_jcr(jcr); 
574    init_done = true;
575    UnlockRes();
576    return NULL;
577 }
578
579
580 /* Clean up and then exit */
581 void terminate_stored(int sig)
582 {
583    static bool in_here = false;
584    DEVRES *device;
585    JCR *jcr;
586
587    if (in_here) {                     /* prevent loops */
588       bmicrosleep(2, 0);              /* yield */
589       exit(1);
590    }
591    in_here = true;
592    debug_level = 0;                   /* turn off any debug */
593    stop_watchdog();
594
595    if (sig == SIGTERM) {              /* normal shutdown request? */
596       /*
597        * This is a normal shutdown request. We wiffle through
598        *   all open jobs canceling them and trying to wake
599        *   them up so that they will report back the correct
600        *   volume status.
601        */
602       foreach_jcr(jcr) {
603          BSOCK *fd;
604          if (jcr->JobId == 0) {
605             free_jcr(jcr);
606             continue;                 /* ignore console */
607          }
608          set_jcr_job_status(jcr, JS_Canceled);
609          fd = jcr->file_bsock;
610          if (fd) {
611             fd->set_timed_out();
612             Dmsg1(100, "term_stored killing JobId=%d\n", jcr->JobId);
613             pthread_kill(jcr->my_thread_id, TIMEOUT_SIGNAL);
614             /* ***FIXME*** wiffle through all dcrs */
615             if (jcr->dcr && jcr->dcr->dev && jcr->dcr->dev->blocked()) {
616                pthread_cond_broadcast(&jcr->dcr->dev->wait_next_vol);
617                Dmsg1(100, "JobId=%u broadcast wait_device_release\n", (uint32_t)jcr->JobId);
618                pthread_cond_broadcast(&wait_device_release);
619             }
620             if (jcr->read_dcr && jcr->read_dcr->dev && jcr->read_dcr->dev->blocked()) {
621                pthread_cond_broadcast(&jcr->read_dcr->dev->wait_next_vol);
622                pthread_cond_broadcast(&wait_device_release);
623             }
624             bmicrosleep(0, 50000);
625          }
626          free_jcr(jcr);
627       }
628       bmicrosleep(0, 500000);         /* give them 1/2 sec to clean up */
629    }
630
631    write_state_file(me->working_directory, "bacula-sd", get_first_port_host_order(me->sdaddrs));
632    delete_pid_file(me->pid_directory, "bacula-sd", get_first_port_host_order(me->sdaddrs));
633
634    Dmsg1(200, "In terminate_stored() sig=%d\n", sig);
635
636    unload_plugins();
637    free_volume_lists();
638
639    foreach_res(device, R_DEVICE) {
640       Dmsg1(10, "Term device %s\n", device->device_name);
641       if (device->dev) {
642          device->dev->clear_volhdr();
643          device->dev->term();
644          device->dev = NULL;
645       } else {
646          Dmsg1(10, "No dev structure %s\n", device->device_name);
647       }
648    }
649
650    if (configfile) {
651       free(configfile);
652       configfile = NULL;
653    }
654    if (config) {
655       config->free_resources();
656       free(config);
657       config = NULL;
658   }
659
660    if (debug_level > 10) {
661       print_memory_pool_stats();
662    }
663    term_msg();
664    cleanup_crypto();
665    term_reservations_lock();
666    close_memory_pool();
667
668    sm_dump(false);                    /* dump orphaned buffers */
669    exit(sig);
670 }