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;
915
char dso_name[PATH_MAX];
917
if (strchr(data->dso_name, '/') == NULL) {
918
strcpy(dso_name, PLUGIN_PATH);
919
strncat(dso_name, data->dso_name, sizeof(dso_name));
921
strncpy(dso_name, data->dso_name, sizeof(dso_name));
923
dso_name[sizeof(dso_name) - 1] = 0;
925
if (!(dl = dlopen(dso_name, RTLD_NOW))) {
926
const char *dlerr = dlerror();
927
syslog(LOG_ERR, "dmeventd %s dlopen failed: %s", data->dso_name,
930
dm_asprintf(&(data->msg->data), "%s %s dlopen failed: %s",
931
data->id, data->dso_name, dlerr);
935
if (!(ret = _alloc_dso_data(data))) {
940
if (!(lookup_symbols(dl, ret))) {
947
* Keep handle to close the library once
948
* we've got no references to it any more.
950
ret->dso_handle = dl;
960
/* Return success on daemon active check. */
961
static int _active(struct message_data *message_data)
967
* Register for an event.
969
* Only one caller at a time here, because we use
970
* a FIFO and lock it against multiple accesses.
972
static int _register_for_event(struct message_data *message_data)
975
struct thread_status *thread, *thread_new = NULL;
976
struct dso_data *dso_data;
978
if (!(dso_data = _lookup_dso(message_data)) &&
979
!(dso_data = _load_dso(message_data))) {
989
/* Preallocate thread status struct to avoid deadlock. */
990
if (!(thread_new = _alloc_thread_status(message_data, dso_data))) {
996
if (!_fill_device_data(thread_new)) {
1004
/* If creation of timeout thread fails (as it may), we fail
1005
here completely. The client is responsible for either
1006
retrying later or trying to register without timeout
1007
events. However, if timeout thread cannot be started, it
1008
usually means we are so starved on resources that we are
1009
almost as good as dead already... */
1010
if (thread_new->events & DM_EVENT_TIMEOUT) {
1011
ret = -_register_for_timeout(thread_new);
1016
if (!(thread = _lookup_thread_status(message_data))) {
1019
if (!(ret = _do_register_device(thread_new)))
1022
thread = thread_new;
1025
/* Try to create the monitoring thread for this device. */
1027
if ((ret = -_create_thread(thread))) {
1029
_do_unregister_device(thread);
1030
_free_thread_status(thread);
1033
LINK_THREAD(thread);
1036
/* Or event # into events bitfield. */
1037
thread->events |= message_data->events.field;
1044
* Deallocate thread status after releasing
1045
* the lock in case we haven't used it.
1048
_free_thread_status(thread_new);
1054
* Unregister for an event.
1056
* Only one caller at a time here as with register_for_event().
1058
static int _unregister_for_event(struct message_data *message_data)
1061
struct thread_status *thread;
1064
* Clear event in bitfield and deactivate
1065
* monitoring thread in case bitfield is 0.
1069
if (!(thread = _lookup_thread_status(message_data))) {
1075
if (thread->status == DM_THREAD_DONE) {
1076
/* the thread has terminated while we were not
1082
thread->events &= ~message_data->events.field;
1084
if (!(thread->events & DM_EVENT_TIMEOUT))
1085
_unregister_for_timeout(thread);
1087
* In case there's no events to monitor on this device ->
1088
* unlink and terminate its monitoring thread.
1090
if (!thread->events) {
1091
pthread_mutex_lock(&_timeout_mutex);
1092
UNLINK_THREAD(thread);
1093
LINK(thread, &_thread_registry_unused);
1094
pthread_mutex_unlock(&_timeout_mutex);
1103
* Get registered device.
1105
* Only one caller at a time here as with register_for_event().
1107
static int _registered_device(struct message_data *message_data,
1108
struct thread_status *thread)
1110
struct dm_event_daemon_message *msg = message_data->msg;
1112
const char *fmt = "%s %s %s %u";
1113
const char *id = message_data->id;
1114
const char *dso = thread->dso_data->dso_name;
1115
const char *dev = thread->device.uuid;
1117
unsigned events = ((thread->status == DM_THREAD_RUNNING)
1118
&& (thread->events)) ? thread->events : thread->
1119
events | DM_EVENT_REGISTRATION_PENDING;
1123
if ((r = dm_asprintf(&(msg->data), fmt, id, dso, dev, events)) < 0) {
1128
msg->size = (uint32_t) r;
1133
static int _want_registered_device(char *dso_name, char *device_uuid,
1134
struct thread_status *thread)
1136
/* If DSO names and device paths are equal. */
1137
if (dso_name && device_uuid)
1138
return !strcmp(dso_name, thread->dso_data->dso_name) &&
1139
!strcmp(device_uuid, thread->device.uuid) &&
1140
(thread->status == DM_THREAD_RUNNING ||
1141
(thread->events & DM_EVENT_REGISTRATION_PENDING));
1143
/* If DSO names are equal. */
1145
return !strcmp(dso_name, thread->dso_data->dso_name) &&
1146
(thread->status == DM_THREAD_RUNNING ||
1147
(thread->events & DM_EVENT_REGISTRATION_PENDING));
1149
/* If device paths are equal. */
1151
return !strcmp(device_uuid, thread->device.uuid) &&
1152
(thread->status == DM_THREAD_RUNNING ||
1153
(thread->events & DM_EVENT_REGISTRATION_PENDING));
1158
static int _get_registered_dev(struct message_data *message_data, int next)
1160
struct thread_status *thread, *hit = NULL;
1165
/* Iterate list of threads checking if we want a particular one. */
1166
dm_list_iterate_items(thread, &_thread_registry)
1167
if (_want_registered_device(message_data->dso_name,
1168
message_data->device_uuid,
1175
* If we got a registered device and want the next one ->
1176
* fetch next conforming element off the list.
1185
if (dm_list_end(&_thread_registry, &thread->list))
1188
thread = dm_list_item(thread->list.n, struct thread_status);
1189
if (_want_registered_device(message_data->dso_name, NULL, thread)) {
1196
ret = _registered_device(message_data, hit);
1204
static int _get_registered_device(struct message_data *message_data)
1206
return _get_registered_dev(message_data, 0);
1209
static int _get_next_registered_device(struct message_data *message_data)
1211
return _get_registered_dev(message_data, 1);
1214
static int _set_timeout(struct message_data *message_data)
1216
struct thread_status *thread;
1219
if ((thread = _lookup_thread_status(message_data)))
1220
thread->timeout = message_data->timeout.secs;
1223
return thread ? 0 : -ENODEV;
1226
static int _get_timeout(struct message_data *message_data)
1228
struct thread_status *thread;
1229
struct dm_event_daemon_message *msg = message_data->msg;
1234
if ((thread = _lookup_thread_status(message_data))) {
1236
dm_asprintf(&(msg->data), "%s %" PRIu32, message_data->id,
1244
return thread ? 0 : -ENODEV;
1247
/* Initialize a fifos structure with path names. */
1248
static void _init_fifos(struct dm_event_fifos *fifos)
1250
memset(fifos, 0, sizeof(*fifos));
1252
fifos->client_path = DM_EVENT_FIFO_CLIENT;
1253
fifos->server_path = DM_EVENT_FIFO_SERVER;
1256
/* Open fifos used for client communication. */
1257
static int _open_fifos(struct dm_event_fifos *fifos)
1261
/* Create client fifo. */
1262
(void) dm_prepare_selinux_context(fifos->client_path, S_IFIFO);
1263
if ((mkfifo(fifos->client_path, 0600) == -1) && errno != EEXIST) {
1264
syslog(LOG_ERR, "%s: Failed to create client fifo %s: %m.\n",
1265
__func__, fifos->client_path);
1266
(void) dm_prepare_selinux_context(NULL, 0);
1270
/* Create server fifo. */
1271
(void) dm_prepare_selinux_context(fifos->server_path, S_IFIFO);
1272
if ((mkfifo(fifos->server_path, 0600) == -1) && errno != EEXIST) {
1273
syslog(LOG_ERR, "%s: Failed to create server fifo %s: %m.\n",
1274
__func__, fifos->server_path);
1275
(void) dm_prepare_selinux_context(NULL, 0);
1279
(void) dm_prepare_selinux_context(NULL, 0);
1281
/* Warn about wrong permissions if applicable */
1282
if ((!stat(fifos->client_path, &st)) && (st.st_mode & 0777) != 0600)
1283
syslog(LOG_WARNING, "Fixing wrong permissions on %s: %m.\n",
1284
fifos->client_path);
1286
if ((!stat(fifos->server_path, &st)) && (st.st_mode & 0777) != 0600)
1287
syslog(LOG_WARNING, "Fixing wrong permissions on %s: %m.\n",
1288
fifos->server_path);
1290
/* If they were already there, make sure permissions are ok. */
1291
if (chmod(fifos->client_path, 0600)) {
1292
syslog(LOG_ERR, "Unable to set correct file permissions on %s: %m.\n",
1293
fifos->client_path);
1297
if (chmod(fifos->server_path, 0600)) {
1298
syslog(LOG_ERR, "Unable to set correct file permissions on %s: %m.\n",
1299
fifos->server_path);
1303
/* Need to open read+write or we will block or fail */
1304
if ((fifos->server = open(fifos->server_path, O_RDWR)) < 0) {
1305
syslog(LOG_ERR, "Failed to open fifo server %s: %m.\n",
1306
fifos->server_path);
1310
/* Need to open read+write for select() to work. */
1311
if ((fifos->client = open(fifos->client_path, O_RDWR)) < 0) {
1312
syslog(LOG_ERR, "Failed to open fifo client %s: %m", fifos->client_path);
1313
if (close(fifos->server))
1314
syslog(LOG_ERR, "Failed to close fifo server %s: %m", fifos->server_path);
1322
* Read message from client making sure that data is available
1323
* and a complete message is read. Must not block indefinitely.
1325
static int _client_read(struct dm_event_fifos *fifos,
1326
struct dm_event_daemon_message *msg)
1332
size_t size = 2 * sizeof(uint32_t); /* status + size */
1333
uint32_t *header = alloca(size);
1334
char *buf = (char *)header;
1339
while (bytes < size && errno != EOF) {
1340
/* Watch client read FIFO for input. */
1342
FD_SET(fifos->client, &fds);
1345
ret = select(fifos->client + 1, &fds, NULL, NULL, &t);
1347
if (!ret && !bytes) /* nothing to read */
1350
if (!ret) /* trying to finish read */
1353
if (ret < 0) /* error */
1356
ret = read(fifos->client, buf + bytes, size - bytes);
1357
bytes += ret > 0 ? ret : 0;
1358
if (header && (bytes == 2 * sizeof(uint32_t))) {
1359
msg->cmd = ntohl(header[0]);
1360
msg->size = ntohl(header[1]);
1361
buf = msg->data = dm_malloc(msg->size);
1368
if (bytes != size) {
1374
return bytes == size;
1378
* Write a message to the client making sure that it is ready to write.
1380
static int _client_write(struct dm_event_fifos *fifos,
1381
struct dm_event_daemon_message *msg)
1387
size_t size = 2 * sizeof(uint32_t) + msg->size;
1388
uint32_t *header = alloca(size);
1389
char *buf = (char *)header;
1391
header[0] = htonl(msg->cmd);
1392
header[1] = htonl(msg->size);
1394
memcpy(buf + 2 * sizeof(uint32_t), msg->data, msg->size);
1397
while (bytes < size && errno != EIO) {
1399
/* Watch client write FIFO to be ready for output. */
1401
FD_SET(fifos->server, &fds);
1402
} while (select(fifos->server + 1, NULL, &fds, NULL, NULL) !=
1405
ret = write(fifos->server, buf + bytes, size - bytes);
1406
bytes += ret > 0 ? ret : 0;
1409
return bytes == size;
1413
* Handle a client request.
1415
* We put the request handling functions into
1416
* a list because of the growing number.
1418
static int _handle_request(struct dm_event_daemon_message *msg,
1419
struct message_data *message_data)
1421
static struct request {
1423
int (*f)(struct message_data *);
1425
{ DM_EVENT_CMD_REGISTER_FOR_EVENT, _register_for_event},
1426
{ DM_EVENT_CMD_UNREGISTER_FOR_EVENT, _unregister_for_event},
1427
{ DM_EVENT_CMD_GET_REGISTERED_DEVICE, _get_registered_device},
1428
{ DM_EVENT_CMD_GET_NEXT_REGISTERED_DEVICE,
1429
_get_next_registered_device},
1430
{ DM_EVENT_CMD_SET_TIMEOUT, _set_timeout},
1431
{ DM_EVENT_CMD_GET_TIMEOUT, _get_timeout},
1432
{ DM_EVENT_CMD_ACTIVE, _active},
1433
{ DM_EVENT_CMD_GET_STATUS, _get_status},
1436
for (req = requests; req < requests + sizeof(requests) / sizeof(struct request); req++)
1437
if (req->cmd == msg->cmd)
1438
return req->f(message_data);
1443
/* Process a request passed from the communication thread. */
1444
static int _do_process_request(struct dm_event_daemon_message *msg)
1448
static struct message_data message_data;
1450
/* Parse the message. */
1451
memset(&message_data, 0, sizeof(message_data));
1452
message_data.msg = msg;
1453
if (msg->cmd == DM_EVENT_CMD_HELLO || msg->cmd == DM_EVENT_CMD_DIE) {
1457
msg->size = dm_asprintf(&(msg->data), "%s %s %d", answer,
1458
msg->cmd == DM_EVENT_CMD_DIE ? "DYING" : "HELLO",
1459
DM_EVENT_PROTOCOL_VERSION);
1465
} else if (msg->cmd != DM_EVENT_CMD_ACTIVE && !_parse_message(&message_data)) {
1469
ret = _handle_request(msg, &message_data);
1473
msg->size = dm_asprintf(&(msg->data), "%s %s", message_data.id, strerror(-ret));
1475
_free_message(&message_data);
1480
/* Only one caller at a time. */
1481
static void _process_request(struct dm_event_fifos *fifos)
1484
struct dm_event_daemon_message msg;
1486
memset(&msg, 0, sizeof(msg));
1489
* Read the request from the client (client_read, client_write
1490
* give true on success and false on failure).
1492
if (!_client_read(fifos, &msg))
1495
if (msg.cmd == DM_EVENT_CMD_DIE)
1498
/* _do_process_request fills in msg (if memory allows for
1499
data, otherwise just cmd and size = 0) */
1500
_do_process_request(&msg);
1502
if (!_client_write(fifos, &msg))
1510
static void _process_initial_registrations(void)
1514
struct dm_event_daemon_message msg = { 0, 0, NULL };
1516
while ((reg = _initial_registrations[i])) {
1517
msg.cmd = DM_EVENT_CMD_REGISTER_FOR_EVENT;
1518
if ((msg.size = strlen(reg))) {
1520
_do_process_request(&msg);
1526
static void _cleanup_unused_threads(void)
1530
struct thread_status *thread;
1534
while ((l = dm_list_first(&_thread_registry_unused))) {
1535
thread = dm_list_item(l, struct thread_status);
1536
if (thread->processing)
1537
break; /* cleanup on the next round */
1539
if (thread->status == DM_THREAD_RUNNING) {
1540
thread->status = DM_THREAD_SHUTDOWN;
1544
if (thread->status == DM_THREAD_SHUTDOWN) {
1545
if (!thread->events) {
1546
/* turn codes negative -- should we be returning this? */
1547
ret = _terminate_thread(thread);
1550
thread->status = DM_THREAD_DONE;
1553
"Unable to terminate thread: %s\n",
1562
"thread can't be on unused list unless !thread->events");
1563
thread->status = DM_THREAD_RUNNING;
1564
LINK_THREAD(thread);
1569
if (thread->status == DM_THREAD_DONE) {
1571
join_ret = pthread_join(thread->thread, NULL);
1572
_free_thread_status(thread);
1579
syslog(LOG_ERR, "Failed pthread_join: %s\n", strerror(join_ret));
1582
static void _sig_alarm(int signum __attribute__((unused)))
1584
pthread_testcancel();
1587
/* Init thread signal handling. */
1588
static void _init_thread_signals(void)
1591
struct sigaction act;
1593
memset(&act, 0, sizeof(act));
1594
act.sa_handler = _sig_alarm;
1595
sigaction(SIGALRM, &act, NULL);
1596
sigfillset(&my_sigset);
1598
/* These are used for exiting */
1599
sigdelset(&my_sigset, SIGTERM);
1600
sigdelset(&my_sigset, SIGINT);
1601
sigdelset(&my_sigset, SIGHUP);
1602
sigdelset(&my_sigset, SIGQUIT);
1604
pthread_sigmask(SIG_BLOCK, &my_sigset, NULL);
1611
* Set the global variable which the process should
1612
* be watching to determine when to exit.
1614
static void _exit_handler(int sig __attribute__((unused)))
1617
* We exit when '_exit_now' is set.
1618
* That is, when a signal has been received.
1620
* We can not simply set '_exit_now' unless all
1621
* threads are done processing.
1623
if (!_thread_registries_empty) {
1624
syslog(LOG_ERR, "There are still devices being monitored.");
1625
syslog(LOG_ERR, "Refusing to exit.");
1632
static int _set_oom_adj(const char *oom_adj_path, int val)
1636
if (!(fp = fopen(oom_adj_path, "w"))) {
1637
perror("oom_adj: fopen failed");
1641
fprintf(fp, "%i", val);
1644
perror("oom_adj: fclose failed");
1650
* Protection against OOM killer if kernel supports it
1652
static int _protect_against_oom_killer(void)
1656
if (stat(OOM_ADJ_FILE, &st) == -1) {
1657
if (errno != ENOENT)
1658
perror(OOM_ADJ_FILE ": stat failed");
1660
/* Try old oom_adj interface as a fallback */
1661
if (stat(OOM_ADJ_FILE_OLD, &st) == -1) {
1662
if (errno == ENOENT)
1663
perror(OOM_ADJ_FILE_OLD " not found");
1665
perror(OOM_ADJ_FILE_OLD ": stat failed");
1669
return _set_oom_adj(OOM_ADJ_FILE_OLD, OOM_DISABLE) ||
1670
_set_oom_adj(OOM_ADJ_FILE_OLD, OOM_ADJUST_MIN);
1673
return _set_oom_adj(OOM_ADJ_FILE, OOM_SCORE_ADJ_MIN);
1676
static int _handle_preloaded_fifo(int fd, const char *path)
1678
struct stat st_fd, st_path;
1681
if ((flags = fcntl(fd, F_GETFD)) < 0)
1684
if (flags & FD_CLOEXEC)
1687
if (fstat(fd, &st_fd) < 0 || !S_ISFIFO(st_fd.st_mode))
1690
if (stat(path, &st_path) < 0 ||
1691
st_path.st_dev != st_fd.st_dev ||
1692
st_path.st_ino != st_fd.st_ino)
1695
if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) < 0)
1701
static int _systemd_handover(struct dm_event_fifos *fifos)
1705
unsigned long env_pid, env_listen_fds;
1708
memset(fifos, 0, sizeof(*fifos));
1710
/* LISTEN_PID must be equal to our PID! */
1711
if (!(e = getenv(SD_LISTEN_PID_ENV_VAR_NAME)))
1715
env_pid = strtoul(e, &p, 10);
1716
if (errno || !p || *p || env_pid <= 0 ||
1717
getpid() != (pid_t) env_pid)
1720
/* LISTEN_FDS must be 2 and the fds must be FIFOSs! */
1721
if (!(e = getenv(SD_LISTEN_FDS_ENV_VAR_NAME)))
1725
env_listen_fds = strtoul(e, &p, 10);
1726
if (errno || !p || *p || env_listen_fds != 2)
1729
/* Check and handle the FIFOs passed in */
1730
r = (_handle_preloaded_fifo(SD_FD_FIFO_SERVER, DM_EVENT_FIFO_SERVER) &&
1731
_handle_preloaded_fifo(SD_FD_FIFO_CLIENT, DM_EVENT_FIFO_CLIENT));
1734
fifos->server = SD_FD_FIFO_SERVER;
1735
fifos->server_path = DM_EVENT_FIFO_SERVER;
1736
fifos->client = SD_FD_FIFO_CLIENT;
1737
fifos->client_path = DM_EVENT_FIFO_CLIENT;
1741
unsetenv(SD_LISTEN_PID_ENV_VAR_NAME);
1742
unsetenv(SD_LISTEN_FDS_ENV_VAR_NAME);
1747
static void remove_lockfile(void)
1749
if (unlink(DMEVENTD_PIDFILE))
1750
perror(DMEVENTD_PIDFILE ": unlink failed");
1753
static void _daemonize(void)
1759
struct timeval tval;
1762
sigemptyset(&my_sigset);
1763
if (sigprocmask(SIG_SETMASK, &my_sigset, NULL) < 0) {
1764
fprintf(stderr, "Unable to restore signals.\n");
1767
signal(SIGTERM, &_exit_handler);
1769
switch (pid = fork()) {
1771
perror("fork failed:");
1778
/* Wait for response from child */
1779
while (!waitpid(pid, &child_status, WNOHANG) && !_exit_now) {
1781
tval.tv_usec = 250000; /* .25 sec */
1782
select(0, NULL, NULL, NULL, &tval);
1785
if (_exit_now) /* Child has signaled it is ok - we can exit now */
1788
/* Problem with child. Determine what it is by exit code */
1789
switch (WEXITSTATUS(child_status)) {
1790
case EXIT_DESC_CLOSE_FAILURE:
1791
case EXIT_DESC_OPEN_FAILURE:
1792
case EXIT_FIFO_FAILURE:
1793
case EXIT_CHDIR_FAILURE:
1795
fprintf(stderr, "Child exited with code %d\n", WEXITSTATUS(child_status));
1799
exit(WEXITSTATUS(child_status));
1803
exit(EXIT_CHDIR_FAILURE);
1805
if (getrlimit(RLIMIT_NOFILE, &rlim) < 0)
1806
fd = 256; /* just have to guess */
1810
for (--fd; fd >= 0; fd--) {
1812
/* Do not close fds preloaded by systemd! */
1813
if (_systemd_activation &&
1814
(fd == SD_FD_FIFO_SERVER || fd == SD_FD_FIFO_CLIENT))
1820
if ((open("/dev/null", O_RDONLY) < 0) ||
1821
(open("/dev/null", O_WRONLY) < 0) ||
1822
(open("/dev/null", O_WRONLY) < 0))
1823
exit(EXIT_DESC_OPEN_FAILURE);
1828
static void restart(void)
1830
struct dm_event_fifos fifos;
1831
struct dm_event_daemon_message msg = { 0, 0, NULL };
1837
/* Get the list of registrations from the running daemon. */
1839
if (!init_fifos(&fifos)) {
1840
fprintf(stderr, "WARNING: Could not initiate communication with existing dmeventd.\n");
1844
if (!dm_event_get_version(&fifos, &version)) {
1845
fprintf(stderr, "WARNING: Could not communicate with existing dmeventd.\n");
1851
fprintf(stderr, "WARNING: The running dmeventd instance is too old.\n"
1852
"Protocol version %d (required: 1). Action cancelled.\n",
1857
if (daemon_talk(&fifos, &msg, DM_EVENT_CMD_GET_STATUS, "-", "-", 0, 0)) {
1862
message = strchr(message, ' ');
1864
length = strlen(msg.data);
1865
for (i = 0; i < length; ++i) {
1866
if (msg.data[i] == ';') {
1872
if (!(_initial_registrations = dm_malloc(sizeof(char*) * (count + 1)))) {
1873
fprintf(stderr, "Memory allocation registration failed.\n");
1877
for (i = 0; i < count; ++i) {
1878
if (!(_initial_registrations[i] = dm_strdup(message))) {
1879
fprintf(stderr, "Memory allocation for message failed.\n");
1882
message += strlen(message) + 1;
1884
_initial_registrations[count] = 0;
1886
if (daemon_talk(&fifos, &msg, DM_EVENT_CMD_DIE, "-", "-", 0, 0)) {
1887
fprintf(stderr, "Old dmeventd refused to die.\n");
1894
static void usage(char *prog, FILE *file)
1896
fprintf(file, "Usage:\n"
1897
"%s [-d [-d [-d]]] [-f] [-h] [-R] [-V] [-?]\n\n"
1898
" -d Log debug messages to syslog (-d, -dd, -ddd)\n"
1899
" -f Don't fork, run in the foreground\n"
1900
" -h -? Show this help information\n"
1901
" -R Restart dmeventd\n"
1902
" -V Show version of dmeventd\n\n", prog);
1905
int main(int argc, char *argv[])
1908
struct dm_event_fifos fifos;
1909
//struct sys_log logdata = {DAEMON_NAME, LOG_DAEMON};
1914
while ((opt = getopt(argc, argv, "?fhVdR")) != EOF) {
1917
usage(argv[0], stdout);
1920
usage(argv[0], stderr);
1932
printf("dmeventd version: %s\n", DM_LIB_VERSION);
1938
* Switch to C locale to avoid reading large locale-archive file
1939
* used by some glibc (on some distributions it takes over 100MB).
1940
* Daemon currently needs to use mlockall().
1942
if (setenv("LANG", "C", 1))
1943
perror("Cannot set LANG to C");
1949
_systemd_activation = _systemd_handover(&fifos);
1955
openlog("dmeventd", LOG_PID, LOG_DAEMON);
1957
(void) dm_prepare_selinux_context(DMEVENTD_PIDFILE, S_IFREG);
1958
if (dm_create_lockfile(DMEVENTD_PIDFILE) == 0)
1961
atexit(remove_lockfile);
1962
(void) dm_prepare_selinux_context(NULL, 0);
1964
/* Set the rest of the signals to cause '_exit_now' to be set */
1965
signal(SIGINT, &_exit_handler);
1966
signal(SIGHUP, &_exit_handler);
1967
signal(SIGQUIT, &_exit_handler);
1970
/* Systemd has adjusted oom killer for us already */
1971
if (!_systemd_activation && !_protect_against_oom_killer())
1972
syslog(LOG_ERR, "Failed to protect against OOM killer");
1975
_init_thread_signals();
1977
//multilog_clear_logging();
1978
//multilog_add_type(std_syslog, &logdata);
1979
//multilog_init_verbose(std_syslog, _LOG_DEBUG);
1980
//multilog_async(1);
1982
if (!_systemd_activation)
1983
_init_fifos(&fifos);
1985
pthread_mutex_init(&_global_mutex, NULL);
1987
if (!_systemd_activation && !_open_fifos(&fifos))
1988
exit(EXIT_FIFO_FAILURE);
1990
/* Signal parent, letting them know we are ready to go. */
1992
kill(getppid(), SIGTERM);
1993
syslog(LOG_NOTICE, "dmeventd ready for processing.");
1995
if (_initial_registrations)
1996
_process_initial_registrations();
1998
while (!_exit_now) {
1999
_process_request(&fifos);
2000
_cleanup_unused_threads();
2002
if (!dm_list_empty(&_thread_registry)
2003
|| !dm_list_empty(&_thread_registry_unused))
2004
_thread_registries_empty = 0;
2006
_thread_registries_empty = 1;
2012
pthread_mutex_destroy(&_global_mutex);
2014
syslog(LOG_NOTICE, "dmeventd shutting down.");