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 ammended 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;
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 */
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"
80 /*********************************************************************
82 * Main Bacula Unix Storage Daemon
85 int main (int argc, char *argv[])
88 int no_signals = FALSE;
89 int test_config = FALSE;
95 my_name_is(argc, argv, "bacula-sd");
98 daemon_start_time = time(NULL);
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);
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);
109 while ((ch = getopt(argc, argv, "c:d:fg:pstu:v?")) != -1) {
111 case 'c': /* configuration file */
112 if (configfile != NULL) {
115 configfile = bstrdup(optarg);
118 case 'd': /* debug level */
119 debug_level = atoi(optarg);
120 if (debug_level <= 0) {
125 case 'f': /* run in foreground */
129 case 'g': /* set group id */
133 case 'p': /* proceed in spite of I/O errors */
137 case 's': /* no signals */
145 case 'u': /* set uid */
149 case 'v': /* verbose */
163 if (configfile != NULL) {
166 configfile = bstrdup(*argv);
174 init_signals(terminate_stored);
177 if (configfile == NULL) {
178 configfile = bstrdup(CONFIG_FILE);
181 parse_config(configfile);
183 if (init_tls() != 0) {
184 Jmsg((JCR *)NULL, M_ERROR_TERM, 0, _("TLS library initialization failed.\n"));
187 if (!check_resources()) {
188 Jmsg((JCR *)NULL, M_ERROR_TERM, 0, _("Please correct configuration file: %s\n"), configfile);
195 my_name_is(0, (char **)NULL, me->hdr.name); /* Set our real name */
198 daemon_start(); /* become daemon */
199 init_stack_dump(); /* pick up new pid */
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));
207 /* Ensure that Volume Session Time and Id are both
208 * set and are both non-zero.
210 VolSessionTime = (long)daemon_start_time;
211 if (VolSessionTime == 0) { /* paranoid */
212 Jmsg0(NULL, M_ABORT, 0, _("Volume Session Time is ZERO!\n"));
215 init_python_interpreter(me->hdr.name, me->scripts_directory, "SDStartUp");
217 /* Make sure on Solaris we can run concurrent, watch dog + servers + misc */
218 set_thread_concurrency(me->max_concurrent_jobs * 2 + 4);
220 create_volume_list();
222 * Start the device allocation thread
224 if (pthread_create(&thid, NULL, device_initialization, NULL) != 0) {
225 Emsg1(M_ABORT, 0, _("Unable to create thread. ERR=%s\n"), strerror(errno));
228 start_watchdog(); /* start watchdog thread */
230 init_jcr_subsystem(); /* start JCR watchdogs etc. */
233 * Sleep a bit to give device thread a chance to lock the resource
234 * chain before we start the server.
238 /* Wait for device initialization to complete */
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 */
248 /* Return a new Session Id */
249 uint32_t newVolSessionId()
260 /* Check Configuration file for necessary info */
261 static int check_resources()
264 AUTOCHANGER *changer;
268 me = (STORES *)GetNextRes(R_STORAGE, NULL);
270 Jmsg1(NULL, M_ERROR, 0, _("No Storage resource defined in %s. Cannot continue.\n"),
275 if (GetNextRes(R_STORAGE, (RES *)me) != NULL) {
276 Jmsg1(NULL, M_ERROR, 0, _("Only one Storage resource permitted in %s\n"),
280 if (GetNextRes(R_DIRECTOR, NULL) == NULL) {
281 Jmsg1(NULL, M_ERROR, 0, _("No Director resource defined in %s. Cannot continue.\n"),
285 if (GetNextRes(R_DEVICE, NULL) == NULL){
286 Jmsg1(NULL, M_ERROR, 0, _("No Device resource defined in %s. Cannot continue.\n"),
292 me->messages = (MSGS *)GetNextRes(R_MSGS, NULL);
294 Jmsg1(NULL, M_ERROR, 0, _("No Messages resource defined in %s. Cannot continue.\n"),
300 if (!me->working_directory) {
301 Jmsg1(NULL, M_ERROR, 0, _("No Working Directory defined in %s. Cannot continue.\n"),
308 foreach_res(store, R_STORAGE) {
309 /* tls_require implies tls_enable */
310 if (store->tls_require) {
312 store->tls_enable = true;
314 Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
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);
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);
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);
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);
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);
359 foreach_res(director, R_DIRECTOR) {
360 /* tls_require implies tls_enable */
361 if (director->tls_require) {
362 director->tls_enable = true;
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);
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);
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);
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);
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);
404 /* Ensure that the media_type for each device is the same */
405 foreach_res(changer, R_AUTOCHANGER) {
407 char *media_type = NULL;
408 foreach_alist(device, changer->device) {
410 * If the device does not have a changer name or changer command
411 * defined, used the one from the Autochanger resource
413 if (!device->changer_name && changer->changer_name) {
414 device->changer_name = bstrdup(changer->changer_name);
416 if (!device->changer_command && changer->changer_command) {
417 device->changer_command = bstrdup(changer->changer_command);
419 if (!device->changer_name) {
420 Jmsg(NULL, M_ERROR, 0,
421 _("No Changer Name given for device %s. Cannot continue.\n"),
425 if (!device->changer_command) {
426 Jmsg(NULL, M_ERROR, 0,
427 _("No Changer Command given for device %s. Cannot continue.\n"),
432 if (media_type == NULL) {
433 media_type = device->media_type; /* get Media Type of first device */
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"),
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);
457 * Here we attempt to init and open each device. This is done
458 * once at startup in a separate thread.
461 void *device_initialization(void *arg)
466 pthread_detach(pthread_self());
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);
473 Jmsg1(NULL, M_ERROR, 0, _("Could not initialize %s\n"), device->device_name);
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);
483 if (device->cap_bits & CAP_AUTOMOUNT && device->dev &&
484 device->dev->is_open()) {
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);
492 Jmsg1(jcr, M_ABORT, 0, _("Unable to init job cond variable: ERR=%s\n"), strerror(errstat));
494 dcr = new_dcr(jcr, device->dev);
495 switch (read_dev_volume_label(dcr)) {
497 memcpy(&dcr->dev->VolCatInfo, &dcr->VolCatInfo, sizeof(dcr->dev->VolCatInfo));
500 Jmsg1(NULL, M_WARNING, 0, _("Could not mount device %s\n"), device->device_name);
511 /* Clean up and then exit */
512 void terminate_stored(int sig)
514 static bool in_here = false;
518 if (in_here) { /* prevent loops */
523 if (sig == SIGTERM) { /* normal shutdown request? */
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
532 if (jcr->JobId == 0) {
534 continue; /* ignore console */
536 set_jcr_job_status(jcr, JS_Canceled);
537 fd = jcr->file_bsock;
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);
547 bmicrosleep(0, 50000);
551 bmicrosleep(0, 500000); /* give them 1/2 sec to clean up */
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));
557 Dmsg1(200, "In terminate_stored() sig=%d\n", sig);
559 foreach_res(device, R_DEVICE) {
561 free_volume(device->dev);
562 term_dev(device->dev);
570 free_config_resources();
572 if (debug_level > 10) {
573 print_memory_pool_stats();
581 sm_dump(false); /* dump orphaned buffers */