2 Bacula® - The Network Backup Solution
4 Copyright (C) 2000-2008 Free Software Foundation Europe e.V.
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
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.
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
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.
29 * Second generation Storage daemon.
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
45 /* Imported functions */
46 extern bool parse_sd_config(CONFIG *config, const char *configfile, int exit_code);
48 /* Forward referenced functions */
49 void terminate_stored(int sig);
50 static int check_resources();
51 static void cleanup_old_files();
53 extern "C" void *device_initialization(void *arg);
55 #define CONFIG_FILE "bacula-sd.conf" /* Default config file */
57 /* Global variables exported */
58 char OK_msg[] = "3000 OK\n";
59 char TERM_msg[] = "3999 Terminate\n";
60 STORES *me = NULL; /* our Global resource */
61 bool forge_on = false; /* proceed inspite of I/O errors */
62 pthread_mutex_t device_release_mutex = PTHREAD_MUTEX_INITIALIZER;
63 pthread_cond_t wait_device_release = PTHREAD_COND_INITIALIZER;
67 static uint32_t VolSessionId = 0;
68 uint32_t VolSessionTime;
69 char *configfile = NULL;
70 bool init_done = false;
72 /* Global static variables */
73 static bool foreground = 0;
74 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
75 static workq_t dird_workq; /* queue for processing connections */
76 static CONFIG *config;
83 "\nVersion: %s (%s)\n\n"
84 "Usage: stored [options] [-c config_file] [config_file]\n"
85 " -c <file> use <file> as configuration file\n"
86 " -d <nn> set debug level to <nn>\n"
87 " -dt print timestamp in debug output\n"
88 " -f run in foreground (for debugging)\n"
89 " -g <group> set groupid to group\n"
90 " -p proceed despite I/O errors\n"
91 " -s no signals (for debugging)\n"
92 " -t test - read config and exit\n"
93 " -u <user> userid to <user>\n"
94 " -v verbose user messages\n"
95 " -? print this message.\n"
96 "\n"), 2000, VERSION, BDATE);
100 /*********************************************************************
102 * Main Bacula Unix Storage Daemon
105 #if defined(HAVE_WIN32)
106 #define main BaculaMain
109 int main (int argc, char *argv[])
112 bool no_signals = false;
113 bool test_config = false;
118 start_heap = sbrk(0);
119 setlocale(LC_ALL, "");
120 bindtextdomain("bacula", LOCALEDIR);
121 textdomain("bacula");
124 my_name_is(argc, argv, "bacula-sd");
125 init_msg(NULL, NULL);
126 daemon_start_time = time(NULL);
129 if (TAPE_BSIZE % B_DEV_BSIZE != 0 || TAPE_BSIZE / B_DEV_BSIZE == 0) {
130 Emsg2(M_ABORT, 0, _("Tape block size (%d) not multiple of system size (%d)\n"),
131 TAPE_BSIZE, B_DEV_BSIZE);
133 if (TAPE_BSIZE != (1 << (ffs(TAPE_BSIZE)-1))) {
134 Emsg1(M_ABORT, 0, _("Tape block size (%d) is not a power of 2\n"), TAPE_BSIZE);
137 while ((ch = getopt(argc, argv, "c:d:fg:pstu:v?")) != -1) {
139 case 'c': /* configuration file */
140 if (configfile != NULL) {
143 configfile = bstrdup(optarg);
146 case 'd': /* debug level */
147 if (*optarg == 't') {
148 dbg_timestamp = true;
150 debug_level = atoi(optarg);
151 if (debug_level <= 0) {
157 case 'f': /* run in foreground */
161 case 'g': /* set group id */
165 case 'p': /* proceed in spite of I/O errors */
169 case 's': /* no signals */
177 case 'u': /* set uid */
181 case 'v': /* verbose */
195 if (configfile != NULL) {
198 configfile = bstrdup(*argv);
206 init_signals(terminate_stored);
209 if (configfile == NULL) {
210 configfile = bstrdup(CONFIG_FILE);
213 config = new_config_parser();
214 parse_sd_config(config, configfile, M_ERROR_TERM);
216 if (init_crypto() != 0) {
217 Jmsg((JCR *)NULL, M_ERROR_TERM, 0, _("Cryptography library initialization failed.\n"));
220 if (!check_resources()) {
221 Jmsg((JCR *)NULL, M_ERROR_TERM, 0, _("Please correct configuration file: %s\n"), configfile);
224 init_reservations_lock();
230 my_name_is(0, (char **)NULL, me->hdr.name); /* Set our real name */
233 daemon_start(); /* become daemon */
234 init_stack_dump(); /* pick up new pid */
237 create_pid_file(me->pid_directory, "bacula-sd", get_first_port_host_order(me->sdaddrs));
238 read_state_file(me->working_directory, "bacula-sd", get_first_port_host_order(me->sdaddrs));
245 /* Ensure that Volume Session Time and Id are both
246 * set and are both non-zero.
248 VolSessionTime = (uint32_t)daemon_start_time;
249 if (VolSessionTime == 0) { /* paranoid */
250 Jmsg0(NULL, M_ABORT, 0, _("Volume Session Time is ZERO!\n"));
253 init_python_interpreter(me->hdr.name, me->scripts_directory, "SDStartUp");
255 /* Make sure on Solaris we can run concurrent, watch dog + servers + misc */
256 set_thread_concurrency(me->max_concurrent_jobs * 2 + 4);
259 * Start the device allocation thread
261 create_volume_list(); /* do before device_init */
262 if (pthread_create(&thid, NULL, device_initialization, NULL) != 0) {
264 Emsg1(M_ABORT, 0, _("Unable to create thread. ERR=%s\n"), be.bstrerror());
267 start_watchdog(); /* start watchdog thread */
268 init_jcr_subsystem(); /* start JCR watchdogs etc. */
270 /* Single server used for Director and File daemon */
271 bnet_thread_server(me->sdaddrs, me->max_concurrent_jobs * 2 + 1,
272 &dird_workq, handle_connection_request);
273 exit(1); /* to keep compiler quiet */
276 /* Return a new Session Id */
277 uint32_t newVolSessionId()
288 /* Check Configuration file for necessary info */
289 static int check_resources()
295 me = (STORES *)GetNextRes(R_STORAGE, NULL);
297 Jmsg1(NULL, M_ERROR, 0, _("No Storage resource defined in %s. Cannot continue.\n"),
302 if (GetNextRes(R_STORAGE, (RES *)me) != NULL) {
303 Jmsg1(NULL, M_ERROR, 0, _("Only one Storage resource permitted in %s\n"),
307 if (GetNextRes(R_DIRECTOR, NULL) == NULL) {
308 Jmsg1(NULL, M_ERROR, 0, _("No Director resource defined in %s. Cannot continue.\n"),
312 if (GetNextRes(R_DEVICE, NULL) == NULL){
313 Jmsg1(NULL, M_ERROR, 0, _("No Device resource defined in %s. Cannot continue.\n"),
319 me->messages = (MSGS *)GetNextRes(R_MSGS, NULL);
321 Jmsg1(NULL, M_ERROR, 0, _("No Messages resource defined in %s. Cannot continue.\n"),
327 if (!me->working_directory) {
328 Jmsg1(NULL, M_ERROR, 0, _("No Working Directory defined in %s. Cannot continue.\n"),
335 foreach_res(store, R_STORAGE) {
336 /* tls_require implies tls_enable */
337 if (store->tls_require) {
339 store->tls_enable = true;
341 Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
347 tls_needed = store->tls_enable || store->tls_authenticate;
349 if (!store->tls_certfile && tls_needed) {
350 Jmsg(NULL, M_FATAL, 0, _("\"TLS Certificate\" file not defined for Storage \"%s\" in %s.\n"),
351 store->hdr.name, configfile);
355 if (!store->tls_keyfile && tls_needed) {
356 Jmsg(NULL, M_FATAL, 0, _("\"TLS Key\" file not defined for Storage \"%s\" in %s.\n"),
357 store->hdr.name, configfile);
361 if ((!store->tls_ca_certfile && !store->tls_ca_certdir) && tls_needed && store->tls_verify_peer) {
362 Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\""
363 " or \"TLS CA Certificate Dir\" are defined for Storage \"%s\" in %s."
364 " At least one CA certificate store is required"
365 " when using \"TLS Verify Peer\".\n"),
366 store->hdr.name, configfile);
370 /* If everything is well, attempt to initialize our per-resource TLS context */
371 if (OK && (tls_needed || store->tls_require)) {
372 /* Initialize TLS context:
373 * Args: CA certfile, CA certdir, Certfile, Keyfile,
374 * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
375 store->tls_ctx = new_tls_context(store->tls_ca_certfile,
376 store->tls_ca_certdir, store->tls_certfile,
377 store->tls_keyfile, NULL, NULL, store->tls_dhfile,
378 store->tls_verify_peer);
380 if (!store->tls_ctx) {
381 Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for Storage \"%s\" in %s.\n"),
382 store->hdr.name, configfile);
388 foreach_res(director, R_DIRECTOR) {
389 /* tls_require implies tls_enable */
390 if (director->tls_require) {
391 director->tls_enable = true;
394 tls_needed = director->tls_enable || director->tls_authenticate;
396 if (!director->tls_certfile && tls_needed) {
397 Jmsg(NULL, M_FATAL, 0, _("\"TLS Certificate\" file not defined for Director \"%s\" in %s.\n"),
398 director->hdr.name, configfile);
402 if (!director->tls_keyfile && tls_needed) {
403 Jmsg(NULL, M_FATAL, 0, _("\"TLS Key\" file not defined for Director \"%s\" in %s.\n"),
404 director->hdr.name, configfile);
408 if ((!director->tls_ca_certfile && !director->tls_ca_certdir) && tls_needed && director->tls_verify_peer) {
409 Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\""
410 " or \"TLS CA Certificate Dir\" are defined for Director \"%s\" in %s."
411 " At least one CA certificate store is required"
412 " when using \"TLS Verify Peer\".\n"),
413 director->hdr.name, configfile);
417 /* If everything is well, attempt to initialize our per-resource TLS context */
418 if (OK && (tls_needed || director->tls_require)) {
419 /* Initialize TLS context:
420 * Args: CA certfile, CA certdir, Certfile, Keyfile,
421 * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
422 director->tls_ctx = new_tls_context(director->tls_ca_certfile,
423 director->tls_ca_certdir, director->tls_certfile,
424 director->tls_keyfile, NULL, NULL, director->tls_dhfile,
425 director->tls_verify_peer);
427 if (!director->tls_ctx) {
428 Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for Director \"%s\" in %s.\n"),
429 director->hdr.name, configfile);
435 OK = init_autochangers();
439 close_msg(NULL); /* close temp message handler */
440 init_msg(NULL, me->messages); /* open daemon message handler */
441 set_working_directory(me->working_directory);
447 static void cleanup_old_files()
449 POOLMEM *cleanup = get_pool_memory(PM_MESSAGE);
450 POOLMEM *results = get_pool_memory(PM_MESSAGE);
451 int len = strlen(me->working_directory);
452 #if defined(HAVE_WIN32)
453 pm_strcpy(cleanup, "del /q ");
455 pm_strcpy(cleanup, "/bin/rm -f ");
457 pm_strcat(cleanup, me->working_directory);
458 if (len > 0 && !IsPathSeparator(me->working_directory[len-1])) {
459 pm_strcat(cleanup, "/");
461 pm_strcat(cleanup, my_name);
462 pm_strcat(cleanup, "*.spool");
463 run_program(cleanup, 0, results);
464 free_pool_memory(cleanup);
465 free_pool_memory(results);
470 * Here we attempt to init and open each device. This is done
471 * once at startup in a separate thread.
474 void *device_initialization(void *arg)
483 pthread_detach(pthread_self());
484 jcr = new_jcr(sizeof(JCR), stored_free_jcr);
485 jcr->set_JobType(JT_SYSTEM);
486 /* Initialize FD start condition variable */
487 int errstat = pthread_cond_init(&jcr->job_start_wait, NULL);
490 Jmsg1(jcr, M_ABORT, 0, _("Unable to init job cond variable: ERR=%s\n"), be.bstrerror(errstat));
493 foreach_res(device, R_DEVICE) {
494 Dmsg1(90, "calling init_dev %s\n", device->device_name);
495 dev = init_dev(NULL, device);
496 Dmsg1(10, "SD init done %s\n", device->device_name);
498 Jmsg1(NULL, M_ERROR, 0, _("Could not initialize %s\n"), device->device_name);
502 jcr->dcr = dcr = new_dcr(jcr, NULL, dev);
503 if (dev->is_autochanger()) {
504 /* If autochanger set slot in dev sturcture */
505 get_autochanger_loaded_slot(dcr);
508 if (device->cap_bits & CAP_ALWAYSOPEN) {
509 Dmsg1(20, "calling first_open_device %s\n", dev->print_name());
510 if (!first_open_device(dcr)) {
511 Jmsg1(NULL, M_ERROR, 0, _("Could not open device %s\n"), dev->print_name());
512 Dmsg1(20, "Could not open device %s\n", dev->print_name());
518 if (device->cap_bits & CAP_AUTOMOUNT && dev->is_open()) {
519 switch (read_dev_volume_label(dcr)) {
521 memcpy(&dev->VolCatInfo, &dcr->VolCatInfo, sizeof(dev->VolCatInfo));
522 volume_unused(dcr); /* mark volume "released" */
525 Jmsg1(NULL, M_WARNING, 0, _("Could not mount device %s\n"), dev->print_name());
534 Dmsg1(000, "free_dcr=%p\n", jcr->dcr);
546 /* Clean up and then exit */
547 void terminate_stored(int sig)
549 static bool in_here = false;
553 if (in_here) { /* prevent loops */
554 bmicrosleep(2, 0); /* yield */
558 debug_level = 0; /* turn off any debug */
561 if (sig == SIGTERM) { /* normal shutdown request? */
563 * This is a normal shutdown request. We wiffle through
564 * all open jobs canceling them and trying to wake
565 * them up so that they will report back the correct
570 if (jcr->JobId == 0) {
572 continue; /* ignore console */
574 set_jcr_job_status(jcr, JS_Canceled);
575 fd = jcr->file_bsock;
578 Dmsg1(100, "term_stored killing JobId=%d\n", jcr->JobId);
579 pthread_kill(jcr->my_thread_id, TIMEOUT_SIGNAL);
580 /* ***FIXME*** wiffle through all dcrs */
581 if (jcr->dcr && jcr->dcr->dev && jcr->dcr->dev->blocked()) {
582 pthread_cond_broadcast(&jcr->dcr->dev->wait_next_vol);
583 Dmsg1(100, "JobId=%u broadcast wait_device_release\n", (uint32_t)jcr->JobId);
584 pthread_cond_broadcast(&wait_device_release);
586 if (jcr->read_dcr && jcr->read_dcr->dev && jcr->read_dcr->dev->blocked()) {
587 pthread_cond_broadcast(&jcr->read_dcr->dev->wait_next_vol);
588 pthread_cond_broadcast(&wait_device_release);
590 bmicrosleep(0, 50000);
594 bmicrosleep(0, 500000); /* give them 1/2 sec to clean up */
597 write_state_file(me->working_directory, "bacula-sd", get_first_port_host_order(me->sdaddrs));
598 delete_pid_file(me->pid_directory, "bacula-sd", get_first_port_host_order(me->sdaddrs));
600 Dmsg1(200, "In terminate_stored() sig=%d\n", sig);
604 foreach_res(device, R_DEVICE) {
605 Dmsg1(10, "Term device %s\n", device->device_name);
607 device->dev->clear_volhdr();
611 Dmsg1(10, "No dev structure %s\n", device->device_name);
620 config->free_resources();
625 if (debug_level > 10) {
626 print_memory_pool_stats();
630 term_reservations_lock();
633 sm_dump(false); /* dump orphaned buffers */