OpenDNSSEC-enforcer  2.1.12
engine.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2009 NLNet Labs. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
14  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
17  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
19  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
21  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
22  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
23  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  *
25  */
26 
32 #include "config.h"
33 
34 #include <pthread.h>
35 
36 #include "daemon/cfg.h"
38 #include "clientpipe.h"
39 #include "cmdhandler.h"
40 #include "locks.h"
41 #include "daemon/engine.h"
42 #include "scheduler/schedule.h"
43 #include "scheduler/task.h"
44 #include "file.h"
45 #include "log.h"
46 #include "privdrop.h"
47 #include "status.h"
48 #include "util.h"
49 #include "db/db_configuration.h"
50 #include "db/db_connection.h"
51 #include "db/database_version.h"
52 #include "hsmkey/hsm_key_factory.h"
53 #include "libhsm.h"
54 #include "locks.h"
55 
56 #include <errno.h>
57 #include <libxml/parser.h>
58 #include <signal.h>
59 #include <stdio.h>
60 #include <stdlib.h>
61 #include <string.h>
62 #include <strings.h>
63 #include <sys/socket.h>
64 #include <sys/types.h>
65 #include <sys/un.h>
66 #include <time.h>
67 #include <unistd.h>
68 #include <fcntl.h>
69 
70 static const char* engine_str = "engine";
71 
72 static engine_type* engine = NULL;
73 
80 {
81  engine = (engine_type*) malloc(sizeof(engine_type));
82  if (!engine) return NULL;
83 
84  pthread_mutex_init(&engine->signal_lock, NULL);
85  pthread_cond_init(&engine->signal_cond, NULL);
86 
87  engine->dbcfg_list = NULL;
88  engine->taskq = schedule_create();
89  if (!engine->taskq) {
90  free(engine);
91  return NULL;
92  }
93  return engine;
94 }
95 
96 void
98 {
99  schedule_cleanup(engine->taskq);
100  pthread_mutex_destroy(&engine->signal_lock);
101  pthread_cond_destroy(&engine->signal_cond);
102  if (engine->dbcfg_list) {
104  }
106  free(engine);
107 }
108 
109 static void
110 engine_start_cmdhandler(engine_type* engine)
111 {
112  ods_log_assert(engine);
113  ods_log_debug("[%s] start command handler", engine_str);
114  janitor_thread_create(&engine->cmdhandler->thread_id, workerthreadclass, (janitor_runfn_t)cmdhandler_start, engine->cmdhandler);
115 }
116 
121 static ods_status
122 engine_privdrop(engine_type* engine)
123 {
124  ods_status status = ODS_STATUS_OK;
125  uid_t uid = -1;
126  gid_t gid = -1;
127 
128  ods_log_assert(engine);
129  ods_log_assert(engine->config);
130  ods_log_debug("[%s] drop privileges", engine_str);
131 
132  if (engine->config->username && engine->config->group) {
133  ods_log_verbose("[%s] drop privileges to user %s, group %s",
134  engine_str, engine->config->username, engine->config->group);
135  } else if (engine->config->username) {
136  ods_log_verbose("[%s] drop privileges to user %s", engine_str,
137  engine->config->username);
138  } else if (engine->config->group) {
139  ods_log_verbose("[%s] drop privileges to group %s", engine_str,
140  engine->config->group);
141  }
142  if (engine->config->chroot) {
143  ods_log_verbose("[%s] chroot to %s", engine_str,
144  engine->config->chroot);
145  }
146  status = privdrop(engine->config->username, engine->config->group,
147  engine->config->chroot, &uid, &gid);
148  engine->uid = uid;
149  engine->gid = gid;
150  privclose(engine->config->username, engine->config->group);
151  return status;
152 }
153 
158 static void
159 engine_create_workers(engine_type* engine)
160 {
161  char* name;
162  int i = 0;
163  ods_log_assert(engine);
164  ods_log_assert(engine->config);
165  engine->workers = (worker_type**) malloc(
166  (size_t)engine->config->num_worker_threads * sizeof(worker_type*));
167  for (i=0; i < (size_t) engine->config->num_worker_threads; i++) {
168  asprintf(&name, "worker[%d]", i+1);
169  engine->workers[i] = worker_create(name, engine->taskq);
170  }
171 }
172 
173 void
175 {
176  size_t i = 0;
177 
178  ods_log_assert(engine);
179  ods_log_assert(engine->config);
180  ods_log_debug("[%s] start workers", engine_str);
181  for (i=0; i < (size_t) engine->config->num_worker_threads; i++) {
182  engine->workers[i]->need_to_exit = 0;
183  engine->workers[i]->context = get_database_connection(engine);
184  if (!engine->workers[i]->context) {
185  ods_log_crit("Failed to start worker, could not connect to database");
186  } else {
187  janitor_thread_create(&engine->workers[i]->thread_id, workerthreadclass, (janitor_runfn_t)worker_start, engine->workers[i]);
188  }
189  }
190 }
191 
192 void
194 {
195  int i = 0;
196 
197  ods_log_assert(engine);
198  ods_log_assert(engine->config);
199  ods_log_debug("[%s] stop workers", engine_str);
200  /* tell them to exit and wake up sleepyheads */
201  for (i=0; i < engine->config->num_worker_threads; i++) {
202  engine->workers[i]->need_to_exit = 1;
203  }
204  engine_wakeup_workers(engine);
205  /* head count */
206  for (i=0; i < engine->config->num_worker_threads; i++) {
207  ods_log_debug("[%s] join worker %i", engine_str, i+1);
208  janitor_thread_join(engine->workers[i]->thread_id);
209  db_connection_free(engine->workers[i]->context);
210  }
211 }
212 
217 void
219 {
220  ods_log_assert(engine);
221  ods_log_debug("[%s] wake up workers", engine_str);
222  schedule_release_all(engine->taskq);
223 }
224 
227 {
228  db_connection_t* dbconn;
229 
230  if (!(dbconn = db_connection_new())
232  || db_connection_setup(dbconn)
233  || db_connection_connect(dbconn))
234  {
235  db_connection_free(dbconn);
236  ods_log_crit("database connection failed");
237  return NULL;
238  }
239  return dbconn;
240 }
241 
242 /*
243  * Try to open a connection to the database and close it again.
244  * \param dbcfg_list, database configuration list
245  * \return 0 on success, 1 on failure.
246  */
247 static int
248 probe_database(engine_type* engine)
249 {
250  db_connection_t *conn;
251  int version;
252 
253  conn = get_database_connection(engine);
254  if (!conn) return 1;
255  version = database_version_get_version(conn);
256  db_connection_free(conn);
257  return !version;
258 }
259 
260 /*
261  * Prepare for database connections and store dbcfg_list in engine
262  * if successfull the counterpart desetup_database() must be called
263  * when quitting the daemon.
264  * \param engine engine config where configuration list is stored
265  * \return 0 on succes, 1 on failure
266  */
267 static int
268 setup_database(engine_type* engine)
269 {
270  db_configuration_t* dbcfg;
271 
272  if (!(engine->dbcfg_list = db_configuration_list_new())) {
273  fprintf(stderr, "db_configuraiton_list_new failed\n");
274  return 1;
275  }
276  if (engine->config->db_type == ENFORCER_DATABASE_TYPE_SQLITE) {
277  if (!(dbcfg = db_configuration_new())
278  || db_configuration_set_name(dbcfg, "backend")
279  || db_configuration_set_value(dbcfg, "sqlite")
280  || db_configuration_list_add(engine->dbcfg_list, dbcfg))
281  {
282  db_configuration_free(dbcfg);
284  engine->dbcfg_list = NULL;
285  fprintf(stderr, "setup configuration backend failed\n");
286  return 1;
287  }
288  if (!(dbcfg = db_configuration_new())
289  || db_configuration_set_name(dbcfg, "file")
290  || db_configuration_set_value(dbcfg, engine->config->datastore)
291  || db_configuration_list_add(engine->dbcfg_list, dbcfg))
292  {
293  db_configuration_free(dbcfg);
295  engine->dbcfg_list = NULL;
296  fprintf(stderr, "setup configuration file failed\n");
297  return 1;
298  }
299  dbcfg = NULL;
300  }
301  else if (engine->config->db_type == ENFORCER_DATABASE_TYPE_MYSQL) {
302  if (!(dbcfg = db_configuration_new())
303  || db_configuration_set_name(dbcfg, "backend")
304  || db_configuration_set_value(dbcfg, "mysql")
305  || db_configuration_list_add(engine->dbcfg_list, dbcfg))
306  {
307  db_configuration_free(dbcfg);
309  engine->dbcfg_list = NULL;
310  fprintf(stderr, "setup configuration backend failed\n");
311  return 1;
312  }
313  if (!(dbcfg = db_configuration_new())
314  || db_configuration_set_name(dbcfg, "host")
315  || db_configuration_set_value(dbcfg, engine->config->db_host)
316  || db_configuration_list_add(engine->dbcfg_list, dbcfg))
317  {
318  db_configuration_free(dbcfg);
320  engine->dbcfg_list = NULL;
321  fprintf(stderr, "setup configuration file failed\n");
322  return 1;
323  }
324  dbcfg = NULL;
325  if (engine->config->db_port) {
326  char str[32];
327  if (snprintf(&str[0], sizeof(str), "%d", engine->config->db_port) >= (int)sizeof(str)) {
329  engine->dbcfg_list = NULL;
330  fprintf(stderr, "setup configuration file failed\n");
331  return 1;
332  }
333  if (!(dbcfg = db_configuration_new())
334  || db_configuration_set_name(dbcfg, "port")
335  || db_configuration_set_value(dbcfg, str)
336  || db_configuration_list_add(engine->dbcfg_list, dbcfg))
337  {
338  db_configuration_free(dbcfg);
340  engine->dbcfg_list = NULL;
341  fprintf(stderr, "setup configuration file failed\n");
342  return 1;
343  }
344  dbcfg = NULL;
345  }
346  if (!(dbcfg = db_configuration_new())
347  || db_configuration_set_name(dbcfg, "user")
348  || db_configuration_set_value(dbcfg, engine->config->db_username)
349  || db_configuration_list_add(engine->dbcfg_list, dbcfg))
350  {
351  db_configuration_free(dbcfg);
353  engine->dbcfg_list = NULL;
354  fprintf(stderr, "setup configuration file failed\n");
355  return 1;
356  }
357  dbcfg = NULL;
358  if (!(dbcfg = db_configuration_new())
359  || db_configuration_set_name(dbcfg, "pass")
360  || db_configuration_set_value(dbcfg, engine->config->db_password)
361  || db_configuration_list_add(engine->dbcfg_list, dbcfg))
362  {
363  db_configuration_free(dbcfg);
365  engine->dbcfg_list = NULL;
366  fprintf(stderr, "setup configuration file failed\n");
367  return 1;
368  }
369  dbcfg = NULL;
370  if (!(dbcfg = db_configuration_new())
371  || db_configuration_set_name(dbcfg, "db")
372  || db_configuration_set_value(dbcfg, engine->config->datastore)
373  || db_configuration_list_add(engine->dbcfg_list, dbcfg))
374  {
375  db_configuration_free(dbcfg);
377  engine->dbcfg_list = NULL;
378  fprintf(stderr, "setup configuration file failed\n");
379  return 1;
380  }
381  dbcfg = NULL;
382  }
383  else {
384  return 1;
385  }
386  return 0;
387 }
388 
389 /*
390  * destroy database configuration. Call only after all connections
391  * are closed.
392  * \param engine engine config where configuration list is stored
393  */
394 static void
395 desetup_database(engine_type* engine)
396 {
398  engine->dbcfg_list = NULL;
399 }
400 
401 static void
402 signal_handler(sig_atomic_t sig)
403 {
404  switch (sig) {
405  case SIGHUP:
406  if (engine) {
407  engine->need_to_reload = 1;
408  pthread_mutex_lock(&engine->signal_lock);
409  pthread_cond_signal(&engine->signal_cond);
410  pthread_mutex_unlock(&engine->signal_lock);
411  }
412  break;
413  case SIGINT:
414  case SIGTERM:
415  if (engine) {
416  engine->need_to_exit = 1;
417  pthread_mutex_lock(&engine->signal_lock);
418  pthread_cond_signal(&engine->signal_cond);
419  pthread_mutex_unlock(&engine->signal_lock);
420  }
421  break;
422  default:
423  break;
424  }
425 }
426 
431 ods_status
433 {
434  int fd, error;
435  int pipefd[2];
436  char buff = '\0';
437 
438  ods_log_debug("[%s] enforcer setup", engine_str);
439 
440  engine->pid = getpid(); /* We need to do this again after fork() */
441 
442  if (!util_pidfile_avail(engine->config->pid_filename)) {
443  ods_log_error("[%s] Pidfile exists and process with PID is running", engine_str);
444  return ODS_STATUS_WRITE_PIDFILE_ERR;
445  }
446  /* setup database configuration */
447  if (setup_database(engine)) return ODS_STATUS_DB_ERR;
448  /* Probe the database, can we connect to it? */
449  if (probe_database(engine)) {
450  ods_log_crit("Could not connect to database or database not set"
451  " up properly.");
452  return ODS_STATUS_DB_ERR;
453  }
454 
455  /* create command handler (before chowning socket file) */
456  engine->cmdhandler = cmdhandler_create(engine->config->clisock_filename, enforcercommands, engine, (void*(*)(void*)) &get_database_connection, (void(*)(void*))&db_connection_free);
457  if (!engine->cmdhandler) {
458  ods_log_error("[%s] create command handler to %s failed",
459  engine_str, engine->config->clisock_filename);
460  return ODS_STATUS_CMDHANDLER_ERR;
461  }
462 
463  if(pipe(pipefd)) {
464  ods_log_error("[%s] unable to pipe: %s", engine_str, strerror(errno));
465  return ODS_STATUS_PIPE_ERR;
466  }
467 
468  if (!engine->init_setup_done) {
469  /* privdrop */
470  engine->uid = privuid(engine->config->username);
471  engine->gid = privgid(engine->config->group);
472  /* TODO: does piddir exists? */
473  /* remove the chown stuff: piddir? */
474  ods_chown(engine->config->pid_filename, engine->uid, engine->gid, 1);
475  ods_chown(engine->config->clisock_filename, engine->uid, engine->gid, 0);
476  ods_chown(engine->config->working_dir, engine->uid, engine->gid, 0);
477  if (engine->config->log_filename && !engine->config->use_syslog) {
478  ods_chown(engine->config->log_filename, engine->uid, engine->gid, 0);
479  }
480  if (engine->config->working_dir &&
481  chdir(engine->config->working_dir) != 0) {
482  ods_log_error("[%s] chdir to %s failed: %s", engine_str,
483  engine->config->working_dir, strerror(errno));
484  return ODS_STATUS_CHDIR_ERR;
485  }
486  if (engine_privdrop(engine) != ODS_STATUS_OK) {
487  ods_log_error("[%s] unable to drop privileges", engine_str);
488  return ODS_STATUS_PRIVDROP_ERR;
489  }
490 
491  /* daemonize */
492  if (engine->daemonize) {
493  switch (fork()) {
494  case -1: /* error */
495  ods_log_error("[%s] unable to fork daemon: %s",
496  engine_str, strerror(errno));
497  return ODS_STATUS_FORK_ERR;
498  case 0: /* child */
499  if ((fd = open("/dev/null", O_RDWR, 0)) != -1) {
500  (void)dup2(fd, STDIN_FILENO);
501  (void)dup2(fd, STDOUT_FILENO);
502  (void)dup2(fd, STDERR_FILENO);
503  if (fd > 2) (void)close(fd);
504  }
505  close(pipefd[0]);
506  break;
507  default: /* parent */
508  close(pipefd[1]);
509  /* Print messages the child may have send us. */
510  while (read(pipefd[0], &buff, 1) != -1) {
511  if (buff <= 1) break;
512  printf("%c", buff);
513  }
514  close(pipefd[0]);
515  if (buff != '\1') {
516  ods_log_error("[%s] fail to start enforcerd completely", engine_str);
517  exit(1);
518  }
519  ods_log_debug("[%s] enforcerd started successfully", engine_str);
520  exit(0);
521  }
522  if (setsid() == -1) {
523  ods_log_error("[%s] unable to setsid daemon (%s)",
524  engine_str, strerror(errno));
525  const char *err = "unable to setsid daemon: ";
526  ods_writen(pipefd[1], err, strlen(err));
527  ods_writeln(pipefd[1], strerror(errno));
528  write(pipefd[1], "\0", 1);
529  close(pipefd[1]);
530  return ODS_STATUS_SETSID_ERR;
531  }
532  }
533  }
534  engine->init_setup_done = 1;
535 
536  engine->pid = getpid();
537  ods_log_info("[%s] running as pid %lu", engine_str,
538  (unsigned long) engine->pid);
539 
540  /* create workers */
541  engine_create_workers(engine);
542 
543  /* write pidfile */
544  if (util_write_pidfile(engine->config->pid_filename, engine->pid) == -1) {
545  hsm_close();
546  ods_log_error("[%s] unable to write pid file", engine_str);
547  if (engine->daemonize) {
548  ods_writeln(pipefd[1], "unable to write pid file");
549  write(pipefd[1], "\0", 1);
550  close(pipefd[1]);
551  }
552  return ODS_STATUS_WRITE_PIDFILE_ERR;
553  }
554  ods_log_info("[%s] enforcer started", engine_str);
555  error = hsm_open2(engine->config->repositories, hsm_prompt_pin);
556  if (error != HSM_OK) {
557  char* errorstr = hsm_get_error(NULL);
558  if (!errorstr)
559  (void)asprintf(&errorstr, "error opening libhsm (errno %i)", error);
560  if (errorstr)
561  ods_log_error("[%s] %s", engine_str, errorstr);
562  if (engine->daemonize) {
563  if (errorstr) ods_writeln(pipefd[1], errorstr);
564  write(pipefd[1], "\0", 1);
565  close(pipefd[1]);
566  }
567  free(errorstr);
568  return ODS_STATUS_HSM_ERR;
569  }
570  engine->need_to_reload = 0;
571  engine_start_cmdhandler(engine);
572 
573  write(pipefd[1], "\1", 1);
574  close(pipefd[1]);
575  if (!engine->daemonize) close(pipefd[0]);
576  engine->daemonize = 0; /* don't fork again on reload */
577  return ODS_STATUS_OK;
578 }
579 
584 void
586 {
587  size_t i = 0;
588 
589  if (!engine) return;
590  if (engine->config) {
591  if (engine->config->pid_filename) {
592  (void)unlink(engine->config->pid_filename);
593  }
594  if (engine->config->clisock_filename) {
595  (void)unlink(engine->config->clisock_filename);
596  }
597  }
598  if (engine->workers && engine->config) {
599  for (i=0; i < (size_t) engine->config->num_worker_threads; i++) {
600  worker_cleanup(engine->workers[i]);
601  }
602  free(engine->workers);
603  engine->workers = NULL;
604  }
605  if (engine->cmdhandler) {
606  cmdhandler_cleanup(engine->cmdhandler);
607  engine->cmdhandler = NULL;
608  }
609  desetup_database(engine);
610 }
611 
612 void
613 engine_init(engine_type* engine, int daemonize)
614 {
615  struct sigaction action;
616 
617  engine->config = NULL;
618  engine->workers = NULL;
619  engine->cmdhandler = NULL;
620  engine->init_setup_done = 0;
621  engine->pid = getpid(); /* We need to do this again after fork() */
622  engine->uid = -1;
623  engine->gid = -1;
624  engine->need_to_exit = 0;
625  engine->need_to_reload = 0;
626  engine->daemonize = daemonize;
627  /* catch signals */
628  action.sa_handler = (void (*)(int))signal_handler;
629  sigfillset(&action.sa_mask);
630  action.sa_flags = 0;
631  sigaction(SIGHUP, &action, NULL);
632  sigaction(SIGTERM, &action, NULL);
633  sigaction(SIGINT, &action, NULL);
634  engine->dbcfg_list = NULL;
635  action.sa_handler = SIG_IGN;
636  sigaction(SIGPIPE, &action, NULL);
637 }
638 
643 int
644 engine_run(engine_type* engine, start_cb_t start, int single_run)
645 {
646  int error;
647  ods_log_assert(engine);
648 
649  engine_start_workers(engine);
650 
651  /* call the external start callback function */
652  start(engine);
653 
654  while (!engine->need_to_exit && !engine->need_to_reload) {
655  if (single_run) {
656  engine->need_to_exit = 1;
657  /* FIXME: all tasks need to terminate, then set need_to_exit to 1 */
658  }
659 
660  /* We must use locking here to avoid race conditions. We want
661  * to sleep indefinitely and want to wake up on signal. This
662  * is to make sure we never mis the signal. */
663  pthread_mutex_lock(&engine->signal_lock);
664  if (!engine->need_to_exit && !engine->need_to_reload && !single_run) {
665  /* TODO: this silly. We should be handling the commandhandler
666  * connections. No reason to spawn that as a thread.
667  * Also it would be easier to wake up the command hander
668  * as signals will reach it if it is the main thread! */
669  ods_log_debug("[%s] taking a break", engine_str);
670  pthread_cond_wait(&engine->signal_cond, &engine->signal_lock);
671  }
672  pthread_mutex_unlock(&engine->signal_lock);
673  }
674  ods_log_debug("[%s] enforcer halted", engine_str);
675  engine_stop_workers(engine);
676  cmdhandler_stop(engine->cmdhandler);
677  schedule_purge(engine->taskq); /* Remove old tasks in queue */
678  hsm_close();
679  return 0;
680 }
@ ENFORCER_DATABASE_TYPE_MYSQL
Definition: cfg.h:46
@ ENFORCER_DATABASE_TYPE_SQLITE
Definition: cfg.h:45
int database_version_get_version(db_connection_t *connection)
db_configuration_t * db_configuration_new(void)
db_configuration_list_t * db_configuration_list_new(void)
void db_configuration_free(db_configuration_t *configuration)
int db_configuration_set_name(db_configuration_t *configuration, const char *name)
int db_configuration_list_add(db_configuration_list_t *configuration_list, db_configuration_t *configuration)
int db_configuration_set_value(db_configuration_t *configuration, const char *value)
void db_configuration_list_free(db_configuration_list_t *configuration_list)
int db_connection_connect(const db_connection_t *connection)
Definition: db_connection.c:88
db_connection_t * db_connection_new(void)
Definition: db_connection.c:38
int db_connection_setup(db_connection_t *connection)
Definition: db_connection.c:66
void db_connection_free(db_connection_t *connection)
Definition: db_connection.c:45
int db_connection_set_configuration_list(db_connection_t *connection, const db_configuration_list_t *configuration_list)
Definition: db_connection.c:54
struct cmd_func_block ** enforcercommands
void engine_teardown(engine_type *engine)
Definition: engine.c:585
void engine_init(engine_type *engine, int daemonize)
Definition: engine.c:613
void engine_dealloc(engine_type *engine)
Definition: engine.c:97
db_connection_t * get_database_connection(engine_type *engine)
Definition: engine.c:226
void engine_wakeup_workers(engine_type *engine)
Definition: engine.c:218
void engine_start_workers(engine_type *engine)
Definition: engine.c:174
int engine_run(engine_type *engine, start_cb_t start, int single_run)
Definition: engine.c:644
engine_type * engine_alloc(void)
Definition: engine.c:79
void engine_stop_workers(engine_type *engine)
Definition: engine.c:193
ods_status engine_setup()
Definition: engine.c:432
void(* start_cb_t)(engine_type *engine)
Definition: engine.h:98
void hsm_key_factory_deinit(void)
schedule_type * taskq
Definition: engine.h:60
pthread_mutex_t signal_lock
Definition: engine.h:65
pid_t pid
Definition: engine.h:50
gid_t gid
Definition: engine.h:52
cmdhandler_type * cmdhandler
Definition: engine.h:61
pthread_cond_t signal_cond
Definition: engine.h:64
int need_to_reload
Definition: engine.h:56
int daemonize
Definition: engine.h:54
uid_t uid
Definition: engine.h:51
int init_setup_done
Definition: engine.h:57
db_configuration_list_t * dbcfg_list
Definition: engine.h:67
int need_to_exit
Definition: engine.h:55
worker_type ** workers
Definition: engine.h:59
engineconfig_type * config
Definition: engine.h:48
const char * chroot
Definition: cfg.h:67
const char * datastore
Definition: cfg.h:68
const char * db_password
Definition: cfg.h:71
const char * group
Definition: cfg.h:66
engineconfig_database_type_t db_type
Definition: cfg.h:80
const char * clisock_filename
Definition: cfg.h:63
const char * working_dir
Definition: cfg.h:64
hsm_repository_t * repositories
Definition: cfg.h:79
int num_worker_threads
Definition: cfg.h:73
int use_syslog
Definition: cfg.h:72
const char * pid_filename
Definition: cfg.h:60
const char * log_filename
Definition: cfg.h:59
const char * db_username
Definition: cfg.h:70
const char * db_host
Definition: cfg.h:69
const char * username
Definition: cfg.h:65