Home | History | Annotate | Line # | Download | only in dmeventd
      1 /*	$NetBSD: dmeventd.c,v 1.1.1.1 2008/12/22 00:18:53 haad Exp $	*/
      2 
      3 /*
      4  * Copyright (C) 2005-2007 Red Hat, Inc. All rights reserved.
      5  *
      6  * This file is part of the device-mapper userspace tools.
      7  *
      8  * This copyrighted material is made available to anyone wishing to use,
      9  * modify, copy, or redistribute it subject to the terms and conditions
     10  * of the GNU Lesser General Public License v.2.1.
     11  *
     12  * You should have received a copy of the GNU Lesser General Public License
     13  * along with this program; if not, write to the Free Software Foundation,
     14  * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     15  */
     16 
     17 /*
     18  * dmeventd - dm event daemon to monitor active mapped devices
     19  */
     20 
     21 #define _GNU_SOURCE
     22 #define _FILE_OFFSET_BITS 64
     23 
     24 #include "configure.h"
     25 #include "libdevmapper.h"
     26 #include "libdevmapper-event.h"
     27 #include "dmeventd.h"
     28 //#include "libmultilog.h"
     29 #include "dm-logging.h"
     30 
     31 #include <dlfcn.h>
     32 #include <errno.h>
     33 #include <pthread.h>
     34 #include <sys/file.h>
     35 #include <sys/stat.h>
     36 #include <sys/wait.h>
     37 #include <sys/time.h>
     38 #include <sys/resource.h>
     39 #include <unistd.h>
     40 #include <signal.h>
     41 #include <arpa/inet.h>		/* for htonl, ntohl */
     42 
     43 #ifdef linux
     44 #  include <malloc.h>
     45 
     46 #  define OOM_ADJ_FILE "/proc/self/oom_adj"
     47 
     48 /* From linux/oom.h */
     49 #  define OOM_DISABLE (-17)
     50 #  define OOM_ADJUST_MIN (-16)
     51 
     52 #endif
     53 
     54 /* FIXME We use syslog for now, because multilog is not yet implemented */
     55 #include <syslog.h>
     56 
     57 static volatile sig_atomic_t _exit_now = 0;	/* set to '1' when signal is given to exit */
     58 static volatile sig_atomic_t _thread_registries_empty = 1;	/* registries are empty initially */
     59 static int _debug = 0;
     60 
     61 /* List (un)link macros. */
     62 #define	LINK(x, head)		dm_list_add(head, &(x)->list)
     63 #define	LINK_DSO(dso)		LINK(dso, &_dso_registry)
     64 #define	LINK_THREAD(thread)	LINK(thread, &_thread_registry)
     65 
     66 #define	UNLINK(x)		dm_list_del(&(x)->list)
     67 #define	UNLINK_DSO(x)		UNLINK(x)
     68 #define	UNLINK_THREAD(x)	UNLINK(x)
     69 
     70 #define DAEMON_NAME "dmeventd"
     71 
     72 /*
     73   Global mutex for thread list access. Has to be held when:
     74   - iterating thread list
     75   - adding or removing elements from thread list
     76   - changing or reading thread_status's fields:
     77     processing, status, events
     78   Use _lock_mutex() and _unlock_mutex() to hold/release it
     79 */
     80 static pthread_mutex_t _global_mutex;
     81 
     82 /*
     83   There are three states a thread can attain (see struct
     84   thread_status, field int status):
     85 
     86   - DM_THREAD_RUNNING: thread has started up and is either working or
     87   waiting for events... transitions to either SHUTDOWN or DONE
     88   - DM_THREAD_SHUTDOWN: thread is still doing something, but it is
     89   supposed to terminate (and transition to DONE) as soon as it
     90   finishes whatever it was doing at the point of flipping state to
     91   SHUTDOWN... the thread is still on the thread list
     92   - DM_THREAD_DONE: thread has terminated and has been moved over to
     93   unused thread list, cleanup pending
     94  */
     95 #define DM_THREAD_RUNNING  0
     96 #define DM_THREAD_SHUTDOWN 1
     97 #define DM_THREAD_DONE     2
     98 
     99 #define THREAD_STACK_SIZE (300*1024)
    100 
    101 #define DEBUGLOG(fmt, args...) _debuglog(fmt, ## args)
    102 
    103 /* Data kept about a DSO. */
    104 struct dso_data {
    105 	struct dm_list list;
    106 
    107 	char *dso_name;		/* DSO name (eg, "evms", "dmraid", "lvm2"). */
    108 
    109 	void *dso_handle;	/* Opaque handle as returned from dlopen(). */
    110 	unsigned int ref_count;	/* Library reference count. */
    111 
    112 	/*
    113 	 * Event processing.
    114 	 *
    115 	 * The DSO can do whatever appropriate steps if an event
    116 	 * happens such as changing the mapping in case a mirror
    117 	 * fails, update the application metadata etc.
    118 	 *
    119 	 * This function gets a dm_task that is a result of
    120 	 * DM_DEVICE_WAITEVENT ioctl (results equivalent to
    121 	 * DM_DEVICE_STATUS). It should not destroy it.
    122 	 * The caller must dispose of the task.
    123 	 */
    124 	void (*process_event)(struct dm_task *dmt, enum dm_event_mask event, void **user);
    125 
    126 	/*
    127 	 * Device registration.
    128 	 *
    129 	 * When an application registers a device for an event, the DSO
    130 	 * can carry out appropriate steps so that a later call to
    131 	 * the process_event() function is sane (eg, read metadata
    132 	 * and activate a mapping).
    133 	 */
    134 	int (*register_device)(const char *device, const char *uuid, int major,
    135 			       int minor, void **user);
    136 
    137 	/*
    138 	 * Device unregistration.
    139 	 *
    140 	 * In case all devices of a mapping (eg, RAID10) are unregistered
    141 	 * for events, the DSO can recognize this and carry out appropriate
    142 	 * steps (eg, deactivate mapping, metadata update).
    143 	 */
    144 	int (*unregister_device)(const char *device, const char *uuid,
    145 				 int major, int minor, void **user);
    146 };
    147 static DM_LIST_INIT(_dso_registry);
    148 
    149 /* Structure to keep parsed register variables from client message. */
    150 struct message_data {
    151 	char *id;
    152 	char *dso_name;		/* Name of DSO. */
    153 	char *device_uuid;	/* Mapped device path. */
    154 	union {
    155 		char *str;	/* Events string as fetched from message. */
    156 		enum dm_event_mask field;	/* Events bitfield. */
    157 	} events;
    158 	union {
    159 		char *str;
    160 		uint32_t secs;
    161 	} timeout;
    162 	struct dm_event_daemon_message *msg;	/* Pointer to message buffer. */
    163 };
    164 
    165 /*
    166  * Housekeeping of thread+device states.
    167  *
    168  * One thread per mapped device which can block on it until an event
    169  * occurs and the event processing function of the DSO gets called.
    170  */
    171 struct thread_status {
    172 	struct dm_list list;
    173 
    174 	pthread_t thread;
    175 
    176 	struct dso_data *dso_data;	/* DSO this thread accesses. */
    177 
    178 	struct {
    179 		char *uuid;
    180 		char *name;
    181 		int major, minor;
    182 	} device;
    183 	uint32_t event_nr;	/* event number */
    184 	int processing;		/* Set when event is being processed */
    185 
    186 	int status;		/* see DM_THREAD_{RUNNING,SHUTDOWN,DONE}
    187 				   constants above */
    188 	enum dm_event_mask events;	/* bitfield for event filter. */
    189 	enum dm_event_mask current_events;	/* bitfield for occured events. */
    190 	struct dm_task *current_task;
    191 	time_t next_time;
    192 	uint32_t timeout;
    193 	struct dm_list timeout_list;
    194 	void *dso_private; /* dso per-thread status variable */
    195 };
    196 static DM_LIST_INIT(_thread_registry);
    197 static DM_LIST_INIT(_thread_registry_unused);
    198 
    199 static int _timeout_running;
    200 static DM_LIST_INIT(_timeout_registry);
    201 static pthread_mutex_t _timeout_mutex = PTHREAD_MUTEX_INITIALIZER;
    202 static pthread_cond_t _timeout_cond = PTHREAD_COND_INITIALIZER;
    203 
    204 static void _debuglog(const char *fmt, ...)
    205 {
    206         time_t P;
    207         va_list ap;
    208 
    209         if (!_debug)
    210                 return;
    211 
    212         va_start(ap,fmt);
    213 
    214         time(&P);
    215         fprintf(stderr, "dmeventd[%p]: %.15s ", (void *) pthread_self(), ctime(&P)+4 );
    216         vfprintf(stderr, fmt, ap);
    217 	fprintf(stderr, "\n");
    218 
    219         va_end(ap);
    220 }
    221 
    222 /* Allocate/free the status structure for a monitoring thread. */
    223 static struct thread_status *_alloc_thread_status(struct message_data *data,
    224 						  struct dso_data *dso_data)
    225 {
    226 	struct thread_status *ret = (typeof(ret)) dm_malloc(sizeof(*ret));
    227 
    228 	if (!ret)
    229 		return NULL;
    230 
    231 	memset(ret, 0, sizeof(*ret));
    232 	if (!(ret->device.uuid = dm_strdup(data->device_uuid))) {
    233 		dm_free(ret);
    234 		return NULL;
    235 	}
    236 
    237 	ret->current_task = NULL;
    238 	ret->device.name = NULL;
    239 	ret->device.major = ret->device.minor = 0;
    240 	ret->dso_data = dso_data;
    241 	ret->events = data->events.field;
    242 	ret->timeout = data->timeout.secs;
    243 	dm_list_init(&ret->timeout_list);
    244 
    245 	return ret;
    246 }
    247 
    248 static void _free_thread_status(struct thread_status *thread)
    249 {
    250 	if (thread->current_task)
    251 		dm_task_destroy(thread->current_task);
    252 	dm_free(thread->device.uuid);
    253 	dm_free(thread->device.name);
    254 	dm_free(thread);
    255 }
    256 
    257 /* Allocate/free DSO data. */
    258 static struct dso_data *_alloc_dso_data(struct message_data *data)
    259 {
    260 	struct dso_data *ret = (typeof(ret)) dm_malloc(sizeof(*ret));
    261 
    262 	if (!ret)
    263 		return NULL;
    264 
    265 	memset(ret, 0, sizeof(*ret));
    266 	if (!(ret->dso_name = dm_strdup(data->dso_name))) {
    267 		dm_free(ret);
    268 		return NULL;
    269 	}
    270 
    271 	return ret;
    272 }
    273 
    274 /* Create a device monitoring thread. */
    275 static int _pthread_create_smallstack(pthread_t *t, void *(*fun)(void *), void *arg)
    276 {
    277 	pthread_attr_t attr;
    278 	pthread_attr_init(&attr);
    279 	/*
    280 	 * We use a smaller stack since it gets preallocated in its entirety
    281 	 */
    282 	pthread_attr_setstacksize(&attr, THREAD_STACK_SIZE);
    283 	return pthread_create(t, &attr, fun, arg);
    284 }
    285 
    286 static void _free_dso_data(struct dso_data *data)
    287 {
    288 	dm_free(data->dso_name);
    289 	dm_free(data);
    290 }
    291 
    292 /*
    293  * Fetch a string off src and duplicate it into *ptr.
    294  * Pay attention to zero-length strings.
    295  */
    296 /* FIXME? move to libdevmapper to share with the client lib (need to
    297    make delimiter a parameter then) */
    298 static int _fetch_string(char **ptr, char **src, const int delimiter)
    299 {
    300 	int ret = 0;
    301 	char *p;
    302 	size_t len;
    303 
    304 	if ((p = strchr(*src, delimiter)))
    305 		*p = 0;
    306 
    307 	if ((*ptr = dm_strdup(*src))) {
    308 		if ((len = strlen(*ptr)))
    309 			*src += len;
    310 		else {
    311 			dm_free(*ptr);
    312 			*ptr = NULL;
    313 		}
    314 
    315 		(*src)++;
    316 		ret = 1;
    317 	}
    318 
    319 	if (p)
    320 		*p = delimiter;
    321 
    322 	return ret;
    323 }
    324 
    325 /* Free message memory. */
    326 static void _free_message(struct message_data *message_data)
    327 {
    328 	if (message_data->id)
    329 		dm_free(message_data->id);
    330 	if (message_data->dso_name)
    331 		dm_free(message_data->dso_name);
    332 
    333 	if (message_data->device_uuid)
    334 		dm_free(message_data->device_uuid);
    335 
    336 }
    337 
    338 /* Parse a register message from the client. */
    339 static int _parse_message(struct message_data *message_data)
    340 {
    341 	int ret = 0;
    342 	char *p = message_data->msg->data;
    343 	struct dm_event_daemon_message *msg = message_data->msg;
    344 
    345 	if (!msg->data)
    346 		return 0;
    347 
    348 	/*
    349 	 * Retrieve application identifier, mapped device
    350 	 * path and events # string from message.
    351 	 */
    352 	if (_fetch_string(&message_data->id, &p, ' ') &&
    353 	    _fetch_string(&message_data->dso_name, &p, ' ') &&
    354 	    _fetch_string(&message_data->device_uuid, &p, ' ') &&
    355 	    _fetch_string(&message_data->events.str, &p, ' ') &&
    356 	    _fetch_string(&message_data->timeout.str, &p, ' ')) {
    357 		if (message_data->events.str) {
    358 			enum dm_event_mask i = atoi(message_data->events.str);
    359 
    360 			/*
    361 			 * Free string representaion of events.
    362 			 * Not needed an more.
    363 			 */
    364 			dm_free(message_data->events.str);
    365 			message_data->events.field = i;
    366 		}
    367 		if (message_data->timeout.str) {
    368 			uint32_t secs = atoi(message_data->timeout.str);
    369 			dm_free(message_data->timeout.str);
    370 			message_data->timeout.secs = secs ? secs :
    371 			    DM_EVENT_DEFAULT_TIMEOUT;
    372 		}
    373 
    374 		ret = 1;
    375 	}
    376 
    377 	dm_free(msg->data);
    378 	msg->data = NULL;
    379 	msg->size = 0;
    380 	return ret;
    381 };
    382 
    383 /* Global mutex to lock access to lists et al. See _global_mutex
    384    above. */
    385 static int _lock_mutex(void)
    386 {
    387 	return pthread_mutex_lock(&_global_mutex);
    388 }
    389 
    390 static int _unlock_mutex(void)
    391 {
    392 	return pthread_mutex_unlock(&_global_mutex);
    393 }
    394 
    395 /* Store pid in pidfile. */
    396 static int _storepid(int lf)
    397 {
    398 	int len;
    399 	char pid[8];
    400 
    401 	if ((len = snprintf(pid, sizeof(pid), "%u\n", getpid())) < 0)
    402 		return 0;
    403 
    404 	if (len > (int) sizeof(pid))
    405 		len = (int) sizeof(pid);
    406 
    407 	if (write(lf, pid, (size_t) len) != len)
    408 		return 0;
    409 
    410 	fsync(lf);
    411 
    412 	return 1;
    413 }
    414 
    415 /* Check, if a device exists. */
    416 static int _fill_device_data(struct thread_status *ts)
    417 {
    418 	struct dm_task *dmt;
    419 	struct dm_info dmi;
    420 
    421 	if (!ts->device.uuid)
    422 		return 0;
    423 
    424 	ts->device.name = NULL;
    425 	ts->device.major = ts->device.minor = 0;
    426 
    427 	dmt = dm_task_create(DM_DEVICE_INFO);
    428 	if (!dmt)
    429 		return 0;
    430 
    431 	dm_task_set_uuid(dmt, ts->device.uuid);
    432 	if (!dm_task_run(dmt))
    433 		goto fail;
    434 
    435 	ts->device.name = dm_strdup(dm_task_get_name(dmt));
    436 	if (!ts->device.name)
    437 		goto fail;
    438 
    439 	if (!dm_task_get_info(dmt, &dmi))
    440 		goto fail;
    441 
    442 	ts->device.major = dmi.major;
    443 	ts->device.minor = dmi.minor;
    444 
    445 	dm_task_destroy(dmt);
    446 	return 1;
    447 
    448       fail:
    449 	dm_task_destroy(dmt);
    450 	dm_free(ts->device.name);
    451 	return 0;
    452 }
    453 
    454 /*
    455  * Find an existing thread for a device.
    456  *
    457  * Mutex must be held when calling this.
    458  */
    459 static struct thread_status *_lookup_thread_status(struct message_data *data)
    460 {
    461 	struct thread_status *thread;
    462 
    463 	dm_list_iterate_items(thread, &_thread_registry)
    464 	    if (!strcmp(data->device_uuid, thread->device.uuid))
    465 		return thread;
    466 
    467 	return NULL;
    468 }
    469 
    470 /* Cleanup at exit. */
    471 static void _exit_dm_lib(void)
    472 {
    473 	dm_lib_release();
    474 	dm_lib_exit();
    475 }
    476 
    477 static void _exit_timeout(void *unused __attribute((unused)))
    478 {
    479 	_timeout_running = 0;
    480 	pthread_mutex_unlock(&_timeout_mutex);
    481 }
    482 
    483 /* Wake up monitor threads every so often. */
    484 static void *_timeout_thread(void *unused __attribute((unused)))
    485 {
    486 	struct timespec timeout;
    487 	time_t curr_time;
    488 
    489 	timeout.tv_nsec = 0;
    490 	pthread_cleanup_push(_exit_timeout, NULL);
    491 	pthread_mutex_lock(&_timeout_mutex);
    492 
    493 	while (!dm_list_empty(&_timeout_registry)) {
    494 		struct thread_status *thread;
    495 
    496 		timeout.tv_sec = 0;
    497 		curr_time = time(NULL);
    498 
    499 		dm_list_iterate_items_gen(thread, &_timeout_registry, timeout_list) {
    500 			if (thread->next_time <= curr_time) {
    501 				thread->next_time = curr_time + thread->timeout;
    502 				pthread_kill(thread->thread, SIGALRM);
    503 			}
    504 
    505 			if (thread->next_time < timeout.tv_sec || !timeout.tv_sec)
    506 				timeout.tv_sec = thread->next_time;
    507 		}
    508 
    509 		pthread_cond_timedwait(&_timeout_cond, &_timeout_mutex,
    510 				       &timeout);
    511 	}
    512 
    513 	pthread_cleanup_pop(1);
    514 
    515 	return NULL;
    516 }
    517 
    518 static int _register_for_timeout(struct thread_status *thread)
    519 {
    520 	int ret = 0;
    521 
    522 	pthread_mutex_lock(&_timeout_mutex);
    523 
    524 	thread->next_time = time(NULL) + thread->timeout;
    525 
    526 	if (dm_list_empty(&thread->timeout_list)) {
    527 		dm_list_add(&_timeout_registry, &thread->timeout_list);
    528 		if (_timeout_running)
    529 			pthread_cond_signal(&_timeout_cond);
    530 	}
    531 
    532 	if (!_timeout_running) {
    533 		pthread_t timeout_id;
    534 
    535 		if (!(ret = -_pthread_create_smallstack(&timeout_id, _timeout_thread, NULL)))
    536 			_timeout_running = 1;
    537 	}
    538 
    539 	pthread_mutex_unlock(&_timeout_mutex);
    540 
    541 	return ret;
    542 }
    543 
    544 static void _unregister_for_timeout(struct thread_status *thread)
    545 {
    546 	pthread_mutex_lock(&_timeout_mutex);
    547 	if (!dm_list_empty(&thread->timeout_list)) {
    548 		dm_list_del(&thread->timeout_list);
    549 		dm_list_init(&thread->timeout_list);
    550 	}
    551 	pthread_mutex_unlock(&_timeout_mutex);
    552 }
    553 
    554 static void _no_intr_log(int level, const char *file, int line,
    555 			const char *f, ...)
    556 {
    557 	va_list ap;
    558 
    559 	if (errno == EINTR)
    560 		return;
    561 	if (level > _LOG_WARN)
    562 		return;
    563 
    564 	va_start(ap, f);
    565 
    566 	if (level < _LOG_WARN)
    567 		vfprintf(stderr, f, ap);
    568 	else
    569 		vprintf(f, ap);
    570 
    571 	va_end(ap);
    572 
    573 	if (level < _LOG_WARN)
    574 		fprintf(stderr, "\n");
    575 	else
    576 		fprintf(stdout, "\n");
    577 }
    578 
    579 static sigset_t _unblock_sigalrm(void)
    580 {
    581 	sigset_t set, old;
    582 
    583 	sigemptyset(&set);
    584 	sigaddset(&set, SIGALRM);
    585 	pthread_sigmask(SIG_UNBLOCK, &set, &old);
    586 	return old;
    587 }
    588 
    589 #define DM_WAIT_RETRY 0
    590 #define DM_WAIT_INTR 1
    591 #define DM_WAIT_FATAL 2
    592 
    593 /* Wait on a device until an event occurs. */
    594 static int _event_wait(struct thread_status *thread, struct dm_task **task)
    595 {
    596 	sigset_t set;
    597 	int ret = DM_WAIT_RETRY;
    598 	struct dm_task *dmt;
    599 	struct dm_info info;
    600 
    601 	*task = 0;
    602 
    603 	if (!(dmt = dm_task_create(DM_DEVICE_WAITEVENT)))
    604 		return DM_WAIT_RETRY;
    605 
    606 	thread->current_task = dmt;
    607 
    608 	if (!dm_task_set_uuid(dmt, thread->device.uuid) ||
    609 	    !dm_task_set_event_nr(dmt, thread->event_nr))
    610 		goto out;
    611 
    612 	/*
    613 	 * This is so that you can break out of waiting on an event,
    614 	 * either for a timeout event, or to cancel the thread.
    615 	 */
    616 	set = _unblock_sigalrm();
    617 	dm_log_init(_no_intr_log);
    618 	errno = 0;
    619 	if (dm_task_run(dmt)) {
    620 		thread->current_events |= DM_EVENT_DEVICE_ERROR;
    621 		ret = DM_WAIT_INTR;
    622 
    623 		if ((ret = dm_task_get_info(dmt, &info)))
    624 			thread->event_nr = info.event_nr;
    625 	} else if (thread->events & DM_EVENT_TIMEOUT && errno == EINTR) {
    626 		thread->current_events |= DM_EVENT_TIMEOUT;
    627 		ret = DM_WAIT_INTR;
    628 	} else if (thread->status == DM_THREAD_SHUTDOWN && errno == EINTR) {
    629 		ret = DM_WAIT_FATAL;
    630 	} else {
    631 		syslog(LOG_NOTICE, "dm_task_run failed, errno = %d, %s",
    632 		       errno, strerror(errno));
    633 		if (errno == ENXIO) {
    634 			syslog(LOG_ERR, "%s disappeared, detaching",
    635 			       thread->device.name);
    636 			ret = DM_WAIT_FATAL;
    637 		}
    638 	}
    639 
    640 	pthread_sigmask(SIG_SETMASK, &set, NULL);
    641 	dm_log_init(NULL);
    642 
    643       out:
    644 	if (ret == DM_WAIT_FATAL || ret == DM_WAIT_RETRY) {
    645 		dm_task_destroy(dmt);
    646 		thread->current_task = NULL;
    647 	} else
    648 		*task = dmt;
    649 
    650 	return ret;
    651 }
    652 
    653 /* Register a device with the DSO. */
    654 static int _do_register_device(struct thread_status *thread)
    655 {
    656 	return thread->dso_data->register_device(thread->device.name,
    657 						 thread->device.uuid,
    658 						 thread->device.major,
    659 						 thread->device.minor,
    660 						 &(thread->dso_private));
    661 }
    662 
    663 /* Unregister a device with the DSO. */
    664 static int _do_unregister_device(struct thread_status *thread)
    665 {
    666 	return thread->dso_data->unregister_device(thread->device.name,
    667 						   thread->device.uuid,
    668 						   thread->device.major,
    669 						   thread->device.minor,
    670 						   &(thread->dso_private));
    671 }
    672 
    673 /* Process an event in the DSO. */
    674 static void _do_process_event(struct thread_status *thread, struct dm_task *task)
    675 {
    676 	thread->dso_data->process_event(task, thread->current_events, &(thread->dso_private));
    677 }
    678 
    679 /* Thread cleanup handler to unregister device. */
    680 static void _monitor_unregister(void *arg)
    681 {
    682 	struct thread_status *thread = arg, *thread_iter;
    683 
    684 	if (!_do_unregister_device(thread))
    685 		syslog(LOG_ERR, "%s: %s unregister failed\n", __func__,
    686 		       thread->device.name);
    687 	if (thread->current_task)
    688 		dm_task_destroy(thread->current_task);
    689 	thread->current_task = NULL;
    690 
    691 	_lock_mutex();
    692 	if (thread->events & DM_EVENT_TIMEOUT) {
    693 		/* _unregister_for_timeout locks another mutex, we
    694 		   don't want to deadlock so we release our mutex for
    695 		   a bit */
    696 		_unlock_mutex();
    697 		_unregister_for_timeout(thread);
    698 		_lock_mutex();
    699 	}
    700 	/* we may have been relinked to unused registry since we were
    701 	   called, so check that */
    702 	dm_list_iterate_items(thread_iter, &_thread_registry_unused)
    703 		if (thread_iter == thread) {
    704 			thread->status = DM_THREAD_DONE;
    705 			_unlock_mutex();
    706 			return;
    707 		}
    708 	thread->status = DM_THREAD_DONE;
    709 	UNLINK_THREAD(thread);
    710 	LINK(thread, &_thread_registry_unused);
    711 	_unlock_mutex();
    712 }
    713 
    714 static struct dm_task *_get_device_status(struct thread_status *ts)
    715 {
    716 	struct dm_task *dmt = dm_task_create(DM_DEVICE_STATUS);
    717 
    718 	if (!dmt)
    719 		return NULL;
    720 
    721 	dm_task_set_uuid(dmt, ts->device.uuid);
    722 
    723 	if (!dm_task_run(dmt)) {
    724 		dm_task_destroy(dmt);
    725 		return NULL;
    726 	}
    727 
    728 	return dmt;
    729 }
    730 
    731 /* Device monitoring thread. */
    732 static void *_monitor_thread(void *arg)
    733 {
    734 	struct thread_status *thread = arg;
    735 	int wait_error = 0;
    736 	struct dm_task *task;
    737 
    738 	pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);
    739 	pthread_cleanup_push(_monitor_unregister, thread);
    740 
    741 	/* Wait for do_process_request() to finish its task. */
    742 	_lock_mutex();
    743 	thread->status = DM_THREAD_RUNNING;
    744 	_unlock_mutex();
    745 
    746 	/* Loop forever awaiting/analyzing device events. */
    747 	while (1) {
    748 		thread->current_events = 0;
    749 
    750 		wait_error = _event_wait(thread, &task);
    751 		if (wait_error == DM_WAIT_RETRY)
    752 			continue;
    753 
    754 		if (wait_error == DM_WAIT_FATAL)
    755 			break;
    756 
    757 		/* Timeout occurred, task is not filled properly.
    758 		 * We get device status here for processing it in DSO.
    759 		 */
    760 		if (wait_error == DM_WAIT_INTR &&
    761 		    thread->current_events & DM_EVENT_TIMEOUT) {
    762 			dm_task_destroy(task);
    763 			task = _get_device_status(thread);
    764 			/* FIXME: syslog fail here ? */
    765 			if (!(thread->current_task = task))
    766 				continue;
    767 		}
    768 
    769 		/*
    770 		 * We know that wait succeeded and stored a
    771 		 * pointer to dm_task with device status into task.
    772 		 */
    773 
    774 		/*
    775 		 * Check against filter.
    776 		 *
    777 		 * If there's current events delivered from _event_wait() AND
    778 		 * the device got registered for those events AND
    779 		 * those events haven't been processed yet, call
    780 		 * the DSO's process_event() handler.
    781 		 */
    782 		_lock_mutex();
    783 		if (thread->status == DM_THREAD_SHUTDOWN) {
    784 			_unlock_mutex();
    785 			break;
    786 		}
    787 		_unlock_mutex();
    788 
    789 		if (thread->events & thread->current_events) {
    790 			_lock_mutex();
    791 			thread->processing = 1;
    792 			_unlock_mutex();
    793 
    794 			_do_process_event(thread, task);
    795 			dm_task_destroy(task);
    796 			thread->current_task = NULL;
    797 
    798 			_lock_mutex();
    799 			thread->processing = 0;
    800 			_unlock_mutex();
    801 		} else {
    802 			dm_task_destroy(task);
    803 			thread->current_task = NULL;
    804 		}
    805 	}
    806 
    807 	pthread_cleanup_pop(1);
    808 
    809 	return NULL;
    810 }
    811 
    812 /* Create a device monitoring thread. */
    813 static int _create_thread(struct thread_status *thread)
    814 {
    815 	return _pthread_create_smallstack(&thread->thread, _monitor_thread, thread);
    816 }
    817 
    818 static int _terminate_thread(struct thread_status *thread)
    819 {
    820 	return pthread_kill(thread->thread, SIGALRM);
    821 }
    822 
    823 /* DSO reference counting. Call with _global_mutex locked! */
    824 static void _lib_get(struct dso_data *data)
    825 {
    826 	data->ref_count++;
    827 }
    828 
    829 static void _lib_put(struct dso_data *data)
    830 {
    831 	if (!--data->ref_count) {
    832 		dlclose(data->dso_handle);
    833 		UNLINK_DSO(data);
    834 		_free_dso_data(data);
    835 	}
    836 }
    837 
    838 /* Find DSO data. */
    839 static struct dso_data *_lookup_dso(struct message_data *data)
    840 {
    841 	struct dso_data *dso_data, *ret = NULL;
    842 
    843 	dm_list_iterate_items(dso_data, &_dso_registry)
    844 	    if (!strcmp(data->dso_name, dso_data->dso_name)) {
    845 		_lib_get(dso_data);
    846 		ret = dso_data;
    847 		break;
    848 	}
    849 
    850 	return ret;
    851 }
    852 
    853 /* Lookup DSO symbols we need. */
    854 static int _lookup_symbol(void *dl, void **symbol, const char *name)
    855 {
    856 	if ((*symbol = dlsym(dl, name)))
    857 		return 1;
    858 
    859 	return 0;
    860 }
    861 
    862 static int lookup_symbols(void *dl, struct dso_data *data)
    863 {
    864 	return _lookup_symbol(dl, (void *) &data->process_event,
    865 			     "process_event") &&
    866 	    _lookup_symbol(dl, (void *) &data->register_device,
    867 			  "register_device") &&
    868 	    _lookup_symbol(dl, (void *) &data->unregister_device,
    869 			  "unregister_device");
    870 }
    871 
    872 /* Load an application specific DSO. */
    873 static struct dso_data *_load_dso(struct message_data *data)
    874 {
    875 	void *dl;
    876 	struct dso_data *ret = NULL;
    877 
    878 	if (!(dl = dlopen(data->dso_name, RTLD_NOW))) {
    879 		const char *dlerr = dlerror();
    880 		syslog(LOG_ERR, "dmeventd %s dlopen failed: %s", data->dso_name,
    881 		       dlerr);
    882 		data->msg->size =
    883 		    dm_asprintf(&(data->msg->data), "%s %s dlopen failed: %s",
    884 				data->id, data->dso_name, dlerr);
    885 		return NULL;
    886 	}
    887 
    888 	if (!(ret = _alloc_dso_data(data))) {
    889 		dlclose(dl);
    890 		return NULL;
    891 	}
    892 
    893 	if (!(lookup_symbols(dl, ret))) {
    894 		_free_dso_data(ret);
    895 		dlclose(dl);
    896 		return NULL;
    897 	}
    898 
    899 	/*
    900 	 * Keep handle to close the library once
    901 	 * we've got no references to it any more.
    902 	 */
    903 	ret->dso_handle = dl;
    904 	_lib_get(ret);
    905 
    906 	_lock_mutex();
    907 	LINK_DSO(ret);
    908 	_unlock_mutex();
    909 
    910 	return ret;
    911 }
    912 
    913 /* Return success on daemon active check. */
    914 static int _active(struct message_data *message_data)
    915 {
    916 	return 0;
    917 }
    918 
    919 /*
    920  * Register for an event.
    921  *
    922  * Only one caller at a time here, because we use
    923  * a FIFO and lock it against multiple accesses.
    924  */
    925 static int _register_for_event(struct message_data *message_data)
    926 {
    927 	int ret = 0;
    928 	struct thread_status *thread, *thread_new = NULL;
    929 	struct dso_data *dso_data;
    930 
    931 	if (!(dso_data = _lookup_dso(message_data)) &&
    932 	    !(dso_data = _load_dso(message_data))) {
    933 		stack;
    934 #ifdef ELIBACC
    935 		ret = -ELIBACC;
    936 #else
    937 		ret = -ENODEV;
    938 #endif
    939 		goto out;
    940 	}
    941 
    942 	/* Preallocate thread status struct to avoid deadlock. */
    943 	if (!(thread_new = _alloc_thread_status(message_data, dso_data))) {
    944 		stack;
    945 		ret = -ENOMEM;
    946 		goto out;
    947 	}
    948 
    949 	if (!_fill_device_data(thread_new)) {
    950 		stack;
    951 		ret = -ENODEV;
    952 		goto out;
    953 	}
    954 
    955 	_lock_mutex();
    956 
    957 	/* If creation of timeout thread fails (as it may), we fail
    958 	   here completely. The client is responsible for either
    959 	   retrying later or trying to register without timeout
    960 	   events. However, if timeout thread cannot be started, it
    961 	   usually means we are so starved on resources that we are
    962 	   almost as good as dead already... */
    963 	if (thread_new->events & DM_EVENT_TIMEOUT) {
    964 		ret = -_register_for_timeout(thread_new);
    965 		if (ret) {
    966 		    _unlock_mutex();
    967 		    goto out;
    968 		}
    969 	}
    970 
    971 	if (!(thread = _lookup_thread_status(message_data))) {
    972 		_unlock_mutex();
    973 
    974 		if (!(ret = _do_register_device(thread_new)))
    975 			goto out;
    976 
    977 		thread = thread_new;
    978 		thread_new = NULL;
    979 
    980 		/* Try to create the monitoring thread for this device. */
    981 		_lock_mutex();
    982 		if ((ret = -_create_thread(thread))) {
    983 			_unlock_mutex();
    984 			_do_unregister_device(thread);
    985 			_free_thread_status(thread);
    986 			goto out;
    987 		} else
    988 			LINK_THREAD(thread);
    989 	}
    990 
    991 	/* Or event # into events bitfield. */
    992 	thread->events |= message_data->events.field;
    993 
    994 	_unlock_mutex();
    995 
    996       out:
    997 	/*
    998 	 * Deallocate thread status after releasing
    999 	 * the lock in case we haven't used it.
   1000 	 */
   1001 	if (thread_new)
   1002 		_free_thread_status(thread_new);
   1003 
   1004 	return ret;
   1005 }
   1006 
   1007 /*
   1008  * Unregister for an event.
   1009  *
   1010  * Only one caller at a time here as with register_for_event().
   1011  */
   1012 static int _unregister_for_event(struct message_data *message_data)
   1013 {
   1014 	int ret = 0;
   1015 	struct thread_status *thread;
   1016 
   1017 	/*
   1018 	 * Clear event in bitfield and deactivate
   1019 	 * monitoring thread in case bitfield is 0.
   1020 	 */
   1021 	_lock_mutex();
   1022 
   1023 	if (!(thread = _lookup_thread_status(message_data))) {
   1024 		_unlock_mutex();
   1025 		ret = -ENODEV;
   1026 		goto out;
   1027 	}
   1028 
   1029 	if (thread->status == DM_THREAD_DONE) {
   1030 		/* the thread has terminated while we were not
   1031 		   watching */
   1032 		_unlock_mutex();
   1033 		return 0;
   1034 	}
   1035 
   1036 	thread->events &= ~message_data->events.field;
   1037 
   1038 	if (!(thread->events & DM_EVENT_TIMEOUT))
   1039 		_unregister_for_timeout(thread);
   1040 	/*
   1041 	 * In case there's no events to monitor on this device ->
   1042 	 * unlink and terminate its monitoring thread.
   1043 	 */
   1044 	if (!thread->events) {
   1045 		UNLINK_THREAD(thread);
   1046 		LINK(thread, &_thread_registry_unused);
   1047 	}
   1048 	_unlock_mutex();
   1049 
   1050       out:
   1051 	return ret;
   1052 }
   1053 
   1054 /*
   1055  * Get registered device.
   1056  *
   1057  * Only one caller at a time here as with register_for_event().
   1058  */
   1059 static int _registered_device(struct message_data *message_data,
   1060 			     struct thread_status *thread)
   1061 {
   1062 	struct dm_event_daemon_message *msg = message_data->msg;
   1063 
   1064 	const char *fmt = "%s %s %s %u";
   1065 	const char *id = message_data->id;
   1066 	const char *dso = thread->dso_data->dso_name;
   1067 	const char *dev = thread->device.uuid;
   1068 	unsigned events = ((thread->status == DM_THREAD_RUNNING)
   1069 			   && (thread->events)) ? thread->events : thread->
   1070 	    events | DM_EVENT_REGISTRATION_PENDING;
   1071 
   1072 	if (msg->data)
   1073 		dm_free(msg->data);
   1074 
   1075 	msg->size = dm_asprintf(&(msg->data), fmt, id, dso, dev, events);
   1076 
   1077 	_unlock_mutex();
   1078 
   1079 	return 0;
   1080 }
   1081 
   1082 static int _want_registered_device(char *dso_name, char *device_uuid,
   1083 				  struct thread_status *thread)
   1084 {
   1085 	/* If DSO names and device paths are equal. */
   1086 	if (dso_name && device_uuid)
   1087 		return !strcmp(dso_name, thread->dso_data->dso_name) &&
   1088 		    !strcmp(device_uuid, thread->device.uuid) &&
   1089 			(thread->status == DM_THREAD_RUNNING ||
   1090 			 (thread->events & DM_EVENT_REGISTRATION_PENDING));
   1091 
   1092 	/* If DSO names are equal. */
   1093 	if (dso_name)
   1094 		return !strcmp(dso_name, thread->dso_data->dso_name) &&
   1095 			(thread->status == DM_THREAD_RUNNING ||
   1096 			 (thread->events & DM_EVENT_REGISTRATION_PENDING));
   1097 
   1098 	/* If device paths are equal. */
   1099 	if (device_uuid)
   1100 		return !strcmp(device_uuid, thread->device.uuid) &&
   1101 			(thread->status == DM_THREAD_RUNNING ||
   1102 			 (thread->events & DM_EVENT_REGISTRATION_PENDING));
   1103 
   1104 	return 1;
   1105 }
   1106 
   1107 static int _get_registered_dev(struct message_data *message_data, int next)
   1108 {
   1109 	struct thread_status *thread, *hit = NULL;
   1110 
   1111 	_lock_mutex();
   1112 
   1113 	/* Iterate list of threads checking if we want a particular one. */
   1114 	dm_list_iterate_items(thread, &_thread_registry)
   1115 		if (_want_registered_device(message_data->dso_name,
   1116 					    message_data->device_uuid,
   1117 					    thread)) {
   1118 			hit = thread;
   1119 			break;
   1120 		}
   1121 
   1122 	/*
   1123 	 * If we got a registered device and want the next one ->
   1124 	 * fetch next conforming element off the list.
   1125 	 */
   1126 	if (hit && !next) {
   1127 		_unlock_mutex();
   1128 		return _registered_device(message_data, hit);
   1129 	}
   1130 
   1131 	if (!hit)
   1132 		goto out;
   1133 
   1134 	thread = hit;
   1135 
   1136 	while (1) {
   1137 		if (dm_list_end(&_thread_registry, &thread->list))
   1138 			goto out;
   1139 
   1140 		thread = dm_list_item(thread->list.n, struct thread_status);
   1141 		if (_want_registered_device(message_data->dso_name, NULL, thread)) {
   1142 			hit = thread;
   1143 			break;
   1144 		}
   1145 	}
   1146 
   1147 	_unlock_mutex();
   1148 	return _registered_device(message_data, hit);
   1149 
   1150       out:
   1151 	_unlock_mutex();
   1152 
   1153 	return -ENOENT;
   1154 }
   1155 
   1156 static int _get_registered_device(struct message_data *message_data)
   1157 {
   1158 	return _get_registered_dev(message_data, 0);
   1159 }
   1160 
   1161 static int _get_next_registered_device(struct message_data *message_data)
   1162 {
   1163 	return _get_registered_dev(message_data, 1);
   1164 }
   1165 
   1166 static int _set_timeout(struct message_data *message_data)
   1167 {
   1168 	struct thread_status *thread;
   1169 
   1170 	_lock_mutex();
   1171 	if ((thread = _lookup_thread_status(message_data)))
   1172 		thread->timeout = message_data->timeout.secs;
   1173 	_unlock_mutex();
   1174 
   1175 	return thread ? 0 : -ENODEV;
   1176 }
   1177 
   1178 static int _get_timeout(struct message_data *message_data)
   1179 {
   1180 	struct thread_status *thread;
   1181 	struct dm_event_daemon_message *msg = message_data->msg;
   1182 
   1183 	if (msg->data)
   1184 		dm_free(msg->data);
   1185 
   1186 	_lock_mutex();
   1187 	if ((thread = _lookup_thread_status(message_data))) {
   1188 		msg->size =
   1189 		    dm_asprintf(&(msg->data), "%s %" PRIu32, message_data->id,
   1190 				thread->timeout);
   1191 	} else {
   1192 		msg->data = NULL;
   1193 		msg->size = 0;
   1194 	}
   1195 	_unlock_mutex();
   1196 
   1197 	return thread ? 0 : -ENODEV;
   1198 }
   1199 
   1200 /* Initialize a fifos structure with path names. */
   1201 static void _init_fifos(struct dm_event_fifos *fifos)
   1202 {
   1203 	memset(fifos, 0, sizeof(*fifos));
   1204 
   1205 	fifos->client_path = DM_EVENT_FIFO_CLIENT;
   1206 	fifos->server_path = DM_EVENT_FIFO_SERVER;
   1207 }
   1208 
   1209 /* Open fifos used for client communication. */
   1210 static int _open_fifos(struct dm_event_fifos *fifos)
   1211 {
   1212 	/* Create fifos */
   1213 	if (((mkfifo(fifos->client_path, 0600) == -1) && errno != EEXIST) ||
   1214 	    ((mkfifo(fifos->server_path, 0600) == -1) && errno != EEXIST)) {
   1215 		syslog(LOG_ERR, "%s: Failed to create a fifo.\n", __func__);
   1216 		stack;
   1217 		return -errno;
   1218 	}
   1219 
   1220 	struct stat st;
   1221 
   1222 	/* Warn about wrong permissions if applicable */
   1223 	if ((!stat(fifos->client_path, &st)) && (st.st_mode & 0777) != 0600)
   1224 		syslog(LOG_WARNING, "Fixing wrong permissions on %s",
   1225 		       fifos->client_path);
   1226 
   1227 	if ((!stat(fifos->server_path, &st)) && (st.st_mode & 0777) != 0600)
   1228 		syslog(LOG_WARNING, "Fixing wrong permissions on %s",
   1229 		       fifos->server_path);
   1230 
   1231 	/* If they were already there, make sure permissions are ok. */
   1232 	if (chmod(fifos->client_path, 0600)) {
   1233 		syslog(LOG_ERR, "Unable to set correct file permissions on %s",
   1234 		       fifos->client_path);
   1235 		return -errno;
   1236 	}
   1237 
   1238 	if (chmod(fifos->server_path, 0600)) {
   1239 		syslog(LOG_ERR, "Unable to set correct file permissions on %s",
   1240 		       fifos->server_path);
   1241 		return -errno;
   1242 	}
   1243 
   1244 	/* Need to open read+write or we will block or fail */
   1245 	if ((fifos->server = open(fifos->server_path, O_RDWR)) < 0) {
   1246 		stack;
   1247 		return -errno;
   1248 	}
   1249 
   1250 	/* Need to open read+write for select() to work. */
   1251 	if ((fifos->client = open(fifos->client_path, O_RDWR)) < 0) {
   1252 		stack;
   1253 		close(fifos->server);
   1254 		return -errno;
   1255 	}
   1256 
   1257 	return 0;
   1258 }
   1259 
   1260 /*
   1261  * Read message from client making sure that data is available
   1262  * and a complete message is read.  Must not block indefinitely.
   1263  */
   1264 static int _client_read(struct dm_event_fifos *fifos,
   1265 		       struct dm_event_daemon_message *msg)
   1266 {
   1267 	struct timeval t;
   1268 	unsigned bytes = 0;
   1269 	int ret = 0;
   1270 	fd_set fds;
   1271 	int header = 1;
   1272 	size_t size = 2 * sizeof(uint32_t);	/* status + size */
   1273 	char *buf = alloca(size);
   1274 
   1275 	msg->data = NULL;
   1276 
   1277 	errno = 0;
   1278 	while (bytes < size && errno != EOF) {
   1279 		/* Watch client read FIFO for input. */
   1280 		FD_ZERO(&fds);
   1281 		FD_SET(fifos->client, &fds);
   1282 		t.tv_sec = 1;
   1283 		t.tv_usec = 0;
   1284 		ret = select(fifos->client + 1, &fds, NULL, NULL, &t);
   1285 
   1286 		if (!ret && !bytes)	/* nothing to read */
   1287 			return 0;
   1288 
   1289 		if (!ret)	/* trying to finish read */
   1290 			continue;
   1291 
   1292 		if (ret < 0)	/* error */
   1293 			return 0;
   1294 
   1295 		ret = read(fifos->client, buf + bytes, size - bytes);
   1296 		bytes += ret > 0 ? ret : 0;
   1297 		if (bytes == 2 * sizeof(uint32_t) && header) {
   1298 			msg->cmd = ntohl(*((uint32_t *) buf));
   1299 			msg->size = ntohl(*((uint32_t *) buf + 1));
   1300 			buf = msg->data = dm_malloc(msg->size);
   1301 			size = msg->size;
   1302 			bytes = 0;
   1303 			header = 0;
   1304 		}
   1305 	}
   1306 
   1307 	if (bytes != size) {
   1308 		if (msg->data)
   1309 			dm_free(msg->data);
   1310 		msg->data = NULL;
   1311 		msg->size = 0;
   1312 	}
   1313 
   1314 	return bytes == size;
   1315 }
   1316 
   1317 /*
   1318  * Write a message to the client making sure that it is ready to write.
   1319  */
   1320 static int _client_write(struct dm_event_fifos *fifos,
   1321 			struct dm_event_daemon_message *msg)
   1322 {
   1323 	unsigned bytes = 0;
   1324 	int ret = 0;
   1325 	fd_set fds;
   1326 
   1327 	size_t size = 2 * sizeof(uint32_t) + msg->size;
   1328 	char *buf = alloca(size);
   1329 
   1330 	*((uint32_t *)buf) = htonl(msg->cmd);
   1331 	*((uint32_t *)buf + 1) = htonl(msg->size);
   1332 	if (msg->data)
   1333 		memcpy(buf + 2 * sizeof(uint32_t), msg->data, msg->size);
   1334 
   1335 	errno = 0;
   1336 	while (bytes < size && errno != EIO) {
   1337 		do {
   1338 			/* Watch client write FIFO to be ready for output. */
   1339 			FD_ZERO(&fds);
   1340 			FD_SET(fifos->server, &fds);
   1341 		} while (select(fifos->server + 1, NULL, &fds, NULL, NULL) !=
   1342 			 1);
   1343 
   1344 		ret = write(fifos->server, buf + bytes, size - bytes);
   1345 		bytes += ret > 0 ? ret : 0;
   1346 	}
   1347 
   1348 	return bytes == size;
   1349 }
   1350 
   1351 /*
   1352  * Handle a client request.
   1353  *
   1354  * We put the request handling functions into
   1355  * a list because of the growing number.
   1356  */
   1357 static int _handle_request(struct dm_event_daemon_message *msg,
   1358 			  struct message_data *message_data)
   1359 {
   1360 	static struct {
   1361 		unsigned int cmd;
   1362 		int (*f)(struct message_data *);
   1363 	} requests[] = {
   1364 		{ DM_EVENT_CMD_REGISTER_FOR_EVENT, _register_for_event},
   1365 		{ DM_EVENT_CMD_UNREGISTER_FOR_EVENT, _unregister_for_event},
   1366 		{ DM_EVENT_CMD_GET_REGISTERED_DEVICE, _get_registered_device},
   1367 		{ DM_EVENT_CMD_GET_NEXT_REGISTERED_DEVICE,
   1368 			_get_next_registered_device},
   1369 		{ DM_EVENT_CMD_SET_TIMEOUT, _set_timeout},
   1370 		{ DM_EVENT_CMD_GET_TIMEOUT, _get_timeout},
   1371 		{ DM_EVENT_CMD_ACTIVE, _active},
   1372 	}, *req;
   1373 
   1374 	for (req = requests; req < requests + sizeof(requests); req++)
   1375 		if (req->cmd == msg->cmd)
   1376 			return req->f(message_data);
   1377 
   1378 	return -EINVAL;
   1379 }
   1380 
   1381 /* Process a request passed from the communication thread. */
   1382 static int _do_process_request(struct dm_event_daemon_message *msg)
   1383 {
   1384 	int ret;
   1385 	char *answer;
   1386 	static struct message_data message_data;
   1387 
   1388 	/* Parse the message. */
   1389 	memset(&message_data, 0, sizeof(message_data));
   1390 	message_data.msg = msg;
   1391 	if (msg->cmd == DM_EVENT_CMD_HELLO)  {
   1392 		ret = 0;
   1393 		answer = msg->data;
   1394 		if (answer) {
   1395 			msg->size = dm_asprintf(&(msg->data), "%s HELLO", answer);
   1396 			dm_free(answer);
   1397 		} else {
   1398 			msg->size = 0;
   1399 			msg->data = NULL;
   1400 		}
   1401 	} else if (msg->cmd != DM_EVENT_CMD_ACTIVE && !_parse_message(&message_data)) {
   1402 		stack;
   1403 		ret = -EINVAL;
   1404 	} else
   1405 		ret = _handle_request(msg, &message_data);
   1406 
   1407 	msg->cmd = ret;
   1408 	if (!msg->data)
   1409 		msg->size = dm_asprintf(&(msg->data), "%s %s", message_data.id, strerror(-ret));
   1410 
   1411 	_free_message(&message_data);
   1412 
   1413 	return ret;
   1414 }
   1415 
   1416 /* Only one caller at a time. */
   1417 static void _process_request(struct dm_event_fifos *fifos)
   1418 {
   1419 	struct dm_event_daemon_message msg;
   1420 
   1421 	memset(&msg, 0, sizeof(msg));
   1422 
   1423 	/*
   1424 	 * Read the request from the client (client_read, client_write
   1425 	 * give true on success and false on failure).
   1426 	 */
   1427 	if (!_client_read(fifos, &msg))
   1428 		return;
   1429 
   1430 	/* _do_process_request fills in msg (if memory allows for
   1431 	   data, otherwise just cmd and size = 0) */
   1432 	_do_process_request(&msg);
   1433 
   1434 	if (!_client_write(fifos, &msg))
   1435 		stack;
   1436 
   1437 	if (msg.data)
   1438 		dm_free(msg.data);
   1439 }
   1440 
   1441 static void _cleanup_unused_threads(void)
   1442 {
   1443 	int ret;
   1444 	struct dm_list *l;
   1445 	struct thread_status *thread;
   1446 
   1447 	_lock_mutex();
   1448 	while ((l = dm_list_first(&_thread_registry_unused))) {
   1449 		thread = dm_list_item(l, struct thread_status);
   1450 		if (thread->processing)
   1451 			break;	/* cleanup on the next round */
   1452 
   1453 		if (thread->status == DM_THREAD_RUNNING) {
   1454 			thread->status = DM_THREAD_SHUTDOWN;
   1455 			break;
   1456 		}
   1457 
   1458 		if (thread->status == DM_THREAD_SHUTDOWN) {
   1459 			if (!thread->events) {
   1460 				/* turn codes negative -- should we be returning this? */
   1461 				ret = _terminate_thread(thread);
   1462 
   1463 				if (ret == ESRCH) {
   1464 					thread->status = DM_THREAD_DONE;
   1465 				} else if (ret) {
   1466 					syslog(LOG_ERR,
   1467 					       "Unable to terminate thread: %s\n",
   1468 					       strerror(-ret));
   1469 					stack;
   1470 				}
   1471 				break;
   1472 			}
   1473 
   1474 			dm_list_del(l);
   1475 			syslog(LOG_ERR,
   1476 			       "thread can't be on unused list unless !thread->events");
   1477 			thread->status = DM_THREAD_RUNNING;
   1478 			LINK_THREAD(thread);
   1479 
   1480 			continue;
   1481 		}
   1482 
   1483 		if (thread->status == DM_THREAD_DONE) {
   1484 			dm_list_del(l);
   1485 			pthread_join(thread->thread, NULL);
   1486 			_lib_put(thread->dso_data);
   1487 			_free_thread_status(thread);
   1488 		}
   1489 	}
   1490 
   1491 	_unlock_mutex();
   1492 }
   1493 
   1494 static void _sig_alarm(int signum __attribute((unused)))
   1495 {
   1496 	pthread_testcancel();
   1497 }
   1498 
   1499 /* Init thread signal handling. */
   1500 static void _init_thread_signals(void)
   1501 {
   1502 	sigset_t my_sigset;
   1503 	struct sigaction act;
   1504 
   1505 	memset(&act, 0, sizeof(act));
   1506 	act.sa_handler = _sig_alarm;
   1507 	sigaction(SIGALRM, &act, NULL);
   1508 	sigfillset(&my_sigset);
   1509 
   1510 	/* These are used for exiting */
   1511 	sigdelset(&my_sigset, SIGTERM);
   1512 	sigdelset(&my_sigset, SIGINT);
   1513 	sigdelset(&my_sigset, SIGHUP);
   1514 	sigdelset(&my_sigset, SIGQUIT);
   1515 
   1516 	pthread_sigmask(SIG_BLOCK, &my_sigset, NULL);
   1517 }
   1518 
   1519 /*
   1520  * exit_handler
   1521  * @sig
   1522  *
   1523  * Set the global variable which the process should
   1524  * be watching to determine when to exit.
   1525  */
   1526 static void _exit_handler(int sig __attribute((unused)))
   1527 {
   1528 	/*
   1529 	 * We exit when '_exit_now' is set.
   1530 	 * That is, when a signal has been received.
   1531 	 *
   1532 	 * We can not simply set '_exit_now' unless all
   1533 	 * threads are done processing.
   1534 	 */
   1535 	if (!_thread_registries_empty) {
   1536 		syslog(LOG_ERR, "There are still devices being monitored.");
   1537 		syslog(LOG_ERR, "Refusing to exit.");
   1538 	} else
   1539 		_exit_now = 1;
   1540 
   1541 }
   1542 
   1543 static int _lock_pidfile(void)
   1544 {
   1545 	int lf;
   1546 	char pidfile[] = DMEVENTD_PIDFILE;
   1547 
   1548 	if ((lf = open(pidfile, O_CREAT | O_RDWR, 0644)) < 0)
   1549 		exit(EXIT_OPEN_PID_FAILURE);
   1550 
   1551 	if (flock(lf, LOCK_EX | LOCK_NB) < 0)
   1552 		exit(EXIT_LOCKFILE_INUSE);
   1553 
   1554 	if (!_storepid(lf))
   1555 		exit(EXIT_FAILURE);
   1556 
   1557 	return 0;
   1558 }
   1559 
   1560 #ifdef linux
   1561 /*
   1562  * Protection against OOM killer if kernel supports it
   1563  */
   1564 static int _set_oom_adj(int val)
   1565 {
   1566 	FILE *fp;
   1567 
   1568 	struct stat st;
   1569 
   1570 	if (stat(OOM_ADJ_FILE, &st) == -1) {
   1571 		if (errno == ENOENT)
   1572 			DEBUGLOG(OOM_ADJ_FILE " not found");
   1573 		else
   1574 			perror(OOM_ADJ_FILE ": stat failed");
   1575 		return 1;
   1576 	}
   1577 
   1578 	if (!(fp = fopen(OOM_ADJ_FILE, "w"))) {
   1579 		perror(OOM_ADJ_FILE ": fopen failed");
   1580 		return 0;
   1581 	}
   1582 
   1583 	fprintf(fp, "%i", val);
   1584 	if (dm_fclose(fp))
   1585 		perror(OOM_ADJ_FILE ": fclose failed");
   1586 
   1587 	return 1;
   1588 }
   1589 #endif
   1590 
   1591 static void _daemonize(void)
   1592 {
   1593 	int child_status;
   1594 	int fd;
   1595 	pid_t pid;
   1596 	struct rlimit rlim;
   1597 	struct timeval tval;
   1598 	sigset_t my_sigset;
   1599 
   1600 	sigemptyset(&my_sigset);
   1601 	if (sigprocmask(SIG_SETMASK, &my_sigset, NULL) < 0) {
   1602 		fprintf(stderr, "Unable to restore signals.\n");
   1603 		exit(EXIT_FAILURE);
   1604 	}
   1605 	signal(SIGTERM, &_exit_handler);
   1606 
   1607 	switch (pid = fork()) {
   1608 	case -1:
   1609 		perror("fork failed:");
   1610 		exit(EXIT_FAILURE);
   1611 
   1612 	case 0:		/* Child */
   1613 		break;
   1614 
   1615 	default:
   1616 		/* Wait for response from child */
   1617 		while (!waitpid(pid, &child_status, WNOHANG) && !_exit_now) {
   1618 			tval.tv_sec = 0;
   1619 			tval.tv_usec = 250000;	/* .25 sec */
   1620 			select(0, NULL, NULL, NULL, &tval);
   1621 		}
   1622 
   1623 		if (_exit_now)	/* Child has signaled it is ok - we can exit now */
   1624 			exit(EXIT_SUCCESS);
   1625 
   1626 		/* Problem with child.  Determine what it is by exit code */
   1627 		switch (WEXITSTATUS(child_status)) {
   1628 		case EXIT_LOCKFILE_INUSE:
   1629 			fprintf(stderr, "Another dmeventd daemon is already running\n");
   1630 			break;
   1631 		case EXIT_DESC_CLOSE_FAILURE:
   1632 		case EXIT_DESC_OPEN_FAILURE:
   1633 		case EXIT_OPEN_PID_FAILURE:
   1634 		case EXIT_FIFO_FAILURE:
   1635 		case EXIT_CHDIR_FAILURE:
   1636 		default:
   1637 			fprintf(stderr, "Child exited with code %d\n", WEXITSTATUS(child_status));
   1638 			break;
   1639 		}
   1640 
   1641 		exit(WEXITSTATUS(child_status));
   1642 	}
   1643 
   1644 	if (chdir("/"))
   1645 		exit(EXIT_CHDIR_FAILURE);
   1646 
   1647 	if (getrlimit(RLIMIT_NOFILE, &rlim) < 0)
   1648 		fd = 256;	/* just have to guess */
   1649 	else
   1650 		fd = rlim.rlim_cur;
   1651 
   1652 	for (--fd; fd >= 0; fd--)
   1653 		close(fd);
   1654 
   1655 	if ((open("/dev/null", O_RDONLY) < 0) ||
   1656 	    (open("/dev/null", O_WRONLY) < 0) ||
   1657 	    (open("/dev/null", O_WRONLY) < 0))
   1658 		exit(EXIT_DESC_OPEN_FAILURE);
   1659 
   1660 	setsid();
   1661 }
   1662 
   1663 static void usage(char *prog, FILE *file)
   1664 {
   1665 	fprintf(file, "Usage:\n");
   1666 	fprintf(file, "%s [Vhd]\n", prog);
   1667 	fprintf(file, "\n");
   1668 	fprintf(file, "   -V       Show version of dmeventd\n");
   1669 	fprintf(file, "   -h       Show this help information\n");
   1670 	fprintf(file, "   -d       Don't fork, run in the foreground\n");
   1671 	fprintf(file, "\n");
   1672 }
   1673 
   1674 int main(int argc, char *argv[])
   1675 {
   1676 	int ret;
   1677 	signed char opt;
   1678 	struct dm_event_fifos fifos;
   1679 	//struct sys_log logdata = {DAEMON_NAME, LOG_DAEMON};
   1680 
   1681 	opterr = 0;
   1682 	optind = 0;
   1683 
   1684 	while ((opt = getopt(argc, argv, "?hVd")) != EOF) {
   1685 		switch (opt) {
   1686 		case 'h':
   1687 			usage(argv[0], stdout);
   1688 			exit(0);
   1689 		case '?':
   1690 			usage(argv[0], stderr);
   1691 			exit(0);
   1692 		case 'd':
   1693 			_debug++;
   1694 			break;
   1695 		case 'V':
   1696 			printf("dmeventd version: %s\n", DM_LIB_VERSION);
   1697 			exit(1);
   1698 			break;
   1699 		}
   1700 	}
   1701 
   1702 	if (!_debug)
   1703 		_daemonize();
   1704 
   1705 	openlog("dmeventd", LOG_PID, LOG_DAEMON);
   1706 
   1707 	_lock_pidfile();		/* exits if failure */
   1708 
   1709 	/* Set the rest of the signals to cause '_exit_now' to be set */
   1710 	signal(SIGINT, &_exit_handler);
   1711 	signal(SIGHUP, &_exit_handler);
   1712 	signal(SIGQUIT, &_exit_handler);
   1713 
   1714 #ifdef linux
   1715 	if (!_set_oom_adj(OOM_DISABLE) && !_set_oom_adj(OOM_ADJUST_MIN))
   1716 		syslog(LOG_ERR, "Failed to set oom_adj to protect against OOM killer");
   1717 #endif
   1718 
   1719 	_init_thread_signals();
   1720 
   1721 	//multilog_clear_logging();
   1722 	//multilog_add_type(std_syslog, &logdata);
   1723 	//multilog_init_verbose(std_syslog, _LOG_DEBUG);
   1724 	//multilog_async(1);
   1725 
   1726 	_init_fifos(&fifos);
   1727 
   1728 	pthread_mutex_init(&_global_mutex, NULL);
   1729 
   1730 #ifdef MCL_CURRENT
   1731 	if (mlockall(MCL_CURRENT | MCL_FUTURE) == -1)
   1732 		exit(EXIT_FAILURE);
   1733 #endif
   1734 
   1735 	if ((ret = _open_fifos(&fifos)))
   1736 		exit(EXIT_FIFO_FAILURE);
   1737 
   1738 	/* Signal parent, letting them know we are ready to go. */
   1739 	kill(getppid(), SIGTERM);
   1740 	syslog(LOG_NOTICE, "dmeventd ready for processing.");
   1741 
   1742 	while (!_exit_now) {
   1743 		_process_request(&fifos);
   1744 		_cleanup_unused_threads();
   1745 		if (!dm_list_empty(&_thread_registry)
   1746 		    || !dm_list_empty(&_thread_registry_unused))
   1747 			_thread_registries_empty = 0;
   1748 		else
   1749 			_thread_registries_empty = 1;
   1750 	}
   1751 
   1752 	_exit_dm_lib();
   1753 
   1754 #ifdef MCL_CURRENT
   1755 	munlockall();
   1756 #endif
   1757 	pthread_mutex_destroy(&_global_mutex);
   1758 
   1759 	syslog(LOG_NOTICE, "dmeventd shutting down.");
   1760 	closelog();
   1761 
   1762 	exit(EXIT_SUCCESS);
   1763 }
   1764