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