2
* Copyright (C) 2005-2007 Red Hat, Inc. All rights reserved.
4
* This file is part of the device-mapper userspace tools.
6
* This copyrighted material is made available to anyone wishing to use,
7
* modify, copy, or redistribute it subject to the terms and conditions
8
* of the GNU Lesser General Public License v.2.1.
10
* You should have received a copy of the GNU Lesser General Public License
11
* along with this program; if not, write to the Free Software Foundation,
12
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16
* dmeventd - dm event daemon to monitor active mapped devices
20
#define _FILE_OFFSET_BITS 64
22
#include "configure.h"
23
#include "libdevmapper.h"
24
#include "libdevmapper-event.h"
26
//#include "libmultilog.h"
27
#include "dm-logging.h"
36
#include <sys/resource.h>
39
#include <arpa/inet.h> /* for htonl, ntohl */
45
* Kernel version 2.6.36 and higher has
46
* new OOM killer adjustment interface.
48
# define OOM_ADJ_FILE_OLD "/proc/self/oom_adj"
49
# define OOM_ADJ_FILE "/proc/self/oom_score_adj"
51
/* From linux/oom.h */
53
# define OOM_DISABLE (-17)
54
# define OOM_ADJUST_MIN (-16)
56
# define OOM_SCORE_ADJ_MIN (-1000)
58
/* Systemd on-demand activation support */
59
# define SD_LISTEN_PID_ENV_VAR_NAME "LISTEN_PID"
60
# define SD_LISTEN_FDS_ENV_VAR_NAME "LISTEN_FDS"
61
# define SD_LISTEN_FDS_START 3
62
# define SD_FD_FIFO_SERVER SD_LISTEN_FDS_START
63
# define SD_FD_FIFO_CLIENT (SD_LISTEN_FDS_START + 1)
67
/* FIXME We use syslog for now, because multilog is not yet implemented */
70
static volatile sig_atomic_t _exit_now = 0; /* set to '1' when signal is given to exit */
71
static volatile sig_atomic_t _thread_registries_empty = 1; /* registries are empty initially */
73
/* List (un)link macros. */
74
#define LINK(x, head) dm_list_add(head, &(x)->list)
75
#define LINK_DSO(dso) LINK(dso, &_dso_registry)
76
#define LINK_THREAD(thread) LINK(thread, &_thread_registry)
78
#define UNLINK(x) dm_list_del(&(x)->list)
79
#define UNLINK_DSO(x) UNLINK(x)
80
#define UNLINK_THREAD(x) UNLINK(x)
82
#define DAEMON_NAME "dmeventd"
85
Global mutex for thread list access. Has to be held when:
86
- iterating thread list
87
- adding or removing elements from thread list
88
- changing or reading thread_status's fields:
89
processing, status, events
90
Use _lock_mutex() and _unlock_mutex() to hold/release it
92
static pthread_mutex_t _global_mutex;
95
There are three states a thread can attain (see struct
96
thread_status, field int status):
98
- DM_THREAD_RUNNING: thread has started up and is either working or
99
waiting for events... transitions to either SHUTDOWN or DONE
100
- DM_THREAD_SHUTDOWN: thread is still doing something, but it is
101
supposed to terminate (and transition to DONE) as soon as it
102
finishes whatever it was doing at the point of flipping state to
103
SHUTDOWN... the thread is still on the thread list
104
- DM_THREAD_DONE: thread has terminated and has been moved over to
105
unused thread list, cleanup pending
107
#define DM_THREAD_RUNNING 0
108
#define DM_THREAD_SHUTDOWN 1
109
#define DM_THREAD_DONE 2
111
#define THREAD_STACK_SIZE (300*1024)
113
int dmeventd_debug = 0;
114
static int _systemd_activation = 0;
115
static int _foreground = 0;
116
static int _restart = 0;
117
static char **_initial_registrations = 0;
119
/* Data kept about a DSO. */
123
char *dso_name; /* DSO name (eg, "evms", "dmraid", "lvm2"). */
125
void *dso_handle; /* Opaque handle as returned from dlopen(). */
126
unsigned int ref_count; /* Library reference count. */
131
* The DSO can do whatever appropriate steps if an event
132
* happens such as changing the mapping in case a mirror
133
* fails, update the application metadata etc.
135
* This function gets a dm_task that is a result of
136
* DM_DEVICE_WAITEVENT ioctl (results equivalent to
137
* DM_DEVICE_STATUS). It should not destroy it.
138
* The caller must dispose of the task.
140
void (*process_event)(struct dm_task *dmt, enum dm_event_mask event, void **user);
143
* Device registration.
145
* When an application registers a device for an event, the DSO
146
* can carry out appropriate steps so that a later call to
147
* the process_event() function is sane (eg, read metadata
148
* and activate a mapping).
150
int (*register_device)(const char *device, const char *uuid, int major,
151
int minor, void **user);
154
* Device unregistration.
156
* In case all devices of a mapping (eg, RAID10) are unregistered
157
* for events, the DSO can recognize this and carry out appropriate
158
* steps (eg, deactivate mapping, metadata update).
160
int (*unregister_device)(const char *device, const char *uuid,
161
int major, int minor, void **user);
163
static DM_LIST_INIT(_dso_registry);
165
/* Structure to keep parsed register variables from client message. */
166
struct message_data {
168
char *dso_name; /* Name of DSO. */
169
char *device_uuid; /* Mapped device path. */
171
char *str; /* Events string as fetched from message. */
172
enum dm_event_mask field; /* Events bitfield. */
178
struct dm_event_daemon_message *msg; /* Pointer to message buffer. */
182
* Housekeeping of thread+device states.
184
* One thread per mapped device which can block on it until an event
185
* occurs and the event processing function of the DSO gets called.
187
struct thread_status {
192
struct dso_data *dso_data; /* DSO this thread accesses. */
199
uint32_t event_nr; /* event number */
200
int processing; /* Set when event is being processed */
202
int status; /* see DM_THREAD_{RUNNING,SHUTDOWN,DONE}
204
enum dm_event_mask events; /* bitfield for event filter. */
205
enum dm_event_mask current_events; /* bitfield for occured events. */
206
struct dm_task *current_task;
209
struct dm_list timeout_list;
210
void *dso_private; /* dso per-thread status variable */
212
static DM_LIST_INIT(_thread_registry);
213
static DM_LIST_INIT(_thread_registry_unused);
215
static int _timeout_running;
216
static DM_LIST_INIT(_timeout_registry);
217
static pthread_mutex_t _timeout_mutex = PTHREAD_MUTEX_INITIALIZER;
218
static pthread_cond_t _timeout_cond = PTHREAD_COND_INITIALIZER;
220
/* Allocate/free the status structure for a monitoring thread. */
221
static struct thread_status *_alloc_thread_status(struct message_data *data,
222
struct dso_data *dso_data)
224
struct thread_status *ret = (typeof(ret)) dm_zalloc(sizeof(*ret));
229
if (!(ret->device.uuid = dm_strdup(data->device_uuid))) {
234
ret->current_task = NULL;
235
ret->device.name = NULL;
236
ret->device.major = ret->device.minor = 0;
237
ret->dso_data = dso_data;
238
ret->events = data->events.field;
239
ret->timeout = data->timeout.secs;
240
dm_list_init(&ret->timeout_list);
245
static void _lib_put(struct dso_data *data);
246
static void _free_thread_status(struct thread_status *thread)
248
_lib_put(thread->dso_data);
249
if (thread->current_task)
250
dm_task_destroy(thread->current_task);
251
dm_free(thread->device.uuid);
252
dm_free(thread->device.name);
256
/* Allocate/free DSO data. */
257
static struct dso_data *_alloc_dso_data(struct message_data *data)
259
struct dso_data *ret = (typeof(ret)) dm_zalloc(sizeof(*ret));
264
if (!(ret->dso_name = dm_strdup(data->dso_name))) {
272
/* Create a device monitoring thread. */
273
static int _pthread_create_smallstack(pthread_t *t, void *(*fun)(void *), void *arg)
276
pthread_attr_init(&attr);
278
* We use a smaller stack since it gets preallocated in its entirety
280
pthread_attr_setstacksize(&attr, THREAD_STACK_SIZE);
281
return pthread_create(t, &attr, fun, arg);
284
static void _free_dso_data(struct dso_data *data)
286
dm_free(data->dso_name);
291
* Fetch a string off src and duplicate it into *ptr.
292
* Pay attention to zero-length strings.
294
/* FIXME? move to libdevmapper to share with the client lib (need to
295
make delimiter a parameter then) */
296
static int _fetch_string(char **ptr, char **src, const int delimiter)
302
if ((p = strchr(*src, delimiter)))
305
if ((*ptr = dm_strdup(*src))) {
306
if ((len = strlen(*ptr)))
323
/* Free message memory. */
324
static void _free_message(struct message_data *message_data)
326
dm_free(message_data->id);
327
dm_free(message_data->dso_name);
329
dm_free(message_data->device_uuid);
333
/* Parse a register message from the client. */
334
static int _parse_message(struct message_data *message_data)
337
char *p = message_data->msg->data;
338
struct dm_event_daemon_message *msg = message_data->msg;
344
* Retrieve application identifier, mapped device
345
* path and events # string from message.
347
if (_fetch_string(&message_data->id, &p, ' ') &&
348
_fetch_string(&message_data->dso_name, &p, ' ') &&
349
_fetch_string(&message_data->device_uuid, &p, ' ') &&
350
_fetch_string(&message_data->events.str, &p, ' ') &&
351
_fetch_string(&message_data->timeout.str, &p, ' ')) {
352
if (message_data->events.str) {
353
enum dm_event_mask i = atoi(message_data->events.str);
356
* Free string representaion of events.
357
* Not needed an more.
359
dm_free(message_data->events.str);
360
message_data->events.field = i;
362
if (message_data->timeout.str) {
363
uint32_t secs = atoi(message_data->timeout.str);
364
dm_free(message_data->timeout.str);
365
message_data->timeout.secs = secs ? secs :
366
DM_EVENT_DEFAULT_TIMEOUT;
378
/* Global mutex to lock access to lists et al. See _global_mutex
380
static int _lock_mutex(void)
382
return pthread_mutex_lock(&_global_mutex);
385
static int _unlock_mutex(void)
387
return pthread_mutex_unlock(&_global_mutex);
390
/* Check, if a device exists. */
391
static int _fill_device_data(struct thread_status *ts)
396
if (!ts->device.uuid)
399
ts->device.name = NULL;
400
ts->device.major = ts->device.minor = 0;
402
dmt = dm_task_create(DM_DEVICE_INFO);
406
if (!dm_task_set_uuid(dmt, ts->device.uuid))
409
if (!dm_task_run(dmt))
412
ts->device.name = dm_strdup(dm_task_get_name(dmt));
413
if (!ts->device.name)
416
if (!dm_task_get_info(dmt, &dmi))
419
ts->device.major = dmi.major;
420
ts->device.minor = dmi.minor;
422
dm_task_destroy(dmt);
426
dm_task_destroy(dmt);
427
dm_free(ts->device.name);
432
* Find an existing thread for a device.
434
* Mutex must be held when calling this.
436
static struct thread_status *_lookup_thread_status(struct message_data *data)
438
struct thread_status *thread;
440
dm_list_iterate_items(thread, &_thread_registry)
441
if (!strcmp(data->device_uuid, thread->device.uuid))
447
static int _get_status(struct message_data *message_data)
449
struct dm_event_daemon_message *msg = message_data->msg;
450
struct thread_status *thread;
453
int count = dm_list_size(&_thread_registry);
454
int size = 0, current = 0;
455
char *buffers[count];
460
for (i = 0; i < count; ++i)
465
dm_list_iterate_items(thread, &_thread_registry) {
466
if ((current = dm_asprintf(buffers + i, "0:%d %s %s %u %" PRIu32 ";",
467
i, thread->dso_data->dso_name,
468
thread->device.uuid, thread->events,
469
thread->timeout)) < 0) {
478
msg->size = size + strlen(message_data->id) + 1;
479
msg->data = dm_malloc(msg->size);
485
strcpy(message, message_data->id);
486
message += strlen(message_data->id);
489
for (j = 0; j < i; ++j) {
490
strcpy(message, buffers[j]);
491
message += strlen(buffers[j]);
496
for (j = 0; j < i; ++j)
502
/* Cleanup at exit. */
503
static void _exit_dm_lib(void)
509
static void _exit_timeout(void *unused __attribute__((unused)))
511
_timeout_running = 0;
512
pthread_mutex_unlock(&_timeout_mutex);
515
/* Wake up monitor threads every so often. */
516
static void *_timeout_thread(void *unused __attribute__((unused)))
518
struct timespec timeout;
522
pthread_cleanup_push(_exit_timeout, NULL);
523
pthread_mutex_lock(&_timeout_mutex);
525
while (!dm_list_empty(&_timeout_registry)) {
526
struct thread_status *thread;
529
curr_time = time(NULL);
531
dm_list_iterate_items_gen(thread, &_timeout_registry, timeout_list) {
532
if (thread->next_time <= curr_time) {
533
thread->next_time = curr_time + thread->timeout;
534
pthread_kill(thread->thread, SIGALRM);
537
if (thread->next_time < timeout.tv_sec || !timeout.tv_sec)
538
timeout.tv_sec = thread->next_time;
541
pthread_cond_timedwait(&_timeout_cond, &_timeout_mutex,
545
pthread_cleanup_pop(1);
550
static int _register_for_timeout(struct thread_status *thread)
554
pthread_mutex_lock(&_timeout_mutex);
556
thread->next_time = time(NULL) + thread->timeout;
558
if (dm_list_empty(&thread->timeout_list)) {
559
dm_list_add(&_timeout_registry, &thread->timeout_list);
560
if (_timeout_running)
561
pthread_cond_signal(&_timeout_cond);
564
if (!_timeout_running) {
565
pthread_t timeout_id;
567
if (!(ret = -_pthread_create_smallstack(&timeout_id, _timeout_thread, NULL)))
568
_timeout_running = 1;
571
pthread_mutex_unlock(&_timeout_mutex);
576
static void _unregister_for_timeout(struct thread_status *thread)
578
pthread_mutex_lock(&_timeout_mutex);
579
if (!dm_list_empty(&thread->timeout_list)) {
580
dm_list_del(&thread->timeout_list);
581
dm_list_init(&thread->timeout_list);
583
pthread_mutex_unlock(&_timeout_mutex);
586
__attribute__((format(printf, 4, 5)))
587
static void _no_intr_log(int level, const char *file, int line,
594
if (level > _LOG_WARN)
599
if (level < _LOG_WARN)
600
vfprintf(stderr, f, ap);
606
if (level < _LOG_WARN)
607
fprintf(stderr, "\n");
609
fprintf(stdout, "\n");
612
static sigset_t _unblock_sigalrm(void)
617
sigaddset(&set, SIGALRM);
618
pthread_sigmask(SIG_UNBLOCK, &set, &old);
622
#define DM_WAIT_RETRY 0
623
#define DM_WAIT_INTR 1
624
#define DM_WAIT_FATAL 2
626
/* Wait on a device until an event occurs. */
627
static int _event_wait(struct thread_status *thread, struct dm_task **task)
630
int ret = DM_WAIT_RETRY;
636
if (!(dmt = dm_task_create(DM_DEVICE_WAITEVENT)))
637
return DM_WAIT_RETRY;
639
thread->current_task = dmt;
641
if (!dm_task_set_uuid(dmt, thread->device.uuid) ||
642
!dm_task_set_event_nr(dmt, thread->event_nr))
646
* This is so that you can break out of waiting on an event,
647
* either for a timeout event, or to cancel the thread.
649
set = _unblock_sigalrm();
650
dm_log_init(_no_intr_log);
652
if (dm_task_run(dmt)) {
653
thread->current_events |= DM_EVENT_DEVICE_ERROR;
656
if ((ret = dm_task_get_info(dmt, &info)))
657
thread->event_nr = info.event_nr;
658
} else if (thread->events & DM_EVENT_TIMEOUT && errno == EINTR) {
659
thread->current_events |= DM_EVENT_TIMEOUT;
661
} else if (thread->status == DM_THREAD_SHUTDOWN && errno == EINTR) {
664
syslog(LOG_NOTICE, "dm_task_run failed, errno = %d, %s",
665
errno, strerror(errno));
666
if (errno == ENXIO) {
667
syslog(LOG_ERR, "%s disappeared, detaching",
668
thread->device.name);
673
pthread_sigmask(SIG_SETMASK, &set, NULL);
677
if (ret == DM_WAIT_FATAL || ret == DM_WAIT_RETRY) {
678
dm_task_destroy(dmt);
679
thread->current_task = NULL;
686
/* Register a device with the DSO. */
687
static int _do_register_device(struct thread_status *thread)
689
return thread->dso_data->register_device(thread->device.name,
691
thread->device.major,
692
thread->device.minor,
693
&(thread->dso_private));
696
/* Unregister a device with the DSO. */
697
static int _do_unregister_device(struct thread_status *thread)
699
return thread->dso_data->unregister_device(thread->device.name,
701
thread->device.major,
702
thread->device.minor,
703
&(thread->dso_private));
706
/* Process an event in the DSO. */
707
static void _do_process_event(struct thread_status *thread, struct dm_task *task)
709
thread->dso_data->process_event(task, thread->current_events, &(thread->dso_private));
712
/* Thread cleanup handler to unregister device. */
713
static void _monitor_unregister(void *arg)
715
struct thread_status *thread = arg, *thread_iter;
717
if (!_do_unregister_device(thread))
718
syslog(LOG_ERR, "%s: %s unregister failed\n", __func__,
719
thread->device.name);
720
if (thread->current_task)
721
dm_task_destroy(thread->current_task);
722
thread->current_task = NULL;
725
if (thread->events & DM_EVENT_TIMEOUT) {
726
/* _unregister_for_timeout locks another mutex, we
727
don't want to deadlock so we release our mutex for
730
_unregister_for_timeout(thread);
733
/* we may have been relinked to unused registry since we were
734
called, so check that */
735
dm_list_iterate_items(thread_iter, &_thread_registry_unused)
736
if (thread_iter == thread) {
737
thread->status = DM_THREAD_DONE;
741
thread->status = DM_THREAD_DONE;
742
pthread_mutex_lock(&_timeout_mutex);
743
UNLINK_THREAD(thread);
744
LINK(thread, &_thread_registry_unused);
745
pthread_mutex_unlock(&_timeout_mutex);
749
static struct dm_task *_get_device_status(struct thread_status *ts)
751
struct dm_task *dmt = dm_task_create(DM_DEVICE_STATUS);
756
if (!dm_task_set_uuid(dmt, ts->device.uuid)) {
757
dm_task_destroy(dmt);
761
if (!dm_task_run(dmt)) {
762
dm_task_destroy(dmt);
769
/* Device monitoring thread. */
770
static void *_monitor_thread(void *arg)
772
struct thread_status *thread = arg;
774
struct dm_task *task;
776
pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);
777
pthread_cleanup_push(_monitor_unregister, thread);
779
/* Wait for do_process_request() to finish its task. */
781
thread->status = DM_THREAD_RUNNING;
784
/* Loop forever awaiting/analyzing device events. */
786
thread->current_events = 0;
788
wait_error = _event_wait(thread, &task);
789
if (wait_error == DM_WAIT_RETRY)
792
if (wait_error == DM_WAIT_FATAL)
795
/* Timeout occurred, task is not filled properly.
796
* We get device status here for processing it in DSO.
798
if (wait_error == DM_WAIT_INTR &&
799
thread->current_events & DM_EVENT_TIMEOUT) {
800
dm_task_destroy(task);
801
task = _get_device_status(thread);
802
/* FIXME: syslog fail here ? */
803
if (!(thread->current_task = task))
808
* We know that wait succeeded and stored a
809
* pointer to dm_task with device status into task.
813
* Check against filter.
815
* If there's current events delivered from _event_wait() AND
816
* the device got registered for those events AND
817
* those events haven't been processed yet, call
818
* the DSO's process_event() handler.
821
if (thread->status == DM_THREAD_SHUTDOWN) {
827
if (thread->events & thread->current_events) {
829
thread->processing = 1;
832
_do_process_event(thread, task);
833
dm_task_destroy(task);
834
thread->current_task = NULL;
837
thread->processing = 0;
840
dm_task_destroy(task);
841
thread->current_task = NULL;
845
pthread_cleanup_pop(1);
850
/* Create a device monitoring thread. */
851
static int _create_thread(struct thread_status *thread)
853
return _pthread_create_smallstack(&thread->thread, _monitor_thread, thread);
856
static int _terminate_thread(struct thread_status *thread)
858
return pthread_kill(thread->thread, SIGALRM);
861
/* DSO reference counting. Call with _global_mutex locked! */
862
static void _lib_get(struct dso_data *data)
867
static void _lib_put(struct dso_data *data)
869
if (!--data->ref_count) {
870
dlclose(data->dso_handle);
872
_free_dso_data(data);
877
static struct dso_data *_lookup_dso(struct message_data *data)
879
struct dso_data *dso_data, *ret = NULL;
881
dm_list_iterate_items(dso_data, &_dso_registry)
882
if (!strcmp(data->dso_name, dso_data->dso_name)) {
891
/* Lookup DSO symbols we need. */
892
static int _lookup_symbol(void *dl, void **symbol, const char *name)
894
if ((*symbol = dlsym(dl, name)))
900
static int lookup_symbols(void *dl, struct dso_data *data)
902
return _lookup_symbol(dl, (void *) &data->process_event,
904
_lookup_symbol(dl, (void *) &data->register_device,
905
"register_device") &&
906
_lookup_symbol(dl, (void *) &data->unregister_device,
907
"unregister_device");
910
/* Load an application specific DSO. */
911
static struct dso_data *_load_dso(struct message_data *data)
914
struct dso_data *ret = NULL;
916
if (!(dl = dlopen(data->dso_name, RTLD_NOW))) {
917
const char *dlerr = dlerror();
918
syslog(LOG_ERR, "dmeventd %s dlopen failed: %s", data->dso_name,
921
dm_asprintf(&(data->msg->data), "%s %s dlopen failed: %s",
922
data->id, data->dso_name, dlerr);
926
if (!(ret = _alloc_dso_data(data))) {
931
if (!(lookup_symbols(dl, ret))) {
938
* Keep handle to close the library once
939
* we've got no references to it any more.
941
ret->dso_handle = dl;
951
/* Return success on daemon active check. */
952
static int _active(struct message_data *message_data)
958
* Register for an event.
960
* Only one caller at a time here, because we use
961
* a FIFO and lock it against multiple accesses.
963
static int _register_for_event(struct message_data *message_data)
966
struct thread_status *thread, *thread_new = NULL;
967
struct dso_data *dso_data;
969
if (!(dso_data = _lookup_dso(message_data)) &&
970
!(dso_data = _load_dso(message_data))) {
980
/* Preallocate thread status struct to avoid deadlock. */
981
if (!(thread_new = _alloc_thread_status(message_data, dso_data))) {
987
if (!_fill_device_data(thread_new)) {
995
/* If creation of timeout thread fails (as it may), we fail
996
here completely. The client is responsible for either
997
retrying later or trying to register without timeout
998
events. However, if timeout thread cannot be started, it
999
usually means we are so starved on resources that we are
1000
almost as good as dead already... */
1001
if (thread_new->events & DM_EVENT_TIMEOUT) {
1002
ret = -_register_for_timeout(thread_new);
1007
if (!(thread = _lookup_thread_status(message_data))) {
1010
if (!(ret = _do_register_device(thread_new)))
1013
thread = thread_new;
1016
/* Try to create the monitoring thread for this device. */
1018
if ((ret = -_create_thread(thread))) {
1020
_do_unregister_device(thread);
1021
_free_thread_status(thread);
1024
LINK_THREAD(thread);
1027
/* Or event # into events bitfield. */
1028
thread->events |= message_data->events.field;
1035
* Deallocate thread status after releasing
1036
* the lock in case we haven't used it.
1039
_free_thread_status(thread_new);
1045
* Unregister for an event.
1047
* Only one caller at a time here as with register_for_event().
1049
static int _unregister_for_event(struct message_data *message_data)
1052
struct thread_status *thread;
1055
* Clear event in bitfield and deactivate
1056
* monitoring thread in case bitfield is 0.
1060
if (!(thread = _lookup_thread_status(message_data))) {
1066
if (thread->status == DM_THREAD_DONE) {
1067
/* the thread has terminated while we were not
1073
thread->events &= ~message_data->events.field;
1075
if (!(thread->events & DM_EVENT_TIMEOUT))
1076
_unregister_for_timeout(thread);
1078
* In case there's no events to monitor on this device ->
1079
* unlink and terminate its monitoring thread.
1081
if (!thread->events) {
1082
pthread_mutex_lock(&_timeout_mutex);
1083
UNLINK_THREAD(thread);
1084
LINK(thread, &_thread_registry_unused);
1085
pthread_mutex_unlock(&_timeout_mutex);
1094
* Get registered device.
1096
* Only one caller at a time here as with register_for_event().
1098
static int _registered_device(struct message_data *message_data,
1099
struct thread_status *thread)
1101
struct dm_event_daemon_message *msg = message_data->msg;
1103
const char *fmt = "%s %s %s %u";
1104
const char *id = message_data->id;
1105
const char *dso = thread->dso_data->dso_name;
1106
const char *dev = thread->device.uuid;
1108
unsigned events = ((thread->status == DM_THREAD_RUNNING)
1109
&& (thread->events)) ? thread->events : thread->
1110
events | DM_EVENT_REGISTRATION_PENDING;
1114
if ((r = dm_asprintf(&(msg->data), fmt, id, dso, dev, events)) < 0) {
1119
msg->size = (uint32_t) r;
1124
static int _want_registered_device(char *dso_name, char *device_uuid,
1125
struct thread_status *thread)
1127
/* If DSO names and device paths are equal. */
1128
if (dso_name && device_uuid)
1129
return !strcmp(dso_name, thread->dso_data->dso_name) &&
1130
!strcmp(device_uuid, thread->device.uuid) &&
1131
(thread->status == DM_THREAD_RUNNING ||
1132
(thread->events & DM_EVENT_REGISTRATION_PENDING));
1134
/* If DSO names are equal. */
1136
return !strcmp(dso_name, thread->dso_data->dso_name) &&
1137
(thread->status == DM_THREAD_RUNNING ||
1138
(thread->events & DM_EVENT_REGISTRATION_PENDING));
1140
/* If device paths are equal. */
1142
return !strcmp(device_uuid, thread->device.uuid) &&
1143
(thread->status == DM_THREAD_RUNNING ||
1144
(thread->events & DM_EVENT_REGISTRATION_PENDING));
1149
static int _get_registered_dev(struct message_data *message_data, int next)
1151
struct thread_status *thread, *hit = NULL;
1156
/* Iterate list of threads checking if we want a particular one. */
1157
dm_list_iterate_items(thread, &_thread_registry)
1158
if (_want_registered_device(message_data->dso_name,
1159
message_data->device_uuid,
1166
* If we got a registered device and want the next one ->
1167
* fetch next conforming element off the list.
1176
if (dm_list_end(&_thread_registry, &thread->list))
1179
thread = dm_list_item(thread->list.n, struct thread_status);
1180
if (_want_registered_device(message_data->dso_name, NULL, thread)) {
1187
ret = _registered_device(message_data, hit);
1195
static int _get_registered_device(struct message_data *message_data)
1197
return _get_registered_dev(message_data, 0);
1200
static int _get_next_registered_device(struct message_data *message_data)
1202
return _get_registered_dev(message_data, 1);
1205
static int _set_timeout(struct message_data *message_data)
1207
struct thread_status *thread;
1210
if ((thread = _lookup_thread_status(message_data)))
1211
thread->timeout = message_data->timeout.secs;
1214
return thread ? 0 : -ENODEV;
1217
static int _get_timeout(struct message_data *message_data)
1219
struct thread_status *thread;
1220
struct dm_event_daemon_message *msg = message_data->msg;
1225
if ((thread = _lookup_thread_status(message_data))) {
1227
dm_asprintf(&(msg->data), "%s %" PRIu32, message_data->id,
1235
return thread ? 0 : -ENODEV;
1238
/* Initialize a fifos structure with path names. */
1239
static void _init_fifos(struct dm_event_fifos *fifos)
1241
memset(fifos, 0, sizeof(*fifos));
1243
fifos->client_path = DM_EVENT_FIFO_CLIENT;
1244
fifos->server_path = DM_EVENT_FIFO_SERVER;
1247
/* Open fifos used for client communication. */
1248
static int _open_fifos(struct dm_event_fifos *fifos)
1252
/* Create client fifo. */
1253
(void) dm_prepare_selinux_context(fifos->client_path, S_IFIFO);
1254
if ((mkfifo(fifos->client_path, 0600) == -1) && errno != EEXIST) {
1255
syslog(LOG_ERR, "%s: Failed to create client fifo %s: %m.\n",
1256
__func__, fifos->client_path);
1257
(void) dm_prepare_selinux_context(NULL, 0);
1261
/* Create server fifo. */
1262
(void) dm_prepare_selinux_context(fifos->server_path, S_IFIFO);
1263
if ((mkfifo(fifos->server_path, 0600) == -1) && errno != EEXIST) {
1264
syslog(LOG_ERR, "%s: Failed to create server fifo %s: %m.\n",
1265
__func__, fifos->server_path);
1266
(void) dm_prepare_selinux_context(NULL, 0);
1270
(void) dm_prepare_selinux_context(NULL, 0);
1272
/* Warn about wrong permissions if applicable */
1273
if ((!stat(fifos->client_path, &st)) && (st.st_mode & 0777) != 0600)
1274
syslog(LOG_WARNING, "Fixing wrong permissions on %s: %m.\n",
1275
fifos->client_path);
1277
if ((!stat(fifos->server_path, &st)) && (st.st_mode & 0777) != 0600)
1278
syslog(LOG_WARNING, "Fixing wrong permissions on %s: %m.\n",
1279
fifos->server_path);
1281
/* If they were already there, make sure permissions are ok. */
1282
if (chmod(fifos->client_path, 0600)) {
1283
syslog(LOG_ERR, "Unable to set correct file permissions on %s: %m.\n",
1284
fifos->client_path);
1288
if (chmod(fifos->server_path, 0600)) {
1289
syslog(LOG_ERR, "Unable to set correct file permissions on %s: %m.\n",
1290
fifos->server_path);
1294
/* Need to open read+write or we will block or fail */
1295
if ((fifos->server = open(fifos->server_path, O_RDWR)) < 0) {
1296
syslog(LOG_ERR, "Failed to open fifo server %s: %m.\n",
1297
fifos->server_path);
1301
/* Need to open read+write for select() to work. */
1302
if ((fifos->client = open(fifos->client_path, O_RDWR)) < 0) {
1303
syslog(LOG_ERR, "Failed to open fifo client %s: %m", fifos->client_path);
1304
if (close(fifos->server))
1305
syslog(LOG_ERR, "Failed to close fifo server %s: %m", fifos->server_path);
1313
* Read message from client making sure that data is available
1314
* and a complete message is read. Must not block indefinitely.
1316
static int _client_read(struct dm_event_fifos *fifos,
1317
struct dm_event_daemon_message *msg)
1323
size_t size = 2 * sizeof(uint32_t); /* status + size */
1324
uint32_t *header = alloca(size);
1325
char *buf = (char *)header;
1330
while (bytes < size && errno != EOF) {
1331
/* Watch client read FIFO for input. */
1333
FD_SET(fifos->client, &fds);
1336
ret = select(fifos->client + 1, &fds, NULL, NULL, &t);
1338
if (!ret && !bytes) /* nothing to read */
1341
if (!ret) /* trying to finish read */
1344
if (ret < 0) /* error */
1347
ret = read(fifos->client, buf + bytes, size - bytes);
1348
bytes += ret > 0 ? ret : 0;
1349
if (header && (bytes == 2 * sizeof(uint32_t))) {
1350
msg->cmd = ntohl(header[0]);
1351
msg->size = ntohl(header[1]);
1352
buf = msg->data = dm_malloc(msg->size);
1359
if (bytes != size) {
1365
return bytes == size;
1369
* Write a message to the client making sure that it is ready to write.
1371
static int _client_write(struct dm_event_fifos *fifos,
1372
struct dm_event_daemon_message *msg)
1378
size_t size = 2 * sizeof(uint32_t) + msg->size;
1379
uint32_t *header = alloca(size);
1380
char *buf = (char *)header;
1382
header[0] = htonl(msg->cmd);
1383
header[1] = htonl(msg->size);
1385
memcpy(buf + 2 * sizeof(uint32_t), msg->data, msg->size);
1388
while (bytes < size && errno != EIO) {
1390
/* Watch client write FIFO to be ready for output. */
1392
FD_SET(fifos->server, &fds);
1393
} while (select(fifos->server + 1, NULL, &fds, NULL, NULL) !=
1396
ret = write(fifos->server, buf + bytes, size - bytes);
1397
bytes += ret > 0 ? ret : 0;
1400
return bytes == size;
1404
* Handle a client request.
1406
* We put the request handling functions into
1407
* a list because of the growing number.
1409
static int _handle_request(struct dm_event_daemon_message *msg,
1410
struct message_data *message_data)
1412
static struct request {
1414
int (*f)(struct message_data *);
1416
{ DM_EVENT_CMD_REGISTER_FOR_EVENT, _register_for_event},
1417
{ DM_EVENT_CMD_UNREGISTER_FOR_EVENT, _unregister_for_event},
1418
{ DM_EVENT_CMD_GET_REGISTERED_DEVICE, _get_registered_device},
1419
{ DM_EVENT_CMD_GET_NEXT_REGISTERED_DEVICE,
1420
_get_next_registered_device},
1421
{ DM_EVENT_CMD_SET_TIMEOUT, _set_timeout},
1422
{ DM_EVENT_CMD_GET_TIMEOUT, _get_timeout},
1423
{ DM_EVENT_CMD_ACTIVE, _active},
1424
{ DM_EVENT_CMD_GET_STATUS, _get_status},
1427
for (req = requests; req < requests + sizeof(requests) / sizeof(struct request); req++)
1428
if (req->cmd == msg->cmd)
1429
return req->f(message_data);
1434
/* Process a request passed from the communication thread. */
1435
static int _do_process_request(struct dm_event_daemon_message *msg)
1439
static struct message_data message_data;
1441
/* Parse the message. */
1442
memset(&message_data, 0, sizeof(message_data));
1443
message_data.msg = msg;
1444
if (msg->cmd == DM_EVENT_CMD_HELLO || msg->cmd == DM_EVENT_CMD_DIE) {
1448
msg->size = dm_asprintf(&(msg->data), "%s %s %d", answer,
1449
msg->cmd == DM_EVENT_CMD_DIE ? "DYING" : "HELLO",
1450
DM_EVENT_PROTOCOL_VERSION);
1456
} else if (msg->cmd != DM_EVENT_CMD_ACTIVE && !_parse_message(&message_data)) {
1460
ret = _handle_request(msg, &message_data);
1464
msg->size = dm_asprintf(&(msg->data), "%s %s", message_data.id, strerror(-ret));
1466
_free_message(&message_data);
1471
/* Only one caller at a time. */
1472
static void _process_request(struct dm_event_fifos *fifos)
1475
struct dm_event_daemon_message msg;
1477
memset(&msg, 0, sizeof(msg));
1480
* Read the request from the client (client_read, client_write
1481
* give true on success and false on failure).
1483
if (!_client_read(fifos, &msg))
1486
if (msg.cmd == DM_EVENT_CMD_DIE)
1489
/* _do_process_request fills in msg (if memory allows for
1490
data, otherwise just cmd and size = 0) */
1491
_do_process_request(&msg);
1493
if (!_client_write(fifos, &msg))
1501
static void _process_initial_registrations(void)
1505
struct dm_event_daemon_message msg = { 0, 0, NULL };
1507
while ((reg = _initial_registrations[i])) {
1508
msg.cmd = DM_EVENT_CMD_REGISTER_FOR_EVENT;
1509
if ((msg.size = strlen(reg))) {
1511
_do_process_request(&msg);
1517
static void _cleanup_unused_threads(void)
1521
struct thread_status *thread;
1525
while ((l = dm_list_first(&_thread_registry_unused))) {
1526
thread = dm_list_item(l, struct thread_status);
1527
if (thread->processing)
1528
break; /* cleanup on the next round */
1530
if (thread->status == DM_THREAD_RUNNING) {
1531
thread->status = DM_THREAD_SHUTDOWN;
1535
if (thread->status == DM_THREAD_SHUTDOWN) {
1536
if (!thread->events) {
1537
/* turn codes negative -- should we be returning this? */
1538
ret = _terminate_thread(thread);
1541
thread->status = DM_THREAD_DONE;
1544
"Unable to terminate thread: %s\n",
1553
"thread can't be on unused list unless !thread->events");
1554
thread->status = DM_THREAD_RUNNING;
1555
LINK_THREAD(thread);
1560
if (thread->status == DM_THREAD_DONE) {
1562
join_ret = pthread_join(thread->thread, NULL);
1563
_free_thread_status(thread);
1570
syslog(LOG_ERR, "Failed pthread_join: %s\n", strerror(join_ret));
1573
static void _sig_alarm(int signum __attribute__((unused)))
1575
pthread_testcancel();
1578
/* Init thread signal handling. */
1579
static void _init_thread_signals(void)
1582
struct sigaction act;
1584
memset(&act, 0, sizeof(act));
1585
act.sa_handler = _sig_alarm;
1586
sigaction(SIGALRM, &act, NULL);
1587
sigfillset(&my_sigset);
1589
/* These are used for exiting */
1590
sigdelset(&my_sigset, SIGTERM);
1591
sigdelset(&my_sigset, SIGINT);
1592
sigdelset(&my_sigset, SIGHUP);
1593
sigdelset(&my_sigset, SIGQUIT);
1595
pthread_sigmask(SIG_BLOCK, &my_sigset, NULL);
1602
* Set the global variable which the process should
1603
* be watching to determine when to exit.
1605
static void _exit_handler(int sig __attribute__((unused)))
1608
* We exit when '_exit_now' is set.
1609
* That is, when a signal has been received.
1611
* We can not simply set '_exit_now' unless all
1612
* threads are done processing.
1614
if (!_thread_registries_empty) {
1615
syslog(LOG_ERR, "There are still devices being monitored.");
1616
syslog(LOG_ERR, "Refusing to exit.");
1623
static int _set_oom_adj(const char *oom_adj_path, int val)
1627
if (!(fp = fopen(oom_adj_path, "w"))) {
1628
perror("oom_adj: fopen failed");
1632
fprintf(fp, "%i", val);
1635
perror("oom_adj: fclose failed");
1641
* Protection against OOM killer if kernel supports it
1643
static int _protect_against_oom_killer(void)
1647
if (stat(OOM_ADJ_FILE, &st) == -1) {
1648
if (errno != ENOENT)
1649
perror(OOM_ADJ_FILE ": stat failed");
1651
/* Try old oom_adj interface as a fallback */
1652
if (stat(OOM_ADJ_FILE_OLD, &st) == -1) {
1653
if (errno == ENOENT)
1654
perror(OOM_ADJ_FILE_OLD " not found");
1656
perror(OOM_ADJ_FILE_OLD ": stat failed");
1660
return _set_oom_adj(OOM_ADJ_FILE_OLD, OOM_DISABLE) ||
1661
_set_oom_adj(OOM_ADJ_FILE_OLD, OOM_ADJUST_MIN);
1664
return _set_oom_adj(OOM_ADJ_FILE, OOM_SCORE_ADJ_MIN);
1667
static int _handle_preloaded_fifo(int fd, const char *path)
1669
struct stat st_fd, st_path;
1672
if ((flags = fcntl(fd, F_GETFD)) < 0)
1675
if (flags & FD_CLOEXEC)
1678
if (fstat(fd, &st_fd) < 0 || !S_ISFIFO(st_fd.st_mode))
1681
if (stat(path, &st_path) < 0 ||
1682
st_path.st_dev != st_fd.st_dev ||
1683
st_path.st_ino != st_fd.st_ino)
1686
if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) < 0)
1692
static int _systemd_handover(struct dm_event_fifos *fifos)
1696
unsigned long env_pid, env_listen_fds;
1699
memset(fifos, 0, sizeof(*fifos));
1701
/* LISTEN_PID must be equal to our PID! */
1702
if (!(e = getenv(SD_LISTEN_PID_ENV_VAR_NAME)))
1706
env_pid = strtoul(e, &p, 10);
1707
if (errno || !p || *p || env_pid <= 0 ||
1708
getpid() != (pid_t) env_pid)
1711
/* LISTEN_FDS must be 2 and the fds must be FIFOSs! */
1712
if (!(e = getenv(SD_LISTEN_FDS_ENV_VAR_NAME)))
1716
env_listen_fds = strtoul(e, &p, 10);
1717
if (errno || !p || *p || env_listen_fds != 2)
1720
/* Check and handle the FIFOs passed in */
1721
r = (_handle_preloaded_fifo(SD_FD_FIFO_SERVER, DM_EVENT_FIFO_SERVER) &&
1722
_handle_preloaded_fifo(SD_FD_FIFO_CLIENT, DM_EVENT_FIFO_CLIENT));
1725
fifos->server = SD_FD_FIFO_SERVER;
1726
fifos->server_path = DM_EVENT_FIFO_SERVER;
1727
fifos->client = SD_FD_FIFO_CLIENT;
1728
fifos->client_path = DM_EVENT_FIFO_CLIENT;
1732
unsetenv(SD_LISTEN_PID_ENV_VAR_NAME);
1733
unsetenv(SD_LISTEN_FDS_ENV_VAR_NAME);
1738
static void remove_lockfile(void)
1740
if (unlink(DMEVENTD_PIDFILE))
1741
perror(DMEVENTD_PIDFILE ": unlink failed");
1744
static void _daemonize(void)
1750
struct timeval tval;
1753
sigemptyset(&my_sigset);
1754
if (sigprocmask(SIG_SETMASK, &my_sigset, NULL) < 0) {
1755
fprintf(stderr, "Unable to restore signals.\n");
1758
signal(SIGTERM, &_exit_handler);
1760
switch (pid = fork()) {
1762
perror("fork failed:");
1769
/* Wait for response from child */
1770
while (!waitpid(pid, &child_status, WNOHANG) && !_exit_now) {
1772
tval.tv_usec = 250000; /* .25 sec */
1773
select(0, NULL, NULL, NULL, &tval);
1776
if (_exit_now) /* Child has signaled it is ok - we can exit now */
1779
/* Problem with child. Determine what it is by exit code */
1780
switch (WEXITSTATUS(child_status)) {
1781
case EXIT_DESC_CLOSE_FAILURE:
1782
case EXIT_DESC_OPEN_FAILURE:
1783
case EXIT_FIFO_FAILURE:
1784
case EXIT_CHDIR_FAILURE:
1786
fprintf(stderr, "Child exited with code %d\n", WEXITSTATUS(child_status));
1790
exit(WEXITSTATUS(child_status));
1794
exit(EXIT_CHDIR_FAILURE);
1796
if (getrlimit(RLIMIT_NOFILE, &rlim) < 0)
1797
fd = 256; /* just have to guess */
1801
for (--fd; fd >= 0; fd--) {
1803
/* Do not close fds preloaded by systemd! */
1804
if (_systemd_activation &&
1805
(fd == SD_FD_FIFO_SERVER || fd == SD_FD_FIFO_CLIENT))
1811
if ((open("/dev/null", O_RDONLY) < 0) ||
1812
(open("/dev/null", O_WRONLY) < 0) ||
1813
(open("/dev/null", O_WRONLY) < 0))
1814
exit(EXIT_DESC_OPEN_FAILURE);
1819
static void restart(void)
1821
struct dm_event_fifos fifos;
1822
struct dm_event_daemon_message msg = { 0, 0, NULL };
1828
/* Get the list of registrations from the running daemon. */
1830
if (!init_fifos(&fifos)) {
1831
fprintf(stderr, "WARNING: Could not initiate communication with existing dmeventd.\n");
1835
if (!dm_event_get_version(&fifos, &version)) {
1836
fprintf(stderr, "WARNING: Could not communicate with existing dmeventd.\n");
1842
fprintf(stderr, "WARNING: The running dmeventd instance is too old.\n"
1843
"Protocol version %d (required: 1). Action cancelled.\n",
1848
if (daemon_talk(&fifos, &msg, DM_EVENT_CMD_GET_STATUS, "-", "-", 0, 0)) {
1853
message = strchr(message, ' ');
1855
length = strlen(msg.data);
1856
for (i = 0; i < length; ++i) {
1857
if (msg.data[i] == ';') {
1863
if (!(_initial_registrations = dm_malloc(sizeof(char*) * (count + 1)))) {
1864
fprintf(stderr, "Memory allocation registration failed.\n");
1868
for (i = 0; i < count; ++i) {
1869
if (!(_initial_registrations[i] = dm_strdup(message))) {
1870
fprintf(stderr, "Memory allocation for message failed.\n");
1873
message += strlen(message) + 1;
1875
_initial_registrations[count] = 0;
1877
if (daemon_talk(&fifos, &msg, DM_EVENT_CMD_DIE, "-", "-", 0, 0)) {
1878
fprintf(stderr, "Old dmeventd refused to die.\n");
1885
static void usage(char *prog, FILE *file)
1887
fprintf(file, "Usage:\n"
1888
"%s [-d [-d [-d]]] [-f] [-h] [-R] [-V] [-?]\n\n"
1889
" -d Log debug messages to syslog (-d, -dd, -ddd)\n"
1890
" -f Don't fork, run in the foreground\n"
1891
" -h -? Show this help information\n"
1892
" -R Restart dmeventd\n"
1893
" -V Show version of dmeventd\n\n", prog);
1896
int main(int argc, char *argv[])
1899
struct dm_event_fifos fifos;
1900
//struct sys_log logdata = {DAEMON_NAME, LOG_DAEMON};
1905
while ((opt = getopt(argc, argv, "?fhVdR")) != EOF) {
1908
usage(argv[0], stdout);
1911
usage(argv[0], stderr);
1923
printf("dmeventd version: %s\n", DM_LIB_VERSION);
1929
* Switch to C locale to avoid reading large locale-archive file
1930
* used by some glibc (on some distributions it takes over 100MB).
1931
* Daemon currently needs to use mlockall().
1933
if (setenv("LANG", "C", 1))
1934
perror("Cannot set LANG to C");
1940
_systemd_activation = _systemd_handover(&fifos);
1946
openlog("dmeventd", LOG_PID, LOG_DAEMON);
1948
(void) dm_prepare_selinux_context(DMEVENTD_PIDFILE, S_IFREG);
1949
if (dm_create_lockfile(DMEVENTD_PIDFILE) == 0)
1952
atexit(remove_lockfile);
1953
(void) dm_prepare_selinux_context(NULL, 0);
1955
/* Set the rest of the signals to cause '_exit_now' to be set */
1956
signal(SIGINT, &_exit_handler);
1957
signal(SIGHUP, &_exit_handler);
1958
signal(SIGQUIT, &_exit_handler);
1961
/* Systemd has adjusted oom killer for us already */
1962
if (!_systemd_activation && !_protect_against_oom_killer())
1963
syslog(LOG_ERR, "Failed to protect against OOM killer");
1966
_init_thread_signals();
1968
//multilog_clear_logging();
1969
//multilog_add_type(std_syslog, &logdata);
1970
//multilog_init_verbose(std_syslog, _LOG_DEBUG);
1971
//multilog_async(1);
1973
if (!_systemd_activation)
1974
_init_fifos(&fifos);
1976
pthread_mutex_init(&_global_mutex, NULL);
1978
if (!_systemd_activation && !_open_fifos(&fifos))
1979
exit(EXIT_FIFO_FAILURE);
1981
/* Signal parent, letting them know we are ready to go. */
1983
kill(getppid(), SIGTERM);
1984
syslog(LOG_NOTICE, "dmeventd ready for processing.");
1986
if (_initial_registrations)
1987
_process_initial_registrations();
1989
while (!_exit_now) {
1990
_process_request(&fifos);
1991
_cleanup_unused_threads();
1993
if (!dm_list_empty(&_thread_registry)
1994
|| !dm_list_empty(&_thread_registry_unused))
1995
_thread_registries_empty = 0;
1997
_thread_registries_empty = 1;
2003
pthread_mutex_destroy(&_global_mutex);
2005
syslog(LOG_NOTICE, "dmeventd shutting down.");