textdomain("bacula-sd");
init_msg(NULL, NULL);
daemon_start_time = time(NULL);
- memset(&last_job, 0, sizeof(last_job));
/* Sanity checks */
if (TAPE_BSIZE % DEV_BSIZE != 0 || TAPE_BSIZE / DEV_BSIZE == 0) {
while ((ch = getopt(argc, argv, "c:d:fg:stu:v?")) != -1) {
switch (ch) {
- case 'c': /* configuration file */
- if (configfile != NULL) {
- free(configfile);
- }
- configfile = bstrdup(optarg);
- break;
-
- case 'd': /* debug level */
- debug_level = atoi(optarg);
- if (debug_level <= 0) {
- debug_level = 1;
- }
- break;
+ case 'c': /* configuration file */
+ if (configfile != NULL) {
+ free(configfile);
+ }
+ configfile = bstrdup(optarg);
+ break;
- case 'f': /* run in foreground */
- foreground = TRUE;
- break;
+ case 'd': /* debug level */
+ debug_level = atoi(optarg);
+ if (debug_level <= 0) {
+ debug_level = 1;
+ }
+ break;
- case 'g': /* set group id */
- gid = optarg;
- break;
+ case 'f': /* run in foreground */
+ foreground = TRUE;
+ break;
- case 's': /* no signals */
- no_signals = TRUE;
- break;
+ case 'g': /* set group id */
+ gid = optarg;
+ break;
- case 't':
- test_config = TRUE;
- break;
+ case 's': /* no signals */
+ no_signals = TRUE;
+ break;
- case 'u': /* set uid */
- uid = optarg;
- break;
+ case 't':
+ test_config = TRUE;
+ break;
- case 'v': /* verbose */
- verbose++;
- break;
+ case 'u': /* set uid */
+ uid = optarg;
+ break;
- case '?':
- default:
- usage();
+ case 'v': /* verbose */
+ verbose++;
+ break;
+ case '?':
+ default:
+ usage();
+ break;
}
}
argc -= optind;
init_stack_dump(); /* pick up new pid */
}
- drop(uid, gid);
-
create_pid_file(me->pid_directory, "bacula-sd", me->SDport);
+ drop(uid, gid);
+
/* Ensure that Volume Session Time and Id are both
* set and are both non-zero.
*/
start_watchdog(); /* start watchdog thread */
+ init_jcr_subsystem(); /* start JCR watchdogs etc. */
+
/*
* Sleep a bit to give device thread a chance to lock the resource
* chain before we start the server.
/* Check Configuration file for necessary info */
static void check_config()
{
- struct stat stat_buf;
-
LockRes();
me = (STORES *)GetNextRes(R_STORAGE, NULL);
if (!me) {
Emsg1(M_ERROR_TERM, 0, _("No Working Directory defined in %s. Cannot continue.\n"),
configfile);
}
- if (stat(me->working_directory, &stat_buf) != 0) {
- Emsg1(M_ERROR_TERM, 0, _("Working Directory: %s not found. Cannot continue.\n"),
- me->working_directory);
- }
- if (!S_ISDIR(stat_buf.st_mode)) {
- Emsg1(M_ERROR_TERM, 0, _("Working Directory: %s is not a directory. Cannot continue.\n"),
- me->working_directory);
- }
- working_directory = me->working_directory;
+
+ set_working_directory(me->working_directory);
}
/*
{
static int in_here = FALSE;
DEVRES *device;
+ JCR *jcr;
if (in_here) { /* prevent loops */
exit(1);
}
in_here = TRUE;
+ if (sig == SIGTERM) { /* normal shutdown request? */
+ /*
+ * This is a normal shutdown request. We wiffle through
+ * all open jobs canceling them and trying to wake
+ * them up so that they will report back the correct
+ * volume status.
+ */
+ lock_jcr_chain();
+ for (jcr=NULL; (jcr=get_next_jcr(jcr)); ) {
+ BSOCK *fd;
+ free_locked_jcr(jcr);
+ if (jcr->JobId == 0) {
+ continue; /* ignore console */
+ }
+ set_jcr_job_status(jcr, JS_Canceled);
+ fd = jcr->file_bsock;
+ if (fd) {
+ fd->timed_out = TRUE;
+ Dmsg1(100, "killing JobId=%d\n", jcr->JobId);
+ pthread_kill(jcr->my_thread_id, TIMEOUT_SIGNAL);
+ if (jcr->device && jcr->device->dev && jcr->device->dev->dev_blocked) {
+ pthread_cond_signal(&jcr->device->dev->wait_next_vol);
+ }
+ bmicrosleep(0, 50000);
+ }
+ }
+ unlock_jcr_chain();
+ bmicrosleep(0, 500000); /* give them 1/2 sec to clean up */
+ }
+
delete_pid_file(me->pid_directory, "bacula-sd", me->SDport);
- stop_watchdog();
- Dmsg0(200, "In terminate_stored()\n");
+ Dmsg1(200, "In terminate_stored() sig=%d\n", sig);
LockRes();
for (device=NULL; (device=(DEVRES *)GetNextRes(R_DEVICE, (RES *)device)); ) {
print_memory_pool_stats();
}
term_msg();
+ stop_watchdog();
close_memory_pool();
sm_dump(False); /* dump orphaned buffers */