OpenDNSSEC-enforcer  2.0.2
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"
37 #include "daemon/cmdhandler.h"
38 #include "clientpipe.h"
39 #include "daemon/engine.h"
40 #include "daemon/signal.h"
41 #include "daemon/worker.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 
55 #include <errno.h>
56 #include <libxml/parser.h>
57 #include <signal.h>
58 #include <stdio.h>
59 #include <stdlib.h>
60 #include <string.h>
61 #include <strings.h>
62 #include <sys/socket.h>
63 #include <sys/types.h>
64 #include <sys/un.h>
65 #include <time.h>
66 #include <unistd.h>
67 #include <fcntl.h>
68 
69 static const char* engine_str = "engine";
70 
77 {
78  engine_type* engine;
79  engine = (engine_type*) malloc(sizeof(engine_type));
80  if (!engine) return NULL;
81 
82  pthread_mutex_init(&engine->signal_lock, NULL);
83  pthread_mutex_init(&engine->enforce_lock, NULL);
84  pthread_cond_init(&engine->signal_cond, NULL);
85 
86  engine->dbcfg_list = NULL;
87  engine->taskq = schedule_create();
88  if (!engine->taskq) {
89  free(engine);
90  return NULL;
91  }
92  return engine;
93 }
94 
95 void
97 {
98  schedule_cleanup(engine->taskq);
99  pthread_mutex_destroy(&engine->enforce_lock);
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 
113 static void*
114 cmdhandler_thread_start(void* arg)
115 {
116  int err;
117  sigset_t sigset;
118  cmdhandler_type* cmd = (cmdhandler_type*) arg;
119 
120  sigfillset(&sigset);
121  if((err=pthread_sigmask(SIG_SETMASK, &sigset, NULL)))
122  ods_fatal_exit("[%s] pthread_sigmask: %s", engine_str, strerror(err));
123 
124  cmdhandler_start(cmd);
125  return NULL;
126 }
127 
128 static void
129 engine_start_cmdhandler(engine_type* engine)
130 {
131  ods_log_assert(engine);
132  ods_log_debug("[%s] start command handler", engine_str);
133  engine->cmdhandler->engine = engine;
134  pthread_create(&engine->cmdhandler->thread_id, NULL,
135  cmdhandler_thread_start, engine->cmdhandler);
136 }
137 
142 static ods_status
143 engine_privdrop(engine_type* engine)
144 {
145  ods_status status = ODS_STATUS_OK;
146  uid_t uid = -1;
147  gid_t gid = -1;
148 
149  ods_log_assert(engine);
150  ods_log_assert(engine->config);
151  ods_log_debug("[%s] drop privileges", engine_str);
152 
153  if (engine->config->username && engine->config->group) {
154  ods_log_verbose("[%s] drop privileges to user %s, group %s",
155  engine_str, engine->config->username, engine->config->group);
156  } else if (engine->config->username) {
157  ods_log_verbose("[%s] drop privileges to user %s", engine_str,
158  engine->config->username);
159  } else if (engine->config->group) {
160  ods_log_verbose("[%s] drop privileges to group %s", engine_str,
161  engine->config->group);
162  }
163  if (engine->config->chroot) {
164  ods_log_verbose("[%s] chroot to %s", engine_str,
165  engine->config->chroot);
166  }
167  status = privdrop(engine->config->username, engine->config->group,
168  engine->config->chroot, &uid, &gid);
169  engine->uid = uid;
170  engine->gid = gid;
171  privclose(engine->config->username, engine->config->group);
172  return status;
173 }
174 
179 static void
180 engine_create_workers(engine_type* engine)
181 {
182  size_t i = 0;
183  ods_log_assert(engine);
184  ods_log_assert(engine->config);
185  engine->workers = (worker_type**) malloc(
186  (size_t)engine->config->num_worker_threads * sizeof(worker_type*));
187  for (i=0; i < (size_t) engine->config->num_worker_threads; i++) {
188  engine->workers[i] = worker_create(i);
189  }
190 }
191 
192 static void*
193 worker_thread_start(void* arg)
194 {
195  int err;
196  sigset_t sigset;
197  worker_type* worker = (worker_type*) arg;
198 
199  sigfillset(&sigset);
200  if((err=pthread_sigmask(SIG_SETMASK, &sigset, NULL)))
201  ods_fatal_exit("[%s] pthread_sigmask: %s", engine_str, strerror(err));
202 
203  worker->dbconn = get_database_connection(worker->engine->dbcfg_list);
204  if (!worker->dbconn) {
205  ods_log_crit("Failed to start worker, could not connect to database");
206  return NULL;
207  }
208  worker_start(worker);
209  db_connection_free(worker->dbconn);
210  return NULL;
211 }
212 
213 void
215 {
216  size_t i = 0;
217 
218  ods_log_assert(engine);
219  ods_log_assert(engine->config);
220  ods_log_debug("[%s] start workers", engine_str);
221  for (i=0; i < (size_t) engine->config->num_worker_threads; i++) {
222  engine->workers[i]->need_to_exit = 0;
223  engine->workers[i]->engine = (struct engine_struct*) engine;
224  pthread_create(&engine->workers[i]->thread_id, NULL,
225  worker_thread_start, engine->workers[i]);
226  }
227 }
228 
229 void
231 {
232  int i = 0;
233 
234  ods_log_assert(engine);
235  ods_log_assert(engine->config);
236  ods_log_debug("[%s] stop workers", engine_str);
237  /* tell them to exit and wake up sleepyheads */
238  for (i=0; i < engine->config->num_worker_threads; i++) {
239  engine->workers[i]->need_to_exit = 1;
240  }
241  engine_wakeup_workers(engine);
242  /* head count */
243  for (i=0; i < engine->config->num_worker_threads; i++) {
244  ods_log_debug("[%s] join worker %i", engine_str, i+1);
245  (void)pthread_join(engine->workers[i]->thread_id, NULL);
246  engine->workers[i]->engine = NULL;
247  }
248 }
249 
254 void
256 {
257  ods_log_assert(engine);
258  ods_log_debug("[%s] wake up workers", engine_str);
259  schedule_release_all(engine->taskq);
260 }
261 
264 {
265  db_connection_t* dbconn;
266 
267  if (!(dbconn = db_connection_new())
268  || db_connection_set_configuration_list(dbconn, dbcfg_list)
269  || db_connection_setup(dbconn)
270  || db_connection_connect(dbconn))
271  {
272  db_connection_free(dbconn);
273  ods_log_crit("database connection failed");
274  return NULL;
275  }
276  return dbconn;
277 }
278 
279 /*
280  * Try to open a connection to the database and close it again.
281  * \param dbcfg_list, database configuration list
282  * \return 0 on success, 1 on failure.
283  */
284 static int
285 probe_database(db_configuration_list_t* dbcfg_list)
286 {
287  db_connection_t *conn;
288  int version;
289 
290  conn = get_database_connection(dbcfg_list);
291  if (!conn) return 1;
292  version = database_version_get_version(conn);
293  db_connection_free(conn);
294  return !version;
295 }
296 
297 /*
298  * Prepare for database connections and store dbcfg_list in engine
299  * if successfull the counterpart desetup_database() must be called
300  * when quitting the daemon.
301  * \param engine engine config where configuration list is stored
302  * \return 0 on succes, 1 on failure
303  */
304 static int
305 setup_database(engine_type* engine)
306 {
307  db_configuration_t* dbcfg;
308 
309  if (!(engine->dbcfg_list = db_configuration_list_new())) {
310  fprintf(stderr, "db_configuraiton_list_new failed\n");
311  return 1;
312  }
313  if (engine->config->db_type == ENFORCER_DATABASE_TYPE_SQLITE) {
314  if (!(dbcfg = db_configuration_new())
315  || db_configuration_set_name(dbcfg, "backend")
316  || db_configuration_set_value(dbcfg, "sqlite")
317  || db_configuration_list_add(engine->dbcfg_list, dbcfg))
318  {
319  db_configuration_free(dbcfg);
321  engine->dbcfg_list = NULL;
322  fprintf(stderr, "setup configuration backend failed\n");
323  return 1;
324  }
325  if (!(dbcfg = db_configuration_new())
326  || db_configuration_set_name(dbcfg, "file")
327  || db_configuration_set_value(dbcfg, engine->config->datastore)
328  || db_configuration_list_add(engine->dbcfg_list, dbcfg))
329  {
330  db_configuration_free(dbcfg);
332  engine->dbcfg_list = NULL;
333  fprintf(stderr, "setup configuration file failed\n");
334  return 1;
335  }
336  dbcfg = NULL;
337  }
338  else if (engine->config->db_type == ENFORCER_DATABASE_TYPE_MYSQL) {
339  if (!(dbcfg = db_configuration_new())
340  || db_configuration_set_name(dbcfg, "backend")
341  || db_configuration_set_value(dbcfg, "mysql")
342  || db_configuration_list_add(engine->dbcfg_list, dbcfg))
343  {
344  db_configuration_free(dbcfg);
346  engine->dbcfg_list = NULL;
347  fprintf(stderr, "setup configuration backend failed\n");
348  return 1;
349  }
350  if (!(dbcfg = db_configuration_new())
351  || db_configuration_set_name(dbcfg, "host")
352  || db_configuration_set_value(dbcfg, engine->config->db_host)
353  || db_configuration_list_add(engine->dbcfg_list, dbcfg))
354  {
355  db_configuration_free(dbcfg);
357  engine->dbcfg_list = NULL;
358  fprintf(stderr, "setup configuration file failed\n");
359  return 1;
360  }
361  dbcfg = NULL;
362  if (engine->config->db_port) {
363  char str[32];
364  if (snprintf(&str[0], sizeof(str), "%d", engine->config->db_port) >= (int)sizeof(str)) {
366  engine->dbcfg_list = NULL;
367  fprintf(stderr, "setup configuration file failed\n");
368  return 1;
369  }
370  if (!(dbcfg = db_configuration_new())
371  || db_configuration_set_name(dbcfg, "port")
372  || db_configuration_set_value(dbcfg, str)
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  if (!(dbcfg = db_configuration_new())
384  || db_configuration_set_name(dbcfg, "user")
385  || db_configuration_set_value(dbcfg, engine->config->db_username)
386  || db_configuration_list_add(engine->dbcfg_list, dbcfg))
387  {
388  db_configuration_free(dbcfg);
390  engine->dbcfg_list = NULL;
391  fprintf(stderr, "setup configuration file failed\n");
392  return 1;
393  }
394  dbcfg = NULL;
395  if (!(dbcfg = db_configuration_new())
396  || db_configuration_set_name(dbcfg, "pass")
397  || db_configuration_set_value(dbcfg, engine->config->db_password)
398  || db_configuration_list_add(engine->dbcfg_list, dbcfg))
399  {
400  db_configuration_free(dbcfg);
402  engine->dbcfg_list = NULL;
403  fprintf(stderr, "setup configuration file failed\n");
404  return 1;
405  }
406  dbcfg = NULL;
407  if (!(dbcfg = db_configuration_new())
408  || db_configuration_set_name(dbcfg, "db")
409  || db_configuration_set_value(dbcfg, engine->config->datastore)
410  || db_configuration_list_add(engine->dbcfg_list, dbcfg))
411  {
412  db_configuration_free(dbcfg);
414  engine->dbcfg_list = NULL;
415  fprintf(stderr, "setup configuration file failed\n");
416  return 1;
417  }
418  dbcfg = NULL;
419  }
420  else {
421  return 1;
422  }
423  return 0;
424 }
425 
426 /*
427  * destroy database configuration. Call only after all connections
428  * are closed.
429  * \param engine engine config where configuration list is stored
430  */
431 static void
432 desetup_database(engine_type* engine)
433 {
435  engine->dbcfg_list = NULL;
436 }
437 
442 ods_status
444 {
445  int fd;
446 
447  ods_log_debug("[%s] enforcer setup", engine_str);
448 
449  ods_log_init("ods-enforcerd", engine->config->use_syslog, engine->config->log_filename, engine->config->verbosity);
450 
451  engine->pid = getpid(); /* We need to do this again after fork() */
452 
453  if (!util_pidfile_avail(engine->config->pid_filename)) {
454  ods_log_error("[%s] Pidfile exists and process with PID is running", engine_str);
455  return ODS_STATUS_WRITE_PIDFILE_ERR;
456  }
457  /* setup database configuration */
458  if (setup_database(engine)) return ODS_STATUS_DB_ERR;
459  /* Probe the database, can we connect to it? */
460  if (probe_database(engine->dbcfg_list)) {
461  ods_log_crit("Could not connect to database or database not set"
462  " up properly.");
463  return ODS_STATUS_DB_ERR;
464  }
465 
466  /* create command handler (before chowning socket file) */
468  if (!engine->cmdhandler) {
469  ods_log_error("[%s] create command handler to %s failed",
470  engine_str, engine->config->clisock_filename);
471  return ODS_STATUS_CMDHANDLER_ERR;
472  }
473 
474  if (!engine->init_setup_done) {
475  /* privdrop */
476  engine->uid = privuid(engine->config->username);
477  engine->gid = privgid(engine->config->group);
478  /* TODO: does piddir exists? */
479  /* remove the chown stuff: piddir? */
480  ods_chown(engine->config->pid_filename, engine->uid, engine->gid, 1);
481  ods_chown(engine->config->clisock_filename, engine->uid, engine->gid, 0);
482  ods_chown(engine->config->working_dir, engine->uid, engine->gid, 0);
483  if (engine->config->log_filename && !engine->config->use_syslog) {
484  ods_chown(engine->config->log_filename, engine->uid, engine->gid, 0);
485  }
486  if (engine->config->working_dir &&
487  chdir(engine->config->working_dir) != 0) {
488  ods_log_error("[%s] chdir to %s failed: %s", engine_str,
489  engine->config->working_dir, strerror(errno));
490  return ODS_STATUS_CHDIR_ERR;
491  }
492  if (engine_privdrop(engine) != ODS_STATUS_OK) {
493  ods_log_error("[%s] unable to drop privileges", engine_str);
494  return ODS_STATUS_PRIVDROP_ERR;
495  }
496 
497  /* daemonize */
498  if (engine->daemonize) {
499  switch (fork()) {
500  case -1: /* error */
501  ods_log_error("[%s] unable to fork daemon: %s",
502  engine_str, strerror(errno));
503  return ODS_STATUS_FORK_ERR;
504  case 0: /* child */
505  if ((fd = open("/dev/null", O_RDWR, 0)) != -1) {
506  (void)dup2(fd, STDIN_FILENO);
507  (void)dup2(fd, STDOUT_FILENO);
508  (void)dup2(fd, STDERR_FILENO);
509  if (fd > 2) (void)close(fd);
510  }
511  engine->daemonize = 0; /* don't fork again on reload */
512  break;
513  default: /* parent */
514  exit(0);
515  }
516  if (setsid() == -1) {
517  ods_log_error("[%s] unable to setsid daemon (%s)",
518  engine_str, strerror(errno));
519  return ODS_STATUS_SETSID_ERR;
520  }
521  }
522  }
523  engine->init_setup_done = 1;
524 
525  engine->pid = getpid();
526  ods_log_info("[%s] running as pid %lu", engine_str,
527  (unsigned long) engine->pid);
528 
529  /* create workers */
530  engine_create_workers(engine);
531 
532  /* start command handler */
533  engine->cmdhandler_done = 0;
534 
535  /* write pidfile */
536  if (util_write_pidfile(engine->config->pid_filename, engine->pid) == -1) {
537  hsm_close();
538  ods_log_error("[%s] unable to write pid file", engine_str);
539  return ODS_STATUS_WRITE_PIDFILE_ERR;
540  }
541 
542  return ODS_STATUS_OK;
543 }
544 
549 void
551 {
552  size_t i = 0;
553 
554  if (!engine) return;
555  if (engine->config) {
556  if (engine->config->pid_filename) {
557  (void)unlink(engine->config->pid_filename);
558  }
559  if (engine->config->clisock_filename) {
560  (void)unlink(engine->config->clisock_filename);
561  }
562  }
563  if (engine->workers && engine->config) {
564  for (i=0; i < (size_t) engine->config->num_worker_threads; i++) {
565  worker_cleanup(engine->workers[i]);
566  }
567  free(engine->workers);
568  engine->workers = NULL;
569  }
570  if (engine->cmdhandler) {
572  engine->cmdhandler = NULL;
573  }
574  desetup_database(engine);
575 }
576 
577 void
579 {
580  struct sigaction action;
581 
582  engine->config = NULL;
583  engine->workers = NULL;
584  engine->cmdhandler = NULL;
585  engine->cmdhandler_done = 1;
586  engine->init_setup_done = 0;
587  engine->pid = getpid(); /* We need to do this again after fork() */
588  engine->uid = -1;
589  engine->gid = -1;
590  engine->need_to_exit = 0;
591  engine->need_to_reload = 0;
592  engine->daemonize = daemonize;
593  /* catch signals */
594  signal_set_engine(engine);
595  action.sa_handler = (void (*)(int))signal_handler;
596  sigfillset(&action.sa_mask);
597  action.sa_flags = 0;
598  sigaction(SIGHUP, &action, NULL);
599  sigaction(SIGTERM, &action, NULL);
600  sigaction(SIGINT, &action, NULL);
601  engine->dbcfg_list = NULL;
602 }
603 
608 int
609 engine_run(engine_type* engine, start_cb_t start, int single_run)
610 {
611  int error;
612  ods_log_assert(engine);
613  ods_log_info("[%s] enforcer started", engine_str);
614 
615  error = hsm_open2(engine->config->repositories, hsm_prompt_pin);
616  if (error != HSM_OK) {
617  char* errorstr = hsm_get_error(NULL);
618  if (errorstr != NULL) {
619  ods_log_error("[%s] %s", engine_str, errorstr);
620  free(errorstr);
621  } else {
622  ods_log_crit("[%s] error opening libhsm (errno %i)", engine_str,
623  error);
624  }
625  return 1;
626  }
627 
628  engine->need_to_reload = 0;
629  engine_start_cmdhandler(engine);
630  engine_start_workers(engine);
631 
632  /* call the external start callback function */
633  start(engine);
634 
635  while (!engine->need_to_exit && !engine->need_to_reload) {
636  if (single_run) {
637  engine->need_to_exit = 1;
638  /* FIXME: all tasks need to terminate, then set need_to_exit to 1 */
639  }
640 
641  /* We must use locking here to avoid race conditions. We want
642  * to sleep indefinitely and want to wake up on signal. This
643  * is to make sure we never mis the signal. */
644  pthread_mutex_lock(&engine->signal_lock);
645  if (!engine->need_to_exit && !engine->need_to_reload && !single_run) {
646  /* TODO: this silly. We should be handling the commandhandler
647  * connections. No reason to spawn that as a thread.
648  * Also it would be easier to wake up the command hander
649  * as signals will reach it if it is the main thread! */
650  ods_log_debug("[%s] taking a break", engine_str);
651  pthread_cond_wait(&engine->signal_cond, &engine->signal_lock);
652  }
653  pthread_mutex_unlock(&engine->signal_lock);
654  }
655  ods_log_debug("[%s] enforcer halted", engine_str);
656  engine_stop_workers(engine);
657  cmdhandler_stop(engine);
658  schedule_purge(engine->taskq); /* Remove old tasks in queue */
659  hsm_close();
660  return 0;
661 }
void engine_wakeup_workers(engine_type *engine)
Definition: engine.c:255
void cmdhandler_stop(struct engine_struct *engine)
Definition: cmdhandler.c:594
const char * datastore
Definition: cfg.h:68
schedule_type * schedule_create()
Definition: schedule.c:189
void engine_teardown(engine_type *engine)
Definition: engine.c:550
void ods_log_debug(const char *format,...)
Definition: log.c:41
int db_connection_setup(db_connection_t *connection)
Definition: db_connection.c:66
void engine_start_workers(engine_type *engine)
Definition: engine.c:214
db_configuration_t * db_configuration_new(void)
worker_type * worker_create(int num)
Definition: worker.c:46
const char * db_host
Definition: cfg.h:69
struct engine_struct * engine
Definition: cmdhandler.h:47
ods_status engine_setup(engine_type *engine)
Definition: engine.c:443
void ods_fatal_exit(const char *format,...)
Definition: log.c:94
int db_configuration_set_name(db_configuration_t *configuration, const char *name)
void ods_log_info(const char *format,...)
Definition: log.c:55
const char * group
Definition: cfg.h:66
void worker_start(worker_type *worker)
Definition: worker.c:99
void schedule_purge(schedule_type *schedule)
Definition: schedule.c:342
int need_to_exit
Definition: worker.h:53
void ods_log_error(const char *format,...)
Definition: log.c:69
void cmdhandler_start(cmdhandler_type *cmdhandler)
Definition: cmdhandler.c:457
void worker_cleanup(worker_type *worker)
Definition: worker.c:131
pthread_cond_t signal_cond
Definition: engine.h:69
struct engine_struct * engine
Definition: worker.h:46
void engine_stop_workers(engine_type *engine)
Definition: engine.c:230
int db_configuration_list_add(db_configuration_list_t *configuration_list, db_configuration_t *configuration)
const char * db_password
Definition: cfg.h:71
db_configuration_list_t * dbcfg_list
Definition: engine.h:74
int engine_run(engine_type *engine, start_cb_t start, int single_run)
Definition: engine.c:609
void ods_log_crit(const char *format,...)
Definition: log.c:80
const char * log_filename
Definition: cfg.h:59
const char * clisock_filename
Definition: cfg.h:63
void hsm_key_factory_deinit(void)
engineconfig_type * config
Definition: engine.h:53
void engine_init(engine_type *engine, int daemonize)
Definition: engine.c:578
void schedule_release_all(schedule_type *schedule)
Definition: schedule.c:475
pthread_t thread_id
Definition: worker.h:45
int num_worker_threads
Definition: cfg.h:73
void db_configuration_free(db_configuration_t *configuration)
hsm_repository_t * repositories
Definition: cfg.h:78
worker_type ** workers
Definition: engine.h:54
engine_type * engine_alloc(void)
Definition: engine.c:76
int init_setup_done
Definition: engine.h:58
int database_version_get_version(db_connection_t *connection)
const char * db_username
Definition: cfg.h:70
gid_t gid
Definition: engine.h:62
pid_t pid
Definition: engine.h:60
cmdhandler_type * cmdhandler
Definition: engine.h:56
void signal_set_engine(struct engine_struct *engine)
Definition: signal.c:52
db_connection_t * get_database_connection(db_configuration_list_t *dbcfg_list)
Definition: engine.c:263
db_connection_t * dbconn
Definition: worker.h:54
pthread_t thread_id
Definition: cmdhandler.h:49
pthread_mutex_t enforce_lock
Definition: engine.h:72
pthread_mutex_t signal_lock
Definition: engine.h:70
const char * working_dir
Definition: cfg.h:64
db_configuration_list_t * db_configuration_list_new(void)
int use_syslog
Definition: cfg.h:72
void ods_log_verbose(const char *format,...)
Definition: log.c:48
const char * username
Definition: cfg.h:65
int db_connection_set_configuration_list(db_connection_t *connection, const db_configuration_list_t *configuration_list)
Definition: db_connection.c:54
schedule_type * taskq
Definition: engine.h:55
cmdhandler_type * cmdhandler_create(const char *filename)
Definition: cmdhandler.c:367
void db_connection_free(db_connection_t *connection)
Definition: db_connection.c:45
void * signal_handler(sig_atomic_t sig)
Definition: signal.c:63
void schedule_cleanup(schedule_type *schedule)
Definition: schedule.c:220
int daemonize
Definition: engine.h:64
int need_to_exit
Definition: engine.h:65
int db_configuration_set_value(db_configuration_t *configuration, const char *value)
engineconfig_database_type_t db_type
Definition: cfg.h:79
int need_to_reload
Definition: engine.h:66
const char * pid_filename
Definition: cfg.h:60
const char * chroot
Definition: cfg.h:67
void engine_dealloc(engine_type *engine)
Definition: engine.c:96
int db_connection_connect(const db_connection_t *connection)
Definition: db_connection.c:88
void(* start_cb_t)(engine_type *engine)
Definition: engine.h:104
void cmdhandler_cleanup(cmdhandler_type *cmdhandler)
Definition: cmdhandler.c:446
db_connection_t * db_connection_new(void)
Definition: db_connection.c:38
int cmdhandler_done
Definition: engine.h:57
uid_t uid
Definition: engine.h:61
void db_configuration_list_free(db_configuration_list_t *configuration_list)