summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlasdair Kergon <agk@redhat.com>2005-12-02 15:39:16 +0000
committerAlasdair Kergon <agk@redhat.com>2005-12-02 15:39:16 +0000
commitab931b177dd842b9568510e5d3c0e59093b678c9 (patch)
tree182d26cd8bab94741abf4112fcedb9b34be1eb8a
parent9aa34655137da3387beca561ba7edba0c3c6ba3d (diff)
downloadlvm2-1_02_02.tar.gz
dmeventd updatesv1_02_02old-v1_02_02
-rw-r--r--daemons/dmeventd/.exported_symbols8
-rw-r--r--daemons/dmeventd/Makefile.in51
-rw-r--r--daemons/dmeventd/dmevent.c240
-rw-r--r--daemons/dmeventd/dmeventd.c825
-rw-r--r--daemons/dmeventd/dmeventd.h12
-rw-r--r--daemons/dmeventd/libdevmapper-event.c465
-rw-r--r--daemons/dmeventd/libdevmapper-event.h99
-rw-r--r--daemons/dmeventd/mktestdevices12
-rw-r--r--daemons/dmeventd/noop.c39
-rw-r--r--libdm/Makefile.in8
-rw-r--r--libdm/libdm-event.h95
11 files changed, 1123 insertions, 731 deletions
diff --git a/daemons/dmeventd/.exported_symbols b/daemons/dmeventd/.exported_symbols
index 4854e9828..7847409d2 100644
--- a/daemons/dmeventd/.exported_symbols
+++ b/daemons/dmeventd/.exported_symbols
@@ -1,3 +1,5 @@
-process_event
-register_device
-unregister_device \ No newline at end of file
+dm_register_for_event
+dm_unregister_for_event
+dm_get_registered_device
+dm_set_event_timeout
+dm_get_event_timeout
diff --git a/daemons/dmeventd/Makefile.in b/daemons/dmeventd/Makefile.in
index 394f61e52..369f5e2b3 100644
--- a/daemons/dmeventd/Makefile.in
+++ b/daemons/dmeventd/Makefile.in
@@ -1,51 +1,56 @@
#
-# Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
-# Copyright (C) 2004 Red Hat, Inc. All rights reserved.
+# Copyright (C) 2005 Red Hat, Inc. All rights reserved.
#
# This file is part of the device-mapper userspace tools.
#
# This copyrighted material is made available to anyone wishing to use,
# modify, copy, or redistribute it subject to the terms and conditions
-# of the GNU General Public License v.2.
+# of the GNU Lesser General Public License v.2.1.
#
-# You should have received a copy of the GNU General Public License
+# You should have received a copy of the GNU Lesser General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
+interface = @interface@
-TARGETS = dmevent dmeventd
-INSTALL_TYPE = install_dynamic
+SOURCES = libdevmapper-event.c \
+ dmeventd.c
-SOURCES = noop.c
-CLEAN_TARGETS = dmevent.o dmeventd.o
+LIB_STATIC = libdevmapper-event.a
ifeq ("@LIB_SUFFIX@","dylib")
- LIB_SHARED = libdmeventdnoop.dylib
+ LIB_SHARED = libdevmapper-event.dylib
else
- LIB_SHARED = libdmeventdnoop.so
+ LIB_SHARED = libdevmapper-event.so
endif
-
-LDFLAGS += -ldl -ldevmapper -lmultilog
+
+CLDFLAGS += -ldl -ldevmapper -lpthread
include ../make.tmpl
-libdmeventdnoop.so: noop.o
+.PHONY: install_dynamic install_static
-dmevent: dmevent.o $(interfacedir)/libdevmapper.$(LIB_SUFFIX) $(top_srcdir)/lib/event/libdmevent.$(LIB_SUFFIX)
- $(CC) -o $@ dmevent.o $(LDFLAGS) \
- -L$(interfacedir) -L$(DESTDIR)/lib -L$(top_srcdir)/lib/event -L$(top_srcdir)/multilog $(LIBS)
+INSTALL_TYPE = install_dynamic
-dmeventd: dmeventd.o $(interfacedir)/libdevmapper.$(LIB_SUFFIX) $(top_srcdir)/lib/event/libdmevent.$(LIB_SUFFIX)
- $(CC) -o $@ dmeventd.o $(LDFLAGS) \
- -L$(interfacedir) -L$(DESTDIR)/lib -L$(top_srcdir)/lib/event -L$(top_srcdir)/multilog -lpthread -ldmevent $(LIBS)
+ifeq ("@STATIC_LINK@", "yes")
+ INSTALL_TYPE += install_static
+endif
install: $(INSTALL_TYPE)
-.PHONY: install_dynamic
-
-install_dynamic: dmeventd
- $(INSTALL) -D $(OWNER) $(GROUP) -m 555 $(STRIP) dmeventd $(sbindir)/dmeventd
+install_dynamic: libdevmapper-event.$(LIB_SUFFIX)
+ $(INSTALL) -D $(OWNER) $(GROUP) -m 555 $(STRIP) $< \
+ $(libdir)/libdevmapper-event.$(LIB_SUFFIX).$(LIB_VERSION)
+ $(LN_S) -f libdevmapper-event.$(LIB_SUFFIX).$(LIB_VERSION) \
+ $(libdir)/libdevmapper-event.$(LIB_SUFFIX)
+ $(INSTALL) -D $(OWNER) $(GROUP) -m 444 libdevmapper-event.h \
+ $(includedir)/libdevmapper-event.h
+
+install_static: libdevmapper-event.a
+ $(INSTALL) -D $(OWNER) $(GROUP) -m 555 $(STRIP) $< \
+ $(libdir)/libdevmapper-event.a.$(LIB_VERSION)
+ $(LN_S) -f libdevmapper-event.a.$(LIB_VERSION) $(libdir)/libdevmapper-event.a
diff --git a/daemons/dmeventd/dmevent.c b/daemons/dmeventd/dmevent.c
deleted file mode 100644
index 6e9eb4601..000000000
--- a/daemons/dmeventd/dmevent.c
+++ /dev/null
@@ -1,240 +0,0 @@
-/*
- * Copyright (C) 2005 Red Hat, Inc. All rights reserved.
- *
- * This file is part of the device-mapper userspace tools.
- *
- * This copyrighted material is made available to anyone wishing to use,
- * modify, copy, or redistribute it subject to the terms and conditions
- * of the GNU Lesser General Public License v.2.1.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "libdevmapper.h"
-#include "libdm-event.h"
-#include "libmultilog.h"
-
-#include <errno.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/file.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <dlfcn.h>
-
-static enum event_type events = ALL_ERRORS; /* All until we can distinguish. */
-static char default_dso_name[] = "noop"; /* default DSO is noop */
-static int default_reg = 1; /* default action is register */
-static uint32_t timeout;
-
-struct event_ops {
-int (*dm_register_for_event)(char *dso_name, char *device,
- enum event_type event_types);
-int (*dm_unregister_for_event)(char *dso_name, char *device,
- enum event_type event_types);
-int (*dm_get_registered_device)(char **dso_name, char **device,
- enum event_type *event_types, int next);
-int (*dm_set_event_timeout)(char *device, uint32_t time);
-int (*dm_get_event_timeout)(char *device, uint32_t *time);
-};
-
-/* Display help. */
-static void print_usage(char *name)
-{
- char *cmd = strrchr(name, '/');
-
- cmd = cmd ? cmd + 1 : name;
- printf("Usage::\n"
- "%s [options] <device>\n"
- "\n"
- "Options:\n"
- " -d <dso> Specify the DSO to use.\n"
- " -h Print this usage.\n"
- " -l List registered devices.\n"
- " -r Register for event (default).\n"
- " -t <timeout> (un)register for timeout event.\n"
- " -u Unregister for event.\n"
- "\n", cmd);
-}
-
-/* Parse command line arguments. */
-static int parse_argv(int argc, char **argv, char **dso_name_arg,
- char **device_arg, int *reg, int *list)
-{
- int c;
- const char *options = "d:hlrt:u";
-
- while ((c = getopt(argc, argv, options)) != -1) {
- switch (c) {
- case 'd':
- *dso_name_arg = optarg;
- break;
- case 'h':
- print_usage(argv[0]);
- exit(EXIT_SUCCESS);
- case 'l':
- *list = 1;
- break;
- case 'r':
- *reg = 1;
- break;
- case 't':
- events = TIMEOUT;
- if (sscanf(optarg, "%"SCNu32, &timeout) != 1){
- fprintf(stderr, "invalid timeout '%s'\n",
- optarg);
- timeout = 0;
- }
- break;
- case 'u':
- *reg = 0;
- break;
- default:
- fprintf(stderr, "Unknown option '%c'.\n"
- "Try '-h' for help.\n", c);
-
- return 0;
- }
- }
-
- if (optind >= argc) {
- if (!*list) {
- fprintf(stderr, "You need to specify a device.\n");
- return 0;
- }
- } else
- *device_arg = argv[optind];
-
- return 1;
-}
-
-
-static int lookup_symbol(void *dl, void **symbol, const char *name)
-{
- if ((*symbol = dlsym(dl, name)))
- return 1;
-
- fprintf(stderr, "error looking up %s symbol: %s\n", name, dlerror());
-
- return 0;
-}
-
-static int lookup_symbols(void *dl, struct event_ops *e)
-{
- return lookup_symbol(dl, (void *) &e->dm_register_for_event,
- "dm_register_for_event") &&
- lookup_symbol(dl, (void *) &e->dm_unregister_for_event,
- "dm_unregister_for_event") &&
- lookup_symbol(dl, (void *) &e->dm_get_registered_device,
- "dm_get_registered_device") &&
- lookup_symbol(dl, (void *) &e->dm_set_event_timeout,
- "dm_set_event_timeout") &&
- lookup_symbol(dl, (void *) &e->dm_get_event_timeout,
- "dm_get_event_timeout");
-}
-
-int main(int argc, char **argv)
-{
- void *dl;
- struct event_ops e;
- int list = 0, next = 0, ret, reg = default_reg;
- char *device, *device_arg = NULL, *dso_name, *dso_name_arg = NULL;
-
- if (!parse_argv(argc, argv, &dso_name_arg, &device_arg, &reg, &list))
- exit(EXIT_FAILURE);
-
- if (device_arg) {
- if (!(device = strdup(device_arg)))
- exit(EXIT_FAILURE);
- } else
- device = NULL;
-
- if (dso_name_arg) {
- if (!(dso_name = strdup(dso_name_arg)))
- exit(EXIT_FAILURE);
- } else {
- if (!(dso_name = strdup(default_dso_name)))
- exit(EXIT_FAILURE);
- }
-
- /* FIXME: use -v/-q options to set this */
- multilog_add_type(standard, NULL);
- multilog_init_verbose(standard, _LOG_DEBUG);
-
- if (!(dl = dlopen("libdmevent.so", RTLD_NOW))){
- fprintf(stderr, "Cannot dlopen libdmevent.so: %s\n", dlerror());
- goto out;
- }
- if (!(lookup_symbols(dl, &e)))
- goto out;
- if (list) {
- while (1) {
- if ((ret= e.dm_get_registered_device(&dso_name,
- &device,
- &events, next)))
- break;
- printf("%s %s 0x%x", dso_name, device, events);
- if (events & TIMEOUT){
- if ((ret = e.dm_get_event_timeout(device,
- &timeout))) {
- ret = EXIT_FAILURE;
- goto out;
- }
- printf(" %"PRIu32"\n", timeout);
- } else
- printf("\n");
- if (device_arg)
- break;
-
- next = 1;
- }
-
- ret = (ret && device_arg) ? EXIT_FAILURE : EXIT_SUCCESS;
- goto out;
- }
-
- if ((ret = reg ? e.dm_register_for_event(dso_name, device, events) :
- e.dm_unregister_for_event(dso_name, device, events))) {
- fprintf(stderr, "Failed to %sregister %s: %s\n",
- reg ? "": "un", device, strerror(-ret));
- ret = EXIT_FAILURE;
- } else {
- if (reg && (events & TIMEOUT) &&
- ((ret = e.dm_set_event_timeout(device, timeout)))){
- fprintf(stderr, "Failed to set timeout for %s: %s\n",
- device, strerror(-ret));
- ret = EXIT_FAILURE;
- } else {
- printf("%s %sregistered successfully.\n",
- device, reg ? "" : "un");
- ret = EXIT_SUCCESS;
- }
- }
-
- out:
- multilog_del_type(standard);
-
- if (device)
- free(device);
- if (dso_name)
- free(dso_name);
-
- exit(ret);
-}
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/daemons/dmeventd/dmeventd.c b/daemons/dmeventd/dmeventd.c
index 572bce074..8ec2b31fa 100644
--- a/daemons/dmeventd/dmeventd.c
+++ b/daemons/dmeventd/dmeventd.c
@@ -14,20 +14,19 @@
/*
* dmeventd - dm event daemon to monitor active mapped devices
- *
- * Author - Heinz Mauelshagen, Red Hat GmbH.
*/
#include "libdevmapper.h"
-#include "libdm-event.h"
+#include "libdevmapper-event.h"
#include "list.h"
+#include "dmeventd.h"
+//#include "libmultilog.h"
+#include "log.h"
#include <dlfcn.h>
#include <errno.h>
#include <fcntl.h>
-#include <libdevmapper.h>
#include <libgen.h>
-#include <malloc.h>
#include <pthread.h>
#include <signal.h>
#include <stdio.h>
@@ -40,16 +39,19 @@
#include <sys/stat.h>
#include <sys/wait.h>
#include <unistd.h>
+#include <stdarg.h>
-#include "libmultilog.h"
-
+#ifdef linux
+#include <malloc.h>
+#endif
+/* FIXME Use dm library */
#define dbg_malloc(x...) malloc(x)
#define dbg_strdup(x...) strdup(x)
#define dbg_free(x...) free(x)
/* List (un)link macros. */
-#define LINK(x, head) list_add(&(x)->list, head)
+#define LINK(x, head) list_add(head, &(x)->list)
#define LINK_DSO(dso) LINK(dso, &dso_registry)
#define LINK_THREAD(thread) LINK(thread, &thread_registry)
@@ -57,7 +59,7 @@
#define UNLINK_DSO(x) UNLINK(x)
#define UNLINK_THREAD(x) UNLINK(x)
-#define DAEMON_NAME "dmeventd"
+#define DAEMON_NAME "dmeventd"
/* Global mutex for list accesses. */
static pthread_mutex_t mutex;
@@ -78,7 +80,7 @@ struct dso_data {
* such as changing the mapping in case a mirror fails, update
* the application metadata etc.
*/
- void (*process_event)(char *device, enum event_type event);
+ void (*process_event)(const char *device, enum dm_event_type event);
/*
* Device registration.
@@ -88,7 +90,7 @@ struct dso_data {
* the process_event() function is sane (eg, read metadata
* and activate a mapping).
*/
- int (*register_device)(char *device);
+ int (*register_device)(const char *device);
/*
* Device unregistration.
@@ -97,7 +99,7 @@ struct dso_data {
* for events, the DSO can recognize this and carry out appropriate
* steps (eg, deactivate mapping, metadata update).
*/
- int (*unregister_device)(char *device);
+ int (*unregister_device)(const char *device);
};
static LIST_INIT(dso_registry);
@@ -107,9 +109,13 @@ struct message_data {
char *device_path; /* Mapped device path. */
union {
char *str; /* Events string as fetched from message. */
- enum event_type field; /* Events bitfield. */
+ enum dm_event_type field; /* Events bitfield. */
} events;
- struct daemon_message *msg; /* Pointer to message buffer. */
+ union {
+ char *str;
+ uint32_t secs;
+ } timeout;
+ struct dm_event_daemon_message *msg; /* Pointer to message buffer. */
};
/*
@@ -121,17 +127,26 @@ struct message_data {
struct thread_status {
struct list list;
- pthread_t thread;
+ pthread_t thread;
struct dso_data *dso_data;/* DSO this thread accesses. */
char *device_path; /* Mapped device path. */
- enum event_type events; /* bitfield for event filter. */
- enum event_type current_events;/* bitfield for occured events. */
- enum event_type processed_events;/* bitfield for processed events. */
+ int event_nr; /* event number */
+ enum dm_event_type events; /* bitfield for event filter. */
+ enum dm_event_type current_events;/* bitfield for occured events. */
+ enum dm_event_type processed_events;/* bitfield for processed events. */
+ time_t next_time;
+ uint32_t timeout;
+ struct list timeout_list;
};
static LIST_INIT(thread_registry);
+static int timeout_running;
+static LIST_INIT(timeout_registry);
+static pthread_mutex_t timeout_mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_cond_t timeout_cond = PTHREAD_COND_INITIALIZER;
+
/* Allocate/free the status structure for a monitoring thread. */
static struct thread_status *alloc_thread_status(struct message_data *data,
struct dso_data *dso_data)
@@ -139,13 +154,15 @@ static struct thread_status *alloc_thread_status(struct message_data *data,
struct thread_status *ret = (typeof(ret)) dbg_malloc(sizeof(*ret));
if (ret) {
- memset(ret, 0, sizeof(*ret));
- if ((ret->device_path = dbg_strdup(data->device_path))) {
- ret->dso_data = dso_data;
- ret->events = data->events.field;
- } else {
+ if (!memset(ret, 0, sizeof(*ret)) ||
+ !(ret->device_path = dbg_strdup(data->device_path))) {
dbg_free(ret);
ret = NULL;
+ } else {
+ ret->dso_data = dso_data;
+ ret->events = data->events.field;
+ ret->timeout = data->timeout.secs;
+ list_init(&ret->timeout_list);
}
}
@@ -164,8 +181,8 @@ static struct dso_data *alloc_dso_data(struct message_data *data)
struct dso_data *ret = (typeof(ret)) dbg_malloc(sizeof(*ret));
if (ret) {
- memset(ret, 0, sizeof(*ret));
- if (!(ret->dso_name = dbg_strdup(data->dso_name))) {
+ if (!memset(ret, 0, sizeof(*ret)) ||
+ !(ret->dso_name = dbg_strdup(data->dso_name))) {
dbg_free(ret);
ret = NULL;
}
@@ -180,18 +197,40 @@ static void free_dso_data(struct dso_data *data)
dbg_free(data);
}
-/* Fetch a string off src and duplicate it into *dest. */
+/* FIXME: Factor out. */
+static char *dm_basename(char *str)
+{
+ char *p = strrchr(str, '/');
+
+ return p ? p + 1 : str;
+}
+
+/*
+ * Fetch a string off src and duplicate it into *ptr.
+ * Pay attention to 0 lenght strings.
+ */
/* FIXME: move to separate module to share with the client lib. */
static const char delimiter = ' ';
-static char *fetch_string(char **src)
+static int fetch_string(char **ptr, char **src)
{
- char *p, *ret;
+ int ret = 0;
+ char *p;
+ size_t len;
if ((p = strchr(*src, delimiter)))
*p = 0;
- if ((ret = strdup(*src)))
- *src += strlen(ret) + 1;
+ if ((*ptr = dbg_strdup(*src))) {
+ if ((len = strlen(*ptr)))
+ *src += len;
+ else {
+ dbg_free(*ptr);
+ *ptr = NULL;
+ }
+
+ (*src)++;
+ ret = 1;
+ }
if (p)
*p = delimiter;
@@ -214,19 +253,16 @@ static int parse_message(struct message_data *message_data)
{
char *p = message_data->msg->msg;
-log_print("%s: here\n", __func__);
-fflush(stdout);
-
/*
* Retrieve application identifier, mapped device
* path and events # string from message.
*/
- if ((message_data->dso_name = fetch_string(&p)) &&
- (message_data->device_path = fetch_string(&p)) &&
- (message_data->events.str = fetch_string(&p))) {
-log_print("%s: %s %s %s\n", __func__, message_data->dso_name, message_data->device_path, message_data->events.str);
+ if (fetch_string(&message_data->dso_name, &p) &&
+ fetch_string(&message_data->device_path, &p) &&
+ fetch_string(&message_data->events.str, &p) &&
+ fetch_string(&message_data->timeout.str, &p)) {
if (message_data->events.str) {
- enum event_type i = atoi(message_data->events.str);
+ enum dm_event_type i = atoi(message_data->events.str);
/*
* Free string representaion of events.
@@ -235,12 +271,16 @@ log_print("%s: %s %s %s\n", __func__, message_data->dso_name, message_data->devi
dbg_free(message_data->events.str);
message_data->events.field = i;
}
+ if (message_data->timeout.str) {
+ uint32_t secs = atoi(message_data->timeout.str);
+ dbg_free(message_data->timeout.str);
+ message_data->timeout.secs = secs ? secs :
+ DM_EVENT_DEFAULT_TIMEOUT;
+ }
return 1;
}
- free_message(message_data);
-
return 0;
};
@@ -275,50 +315,6 @@ static int storepid(int lf)
return 1;
}
-/*
- * create+flock file.
- *
- * Used to synchronize daemon startups.
- */
-static int lf = -1;
-static char pidfile[] = "/var/run/dmeventd.pid";
-
-/* Store pid in pidfile. */
-static int lock(void)
-{
- /* Already locked. */
- if (lf > -1)
- return 1;
-
- if ((lf = open(pidfile, O_CREAT | O_RDWR, 0644)) == -1) {
- log_err("opening pid file\n");
- return 0;
- }
-
- if (flock(lf, LOCK_EX | LOCK_NB) == -1) {
- log_err("lock pid file\n");
- close(lf);
- lf = -1;
- return 0;
- }
-
- return 1;
-}
-
-static void unlock(void)
-{
- /* Not locked! */
- if (lf == -1)
- return;
-
- if (flock(lf, LOCK_UN))
- log_err("flock unlock %s\n", pidfile);
-
- if (close(lf))
- log_err("close %s\n", pidfile);
-
- lf = -1;
-}
/* Check, if a device exists. */
static int device_exists(char *device)
@@ -354,46 +350,199 @@ static void exit_dm_lib(void)
}
/* Derive error case from target parameter string. */
+/* FIXME Remove? */
+static int error_detected(struct thread_status *thread, char *params) __attribute__ ((unused));
static int error_detected(struct thread_status *thread, char *params)
{
size_t len;
-
+/*
+ Leave it to the DSO to decide how to interpret the status info
if ((len = strlen(params)) &&
params[len - 1] == 'F') {
- thread->current_events |= DEVICE_ERROR;
+*/
+ if (params && (len = strlen(params))) {
+ thread->current_events |= DM_EVENT_DEVICE_ERROR;
return 1;
}
return 0;
}
+static void exit_timeout(void *unused)
+{
+ timeout_running = 0;
+ pthread_mutex_unlock(&timeout_mutex);
+}
+
+/* Wake up monitor threads every so often. */
+static void *timeout_thread(void *unused)
+{
+ struct timespec timeout;
+ time_t curr_time;
+
+ timeout.tv_nsec = 0;
+ pthread_cleanup_push(exit_timeout, NULL);
+ pthread_mutex_lock(&timeout_mutex);
+
+ while (!list_empty(&timeout_registry)) {
+ struct thread_status *thread;
+
+ timeout.tv_sec = (time_t)-1;
+ curr_time = time(NULL);
+
+ list_iterate_items_gen(thread, &timeout_registry,
+ timeout_list) {
+ if (thread->next_time < curr_time) {
+ thread->next_time = curr_time + thread->timeout;
+ pthread_kill(thread->thread, SIGALRM);
+ }
+
+ if (thread->next_time < timeout.tv_sec)
+ timeout.tv_sec = thread->next_time;
+ }
+
+ pthread_cond_timedwait(&timeout_cond, &timeout_mutex, &timeout);
+ }
+
+ pthread_cleanup_pop(1);
+
+ return NULL;
+}
+
+static int register_for_timeout(struct thread_status *thread)
+{
+ int ret = 0;
+
+ pthread_mutex_lock(&timeout_mutex);
+
+ thread->next_time = time(NULL) + thread->timeout;
+
+ if (list_empty(&thread->timeout_list)) {
+ list_add(&timeout_registry, &thread->timeout_list);
+ if (timeout_running)
+ pthread_cond_signal(&timeout_cond);
+ }
+
+ if (!timeout_running) {
+ pthread_t timeout_id;
+
+ if (!(ret = -pthread_create(&timeout_id, NULL,
+ timeout_thread, NULL)))
+ timeout_running = 1;
+ }
+
+ pthread_mutex_unlock(&timeout_mutex);
+
+ return ret;
+}
+
+static void unregister_for_timeout(struct thread_status *thread)
+{
+ pthread_mutex_lock(&timeout_mutex);
+ if (!list_empty(&thread->timeout_list)) {
+ list_del(&thread->timeout_list);
+ list_init(&thread->timeout_list);
+ }
+ pthread_mutex_unlock(&timeout_mutex);
+}
+
+static void no_intr_log(int level, const char *file, int line,
+ const char *f, ...)
+{
+ va_list ap;
+
+ if (errno == EINTR)
+ return;
+ if (level > _LOG_WARN)
+ return;
+
+ va_start(ap, f);
+
+ if (level < _LOG_WARN)
+ vfprintf(stderr, f, ap);
+ else
+ vprintf(f, ap);
+
+ va_end(ap);
+
+ if (level < _LOG_WARN)
+ fprintf(stderr, "\n");
+ else
+ fprintf(stdout, "\n");
+}
+
+static sigset_t unblock_sigalrm(void)
+{
+ sigset_t set, old;
+
+ sigemptyset(&set);
+ sigaddset(&set, SIGALRM);
+ pthread_sigmask(SIG_UNBLOCK, &set, &old);
+ return old;
+}
+
/* Wait on a device until an event occurs. */
static int event_wait(struct thread_status *thread)
{
+ sigset_t set;
int ret = 0;
+/*
void *next = NULL;
char *params, *target_type;
uint64_t start, length;
+*/
struct dm_task *dmt;
+ struct dm_info info;
if (!(dmt = dm_task_create(DM_DEVICE_WAITEVENT)))
return 0;
- if ((ret = dm_task_set_name(dmt, basename(thread->device_path))) &&
- (ret = dm_task_set_event_nr(dmt, 0)) &&
- (ret = dm_task_run(dmt))) {
+ if (!(ret = dm_task_set_name(dmt, dm_basename(thread->device_path))) ||
+ !(ret = dm_task_set_event_nr(dmt, thread->event_nr)))
+ goto out;
+
+ /*
+ * This is so that you can break out of waiting on an event,
+ * either for a timeout event, or to cancel the thread.
+ */
+ set = unblock_sigalrm();
+ dm_log_init(no_intr_log);
+ errno = 0;
+ if ((ret = dm_task_run(dmt))) {
+/*
do {
- /* Retrieve next target. */
params = NULL;
next = dm_get_next_target(dmt, next, &start, &length,
&target_type, &params);
-log_print("%s: %s\n", __func__, params);
+ log_error("%s: %s\n", __func__, params);
if ((ret = error_detected(thread, params)))
break;
} while(next);
+*/
+ thread->current_events |= DM_EVENT_DEVICE_ERROR;
+ ret = 1;
+
+ /*
+ * FIXME: I am setting processed_events to zero here
+ * because it is causing problems. for example, the
+ * mirror target emits a signal for INSYNC, then
+ * subsequent events (device failures) are not handled
+ */
+ thread->processed_events = 0;
+
+ if ((ret = dm_task_get_info(dmt, &info)))
+ thread->event_nr = info.event_nr;
+ } else if (thread->events & DM_EVENT_TIMEOUT && errno == EINTR) {
+ thread->current_events |= DM_EVENT_TIMEOUT;
+ ret = 1;
+ thread->processed_events = 0;
}
+ pthread_sigmask(SIG_SETMASK, &set, NULL);
+ dm_log_init(NULL);
+
+ out:
dm_task_destroy(dmt);
return ret;
@@ -411,7 +560,7 @@ static int do_unregister_device(struct thread_status *thread)
return thread->dso_data->unregister_device(thread->device_path);
}
-/* Process an event the DSO. */
+/* Process an event in the DSO. */
static void do_process_event(struct thread_status *thread)
{
thread->dso_data->process_event(thread->device_path,
@@ -424,7 +573,7 @@ static void monitor_unregister(void *arg)
struct thread_status *thread = arg;
if (!do_unregister_device(thread))
- log_err("%s: %s unregister failed\n", __func__,
+ log_error("%s: %s unregister failed\n", __func__,
thread->device_path);
}
@@ -436,7 +585,7 @@ static void *monitor_thread(void *arg)
pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);
pthread_cleanup_push(monitor_unregister, thread);
- /* Wait for comm_thread() to finish its task. */
+ /* Wait for do_process_reques() to finish its task. */
lock_mutex();
unlock_mutex();
@@ -447,9 +596,6 @@ static void *monitor_thread(void *arg)
if (!event_wait(thread))
continue;
-/* REMOVEME: */
-log_print("%s: cycle on %s\n", __func__, thread->device_path);
-
/*
* Check against filter.
*
@@ -478,7 +624,12 @@ static int create_thread(struct thread_status *thread)
static int terminate_thread(struct thread_status *thread)
{
- return pthread_cancel(thread->thread);
+ int ret;
+
+ if ((ret = pthread_cancel(thread->thread)))
+ return ret;
+
+ return pthread_kill(thread->thread, SIGALRM);
}
/* DSO reference counting. */
@@ -523,7 +674,7 @@ static int lookup_symbol(void *dl, struct dso_data *data,
if ((*symbol = dlsym(dl, name)))
return 1;
- log_err("looking up %s symbol in %s\n", name, data->dso_name);
+ log_error("looking up %s symbol in %s\n", name, data->dso_name);
return 0;
}
@@ -550,8 +701,6 @@ static char *create_dso_file_name(char *dso_name)
strlen(suffix) + 1)))
sprintf(ret, "%s%s%s", prefix, dso_name, suffix);
-log_print("%s: \"%s\"\n", __func__, ret);
-
return ret;
}
@@ -562,13 +711,13 @@ static struct dso_data *load_dso(struct message_data *data)
struct dso_data *ret = NULL;
char *dso_file;
-log_print("%s: \"%s\"\n", __func__, data->dso_name);
-
if (!(dso_file = create_dso_file_name(data->dso_name)))
return NULL;
- if (!(dl = dlopen(dso_file, RTLD_NOW)))
+ if (!(dl = dlopen(dso_file, RTLD_NOW))){
+ log_error("%s\n", dlerror());
goto free_dso_file;
+ }
if (!(ret = alloc_dso_data(data)))
goto close;
@@ -602,16 +751,22 @@ log_print("%s: \"%s\"\n", __func__, data->dso_name);
}
+/* Return success on daemon active check. */
+static int active(struct message_data *message_data)
+{
+ return 0;
+}
+
/*
* Register for an event.
*
- * Only one caller at a time here, because we use a FIFO and lock
- * it against multiple accesses.
+ * Only one caller at a time here, because we use
+ * a FIFO and lock it against multiple accesses.
*/
static int register_for_event(struct message_data *message_data)
{
int ret = 0;
- struct thread_status *thread, *thread_new;
+ struct thread_status *thread, *thread_new = NULL;
struct dso_data *dso_data;
if (!device_exists(message_data->device_path)) {
@@ -619,13 +774,16 @@ static int register_for_event(struct message_data *message_data)
ret = -ENODEV;
goto out;
}
-log_print("%s\n", __func__);
-fflush(stdout);
if (!(dso_data = lookup_dso(message_data)) &&
!(dso_data = load_dso(message_data))) {
stack;
+/* FIXME */
+#ifdef ELIBACC
ret = -ELIBACC;
+#else
+ ret = -ENODEV;
+#endif
goto out;
}
@@ -636,20 +794,26 @@ fflush(stdout);
goto out;
}
- if (!(ret = do_register_device(thread_new)))
- goto out;
-
lock_mutex();
- if ((thread = lookup_thread_status(message_data)))
- ret = -EPERM;
- else {
+ if (!(thread = lookup_thread_status(message_data))) {
+ unlock_mutex();
+
+ /*
+ * FIXME: better do this asynchronously in the
+ * monitoring thread ?
+ */
+ if (!(ret = do_register_device(thread_new)))
+ goto out;
+
thread = thread_new;
thread_new = NULL;
/* Try to create the monitoring thread for this device. */
+ lock_mutex();
if ((ret = -create_thread(thread))) {
unlock_mutex();
+ do_unregister_device(thread);
free_thread_status(thread);
goto out;
} else
@@ -659,8 +823,18 @@ fflush(stdout);
/* Or event # into events bitfield. */
thread->events |= message_data->events.field;
- unlock_mutex();
+ unlock_mutex();
+ /* FIXME - If you fail to register for timeout events, you
+ still monitor all the other events. Is this the right
+ action for newly created devices? Also, you are still
+ on the timeout registry, so if a timeout thread is
+ successfully started up later, you will start receiving
+ DM_EVENT_TIMEOUT events */
+ if (thread->events & DM_EVENT_TIMEOUT)
+ ret = -register_for_timeout(thread);
+
+ out:
/*
* Deallocate thread status after releasing
* the lock in case we haven't used it.
@@ -668,9 +842,6 @@ fflush(stdout);
if (thread_new)
free_thread_status(thread_new);
- out:
- free_message(message_data);
-
return ret;
}
@@ -692,15 +863,17 @@ static int unregister_for_event(struct message_data *message_data)
if (!(thread = lookup_thread_status(message_data))) {
unlock_mutex();
- ret = -ESRCH;
+ ret = -ENODEV;
goto out;
}
thread->events &= ~message_data->events.field;
+ if (!(thread->events & DM_EVENT_TIMEOUT))
+ unregister_for_timeout(thread);
/*
- * In case there's no events to monitor on this
- * device -> unlink and terminate its monitoring thread.
+ * In case there's no events to monitor on this device ->
+ * unlink and terminate its monitoring thread.
*/
if (!thread->events)
UNLINK_THREAD(thread);
@@ -709,12 +882,12 @@ static int unregister_for_event(struct message_data *message_data)
if (!thread->events) {
/* turn codes negative */
- if ((ret = -terminate_thread(thread))) {
+ if ((ret = -terminate_thread(thread)))
stack;
- } else {
+ else {
pthread_join(thread->thread, NULL);
- lib_put(thread->dso_data);
free_thread_status(thread);
+ lib_put(thread->dso_data);
lock_mutex();
if (list_empty(&thread_registry))
@@ -725,20 +898,18 @@ static int unregister_for_event(struct message_data *message_data)
out:
- free_message(message_data);
-
return ret;
}
/*
- * Get next registered device.
+ * Get registered device.
*
* Only one caller at a time here as with register_for_event().
*/
static int registered_device(struct message_data *message_data,
struct thread_status *thread)
{
- struct daemon_message *msg = message_data->msg;
+ struct dm_event_daemon_message *msg = message_data->msg;
snprintf(msg->msg, sizeof(msg->msg), "%s %s %u",
thread->dso_data->dso_name, thread->device_path,
@@ -749,104 +920,139 @@ static int registered_device(struct message_data *message_data,
return 0;
}
-static int get_registered_device(struct message_data *message_data, int next)
+static int want_registered_device(char *dso_name, char *device_path,
+ struct thread_status *thread)
{
- int dev, dso, hit = 0;
- struct thread_status *thread;
+ /* If DSO names and device paths are equal. */
+ if (dso_name && device_path)
+ return !strcmp(dso_name, thread->dso_data->dso_name) &&
+ !strcmp(device_path, thread->device_path);
+
+ /* If DSO names are equal. */
+ if (dso_name)
+ return !strcmp(dso_name, thread->dso_data->dso_name);
+
+ /* If device paths are equal. */
+ if (device_path)
+ return !strcmp(device_path, thread->device_path);
- lock_mutex();
+ return 1;
+}
- thread = list_item(thread_registry.n, struct thread_status);
+static int _get_registered_device(struct message_data *message_data, int next)
+{
+ int hit = 0;
+ struct thread_status *thread;
- if (!message_data->dso_name &&
- !message_data->device_path)
- goto out;
-
+ lock_mutex();
+ /* Iterate list of threads checking if we want a particular one. */
list_iterate_items(thread, &thread_registry) {
- dev = dso = 0;
-
-log_print("%s: working %s %s %u\n", __func__, thread->dso_data->dso_name, thread->device_path, thread->events);
- /* If DSO name equals. */
- if (message_data->dso_name &&
- !strcmp(message_data->dso_name,
- thread->dso_data->dso_name))
- dso = 1;
-
- /* If dev path equals. */
- if (message_data->device_path &&
- !strcmp(message_data->device_path,
- thread->device_path))
- dev = 1;
-
- /* We've got both DSO name and device patch or either. */
- /* FIXME: wrong logic! */
- if (message_data->dso_name && message_data->device_path &&
- dso && dev)
- hit = 1;
- else if (message_data->dso_name && dso)
- hit = 1;
- else if (message_data->device_path &&
- dev)
- hit = 1;
-
- if (hit)
-{log_print("%s: HIT %s %s %u\n", __func__, thread->dso_data->dso_name, thread->device_path, thread->events);
+ if ((hit = want_registered_device(message_data->dso_name,
+ message_data->device_path,
+ thread)))
break;
-}
}
/*
* If we got a registered device and want the next one ->
- * fetch next element off the list.
+ * fetch next conforming element off the list.
*/
- if (hit && next)
- thread = list_item(&thread->list.n, struct thread_status);
+ if (hit) {
+ if (next) {
+ do {
+ if (list_end(&thread_registry, &thread->list))
+ goto out;
+
+ thread = list_item(thread->list.n,
+ struct thread_status);
+ } while (!want_registered_device(message_data->dso_name,
+ NULL, thread));
+ }
- out:
- if (list_empty(&thread->list) ||
- &thread->list == &thread_registry) {
- unlock_mutex();
- return -ENOENT;
+ return registered_device(message_data, thread);
}
+ out:
unlock_mutex();
- return registered_device(message_data, thread);
+ return -ENOENT;
+}
+
+static int get_registered_device(struct message_data *message_data)
+{
+ return _get_registered_device(message_data, 0);
+}
+
+static int get_next_registered_device(struct message_data *message_data)
+{
+ return _get_registered_device(message_data, 1);
}
+static int set_timeout(struct message_data *message_data)
+{
+ struct thread_status *thread;
+
+ lock_mutex();
+ if ((thread = lookup_thread_status(message_data)))
+ thread->timeout = message_data->timeout.secs;
+ unlock_mutex();
+
+ return thread ? 0 : -ENODEV;
+}
+
+static int get_timeout(struct message_data *message_data)
+{
+ struct thread_status *thread;
+ struct dm_event_daemon_message *msg = message_data->msg;
+
+ lock_mutex();
+ if ((thread = lookup_thread_status(message_data)))
+ snprintf(msg->msg, sizeof(msg->msg),
+ "%"PRIu32, thread->timeout);
+ unlock_mutex();
+
+ return thread ? 0 : -ENODEV;
+}
+
+
/* Initialize a fifos structure with path names. */
-static void init_fifos(struct fifos *fifos)
+static int init_fifos(struct dm_event_fifos *fifos)
{
- memset(fifos, 0, sizeof(*fifos));
- fifos->client_path = FIFO_CLIENT;
- fifos->server_path = FIFO_SERVER;
+ if (memset(fifos, 0, sizeof(*fifos))) {
+ fifos->client_path = DM_EVENT_FIFO_CLIENT;
+ fifos->server_path = DM_EVENT_FIFO_SERVER;
+
+ return 0;
+ }
+
+ return -ENOMEM;
}
/* Open fifos used for client communication. */
-static int open_fifos(struct fifos *fifos)
+static int open_fifos(struct dm_event_fifos *fifos)
{
/* Blocks until client is ready to write. */
- if ((fifos->server = open(fifos->server_path, O_WRONLY)) == -1) {
+ if ((fifos->server = open(fifos->server_path, O_WRONLY)) < 0) {
stack;
- return 0;
+ return -EXIT_FIFO_FAILURE;
}
/* Need to open read+write for select() to work. */
- if ((fifos->client = open(fifos->client_path, O_RDWR)) == -1) {
+ if ((fifos->client = open(fifos->client_path, O_RDWR)) < 0) {
stack;
close(fifos->server);
- return 0;
+ return -EXIT_FIFO_FAILURE;
}
- return 1;
+ return 0;
}
/*
* Read message from client making sure that data is available
* and a complete message is read.
*/
-static int client_read(struct fifos *fifos, struct daemon_message *msg)
+static int client_read(struct dm_event_fifos *fifos, struct dm_event_daemon_message *msg)
{
int bytes = 0, ret = 0;
fd_set fds;
@@ -869,7 +1075,7 @@ static int client_read(struct fifos *fifos, struct daemon_message *msg)
/*
* Write a message to the client making sure that it is ready to write.
*/
-static int client_write(struct fifos *fifos, struct daemon_message *msg)
+static int client_write(struct dm_event_fifos *fifos, struct dm_event_daemon_message *msg)
{
int bytes = 0, ret = 0;
fd_set fds;
@@ -889,184 +1095,181 @@ static int client_write(struct fifos *fifos, struct daemon_message *msg)
return bytes == sizeof(*msg);
}
+/*
+ * Handle a client request.
+ *
+ * We put the request handling functions into
+ * a list because of the growing number.
+ */
+static int handle_request(struct dm_event_daemon_message *msg,
+ struct message_data *message_data)
+{
+ static struct {
+ unsigned int cmd;
+ int (*f)(struct message_data*);
+ } requests[] = {
+ { DM_EVENT_CMD_REGISTER_FOR_EVENT, register_for_event },
+ { DM_EVENT_CMD_UNREGISTER_FOR_EVENT, unregister_for_event },
+ { DM_EVENT_CMD_GET_REGISTERED_DEVICE, get_registered_device },
+ { DM_EVENT_CMD_GET_NEXT_REGISTERED_DEVICE, get_next_registered_device },
+ { DM_EVENT_CMD_SET_TIMEOUT, set_timeout },
+ { DM_EVENT_CMD_GET_TIMEOUT, get_timeout },
+ { DM_EVENT_CMD_ACTIVE, active },
+ }, *req;
+
+ for (req = requests; req < requests + sizeof(requests); req++) {
+ if (req->cmd == msg->opcode.cmd)
+ return req->f(message_data);
+ }
+
+ return -EINVAL;
+}
+
/* Process a request passed from the communication thread. */
-static int do_process_request(struct daemon_message *msg)
+static int do_process_request(struct dm_event_daemon_message *msg)
{
int ret;
static struct message_data message_data;
-log_print("%s: \"%s\"\n", __func__, msg->msg);
/* Parse the message. */
+ memset(&message_data, 0, sizeof(message_data));
message_data.msg = msg;
- if (msg->opcode.cmd != CMD_ACTIVE &&
+ if (msg->opcode.cmd != DM_EVENT_CMD_ACTIVE &&
!parse_message(&message_data)) {
stack;
-fflush(stdout);
- return -EINVAL;
- }
-
-fflush(stdout);
-
- /* Check the request type. */
- switch (msg->opcode.cmd) {
- case CMD_ACTIVE:
- ret = 0;
- break;
- case CMD_REGISTER_FOR_EVENT:
- ret = register_for_event(&message_data);
- break;
- case CMD_UNREGISTER_FOR_EVENT:
- ret = unregister_for_event(&message_data);
- break;
- case CMD_GET_REGISTERED_DEVICE:
- ret = get_registered_device(&message_data, 0);
- break;
- case CMD_GET_NEXT_REGISTERED_DEVICE:
- ret = get_registered_device(&message_data, 1);
- break;
- default:
ret = -EINVAL;
- break;
+ } else {
+log_print("%s: %u \"%s\"\n", __func__, msg->opcode.cmd, message_data.msg->msg);
+ ret = handle_request(msg, &message_data);
}
+ free_message(&message_data);
+
return ret;
}
/* Only one caller at a time. */
-static void process_request(struct fifos *fifos, struct daemon_message *msg)
+static void process_request(struct dm_event_fifos *fifos)
{
+ struct dm_event_daemon_message msg;
+
+ /* FIXME: better error handling */
+
/* Read the request from the client. */
- memset(msg, 0, sizeof(*msg));
- if (!client_read(fifos, msg)) {
+ if (!memset(&msg, 0, sizeof(msg)) ||
+ !client_read(fifos, &msg)) {
stack;
return;
}
- msg->opcode.status = do_process_request(msg);
+ msg.opcode.status = do_process_request(&msg);
- memset(&msg->msg, 0, sizeof(msg->msg));
- if (!client_write(fifos, msg))
+log_print("%s: status: %s\n", __func__, strerror(-msg.opcode.status));
+ if (!client_write(fifos, &msg))
stack;
}
-/* Communication thread. */
-static void comm_thread(struct fifos *fifos)
+static void sig_alarm(int signum)
{
- struct daemon_message msg;
+ pthread_testcancel();
+}
- /* Open fifos (must be created by client). */
- if (!open_fifos(fifos)) {
- stack;
- return;
- }
+/* Init thread signal handling. */
+static void init_thread_signals(void)
+{
+ sigset_t sigset;
+ struct sigaction act;
- /* Exit after last unregister. */
- do {
- process_request(fifos, &msg);
- } while (!list_empty(&thread_registry));
+ memset(&act, 0, sizeof(act));
+ act.sa_handler = sig_alarm;
+ sigaction(SIGALRM, &act, NULL);
+ sigfillset(&sigset);
+ pthread_sigmask(SIG_BLOCK, &sigset, NULL);
}
-/* Fork into the background and detach from our parent process. */
static int daemonize(void)
{
- pid_t pid;
-
- if ((pid = fork()) == -1) {
- log_err("%s: fork", __func__);
- return 0;
- } else if (pid > 0) /* Parent. */
- return 2;
+ setsid();
+ if (chdir("/"))
+ return -EXIT_CHDIR_FAILURE;
-log_print("daemonizing 2nd...\n");
+/* FIXME: activate again after we're done with tracing.
+ if ((close(STDIN_FILENO) < 0) ||
+ (close(STDOUT_FILENO) < 0) ||
+ (close(STDERR_FILENO) < 0))
+ return -EXIT_DESC_CLOSE_FAILURE;
+*/
- setsid();
- if (chdir("/")) {
- log_err("%s: chdir /", __func__);
- return 0;
- }
+ return 0;
+}
-/* REMOVEME: */
- return 1;
+static int lock_pidfile(void)
+{
+ int lf;
+ char pidfile[] = "/var/run/dmeventd.pid";
- log_print("daemonizing 3rd...\n");
+ if ((lf = open(pidfile, O_CREAT | O_RDWR, 0644)) < 0)
+ return -EXIT_OPEN_PID_FAILURE;
- /* Detach ourself. */
- if (close(STDIN_FILENO) == -1 ||
- close(STDOUT_FILENO) == -1 ||
- close(STDERR_FILENO) == -1)
- return 0;
+ if (flock(lf, LOCK_EX | LOCK_NB) < 0)
+ return -EXIT_LOCKFILE_INUSE;
-log_print("daemonized\n");
+ if (!storepid(lf))
+ return -EXIT_FAILURE;
- return 1;
+ return 0;
}
-/* Init thread signal handling. */
-#define HANGUP SIGHUP
-static void init_thread_signals(int hup)
+void dmeventd(void)
{
- sigset_t sigset;
-
- sigfillset(&sigset);
+ int ret;
+ struct dm_event_fifos fifos;
+ // struct sys_log logdata = {DAEMON_NAME, LOG_DAEMON};
- if (hup)
- sigdelset(&sigset, HANGUP);
+ if ((ret = daemonize()))
+ exit(-ret);
- pthread_sigmask(SIG_SETMASK, &sigset, NULL);
-}
+ /* FIXME: set daemon name. */
+ // set_name();
-int main(void)
-{
- struct fifos fifos;
- struct sys_log logdata = {DAEMON_NAME, LOG_DAEMON};
- /* Make sure, parent accepts HANGUP signal. */
- init_thread_signals(1);
-
- switch (daemonize()) {
- case 1: /* Child. */
- /* Try to lock pidfile. */
- if (!lock()) {
- fprintf(stderr, "daemon already running\n");
- break;
- }
+ if ((ret = lock_pidfile()))
+ exit(-ret);
- init_thread_signals(0);
- kill(getppid(), HANGUP);
+ init_thread_signals();
- multilog_clear_logging();
- multilog_add_type(std_syslog, &logdata);
- multilog_init_verbose(std_syslog, _LOG_DEBUG);
- multilog_async(1);
+ //multilog_clear_logging();
+ //multilog_add_type(std_syslog, &logdata);
+ //multilog_init_verbose(std_syslog, _LOG_DEBUG);
+ //multilog_async(1);
- init_fifos(&fifos);
- pthread_mutex_init(&mutex, NULL);
+ if ((ret = init_fifos(&fifos)))
+ exit(-ret);
- if (!storepid(lf)) {
- stack;
- exit(EXIT_FAILURE);
- }
+ pthread_mutex_init(&mutex, NULL);
- if (mlockall(MCL_FUTURE) == -1) {
- stack;
- exit(EXIT_FAILURE);
- }
+#ifdef MCL_CURRENT
+ if (mlockall(MCL_CURRENT | MCL_FUTURE) == -1)
+ exit(EXIT_FAILURE);
+#endif
- /* Communication thread runs forever... */
- comm_thread(&fifos);
+ if ((ret = open_fifos(&fifos)))
+ exit(-ret);
- /* We should never get here. */
- munlockall();
- pthread_mutex_destroy(&mutex);
+ /* Signal parent, letting them know we are ready to go. */
+ kill(getppid(), SIGUSR1);
- case 0: /* Error (either on daemonize() or on comm_thread() return. */
- unlock();
- exit(EXIT_FAILURE);
- break;
+ /*
+ * We exit when there are no more devices to watch.
+ * That is, when the last unregister happens.
+ */
+ do {
+ process_request(&fifos);
+ } while(!list_empty(&thread_registry));
- case 2: /* Parent. */
- wait(NULL);
- break;
- }
+#ifdef MCL_CURRENT
+ munlockall();
+#endif
+ pthread_mutex_destroy(&mutex);
exit(EXIT_SUCCESS);
}
diff --git a/daemons/dmeventd/dmeventd.h b/daemons/dmeventd/dmeventd.h
new file mode 100644
index 000000000..44c7d303d
--- /dev/null
+++ b/daemons/dmeventd/dmeventd.h
@@ -0,0 +1,12 @@
+#ifndef __DMEVENTD_DOT_H__
+#define __DMEVENTD_DOT_H__
+
+#define EXIT_LOCKFILE_INUSE 2
+#define EXIT_DESC_CLOSE_FAILURE 3
+#define EXIT_OPEN_PID_FAILURE 4
+#define EXIT_FIFO_FAILURE 5
+#define EXIT_CHDIR_FAILURE 6
+
+void dmeventd(void);
+
+#endif /* __DMEVENTD_DOT_H__ */
diff --git a/daemons/dmeventd/libdevmapper-event.c b/daemons/dmeventd/libdevmapper-event.c
new file mode 100644
index 000000000..62b12b708
--- /dev/null
+++ b/daemons/dmeventd/libdevmapper-event.c
@@ -0,0 +1,465 @@
+ /*
+ * Copyright (C) 2005 Red Hat, Inc. All rights reserved.
+ *
+ * This file is part of the device-mapper userspace tools.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License v.2.1.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "lib.h"
+#include "libdevmapper-event.h"
+//#include "libmultilog.h"
+#include "dmeventd.h"
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/file.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <signal.h>
+#include <sys/wait.h>
+
+/* Set by any of the external fxns the first time one of them is called */
+/* FIXME Unused */
+// static int _logging = 0;
+
+/* Fetch a string off src and duplicate it into *dest. */
+/* FIXME: move to seperate module to share with the daemon. */
+static const char delimiter = ' ';
+static char *fetch_string(char **src)
+{
+ char *p, *ret;
+
+ if ((p = strchr(*src, delimiter)))
+ *p = 0;
+
+ if ((ret = strdup(*src)))
+ *src += strlen(ret) + 1;
+
+ if (p)
+ *p = delimiter;
+
+ return ret;
+}
+
+/* Parse a device message from the daemon. */
+static int parse_message(struct dm_event_daemon_message *msg, char **dso_name,
+ char **device, enum dm_event_type *events)
+{
+ char *p = msg->msg;
+
+ if ((*dso_name = fetch_string(&p)) &&
+ (*device = fetch_string(&p))) {
+ *events = atoi(p);
+
+ return 0;
+ }
+
+ return -ENOMEM;
+}
+
+/* Read message from daemon. */
+static int daemon_read(struct dm_event_fifos *fifos, struct dm_event_daemon_message *msg)
+{
+ int bytes = 0, ret = 0;
+ fd_set fds;
+
+ memset(msg, 0, sizeof(*msg));
+ errno = 0;
+ /* FIXME Fix error handling. Check 'ret' before errno. EINTR? EAGAIN? */
+ /* FIXME errno != EOF? RTFM! */
+ while (bytes < sizeof(*msg) && errno != EOF) {
+ do {
+ /* Watch daemon read FIFO for input. */
+ FD_ZERO(&fds);
+ FD_SET(fifos->server, &fds);
+ /* FIXME Check for errors e.g. EBADF */
+ } while (select(fifos->server+1, &fds, NULL, NULL, NULL) != 1);
+
+ ret = read(fifos->server, msg, sizeof(*msg) - bytes);
+ bytes += ret > 0 ? ret : 0;
+ }
+
+// log_print("%s: \"%s\"\n", __func__, msg->msg);
+ return bytes == sizeof(*msg);
+}
+
+/* Write message to daemon. */
+static int daemon_write(struct dm_event_fifos *fifos, struct dm_event_daemon_message *msg)
+{
+ int bytes = 0, ret = 0;
+ fd_set fds;
+
+
+// log_print("%s: \"%s\"\n", __func__, msg->msg);
+ errno = 0;
+ /* FIXME Fix error handling. Check 'ret' before errno. EINTR? EAGAIN? */
+ while (bytes < sizeof(*msg) && errno != EIO) {
+ do {
+ /* Watch daemon write FIFO to be ready for output. */
+ FD_ZERO(&fds);
+ FD_SET(fifos->client, &fds);
+ /* FIXME Check for errors e.g. EBADF */
+ } while (select(fifos->client +1, NULL, &fds, NULL, NULL) != 1);
+
+ ret = write(fifos->client, msg, sizeof(*msg) - bytes);
+ bytes += ret > 0 ? ret : 0;
+ }
+
+ return bytes == sizeof(*msg);
+}
+
+static int daemon_talk(struct dm_event_fifos *fifos, struct dm_event_daemon_message *msg,
+ int cmd, char *dso_name, char *device,
+ enum dm_event_type events, uint32_t timeout)
+{
+ memset(msg, 0, sizeof(*msg));
+
+ /*
+ * Set command and pack the arguments
+ * into ASCII message string.
+ */
+ msg->opcode.cmd = cmd;
+
+ if (sizeof(msg->msg) <= snprintf(msg->msg, sizeof(msg->msg),
+ "%s %s %u %"PRIu32,
+ dso_name ? dso_name : "",
+ device ? device : "",
+ events, timeout)) {
+ stack;
+ return -ENAMETOOLONG;
+ }
+
+ /*
+ * Write command and message to and
+ * read status return code from daemon.
+ */
+ if (!daemon_write(fifos, msg)) {
+ stack;
+ return -EIO;
+ }
+
+ if (!daemon_read(fifos, msg)) {
+ stack;
+ return -EIO;
+ }
+
+ return msg->opcode.status;
+}
+
+static volatile sig_atomic_t daemon_running = 0;
+
+static void daemon_running_signal_handler(int sig)
+{
+ daemon_running = 1;
+}
+
+/*
+ * start_daemon
+ *
+ * This function forks off a process (dmeventd) that will handle
+ * the events. A signal must be returned from the child to
+ * indicate when it is ready to handle requests. The parent
+ * (this function) returns 1 if there is a daemon running.
+ *
+ * Returns: 1 on success, 0 otherwise
+ */
+static int start_daemon(void)
+{
+ int pid, ret=0;
+ int old_mask;
+ void *old_hand;
+
+ /* Must be able to acquire signal */
+ old_hand = signal(SIGUSR1, &daemon_running_signal_handler);
+ if (old_hand == SIG_ERR) {
+ log_error("Unable to setup signal handler.");
+ return 0;
+ }
+
+#ifdef linux
+ /* FIXME Deprecated. Try posix sigprocmask instead. */
+ old_mask = siggetmask();
+ old_mask &= ~sigmask(SIGUSR1);
+ old_mask = sigsetmask(old_mask);
+#endif
+
+ pid = fork();
+
+ if (pid < 0)
+ log_error("Unable to fork.\n");
+ else if (pid) { /* parent waits for child to get ready for requests */
+ int status;
+
+ /* FIXME Better way to do this? */
+ while (!waitpid(pid, &status, WNOHANG) && !daemon_running)
+ sleep(1);
+
+ if (daemon_running) {
+ log_print("dmeventd started.\n");
+ ret = 1;
+ } else {
+ switch (WEXITSTATUS(status)) {
+ case EXIT_LOCKFILE_INUSE:
+ /*
+ * Note, this is ok... we still have daemon
+ * that we can communicate with...
+ */
+ log_print("Starting dmeventd failed: "
+ "dmeventd already running.\n");
+ ret = 1;
+ break;
+ default:
+ log_error("Unable to start dmeventd.\n");
+ break;
+ }
+ }
+ } else {
+ signal(SIGUSR1, SIG_IGN); /* don't care about error */
+
+ /* dmeventd function is responsible for properly setting **
+ ** itself up. It must never return - only exit. This is**
+ ** why it is followed by an EXIT_FAILURE */
+ dmeventd();
+ exit(EXIT_FAILURE);
+ }
+
+ /* FIXME What if old_hand is SIG_ERR? */
+ if (signal(SIGUSR1, old_hand) == SIG_ERR)
+ log_error("Unable to reset signal handler.");
+ sigsetmask(old_mask);
+
+ return ret;
+}
+
+/* Initialize client. */
+static int init_client(struct dm_event_fifos *fifos)
+{
+ /* FIXME Is fifo the most suitable method? */
+ /* FIXME Why not share comms/daemon code with something else e.g. multipath? */
+
+ /* init fifos */
+ memset(fifos, 0, sizeof(*fifos));
+ fifos->client_path = DM_EVENT_FIFO_CLIENT;
+ fifos->server_path = DM_EVENT_FIFO_SERVER;
+
+ /* FIXME The server should be responsible for these, not the client. */
+ /* Create fifos */
+ if (((mkfifo(fifos->client_path, 0600) == -1) && errno != EEXIST) ||
+ ((mkfifo(fifos->server_path, 0600) == -1) && errno != EEXIST)) {
+ log_error("%s: Failed to create a fifo.\n", __func__);
+ return 0;
+ }
+
+ /* FIXME Warn/abort if perms are wrong - not something to fix silently. */
+ /* If they were already there, make sure permissions are ok. */
+ if (chmod(fifos->client_path, 0600)) {
+ log_error("Unable to set correct file permissions on %s",
+ fifos->client_path);
+ return 0;
+ }
+
+ if (chmod(fifos->server_path, 0600)) {
+ log_error("Unable to set correct file permissions on %s",
+ fifos->server_path);
+ return 0;
+ }
+
+ /*
+ * Open the fifo used to read from the daemon.
+ * Allows daemon to create its write fifo...
+ */
+ if ((fifos->server = open(fifos->server_path, O_RDWR)) < 0) {
+ log_error("%s: open server fifo %s\n",
+ __func__, fifos->server_path);
+ stack;
+ return 0;
+ }
+
+ /* Lock out anyone else trying to do communication with the daemon. */
+ /* FIXME Why failure not retry? How do multiple processes communicate? */
+ if (flock(fifos->server, LOCK_EX) < 0){
+ log_error("%s: flock %s\n", __func__, fifos->server_path);
+ close(fifos->server);
+ return 0;
+ }
+
+ /* Anyone listening? If not, errno will be ENXIO */
+ if ((fifos->client = open(fifos->client_path,
+ O_WRONLY | O_NONBLOCK)) < 0) {
+ if (errno != ENXIO) {
+ log_error("%s: open client fifo %s\n",
+ __func__, fifos->client_path);
+ close(fifos->server);
+ stack;
+ return 0;
+ }
+
+ /* FIXME Unnecessary if daemon was started before calling this */
+ if (!start_daemon()) {
+ stack;
+ return 0;
+ }
+
+ /* FIXME Unnecessary if daemon was started before calling this */
+ /* Daemon is started, retry the open */
+ fifos->client = open(fifos->client_path, O_WRONLY | O_NONBLOCK);
+ if (fifos->client < 0) {
+ log_error("%s: open client fifo %s\n",
+ __func__, fifos->client_path);
+ close(fifos->server);
+ stack;
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+static void dtr_client(struct dm_event_fifos *fifos)
+{
+ if (flock(fifos->server, LOCK_UN))
+ log_error("flock unlock %s\n", fifos->server_path);
+
+ close(fifos->client);
+ close(fifos->server);
+}
+
+/* Check, if a block device exists. */
+static int device_exists(char *device)
+{
+ struct stat st_buf;
+ char path2[PATH_MAX];
+
+ if (!device)
+ return 0;
+
+ if (device[0] == '/') /* absolute path */
+ return !stat(device, &st_buf) && S_ISBLK(st_buf.st_mode);
+
+ if (PATH_MAX <= snprintf(path2, PATH_MAX, "%s/%s", dm_dir(), device))
+ return 0;
+
+ return !stat(path2, &st_buf) && S_ISBLK(st_buf.st_mode);
+}
+
+/* Handle the event (de)registration call and return negative error codes. */
+static int do_event(int cmd, struct dm_event_daemon_message *msg,
+ char *dso_name, char *device, enum dm_event_type events,
+ uint32_t timeout)
+{
+ int ret;
+ struct dm_event_fifos fifos;
+
+ /* FIXME Start the daemon here if it's not running e.g. exclusive lock file */
+
+ if (!init_client(&fifos)) {
+ stack;
+ return -ESRCH;
+ }
+
+ ret = daemon_talk(&fifos, msg, cmd, dso_name, device, events, timeout);
+
+ /* what is the opposite of init? */
+ dtr_client(&fifos);
+
+ return ret;
+}
+
+/* External library interface. */
+int dm_event_register(char *dso_name, char *device_path,
+ enum dm_event_type events)
+{
+ struct dm_event_daemon_message msg;
+
+ if (!device_exists(device_path))
+ return -ENODEV;
+
+ return do_event(DM_EVENT_CMD_REGISTER_FOR_EVENT, &msg,
+ dso_name, device_path, events, 0);
+}
+
+int dm_event_unregister(char *dso_name, char *device_path,
+ enum dm_event_type events)
+{
+ struct dm_event_daemon_message msg;
+
+ if (!device_exists(device_path))
+ return -ENODEV;
+
+ return do_event(DM_EVENT_CMD_UNREGISTER_FOR_EVENT, &msg,
+ dso_name, device_path, events, 0);
+}
+
+int dm_event_get_registered_device(char **dso_name, char **device_path,
+ enum dm_event_type *events, int next)
+{
+ int ret;
+ char *dso_name_arg = NULL, *device_path_arg = NULL;
+ struct dm_event_daemon_message msg;
+
+ if (!(ret = do_event(next ? DM_EVENT_CMD_GET_NEXT_REGISTERED_DEVICE :
+ DM_EVENT_CMD_GET_REGISTERED_DEVICE,
+ &msg, *dso_name, *device_path, *events, 0)))
+ ret = parse_message(&msg, &dso_name_arg, &device_path_arg,
+ events);
+
+ if (next){
+ if (*dso_name)
+ free(*dso_name);
+ if (*device_path)
+ free(*device_path);
+ *dso_name = dso_name_arg;
+ *device_path = device_path_arg;
+ } else {
+ if (!(*dso_name))
+ *dso_name = dso_name_arg;
+ if (!(*device_path))
+ *device_path = device_path_arg;
+ }
+
+ return ret;
+}
+
+int dm_event_set_timeout(char *device_path, uint32_t timeout)
+{
+ struct dm_event_daemon_message msg;
+
+ if (!device_exists(device_path))
+ return -ENODEV;
+ return do_event(DM_EVENT_CMD_SET_TIMEOUT, &msg,
+ NULL, device_path, 0, timeout);
+}
+
+int dm_event_get_timeout(char *device_path, uint32_t *timeout)
+{
+ int ret;
+ struct dm_event_daemon_message msg;
+
+ if (!device_exists(device_path))
+ return -ENODEV;
+ if (!(ret = do_event(DM_EVENT_CMD_GET_TIMEOUT, &msg, NULL, device_path, 0, 0)))
+ *timeout = atoi(msg.msg);
+ return ret;
+}
+/*
+ * Overrides for Emacs so that we follow Linus's tabbing style.
+ * Emacs will notice this stuff at the end of the file and automatically
+ * adjust the settings for this buffer only. This must remain at the end
+ * of the file.
+ * ---------------------------------------------------------------------------
+ * Local variables:
+ * c-file-style: "linux"
+ * End:
+ */
diff --git a/daemons/dmeventd/libdevmapper-event.h b/daemons/dmeventd/libdevmapper-event.h
new file mode 100644
index 000000000..9c9d637e5
--- /dev/null
+++ b/daemons/dmeventd/libdevmapper-event.h
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2005 Red Hat, Inc. All rights reserved.
+ *
+ * This file is part of the device-mapper userspace tools.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License v.2.1.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * Note that this file is released only as part of a technology preview
+ * and its contents may change in future updates in ways that do not
+ * preserve compatibility.
+ */
+
+#ifndef LIB_DMEVENT_H
+#define LIB_DMEVENT_H
+
+#include <stdint.h>
+
+/* FIXME This stuff must be configurable. */
+
+#define DM_EVENT_DAEMON "/sbin/dmeventd"
+#define DM_EVENT_LOCKFILE "/var/lock/dmeventd"
+#define DM_EVENT_FIFO_CLIENT "/var/run/dmeventd-client"
+#define DM_EVENT_FIFO_SERVER "/var/run/dmeventd-server"
+#define DM_EVENT_PIDFILE "/var/run/dmeventd.pid"
+
+#define DM_EVENT_DEFAULT_TIMEOUT 10
+
+/* Commands for the daemon passed in the message below. */
+enum dm_event_command {
+ DM_EVENT_CMD_ACTIVE = 1,
+ DM_EVENT_CMD_REGISTER_FOR_EVENT,
+ DM_EVENT_CMD_UNREGISTER_FOR_EVENT,
+ DM_EVENT_CMD_GET_REGISTERED_DEVICE,
+ DM_EVENT_CMD_GET_NEXT_REGISTERED_DEVICE,
+ DM_EVENT_CMD_SET_TIMEOUT,
+ DM_EVENT_CMD_GET_TIMEOUT,
+};
+
+/* Message passed between client and daemon. */
+struct dm_event_daemon_message {
+ union {
+ unsigned int cmd; /* FIXME Use fixed size. */
+ int status; /* FIXME Use fixed size. */
+ } opcode;
+ char msg[252]; /* FIXME Why is this 252 ? */
+} __attribute__((packed)); /* FIXME Do this properly! */
+
+/* FIXME Is this meant to be exported? I can't see where the interface uses it. */
+/* Fifos for client/daemon communication. */
+struct dm_event_fifos {
+ int client;
+ int server;
+ const char *client_path;
+ const char *server_path;
+};
+
+/* Event type definitions. */
+/* FIXME Use masks to separate the types and provide for extension. */
+enum dm_event_type {
+ DM_EVENT_SINGLE = 0x01, /* Report multiple errors just once. */
+ DM_EVENT_MULTI = 0x02, /* Report all of them. */
+
+ DM_EVENT_SECTOR_ERROR = 0x04, /* Failure on a particular sector. */
+ DM_EVENT_DEVICE_ERROR = 0x08, /* Device failure. */
+ DM_EVENT_PATH_ERROR = 0x10, /* Failure on an io path. */
+ DM_EVENT_ADAPTOR_ERROR = 0x20, /* Failure off a host adaptor. */
+
+ DM_EVENT_SYNC_STATUS = 0x40, /* Mirror synchronization completed/failed. */
+ DM_EVENT_TIMEOUT = 0x80, /* Timeout has occured */
+};
+
+/* FIXME Use a mask. */
+#define DM_EVENT_ALL_ERRORS (DM_EVENT_SECTOR_ERROR | DM_EVENT_DEVICE_ERROR | \
+ DM_EVENT_PATH_ERROR | DM_EVENT_ADAPTOR_ERROR)
+
+/* Prototypes for event lib interface. */
+/* FIXME Missing consts? */
+int dm_event_register(char *dso_name, char *device, enum dm_event_type events);
+int dm_event_unregister(char *dso_name, char *device,
+ enum dm_event_type events);
+int dm_event_get_registered_device(char **dso_name, char **device,
+ enum dm_event_type *events, int next);
+int dm_event_set_timeout(char *device, uint32_t timeout);
+int dm_event_get_timeout(char *device, uint32_t *timeout);
+
+/* Prototypes for DSO interface. */
+void process_event(const char *device, enum dm_event_type event);
+int register_device(const char *device);
+int unregister_device(const char *device);
+
+#endif
diff --git a/daemons/dmeventd/mktestdevices b/daemons/dmeventd/mktestdevices
deleted file mode 100644
index 7a6afb099..000000000
--- a/daemons/dmeventd/mktestdevices
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/bin/sh
-#
-# Create test devices for dmeventd
-#
-
-trap "rm -f /tmp/tmp.$$" 0 1 2 3 15
-
-echo "0 1024 zero" > /tmp/tmp.$$
-dmsetup create test /tmp/tmp.$$
-dmsetup create test1 /tmp/tmp.$$
-
-kill -15 $$
diff --git a/daemons/dmeventd/noop.c b/daemons/dmeventd/noop.c
deleted file mode 100644
index deb2ee489..000000000
--- a/daemons/dmeventd/noop.c
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2005 Red Hat, Inc. All rights reserved.
- *
- * This file is part of the device-mapper userspace tools.
- *
- * This copyrighted material is made available to anyone wishing to use,
- * modify, copy, or redistribute it subject to the terms and conditions
- * of the GNU Lesser General Public License v.2.1.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "libdm-event.h"
-#include "libmultilog.h"
-
-
-void process_event(char *device, enum event_type event)
-{
- log_err("[%s] %s(%d) - Device: %s, Event %d\n",
- __FILE__, __func__, __LINE__, device, event);
-}
-
-int register_device(char *device)
-{
- log_err("[%s] %s(%d) - Device: %s\n",
- __FILE__, __func__, __LINE__, device);
-
- return 1;
-}
-
-int unregister_device(char *device)
-{
- log_err("[%s] %s(%d) - Device: %s\n",
- __FILE__, __func__, __LINE__, device);
-
- return 1;
-}
diff --git a/libdm/Makefile.in b/libdm/Makefile.in
index d90a77bd2..f2c8df3c7 100644
--- a/libdm/Makefile.in
+++ b/libdm/Makefile.in
@@ -17,14 +17,6 @@ top_srcdir = @top_srcdir@
VPATH = @srcdir@
interface = @interface@
-ifeq ("@DMEVENTD@", "yes")
- SUBDIRS += event
-endif
-
-ifeq ($(MAKECMDGOALS),distclean)
- SUBDIRS += event
-endif
-
SOURCES =\
datastruct/bitset.c \
datastruct/hash.c \
diff --git a/libdm/libdm-event.h b/libdm/libdm-event.h
deleted file mode 100644
index d92eb71e2..000000000
--- a/libdm/libdm-event.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (C) 2005 Red Hat, Inc. All rights reserved.
- *
- * This file is part of the device-mapper userspace tools.
- *
- * This copyrighted material is made available to anyone wishing to use,
- * modify, copy, or redistribute it subject to the terms and conditions
- * of the GNU Lesser General Public License v.2.1.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef LIB_DMEVENT_H
-#define LIB_DMEVENT_H
-
-#include "list.h"
-
-#include <stdint.h>
-
-#define DAEMON "/sbin/dmeventd"
-#define LOCKFILE "/var/lock/dmeventd"
-#define FIFO_CLIENT "/var/run/dmeventd-client"
-#define FIFO_SERVER "/var/run/dmeventd-server"
-#define PIDFILE "/var/run/dmeventd.pid"
-
-#define DEFAULT_TIMEOUT 10
-/* Commands for the daemon passed in the message below. */
-enum dmeventd_command {
- CMD_ACTIVE = 1,
- CMD_REGISTER_FOR_EVENT,
- CMD_UNREGISTER_FOR_EVENT,
- CMD_GET_REGISTERED_DEVICE,
- CMD_GET_NEXT_REGISTERED_DEVICE,
- CMD_SET_TIMEOUT,
- CMD_GET_TIMEOUT,
-};
-
-/* Message passed between client and daemon. */
-struct daemon_message {
- union {
- unsigned int cmd;
- int status;
- } opcode;
- char msg[252];
-} __attribute__((packed));
-
-/* Fifos for client/daemon communication. */
-struct fifos {
- int client;
- int server;
- const char *client_path;
- const char *server_path;
-};
-
-/* Event type definitions. */
-enum event_type {
- SINGLE = 0x01, /* Report multiple errors just once. */
- MULTI = 0x02, /* Report all of them. */
- SECTOR_ERROR = 0x04, /* Failure on a particular sector. */
- DEVICE_ERROR = 0x08, /* Device failure. */
- PATH_ERROR = 0x10, /* Failure on an io path. */
- ADAPTOR_ERROR = 0x20, /* Failure off a host adaptor. */
- SYNC_STATUS = 0x40, /* Mirror synchronization completed/failed. */
- TIMEOUT = 0x80, /* Timeout has occured */
-};
-#define ALL_ERRORS (SECTOR_ERROR | DEVICE_ERROR | PATH_ERROR | ADAPTOR_ERROR)
-
-/* Prototypes for event lib interface. */
-int dm_register_for_event(char *dso_name, char *device, enum event_type events);
-int dm_unregister_for_event(char *dso_name, char *device,
- enum event_type events);
-int dm_get_registered_device(char **dso_name, char **device,
- enum event_type *events, int next);
-int dm_set_event_timeout(char *device, uint32_t timeout);
-int dm_get_event_timeout(char *device, uint32_t *timeout);
-
-/* Prototypes for DSO interface. */
-void process_event(char *device, enum event_type event);
-int register_device(char *device);
-int unregister_device(char *device);
-
-#endif
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */