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();
36 static void cleanup_old_files();
38 extern "C" void *device_initialization(void *arg);
40 #define CONFIG_FILE "bacula-sd.conf" /* Default config file */
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;
51 static uint32_t VolSessionId = 0;
52 uint32_t VolSessionTime;
53 char *configfile = NULL;
54 bool init_done = false;
56 /* Global static variables */
57 static int foreground = 0;
58 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
59 static workq_t dird_workq; /* queue for processing connections */
65 "Copyright (C) 2000-2005 Kern Sibbald.\n"
66 "\nVersion: " VERSION " (" BDATE ")\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"
82 /*********************************************************************
84 * Main Bacula Unix Storage Daemon
87 int main (int argc, char *argv[])
90 int no_signals = FALSE;
91 int test_config = FALSE;
97 my_name_is(argc, argv, "bacula-sd");
100 daemon_start_time = time(NULL);
103 if (TAPE_BSIZE % B_DEV_BSIZE != 0 || TAPE_BSIZE / B_DEV_BSIZE == 0) {
104 Emsg2(M_ABORT, 0, "Tape block size (%d) not multiple of system size (%d)\n",
105 TAPE_BSIZE, B_DEV_BSIZE);
107 if (TAPE_BSIZE != (1 << (ffs(TAPE_BSIZE)-1))) {
108 Emsg1(M_ABORT, 0, "Tape block size (%d) is not a power of 2\n", TAPE_BSIZE);
111 while ((ch = getopt(argc, argv, "c:d:fg:pstu:v?")) != -1) {
113 case 'c': /* configuration file */
114 if (configfile != NULL) {
117 configfile = bstrdup(optarg);
120 case 'd': /* debug level */
121 debug_level = atoi(optarg);
122 if (debug_level <= 0) {
127 case 'f': /* run in foreground */
131 case 'g': /* set group id */
135 case 'p': /* proceed in spite of I/O errors */
139 case 's': /* no signals */
147 case 'u': /* set uid */
151 case 'v': /* verbose */
165 if (configfile != NULL) {
168 configfile = bstrdup(*argv);
176 init_signals(terminate_stored);
179 if (configfile == NULL) {
180 configfile = bstrdup(CONFIG_FILE);
183 parse_config(configfile);
185 if (init_tls() != 0) {
186 Jmsg((JCR *)NULL, M_ERROR_TERM, 0, _("TLS library initialization failed.\n"));
189 if (!check_resources()) {
190 Jmsg((JCR *)NULL, M_ERROR_TERM, 0, _("Please correct configuration file: %s\n"), configfile);
197 my_name_is(0, (char **)NULL, me->hdr.name); /* Set our real name */
200 daemon_start(); /* become daemon */
201 init_stack_dump(); /* pick up new pid */
204 create_pid_file(me->pid_directory, "bacula-sd", get_first_port_host_order(me->sdaddrs));
205 read_state_file(me->working_directory, "bacula-sd", get_first_port_host_order(me->sdaddrs));
212 /* Ensure that Volume Session Time and Id are both
213 * set and are both non-zero.
215 VolSessionTime = (long)daemon_start_time;
216 if (VolSessionTime == 0) { /* paranoid */
217 Jmsg0(NULL, M_ABORT, 0, _("Volume Session Time is ZERO!\n"));
220 init_python_interpreter(me->hdr.name, me->scripts_directory, "SDStartUp");
222 /* Make sure on Solaris we can run concurrent, watch dog + servers + misc */
223 set_thread_concurrency(me->max_concurrent_jobs * 2 + 4);
226 * Start the device allocation thread
228 create_volume_list(); /* do before device_init */
229 if (pthread_create(&thid, NULL, device_initialization, NULL) != 0) {
230 Emsg1(M_ABORT, 0, _("Unable to create thread. ERR=%s\n"), strerror(errno));
233 start_watchdog(); /* start watchdog thread */
234 init_jcr_subsystem(); /* start JCR watchdogs etc. */
236 /* Single server used for Director and File daemon */
237 bnet_thread_server(me->sdaddrs, me->max_concurrent_jobs * 2 + 1,
238 &dird_workq, handle_connection_request);
239 exit(1); /* to keep compiler quiet */
242 /* Return a new Session Id */
243 uint32_t newVolSessionId()
254 /* Check Configuration file for necessary info */
255 static int check_resources()
258 AUTOCHANGER *changer;
261 me = (STORES *)GetNextRes(R_STORAGE, NULL);
263 Jmsg1(NULL, M_ERROR, 0, _("No Storage resource defined in %s. Cannot continue.\n"),
268 if (GetNextRes(R_STORAGE, (RES *)me) != NULL) {
269 Jmsg1(NULL, M_ERROR, 0, _("Only one Storage resource permitted in %s\n"),
273 if (GetNextRes(R_DIRECTOR, NULL) == NULL) {
274 Jmsg1(NULL, M_ERROR, 0, _("No Director resource defined in %s. Cannot continue.\n"),
278 if (GetNextRes(R_DEVICE, NULL) == NULL){
279 Jmsg1(NULL, M_ERROR, 0, _("No Device resource defined in %s. Cannot continue.\n"),
285 me->messages = (MSGS *)GetNextRes(R_MSGS, NULL);
287 Jmsg1(NULL, M_ERROR, 0, _("No Messages resource defined in %s. Cannot continue.\n"),
293 if (!me->working_directory) {
294 Jmsg1(NULL, M_ERROR, 0, _("No Working Directory defined in %s. Cannot continue.\n"),
301 foreach_res(store, R_STORAGE) {
302 /* tls_require implies tls_enable */
303 if (store->tls_require) {
305 store->tls_enable = true;
307 Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
313 if (!store->tls_certfile && store->tls_enable) {
314 Jmsg(NULL, M_FATAL, 0, _("\"TLS Certificate\" file not defined for Storage \"%s\" in %s.\n"),
315 store->hdr.name, configfile);
319 if (!store->tls_keyfile && store->tls_enable) {
320 Jmsg(NULL, M_FATAL, 0, _("\"TLS Key\" file not defined for Storage \"%s\" in %s.\n"),
321 store->hdr.name, configfile);
325 if ((!store->tls_ca_certfile && !store->tls_ca_certdir) && store->tls_enable && store->tls_verify_peer) {
326 Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\""
327 " or \"TLS CA Certificate Dir\" are defined for Storage \"%s\" in %s."
328 " At least one CA certificate store is required"
329 " when using \"TLS Verify Peer\".\n"),
330 store->hdr.name, configfile);
334 /* If everything is well, attempt to initialize our per-resource TLS context */
335 if (OK && (store->tls_enable || store->tls_require)) {
336 /* Initialize TLS context:
337 * Args: CA certfile, CA certdir, Certfile, Keyfile,
338 * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
339 store->tls_ctx = new_tls_context(store->tls_ca_certfile,
340 store->tls_ca_certdir, store->tls_certfile,
341 store->tls_keyfile, NULL, NULL, store->tls_dhfile,
342 store->tls_verify_peer);
344 if (!store->tls_ctx) {
345 Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for Storage \"%s\" in %s.\n"),
346 store->hdr.name, configfile);
352 foreach_res(director, R_DIRECTOR) {
353 /* tls_require implies tls_enable */
354 if (director->tls_require) {
355 director->tls_enable = true;
358 if (!director->tls_certfile && director->tls_enable) {
359 Jmsg(NULL, M_FATAL, 0, _("\"TLS Certificate\" file not defined for Director \"%s\" in %s.\n"),
360 director->hdr.name, configfile);
364 if (!director->tls_keyfile && director->tls_enable) {
365 Jmsg(NULL, M_FATAL, 0, _("\"TLS Key\" file not defined for Director \"%s\" in %s.\n"),
366 director->hdr.name, configfile);
370 if ((!director->tls_ca_certfile && !director->tls_ca_certdir) && director->tls_enable && director->tls_verify_peer) {
371 Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\""
372 " or \"TLS CA Certificate Dir\" are defined for Director \"%s\" in %s."
373 " At least one CA certificate store is required"
374 " when using \"TLS Verify Peer\".\n"),
375 director->hdr.name, configfile);
379 /* If everything is well, attempt to initialize our per-resource TLS context */
380 if (OK && (director->tls_enable || director->tls_require)) {
381 /* Initialize TLS context:
382 * Args: CA certfile, CA certdir, Certfile, Keyfile,
383 * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
384 director->tls_ctx = new_tls_context(director->tls_ca_certfile,
385 director->tls_ca_certdir, director->tls_certfile,
386 director->tls_keyfile, NULL, NULL, director->tls_dhfile,
387 director->tls_verify_peer);
389 if (!director->tls_ctx) {
390 Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for Director \"%s\" in %s.\n"),
391 director->hdr.name, configfile);
397 /* Ensure that the media_type for each device is the same */
398 foreach_res(changer, R_AUTOCHANGER) {
400 char *media_type = NULL;
401 foreach_alist(device, changer->device) {
403 * If the device does not have a changer name or changer command
404 * defined, used the one from the Autochanger resource
406 if (!device->changer_name && changer->changer_name) {
407 device->changer_name = bstrdup(changer->changer_name);
409 if (!device->changer_command && changer->changer_command) {
410 device->changer_command = bstrdup(changer->changer_command);
412 if (!device->changer_name) {
413 Jmsg(NULL, M_ERROR, 0,
414 _("No Changer Name given for device %s. Cannot continue.\n"),
418 if (!device->changer_command) {
419 Jmsg(NULL, M_ERROR, 0,
420 _("No Changer Command given for device %s. Cannot continue.\n"),
425 if (media_type == NULL) {
426 media_type = device->media_type; /* get Media Type of first device */
429 /* Ensure that other devices Media Types are the same */
430 if (strcmp(media_type, device->media_type) != 0) {
431 Jmsg(NULL, M_ERROR, 0,
432 _("Media Type not the same for all devices in changer %s. Cannot continue.\n"),
441 close_msg(NULL); /* close temp message handler */
442 init_msg(NULL, me->messages); /* open daemon message handler */
443 set_working_directory(me->working_directory);
449 static void cleanup_old_files()
451 POOLMEM *cleanup = get_pool_memory(PM_MESSAGE);
452 int len = strlen(me->working_directory);
453 pm_strcpy(cleanup, "/bin/rm -f ");
454 pm_strcat(cleanup, me->working_directory);
455 if (len > 0 && me->working_directory[len-1] != '/') {
456 pm_strcat(cleanup, "/");
458 pm_strcat(cleanup, my_name);
459 pm_strcat(cleanup, "*.spool");
460 run_program(cleanup, 0, NULL);
461 free_pool_memory(cleanup);
466 * Here we attempt to init and open each device. This is done
467 * once at startup in a separate thread.
470 void *device_initialization(void *arg)
479 pthread_detach(pthread_self());
480 jcr = new_jcr(sizeof(JCR), stored_free_jcr);
481 jcr->JobType = JT_SYSTEM;
482 /* Initialize FD start condition variable */
483 int errstat = pthread_cond_init(&jcr->job_start_wait, NULL);
485 Jmsg1(jcr, M_ABORT, 0, _("Unable to init job cond variable: ERR=%s\n"), strerror(errstat));
488 foreach_res(device, R_DEVICE) {
489 Dmsg1(90, "calling init_dev %s\n", device->device_name);
490 device->dev = dev = init_dev(NULL, device);
491 Dmsg1(10, "SD init done %s\n", device->device_name);
493 Jmsg1(NULL, M_ERROR, 0, _("Could not initialize %s\n"), device->device_name);
497 dcr = new_dcr(jcr, dev);
498 if (dev->is_autochanger()) {
499 /* If autochanger set slot in dev sturcture */
500 get_autochanger_loaded_slot(dcr);
503 if (device->cap_bits & CAP_ALWAYSOPEN) {
504 Dmsg1(20, "calling first_open_device %s\n", dev->print_name());
505 if (!first_open_device(dcr)) {
506 Jmsg1(NULL, M_ERROR, 0, _("Could not open device %s\n"), dev->print_name());
507 Dmsg1(20, "Could not open device %s\n", dev->print_name());
517 if (device->cap_bits & CAP_AUTOMOUNT && dev->is_open()) {
518 switch (read_dev_volume_label(dcr)) {
520 memcpy(&dev->VolCatInfo, &dcr->VolCatInfo, sizeof(dev->VolCatInfo));
523 Jmsg1(NULL, M_WARNING, 0, _("Could not mount device %s\n"), dev->print_name());
536 /* Clean up and then exit */
537 void terminate_stored(int sig)
539 static bool in_here = false;
543 if (in_here) { /* prevent loops */
548 if (sig == SIGTERM) { /* normal shutdown request? */
550 * This is a normal shutdown request. We wiffle through
551 * all open jobs canceling them and trying to wake
552 * them up so that they will report back the correct
557 if (jcr->JobId == 0) {
559 continue; /* ignore console */
561 set_jcr_job_status(jcr, JS_Canceled);
562 fd = jcr->file_bsock;
564 fd->timed_out = true;
565 Dmsg1(100, "term_stored killing JobId=%d\n", jcr->JobId);
566 pthread_kill(jcr->my_thread_id, TIMEOUT_SIGNAL);
567 /* ***FIXME*** wiffle through all dcrs */
568 if (jcr->dcr && jcr->dcr->dev && jcr->dcr->dev->dev_blocked) {
569 pthread_cond_broadcast(&jcr->dcr->dev->wait_next_vol);
570 pthread_cond_broadcast(&wait_device_release);
572 bmicrosleep(0, 50000);
576 bmicrosleep(0, 500000); /* give them 1/2 sec to clean up */
579 write_state_file(me->working_directory, "bacula-sd", get_first_port_host_order(me->sdaddrs));
580 delete_pid_file(me->pid_directory, "bacula-sd", get_first_port_host_order(me->sdaddrs));
582 Dmsg1(200, "In terminate_stored() sig=%d\n", sig);
584 foreach_res(device, R_DEVICE) {
585 Dmsg1(10, "Term device %s\n", device->device_name);
587 free_volume(device->dev);
588 term_dev(device->dev);
590 Dmsg1(10, "No dev structure %s\n", device->device_name);
598 free_config_resources();
600 if (debug_level > 10) {
601 print_memory_pool_stats();
609 sm_dump(false); /* dump orphaned buffers */