2 * Second generation Storage daemon.
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
13 Copyright (C) 2000-2005 Kern Sibbald
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.
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.
30 /* Imported functions */
33 /* Forward referenced functions */
34 void terminate_stored(int sig);
35 static int check_resources();
37 extern "C" void *device_initialization(void *arg);
39 #define CONFIG_FILE "bacula-sd.conf" /* Default config file */
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;
50 static uint32_t VolSessionId = 0;
51 uint32_t VolSessionTime;
52 char *configfile = NULL;
53 bool init_done = false;
55 /* Global static variables */
56 static int foreground = 0;
57 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
58 static workq_t dird_workq; /* queue for processing connections */
64 "Copyright (C) 2000-2005 Kern Sibbald.\n"
65 "\nVersion: " VERSION " (" BDATE ")\n\n"
66 "Usage: stored [options] [-c config_file] [config_file]\n"
67 " -c <file> use <file> as configuration file\n"
68 " -dnn set debug level to nn\n"
69 " -f run in foreground (for debugging)\n"
70 " -g <group> set groupid to group\n"
71 " -p proceed despite I/O errors\n"
72 " -s no signals (for debugging)\n"
73 " -t test - read config and exit\n"
74 " -u <user> userid to <user>\n"
75 " -v verbose user messages\n"
76 " -? print this message.\n"
81 /*********************************************************************
83 * Main Bacula Unix Storage Daemon
86 int main (int argc, char *argv[])
89 int no_signals = FALSE;
90 int test_config = FALSE;
96 my_name_is(argc, argv, "bacula-sd");
99 daemon_start_time = time(NULL);
102 if (TAPE_BSIZE % B_DEV_BSIZE != 0 || TAPE_BSIZE / B_DEV_BSIZE == 0) {
103 Emsg2(M_ABORT, 0, "Tape block size (%d) not multiple of system size (%d)\n",
104 TAPE_BSIZE, B_DEV_BSIZE);
106 if (TAPE_BSIZE != (1 << (ffs(TAPE_BSIZE)-1))) {
107 Emsg1(M_ABORT, 0, "Tape block size (%d) is not a power of 2\n", TAPE_BSIZE);
110 while ((ch = getopt(argc, argv, "c:d:fg:pstu:v?")) != -1) {
112 case 'c': /* configuration file */
113 if (configfile != NULL) {
116 configfile = bstrdup(optarg);
119 case 'd': /* debug level */
120 debug_level = atoi(optarg);
121 if (debug_level <= 0) {
126 case 'f': /* run in foreground */
130 case 'g': /* set group id */
134 case 'p': /* proceed in spite of I/O errors */
138 case 's': /* no signals */
146 case 'u': /* set uid */
150 case 'v': /* verbose */
164 if (configfile != NULL) {
167 configfile = bstrdup(*argv);
175 init_signals(terminate_stored);
178 if (configfile == NULL) {
179 configfile = bstrdup(CONFIG_FILE);
182 parse_config(configfile);
184 if (init_tls() != 0) {
185 Jmsg((JCR *)NULL, M_ERROR_TERM, 0, _("TLS library initialization failed.\n"));
188 if (!check_resources()) {
189 Jmsg((JCR *)NULL, M_ERROR_TERM, 0, _("Please correct configuration file: %s\n"), configfile);
196 my_name_is(0, (char **)NULL, me->hdr.name); /* Set our real name */
199 daemon_start(); /* become daemon */
200 init_stack_dump(); /* pick up new pid */
203 create_pid_file(me->pid_directory, "bacula-sd", get_first_port_host_order(me->sdaddrs));
204 read_state_file(me->working_directory, "bacula-sd", get_first_port_host_order(me->sdaddrs));
208 /* Ensure that Volume Session Time and Id are both
209 * set and are both non-zero.
211 VolSessionTime = (long)daemon_start_time;
212 if (VolSessionTime == 0) { /* paranoid */
213 Jmsg0(NULL, M_ABORT, 0, _("Volume Session Time is ZERO!\n"));
216 init_python_interpreter(me->hdr.name, me->scripts_directory, "SDStartUp");
218 /* Make sure on Solaris we can run concurrent, watch dog + servers + misc */
219 set_thread_concurrency(me->max_concurrent_jobs * 2 + 4);
222 * Start the device allocation thread
224 create_volume_list(); /* do before device_init */
225 if (pthread_create(&thid, NULL, device_initialization, NULL) != 0) {
226 Emsg1(M_ABORT, 0, _("Unable to create thread. ERR=%s\n"), strerror(errno));
229 start_watchdog(); /* start watchdog thread */
230 init_jcr_subsystem(); /* start JCR watchdogs etc. */
232 /* Single server used for Director and File daemon */
233 bnet_thread_server(me->sdaddrs, me->max_concurrent_jobs * 2 + 1,
234 &dird_workq, handle_connection_request);
235 exit(1); /* to keep compiler quiet */
238 /* Return a new Session Id */
239 uint32_t newVolSessionId()
250 /* Check Configuration file for necessary info */
251 static int check_resources()
254 AUTOCHANGER *changer;
257 me = (STORES *)GetNextRes(R_STORAGE, NULL);
259 Jmsg1(NULL, M_ERROR, 0, _("No Storage resource defined in %s. Cannot continue.\n"),
264 if (GetNextRes(R_STORAGE, (RES *)me) != NULL) {
265 Jmsg1(NULL, M_ERROR, 0, _("Only one Storage resource permitted in %s\n"),
269 if (GetNextRes(R_DIRECTOR, NULL) == NULL) {
270 Jmsg1(NULL, M_ERROR, 0, _("No Director resource defined in %s. Cannot continue.\n"),
274 if (GetNextRes(R_DEVICE, NULL) == NULL){
275 Jmsg1(NULL, M_ERROR, 0, _("No Device resource defined in %s. Cannot continue.\n"),
281 me->messages = (MSGS *)GetNextRes(R_MSGS, NULL);
283 Jmsg1(NULL, M_ERROR, 0, _("No Messages resource defined in %s. Cannot continue.\n"),
289 if (!me->working_directory) {
290 Jmsg1(NULL, M_ERROR, 0, _("No Working Directory defined in %s. Cannot continue.\n"),
297 foreach_res(store, R_STORAGE) {
298 /* tls_require implies tls_enable */
299 if (store->tls_require) {
301 store->tls_enable = true;
303 Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
309 if (!store->tls_certfile && store->tls_enable) {
310 Jmsg(NULL, M_FATAL, 0, _("\"TLS Certificate\" file not defined for Storage \"%s\" in %s.\n"),
311 store->hdr.name, configfile);
315 if (!store->tls_keyfile && store->tls_enable) {
316 Jmsg(NULL, M_FATAL, 0, _("\"TLS Key\" file not defined for Storage \"%s\" in %s.\n"),
317 store->hdr.name, configfile);
321 if ((!store->tls_ca_certfile && !store->tls_ca_certdir) && store->tls_enable && store->tls_verify_peer) {
322 Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\""
323 " or \"TLS CA Certificate Dir\" are defined for Storage \"%s\" in %s."
324 " At least one CA certificate store is required"
325 " when using \"TLS Verify Peer\".\n"),
326 store->hdr.name, configfile);
330 /* If everything is well, attempt to initialize our per-resource TLS context */
331 if (OK && (store->tls_enable || store->tls_require)) {
332 /* Initialize TLS context:
333 * Args: CA certfile, CA certdir, Certfile, Keyfile,
334 * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
335 store->tls_ctx = new_tls_context(store->tls_ca_certfile,
336 store->tls_ca_certdir, store->tls_certfile,
337 store->tls_keyfile, NULL, NULL, store->tls_dhfile,
338 store->tls_verify_peer);
340 if (!store->tls_ctx) {
341 Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for Storage \"%s\" in %s.\n"),
342 store->hdr.name, configfile);
348 foreach_res(director, R_DIRECTOR) {
349 /* tls_require implies tls_enable */
350 if (director->tls_require) {
351 director->tls_enable = true;
354 if (!director->tls_certfile && director->tls_enable) {
355 Jmsg(NULL, M_FATAL, 0, _("\"TLS Certificate\" file not defined for Director \"%s\" in %s.\n"),
356 director->hdr.name, configfile);
360 if (!director->tls_keyfile && director->tls_enable) {
361 Jmsg(NULL, M_FATAL, 0, _("\"TLS Key\" file not defined for Director \"%s\" in %s.\n"),
362 director->hdr.name, configfile);
366 if ((!director->tls_ca_certfile && !director->tls_ca_certdir) && director->tls_enable && director->tls_verify_peer) {
367 Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\""
368 " or \"TLS CA Certificate Dir\" are defined for Director \"%s\" in %s."
369 " At least one CA certificate store is required"
370 " when using \"TLS Verify Peer\".\n"),
371 director->hdr.name, configfile);
375 /* If everything is well, attempt to initialize our per-resource TLS context */
376 if (OK && (director->tls_enable || director->tls_require)) {
377 /* Initialize TLS context:
378 * Args: CA certfile, CA certdir, Certfile, Keyfile,
379 * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
380 director->tls_ctx = new_tls_context(director->tls_ca_certfile,
381 director->tls_ca_certdir, director->tls_certfile,
382 director->tls_keyfile, NULL, NULL, director->tls_dhfile,
383 director->tls_verify_peer);
385 if (!director->tls_ctx) {
386 Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for Director \"%s\" in %s.\n"),
387 director->hdr.name, configfile);
393 /* Ensure that the media_type for each device is the same */
394 foreach_res(changer, R_AUTOCHANGER) {
396 char *media_type = NULL;
397 foreach_alist(device, changer->device) {
399 * If the device does not have a changer name or changer command
400 * defined, used the one from the Autochanger resource
402 if (!device->changer_name && changer->changer_name) {
403 device->changer_name = bstrdup(changer->changer_name);
405 if (!device->changer_command && changer->changer_command) {
406 device->changer_command = bstrdup(changer->changer_command);
408 if (!device->changer_name) {
409 Jmsg(NULL, M_ERROR, 0,
410 _("No Changer Name given for device %s. Cannot continue.\n"),
414 if (!device->changer_command) {
415 Jmsg(NULL, M_ERROR, 0,
416 _("No Changer Command given for device %s. Cannot continue.\n"),
421 if (media_type == NULL) {
422 media_type = device->media_type; /* get Media Type of first device */
425 /* Ensure that other devices Media Types are the same */
426 if (strcmp(media_type, device->media_type) != 0) {
427 Jmsg(NULL, M_ERROR, 0,
428 _("Media Type not the same for all devices in changer %s. Cannot continue.\n"),
437 close_msg(NULL); /* close temp message handler */
438 init_msg(NULL, me->messages); /* open daemon message handler */
439 set_working_directory(me->working_directory);
446 * Here we attempt to init and open each device. This is done
447 * once at startup in a separate thread.
450 void *device_initialization(void *arg)
459 pthread_detach(pthread_self());
460 jcr = new_jcr(sizeof(JCR), stored_free_jcr);
461 jcr->JobType = JT_SYSTEM;
462 /* Initialize FD start condition variable */
463 int errstat = pthread_cond_init(&jcr->job_start_wait, NULL);
465 Jmsg1(jcr, M_ABORT, 0, _("Unable to init job cond variable: ERR=%s\n"), strerror(errstat));
468 foreach_res(device, R_DEVICE) {
469 Dmsg1(90, "calling init_dev %s\n", device->device_name);
470 device->dev = dev = init_dev(NULL, device);
471 Dmsg1(10, "SD init done %s\n", device->device_name);
473 Jmsg1(NULL, M_ERROR, 0, _("Could not initialize %s\n"), device->device_name);
477 dcr = new_dcr(jcr, dev);
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());
490 if (device->cap_bits & CAP_AUTOMOUNT && dev->is_open()) {
491 switch (read_dev_volume_label(dcr)) {
493 memcpy(&dev->VolCatInfo, &dcr->VolCatInfo, sizeof(dev->VolCatInfo));
496 Jmsg1(NULL, M_WARNING, 0, _("Could not mount device %s\n"), dev->print_name());
509 /* Clean up and then exit */
510 void terminate_stored(int sig)
512 static bool in_here = false;
516 if (in_here) { /* prevent loops */
521 if (sig == SIGTERM) { /* normal shutdown request? */
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
530 if (jcr->JobId == 0) {
532 continue; /* ignore console */
534 set_jcr_job_status(jcr, JS_Canceled);
535 fd = jcr->file_bsock;
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);
545 bmicrosleep(0, 50000);
549 bmicrosleep(0, 500000); /* give them 1/2 sec to clean up */
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));
555 Dmsg1(200, "In terminate_stored() sig=%d\n", sig);
557 foreach_res(device, R_DEVICE) {
558 Dmsg1(10, "Term device %s\n", device->device_name);
560 free_volume(device->dev);
561 term_dev(device->dev);
563 Dmsg1(10, "No dev structure %s\n", device->device_name);
571 free_config_resources();
573 if (debug_level > 10) {
574 print_memory_pool_stats();
582 sm_dump(false); /* dump orphaned buffers */