summaryrefslogtreecommitdiff
path: root/daemons/dmeventd/dmeventd.c
diff options
context:
space:
mode:
Diffstat (limited to 'daemons/dmeventd/dmeventd.c')
-rw-r--r--daemons/dmeventd/dmeventd.c373
1 files changed, 258 insertions, 115 deletions
diff --git a/daemons/dmeventd/dmeventd.c b/daemons/dmeventd/dmeventd.c
index 2b454f9..13148c3 100644
--- a/daemons/dmeventd/dmeventd.c
+++ b/daemons/dmeventd/dmeventd.c
@@ -39,13 +39,27 @@
#include <arpa/inet.h> /* for htonl, ntohl */
#ifdef linux
-# include <malloc.h>
-
-# define OOM_ADJ_FILE "/proc/self/oom_adj"
+/*
+ * Kernel version 2.6.36 and higher has
+ * new OOM killer adjustment interface.
+ */
+# define OOM_ADJ_FILE_OLD "/proc/self/oom_adj"
+# define OOM_ADJ_FILE "/proc/self/oom_score_adj"
/* From linux/oom.h */
+/* Old interface */
# define OOM_DISABLE (-17)
# define OOM_ADJUST_MIN (-16)
+/* New interface */
+# define OOM_SCORE_ADJ_MIN (-1000)
+
+/* Systemd on-demand activation support */
+# define SD_ACTIVATION_ENV_VAR_NAME "SD_ACTIVATION"
+# define SD_LISTEN_PID_ENV_VAR_NAME "LISTEN_PID"
+# define SD_LISTEN_FDS_ENV_VAR_NAME "LISTEN_FDS"
+# define SD_LISTEN_FDS_START 3
+# define SD_FD_FIFO_SERVER SD_LISTEN_FDS_START
+# define SD_FD_FIFO_CLIENT (SD_LISTEN_FDS_START + 1)
#endif
@@ -95,9 +109,8 @@ static pthread_mutex_t _global_mutex;
#define THREAD_STACK_SIZE (300*1024)
-#define DEBUGLOG(fmt, args...) _debuglog(fmt, ## args)
-
int dmeventd_debug = 0;
+static int _systemd_activation = 0;
static int _foreground = 0;
static int _restart = 0;
static char **_initial_registrations = 0;
@@ -203,24 +216,6 @@ static DM_LIST_INIT(_timeout_registry);
static pthread_mutex_t _timeout_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t _timeout_cond = PTHREAD_COND_INITIALIZER;
-static void _debuglog(const char *fmt, ...)
-{
- time_t P;
- va_list ap;
-
- if (!_foreground)
- return;
-
- va_start(ap,fmt);
-
- time(&P);
- fprintf(stderr, "dmeventd[%p]: %.15s ", (void *) pthread_self(), ctime(&P)+4 );
- vfprintf(stderr, fmt, ap);
- fprintf(stderr, "\n");
-
- va_end(ap);
-}
-
/* Allocate/free the status structure for a monitoring thread. */
static struct thread_status *_alloc_thread_status(struct message_data *data,
struct dso_data *dso_data)
@@ -407,7 +402,9 @@ static int _fill_device_data(struct thread_status *ts)
if (!dmt)
return 0;
- dm_task_set_uuid(dmt, ts->device.uuid);
+ if (!dm_task_set_uuid(dmt, ts->device.uuid))
+ goto fail;
+
if (!dm_task_run(dmt))
goto fail;
@@ -450,7 +447,7 @@ static int _get_status(struct message_data *message_data)
{
struct dm_event_daemon_message *msg = message_data->msg;
struct thread_status *thread;
- int i = 0, j = 0;
+ int i, j;
int ret = -1;
int count = dm_list_size(&_thread_registry);
int size = 0, current = 0;
@@ -585,6 +582,7 @@ static void _unregister_for_timeout(struct thread_status *thread)
pthread_mutex_unlock(&_timeout_mutex);
}
+__attribute__((format(printf, 4, 5)))
static void _no_intr_log(int level, const char *file, int line,
const char *f, ...)
{
@@ -740,8 +738,10 @@ static void _monitor_unregister(void *arg)
return;
}
thread->status = DM_THREAD_DONE;
+ pthread_mutex_lock(&_timeout_mutex);
UNLINK_THREAD(thread);
LINK(thread, &_thread_registry_unused);
+ pthread_mutex_unlock(&_timeout_mutex);
_unlock_mutex();
}
@@ -752,7 +752,10 @@ static struct dm_task *_get_device_status(struct thread_status *ts)
if (!dmt)
return NULL;
- dm_task_set_uuid(dmt, ts->device.uuid);
+ if (!dm_task_set_uuid(dmt, ts->device.uuid)) {
+ dm_task_destroy(dmt);
+ return NULL;
+ }
if (!dm_task_run(dmt)) {
dm_task_destroy(dmt);
@@ -996,10 +999,8 @@ static int _register_for_event(struct message_data *message_data)
almost as good as dead already... */
if (thread_new->events & DM_EVENT_TIMEOUT) {
ret = -_register_for_timeout(thread_new);
- if (ret) {
- _unlock_mutex();
- goto out;
- }
+ if (ret)
+ goto outth;
}
if (!(thread = _lookup_thread_status(message_data))) {
@@ -1025,6 +1026,7 @@ static int _register_for_event(struct message_data *message_data)
/* Or event # into events bitfield. */
thread->events |= message_data->events.field;
+ outth:
_unlock_mutex();
out:
@@ -1076,8 +1078,10 @@ static int _unregister_for_event(struct message_data *message_data)
* unlink and terminate its monitoring thread.
*/
if (!thread->events) {
+ pthread_mutex_lock(&_timeout_mutex);
UNLINK_THREAD(thread);
LINK(thread, &_thread_registry_unused);
+ pthread_mutex_unlock(&_timeout_mutex);
}
_unlock_mutex();
@@ -1099,15 +1103,19 @@ static int _registered_device(struct message_data *message_data,
const char *id = message_data->id;
const char *dso = thread->dso_data->dso_name;
const char *dev = thread->device.uuid;
+ int r;
unsigned events = ((thread->status == DM_THREAD_RUNNING)
&& (thread->events)) ? thread->events : thread->
events | DM_EVENT_REGISTRATION_PENDING;
dm_free(msg->data);
- msg->size = dm_asprintf(&(msg->data), fmt, id, dso, dev, events);
+ if ((r = dm_asprintf(&(msg->data), fmt, id, dso, dev, events)) < 0) {
+ msg->size = 0;
+ return -ENOMEM;
+ }
- _unlock_mutex();
+ msg->size = (uint32_t) r;
return 0;
}
@@ -1140,6 +1148,7 @@ static int _want_registered_device(char *dso_name, char *device_uuid,
static int _get_registered_dev(struct message_data *message_data, int next)
{
struct thread_status *thread, *hit = NULL;
+ int ret = -ENOENT;
_lock_mutex();
@@ -1156,16 +1165,12 @@ static int _get_registered_dev(struct message_data *message_data, int next)
* If we got a registered device and want the next one ->
* fetch next conforming element off the list.
*/
- if (hit && !next) {
- _unlock_mutex();
- return _registered_device(message_data, hit);
- }
+ if (hit && !next)
+ goto reg;
if (!hit)
goto out;
- thread = hit;
-
while (1) {
if (dm_list_end(&_thread_registry, &thread->list))
goto out;
@@ -1177,13 +1182,13 @@ static int _get_registered_dev(struct message_data *message_data, int next)
}
}
- _unlock_mutex();
- return _registered_device(message_data, hit);
+ reg:
+ ret = _registered_device(message_data, hit);
out:
_unlock_mutex();
-
- return -ENOENT;
+
+ return ret;
}
static int _get_registered_device(struct message_data *message_data)
@@ -1241,68 +1246,66 @@ static void _init_fifos(struct dm_event_fifos *fifos)
/* Open fifos used for client communication. */
static int _open_fifos(struct dm_event_fifos *fifos)
{
- int orig_errno;
+ struct stat st;
/* Create client fifo. */
(void) dm_prepare_selinux_context(fifos->client_path, S_IFIFO);
if ((mkfifo(fifos->client_path, 0600) == -1) && errno != EEXIST) {
- syslog(LOG_ERR, "%s: Failed to create client fifo.\n", __func__);
- orig_errno = errno;
+ syslog(LOG_ERR, "%s: Failed to create client fifo %s: %m.\n",
+ __func__, fifos->client_path);
(void) dm_prepare_selinux_context(NULL, 0);
- stack;
- return -orig_errno;
+ return 0;
}
/* Create server fifo. */
(void) dm_prepare_selinux_context(fifos->server_path, S_IFIFO);
if ((mkfifo(fifos->server_path, 0600) == -1) && errno != EEXIST) {
- syslog(LOG_ERR, "%s: Failed to create server fifo.\n", __func__);
- orig_errno = errno;
+ syslog(LOG_ERR, "%s: Failed to create server fifo %s: %m.\n",
+ __func__, fifos->server_path);
(void) dm_prepare_selinux_context(NULL, 0);
- stack;
- return -orig_errno;
+ return 0;
}
(void) dm_prepare_selinux_context(NULL, 0);
- struct stat st;
-
/* Warn about wrong permissions if applicable */
if ((!stat(fifos->client_path, &st)) && (st.st_mode & 0777) != 0600)
- syslog(LOG_WARNING, "Fixing wrong permissions on %s",
+ syslog(LOG_WARNING, "Fixing wrong permissions on %s: %m.\n",
fifos->client_path);
if ((!stat(fifos->server_path, &st)) && (st.st_mode & 0777) != 0600)
- syslog(LOG_WARNING, "Fixing wrong permissions on %s",
+ syslog(LOG_WARNING, "Fixing wrong permissions on %s: %m.\n",
fifos->server_path);
/* If they were already there, make sure permissions are ok. */
if (chmod(fifos->client_path, 0600)) {
- syslog(LOG_ERR, "Unable to set correct file permissions on %s",
+ syslog(LOG_ERR, "Unable to set correct file permissions on %s: %m.\n",
fifos->client_path);
- return -errno;
+ return 0;
}
if (chmod(fifos->server_path, 0600)) {
- syslog(LOG_ERR, "Unable to set correct file permissions on %s",
+ syslog(LOG_ERR, "Unable to set correct file permissions on %s: %m.\n",
fifos->server_path);
- return -errno;
+ return 0;
}
/* Need to open read+write or we will block or fail */
if ((fifos->server = open(fifos->server_path, O_RDWR)) < 0) {
- stack;
- return -errno;
+ syslog(LOG_ERR, "Failed to open fifo server %s: %m.\n",
+ fifos->server_path);
+ return 0;
}
/* Need to open read+write for select() to work. */
if ((fifos->client = open(fifos->client_path, O_RDWR)) < 0) {
- stack;
- close(fifos->server);
- return -errno;
+ syslog(LOG_ERR, "Failed to open fifo client %s: %m", fifos->client_path);
+ if (close(fifos->server))
+ syslog(LOG_ERR, "Failed to close fifo server %s: %m", fifos->server_path);
+ return 0;
}
- return 0;
+ return 1;
}
/*
@@ -1405,7 +1408,7 @@ static int _client_write(struct dm_event_fifos *fifos,
static int _handle_request(struct dm_event_daemon_message *msg,
struct message_data *message_data)
{
- static struct {
+ static struct request {
unsigned int cmd;
int (*f)(struct message_data *);
} requests[] = {
@@ -1420,7 +1423,7 @@ static int _handle_request(struct dm_event_daemon_message *msg,
{ DM_EVENT_CMD_GET_STATUS, _get_status},
}, *req;
- for (req = requests; req < requests + sizeof(requests); req++)
+ for (req = requests; req < requests + sizeof(requests) / sizeof(struct request); req++)
if (req->cmd == msg->cmd)
return req->f(message_data);
@@ -1432,17 +1435,16 @@ static int _do_process_request(struct dm_event_daemon_message *msg)
{
int ret;
char *answer;
- static struct message_data message_data;
+ struct message_data message_data = { .msg = msg };
/* Parse the message. */
- memset(&message_data, 0, sizeof(message_data));
- message_data.msg = msg;
if (msg->cmd == DM_EVENT_CMD_HELLO || msg->cmd == DM_EVENT_CMD_DIE) {
ret = 0;
answer = msg->data;
if (answer) {
- msg->size = dm_asprintf(&(msg->data), "%s %s", answer,
- msg->cmd == DM_EVENT_CMD_DIE ? "DYING" : "HELLO");
+ msg->size = dm_asprintf(&(msg->data), "%s %s %d", answer,
+ msg->cmd == DM_EVENT_CMD_DIE ? "DYING" : "HELLO",
+ DM_EVENT_PROTOCOL_VERSION);
dm_free(answer);
} else {
msg->size = 0;
@@ -1467,9 +1469,7 @@ static int _do_process_request(struct dm_event_daemon_message *msg)
static void _process_request(struct dm_event_fifos *fifos)
{
int die = 0;
- struct dm_event_daemon_message msg;
-
- memset(&msg, 0, sizeof(msg));
+ struct dm_event_daemon_message msg = { 0 };
/*
* Read the request from the client (client_read, client_write
@@ -1488,9 +1488,9 @@ static void _process_request(struct dm_event_fifos *fifos)
if (!_client_write(fifos, &msg))
stack;
- if (die) raise(9);
-
dm_free(msg.data);
+
+ if (die) raise(9);
}
static void _process_initial_registrations(void)
@@ -1501,9 +1501,10 @@ static void _process_initial_registrations(void)
while ((reg = _initial_registrations[i])) {
msg.cmd = DM_EVENT_CMD_REGISTER_FOR_EVENT;
- msg.size = strlen(reg);
- msg.data = reg;
- _do_process_request(&msg);
+ if ((msg.size = strlen(reg))) {
+ msg.data = reg;
+ _do_process_request(&msg);
+ }
++ i;
}
}
@@ -1513,6 +1514,7 @@ static void _cleanup_unused_threads(void)
int ret;
struct dm_list *l;
struct thread_status *thread;
+ int join_ret = 0;
_lock_mutex();
while ((l = dm_list_first(&_thread_registry_unused))) {
@@ -1552,12 +1554,15 @@ static void _cleanup_unused_threads(void)
if (thread->status == DM_THREAD_DONE) {
dm_list_del(l);
- pthread_join(thread->thread, NULL);
+ join_ret = pthread_join(thread->thread, NULL);
_free_thread_status(thread);
}
}
_unlock_mutex();
+
+ if (join_ret)
+ syslog(LOG_ERR, "Failed pthread_join: %s\n", strerror(join_ret));
}
static void _sig_alarm(int signum __attribute__((unused)))
@@ -1569,10 +1574,8 @@ static void _sig_alarm(int signum __attribute__((unused)))
static void _init_thread_signals(void)
{
sigset_t my_sigset;
- struct sigaction act;
+ struct sigaction act = { .sa_handler = _sig_alarm };
- memset(&act, 0, sizeof(act));
- act.sa_handler = _sig_alarm;
sigaction(SIGALRM, &act, NULL);
sigfillset(&my_sigset);
@@ -1610,40 +1613,138 @@ static void _exit_handler(int sig __attribute__((unused)))
}
#ifdef linux
+static int _set_oom_adj(const char *oom_adj_path, int val)
+{
+ FILE *fp;
+
+ if (!(fp = fopen(oom_adj_path, "w"))) {
+ perror("oom_adj: fopen failed");
+ return 0;
+ }
+
+ fprintf(fp, "%i", val);
+
+ if (dm_fclose(fp))
+ perror("oom_adj: fclose failed");
+
+ return 1;
+}
+
/*
* Protection against OOM killer if kernel supports it
*/
-static int _set_oom_adj(int val)
+static int _protect_against_oom_killer(void)
{
- FILE *fp;
-
struct stat st;
if (stat(OOM_ADJ_FILE, &st) == -1) {
- if (errno == ENOENT)
- DEBUGLOG(OOM_ADJ_FILE " not found");
- else
+ if (errno != ENOENT)
perror(OOM_ADJ_FILE ": stat failed");
- return 1;
+
+ /* Try old oom_adj interface as a fallback */
+ if (stat(OOM_ADJ_FILE_OLD, &st) == -1) {
+ if (errno == ENOENT)
+ perror(OOM_ADJ_FILE_OLD " not found");
+ else
+ perror(OOM_ADJ_FILE_OLD ": stat failed");
+ return 1;
+ }
+
+ return _set_oom_adj(OOM_ADJ_FILE_OLD, OOM_DISABLE) ||
+ _set_oom_adj(OOM_ADJ_FILE_OLD, OOM_ADJUST_MIN);
}
- if (!(fp = fopen(OOM_ADJ_FILE, "w"))) {
- perror(OOM_ADJ_FILE ": fopen failed");
+ return _set_oom_adj(OOM_ADJ_FILE, OOM_SCORE_ADJ_MIN);
+}
+
+static int _handle_preloaded_fifo(int fd, const char *path)
+{
+ struct stat st_fd, st_path;
+ int flags;
+
+ if ((flags = fcntl(fd, F_GETFD)) < 0)
return 0;
- }
- fprintf(fp, "%i", val);
- if (dm_fclose(fp))
- perror(OOM_ADJ_FILE ": fclose failed");
+ if (flags & FD_CLOEXEC)
+ return 0;
+
+ if (fstat(fd, &st_fd) < 0 || !S_ISFIFO(st_fd.st_mode))
+ return 0;
+
+ if (stat(path, &st_path) < 0 ||
+ st_path.st_dev != st_fd.st_dev ||
+ st_path.st_ino != st_fd.st_ino)
+ return 0;
+
+ if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) < 0)
+ return 0;
return 1;
}
+
+static int _systemd_handover(struct dm_event_fifos *fifos)
+{
+ const char *e;
+ char *p;
+ unsigned long env_pid, env_listen_fds;
+ int r = 0;
+
+ memset(fifos, 0, sizeof(*fifos));
+
+ /* SD_ACTIVATION must be set! */
+ if (!(e = getenv(SD_ACTIVATION_ENV_VAR_NAME)) || strcmp(e, "1"))
+ goto out;
+
+ /* LISTEN_PID must be equal to our PID! */
+ if (!(e = getenv(SD_LISTEN_PID_ENV_VAR_NAME)))
+ goto out;
+
+ errno = 0;
+ env_pid = strtoul(e, &p, 10);
+ if (errno || !p || *p || env_pid <= 0 ||
+ getpid() != (pid_t) env_pid)
+ goto out;
+
+ /* LISTEN_FDS must be 2 and the fds must be FIFOSs! */
+ if (!(e = getenv(SD_LISTEN_FDS_ENV_VAR_NAME)))
+ goto out;
+
+ errno = 0;
+ env_listen_fds = strtoul(e, &p, 10);
+ if (errno || !p || *p || env_listen_fds != 2)
+ goto out;
+
+ /* Check and handle the FIFOs passed in */
+ r = (_handle_preloaded_fifo(SD_FD_FIFO_SERVER, DM_EVENT_FIFO_SERVER) &&
+ _handle_preloaded_fifo(SD_FD_FIFO_CLIENT, DM_EVENT_FIFO_CLIENT));
+
+ if (r) {
+ fifos->server = SD_FD_FIFO_SERVER;
+ fifos->server_path = DM_EVENT_FIFO_SERVER;
+ fifos->client = SD_FD_FIFO_CLIENT;
+ fifos->client_path = DM_EVENT_FIFO_CLIENT;
+ }
+
+out:
+ unsetenv(SD_ACTIVATION_ENV_VAR_NAME);
+ unsetenv(SD_LISTEN_PID_ENV_VAR_NAME);
+ unsetenv(SD_LISTEN_FDS_ENV_VAR_NAME);
+ return r;
+}
#endif
-static void remove_lockfile(void)
+static void _remove_files_on_exit(void)
{
if (unlink(DMEVENTD_PIDFILE))
perror(DMEVENTD_PIDFILE ": unlink failed");
+
+ if (!_systemd_activation) {
+ if (unlink(DM_EVENT_FIFO_CLIENT))
+ perror(DM_EVENT_FIFO_CLIENT " : unlink failed");
+
+ if (unlink(DM_EVENT_FIFO_SERVER))
+ perror(DM_EVENT_FIFO_SERVER " : unlink failed");
+ }
}
static void _daemonize(void)
@@ -1703,8 +1804,15 @@ static void _daemonize(void)
else
fd = rlim.rlim_cur;
- for (--fd; fd >= 0; fd--)
- close(fd);
+ for (--fd; fd >= 0; fd--) {
+#ifdef linux
+ /* Do not close fds preloaded by systemd! */
+ if (_systemd_activation &&
+ (fd == SD_FD_FIFO_SERVER || fd == SD_FD_FIFO_CLIENT))
+ continue;
+#endif
+ (void) close(fd);
+ }
if ((open("/dev/null", O_RDONLY) < 0) ||
(open("/dev/null", O_WRONLY) < 0) ||
@@ -1721,16 +1829,25 @@ static void restart(void)
int i, count = 0;
char *message;
int length;
+ int version;
/* Get the list of registrations from the running daemon. */
if (!init_fifos(&fifos)) {
- fprintf(stderr, "Could not initiate communication with existing dmeventd.\n");
+ fprintf(stderr, "WARNING: Could not initiate communication with existing dmeventd.\n");
+ exit(EXIT_FAILURE);
+ }
+
+ if (!dm_event_get_version(&fifos, &version)) {
+ fprintf(stderr, "WARNING: Could not communicate with existing dmeventd.\n");
+ fini_fifos(&fifos);
exit(EXIT_FAILURE);
}
- if (daemon_talk(&fifos, &msg, DM_EVENT_CMD_HELLO, NULL, NULL, 0, 0)) {
- fprintf(stderr, "Could not communicate with existing dmeventd.\n");
+ if (version < 1) {
+ fprintf(stderr, "WARNING: The running dmeventd instance is too old.\n"
+ "Protocol version %d (required: 1). Action cancelled.\n",
+ version);
exit(EXIT_FAILURE);
}
@@ -1749,9 +1866,16 @@ static void restart(void)
}
}
- _initial_registrations = dm_malloc(sizeof(char*) * (count + 1));
+ if (!(_initial_registrations = dm_malloc(sizeof(char*) * (count + 1)))) {
+ fprintf(stderr, "Memory allocation registration failed.\n");
+ exit(EXIT_FAILURE);
+ }
+
for (i = 0; i < count; ++i) {
- _initial_registrations[i] = dm_strdup(message);
+ if (!(_initial_registrations[i] = dm_strdup(message))) {
+ fprintf(stderr, "Memory allocation for message failed.\n");
+ exit(EXIT_FAILURE);
+ }
message += strlen(message) + 1;
}
_initial_registrations[count] = 0;
@@ -1761,17 +1885,28 @@ static void restart(void)
exit(EXIT_FAILURE);
}
+ /*
+ * Wait for daemon to die, detected by sending further DIE messages
+ * until one fails.
+ */
+ for (i = 0; i < 10; ++i) {
+ if (daemon_talk(&fifos, &msg, DM_EVENT_CMD_DIE, "-", "-", 0, 0))
+ break; /* yep, it's dead probably */
+ usleep(10);
+ }
+
fini_fifos(&fifos);
}
static void usage(char *prog, FILE *file)
{
fprintf(file, "Usage:\n"
- "%s [-V] [-h] [-d] [-d] [-d] [-f]\n\n"
- " -V Show version of dmeventd\n"
- " -h Show this help information\n"
+ "%s [-d [-d [-d]]] [-f] [-h] [-R] [-V] [-?]\n\n"
" -d Log debug messages to syslog (-d, -dd, -ddd)\n"
- " -f Don't fork, run in the foreground\n\n", prog);
+ " -f Don't fork, run in the foreground\n"
+ " -h -? Show this help information\n"
+ " -R Restart dmeventd\n"
+ " -V Show version of dmeventd\n\n", prog);
}
int main(int argc, char *argv[])
@@ -1803,7 +1938,6 @@ int main(int argc, char *argv[])
case 'V':
printf("dmeventd version: %s\n", DM_LIB_VERSION);
exit(1);
- break;
}
}
@@ -1818,6 +1952,10 @@ int main(int argc, char *argv[])
if (_restart)
restart();
+#ifdef linux
+ _systemd_activation = _systemd_handover(&fifos);
+#endif
+
if (!_foreground)
_daemonize();
@@ -1827,17 +1965,19 @@ int main(int argc, char *argv[])
if (dm_create_lockfile(DMEVENTD_PIDFILE) == 0)
exit(EXIT_FAILURE);
- atexit(remove_lockfile);
+ atexit(_remove_files_on_exit);
(void) dm_prepare_selinux_context(NULL, 0);
/* Set the rest of the signals to cause '_exit_now' to be set */
+ signal(SIGTERM, &_exit_handler);
signal(SIGINT, &_exit_handler);
signal(SIGHUP, &_exit_handler);
signal(SIGQUIT, &_exit_handler);
#ifdef linux
- if (!_set_oom_adj(OOM_DISABLE) && !_set_oom_adj(OOM_ADJUST_MIN))
- syslog(LOG_ERR, "Failed to set oom_adj to protect against OOM killer");
+ /* Systemd has adjusted oom killer for us already */
+ if (!_systemd_activation && !_protect_against_oom_killer())
+ syslog(LOG_ERR, "Failed to protect against OOM killer");
#endif
_init_thread_signals();
@@ -1847,11 +1987,12 @@ int main(int argc, char *argv[])
//multilog_init_verbose(std_syslog, _LOG_DEBUG);
//multilog_async(1);
- _init_fifos(&fifos);
+ if (!_systemd_activation)
+ _init_fifos(&fifos);
pthread_mutex_init(&_global_mutex, NULL);
- if (_open_fifos(&fifos))
+ if (!_systemd_activation && !_open_fifos(&fifos))
exit(EXIT_FIFO_FAILURE);
/* Signal parent, letting them know we are ready to go. */
@@ -1865,11 +2006,13 @@ int main(int argc, char *argv[])
while (!_exit_now) {
_process_request(&fifos);
_cleanup_unused_threads();
+ _lock_mutex();
if (!dm_list_empty(&_thread_registry)
|| !dm_list_empty(&_thread_registry_unused))
_thread_registries_empty = 0;
else
_thread_registries_empty = 1;
+ _unlock_mutex();
}
_exit_dm_lib();