[lvm-devel] [RFC][PATCH 2/5] add device list registering interface
Takahiro Yasui
tyasui at redhat.com
Wed Sep 30 00:28:12 UTC 2009
When a LV is registered to dmeventd to be monitored, a list of PVs
associated with the VG which LV belongs to are passed to dmeventd.
The device list is used to generate a filter option string of lvm
commands when dmeventd handles an error.
Signed-off-by: Takahiro Yasui <tyasui at redhat.com>
---
daemons/dmeventd/.exported_symbols | 1
daemons/dmeventd/dmeventd.c | 16 +++-
daemons/dmeventd/libdevmapper-event.c | 42 +++++++---
daemons/dmeventd/libdevmapper-event.h | 4 -
daemons/dmeventd/plugins/mirror/dmeventd_mirror.c | 5 -
daemons/dmeventd/plugins/snapshot/dmeventd_snapshot.c | 3
lib/mirror/mirrored.c | 72 +++++++++++++++++-
7 files changed, 118 insertions(+), 25 deletions(-)
Index: LVM2.02.54-20090928/daemons/dmeventd/.exported_symbols
===================================================================
--- LVM2.02.54-20090928.orig/daemons/dmeventd/.exported_symbols
+++ LVM2.02.54-20090928/daemons/dmeventd/.exported_symbols
@@ -17,3 +17,4 @@ dm_event_unregister_handler
dm_event_get_registered_device
dm_event_handler_set_timeout
dm_event_handler_get_timeout
+dm_event_handler_set_private
Index: LVM2.02.54-20090928/daemons/dmeventd/dmeventd.c
===================================================================
--- LVM2.02.54-20090928.orig/daemons/dmeventd/dmeventd.c
+++ LVM2.02.54-20090928/daemons/dmeventd/dmeventd.c
@@ -130,7 +130,7 @@ struct dso_data {
* and activate a mapping).
*/
int (*register_device)(const char *device, const char *uuid, int major,
- int minor, void **user);
+ int minor, void **user, void *user_data);
/*
* Device unregistration.
@@ -148,6 +148,7 @@ static DM_LIST_INIT(_dso_registry);
struct message_data {
char *id;
char *dso_name; /* Name of DSO. */
+ char *dso_private;
char *device_uuid; /* Mapped device path. */
union {
char *str; /* Events string as fetched from message. */
@@ -331,6 +332,8 @@ static void _free_message(struct message
if (message_data->device_uuid)
dm_free(message_data->device_uuid);
+ if (message_data->dso_private)
+ dm_free(message_data->dso_private);
}
/* Parse a register message from the client. */
@@ -372,6 +375,9 @@ static int _parse_message(struct message
ret = 1;
}
+ if (strlen(p))
+ _fetch_string(&message_data->dso_private, &p, ' ');
+
dm_free(msg->data);
msg->data = NULL;
msg->size = 0;
@@ -649,13 +655,14 @@ static int _event_wait(struct thread_sta
}
/* Register a device with the DSO. */
-static int _do_register_device(struct thread_status *thread)
+static int _do_register_device(struct thread_status *thread, void *priv_data)
{
return thread->dso_data->register_device(thread->device.name,
thread->device.uuid,
thread->device.major,
thread->device.minor,
- &(thread->dso_private));
+ &(thread->dso_private),
+ priv_data);
}
/* Unregister a device with the DSO. */
@@ -969,7 +976,8 @@ static int _register_for_event(struct me
if (!(thread = _lookup_thread_status(message_data))) {
_unlock_mutex();
- if (!(ret = _do_register_device(thread_new)))
+ if (!(ret = _do_register_device(thread_new,
+ message_data->dso_private)))
goto out;
thread = thread_new;
Index: LVM2.02.54-20090928/daemons/dmeventd/libdevmapper-event.c
===================================================================
--- LVM2.02.54-20090928.orig/daemons/dmeventd/libdevmapper-event.c
+++ LVM2.02.54-20090928/daemons/dmeventd/libdevmapper-event.c
@@ -41,6 +41,7 @@ struct dm_event_handler {
int major;
int minor;
uint32_t timeout;
+ char *private;
enum dm_event_mask mask;
};
@@ -53,6 +54,8 @@ static void _dm_event_handler_clear_dev_
dm_free(dmevh->uuid);
dmevh->dev_name = dmevh->uuid = NULL;
dmevh->major = dmevh->minor = 0;
+ if (dmevh->private)
+ dm_free(dmevh->private);
}
struct dm_event_handler *dm_event_handler_create(void)
@@ -66,6 +69,7 @@ struct dm_event_handler *dm_event_handle
dmevh->major = dmevh->minor = 0;
dmevh->mask = 0;
dmevh->timeout = 0;
+ dmevh->private = NULL;
return dmevh;
}
@@ -149,6 +153,16 @@ void dm_event_handler_set_timeout(struct
dmevh->timeout = timeout;
}
+int dm_event_handler_set_private(struct dm_event_handler *dmevh, const char *private)
+{
+ if (!private)
+ return 0;
+ dmevh->private = dm_strdup(private);
+ if (!dmevh->private)
+ return -ENOMEM;
+ return 0;
+}
+
const char *dm_event_handler_get_dso(const struct dm_event_handler *dmevh)
{
return dmevh->dso;
@@ -331,11 +345,12 @@ static int _daemon_write(struct dm_event
static int _daemon_talk(struct dm_event_fifos *fifos,
struct dm_event_daemon_message *msg, int cmd,
const char *dso_name, const char *dev_name,
- enum dm_event_mask evmask, uint32_t timeout)
+ enum dm_event_mask evmask, uint32_t timeout,
+ const char *private)
{
const char *dso = dso_name ? dso_name : "";
const char *dev = dev_name ? dev_name : "";
- const char *fmt = "%d:%d %s %s %u %" PRIu32;
+ const char *fmt = "%d:%d %s %s %u %" PRIu32 " %s";
int msg_size;
memset(msg, 0, sizeof(*msg));
@@ -347,7 +362,7 @@ static int _daemon_talk(struct dm_event_
if (cmd == DM_EVENT_CMD_HELLO)
fmt = "%d:%d HELLO";
if ((msg_size = dm_asprintf(&(msg->data), fmt, getpid(), _sequence_nr,
- dso, dev, evmask, timeout)) < 0) {
+ dso, dev, evmask, timeout, private ?: "")) < 0) {
log_error("_daemon_talk: message allocation failed");
return -ENOMEM;
}
@@ -550,7 +565,8 @@ failed:
/* Handle the event (de)registration call and return negative error codes. */
static int _do_event(int cmd, struct dm_event_daemon_message *msg,
const char *dso_name, const char *dev_name,
- enum dm_event_mask evmask, uint32_t timeout)
+ enum dm_event_mask evmask, uint32_t timeout,
+ const char *private)
{
int ret;
struct dm_event_fifos fifos;
@@ -560,14 +576,14 @@ static int _do_event(int cmd, struct dm_
return -ESRCH;
}
- ret = _daemon_talk(&fifos, msg, DM_EVENT_CMD_HELLO, 0, 0, 0, 0);
+ ret = _daemon_talk(&fifos, msg, DM_EVENT_CMD_HELLO, 0, 0, 0, 0, 0);
if (msg->data)
dm_free(msg->data);
msg->data = 0;
if (!ret)
- ret = _daemon_talk(&fifos, msg, cmd, dso_name, dev_name, evmask, timeout);
+ ret = _daemon_talk(&fifos, msg, cmd, dso_name, dev_name, evmask, timeout, private);
/* what is the opposite of init? */
_dtr_client(&fifos);
@@ -590,8 +606,8 @@ int dm_event_register_handler(const stru
uuid = dm_task_get_uuid(dmt);
- if ((err = _do_event(DM_EVENT_CMD_REGISTER_FOR_EVENT, &msg,
- dmevh->dso, uuid, dmevh->mask, dmevh->timeout)) < 0) {
+ if ((err = _do_event(DM_EVENT_CMD_REGISTER_FOR_EVENT, &msg, dmevh->dso,
+ uuid, dmevh->mask, dmevh->timeout, dmevh->private)) < 0) {
log_error("%s: event registration failed: %s",
dm_task_get_name(dmt),
msg.data ? msg.data : strerror(-err));
@@ -621,7 +637,7 @@ int dm_event_unregister_handler(const st
uuid = dm_task_get_uuid(dmt);
if ((err = _do_event(DM_EVENT_CMD_UNREGISTER_FOR_EVENT, &msg,
- dmevh->dso, uuid, dmevh->mask, dmevh->timeout)) < 0) {
+ dmevh->dso, uuid, dmevh->mask, dmevh->timeout, NULL)) < 0) {
log_error("%s: event deregistration failed: %s",
dm_task_get_name(dmt),
msg.data ? msg.data : strerror(-err));
@@ -695,8 +711,8 @@ int dm_event_get_registered_device(struc
uuid = dm_task_get_uuid(dmt);
if (!(ret = _do_event(next ? DM_EVENT_CMD_GET_NEXT_REGISTERED_DEVICE :
- DM_EVENT_CMD_GET_REGISTERED_DEVICE,
- &msg, dmevh->dso, uuid, dmevh->mask, 0))) {
+ DM_EVENT_CMD_GET_REGISTERED_DEVICE, &msg,
+ dmevh->dso, uuid, dmevh->mask, 0, dmevh->private))) {
/* FIXME this will probably horribly break if we get
ill-formatted reply */
ret = _parse_message(&msg, &reply_dso, &reply_uuid, &reply_mask);
@@ -788,7 +804,7 @@ int dm_event_set_timeout(const char *dev
return -ENODEV;
return _do_event(DM_EVENT_CMD_SET_TIMEOUT, &msg,
- NULL, device_path, 0, timeout);
+ NULL, device_path, 0, timeout, NULL);
}
int dm_event_get_timeout(const char *device_path, uint32_t *timeout)
@@ -799,7 +815,7 @@ int dm_event_get_timeout(const char *dev
if (!device_exists(device_path))
return -ENODEV;
if (!(ret = _do_event(DM_EVENT_CMD_GET_TIMEOUT, &msg, NULL, device_path,
- 0, 0))) {
+ 0, 0, NULL))) {
char *p = _skip_string(msg.data, ' ');
if (!p) {
log_error("malformed reply from dmeventd '%s'\n",
Index: LVM2.02.54-20090928/daemons/dmeventd/libdevmapper-event.h
===================================================================
--- LVM2.02.54-20090928.orig/daemons/dmeventd/libdevmapper-event.h
+++ LVM2.02.54-20090928/daemons/dmeventd/libdevmapper-event.h
@@ -72,6 +72,7 @@ int dm_event_handler_set_uuid(struct dm_
void dm_event_handler_set_major(struct dm_event_handler *dmevh, int major);
void dm_event_handler_set_minor(struct dm_event_handler *dmevh, int minor);
void dm_event_handler_set_timeout(struct dm_event_handler *dmevh, int timeout);
+int dm_event_handler_set_private(struct dm_event_handler *dmevh, const char *private);
/*
* Specify mask for events to monitor.
@@ -99,7 +100,8 @@ int dm_event_unregister_handler(const st
/* Prototypes for DSO interface, see dmeventd.c, struct dso_data for
detailed descriptions. */
void process_event(struct dm_task *dmt, enum dm_event_mask evmask, void **user);
-int register_device(const char *device_name, const char *uuid, int major, int minor, void **user);
+int register_device(const char *device_name, const char *uuid, int major,
+ int minor, void **user, void *user_data);
int unregister_device(const char *device_name, const char *uuid, int major,
int minor, void **user);
Index: LVM2.02.54-20090928/daemons/dmeventd/plugins/mirror/dmeventd_mirror.c
===================================================================
--- LVM2.02.54-20090928.orig/daemons/dmeventd/plugins/mirror/dmeventd_mirror.c
+++ LVM2.02.54-20090928/daemons/dmeventd/plugins/mirror/dmeventd_mirror.c
@@ -237,7 +237,8 @@ int register_device(const char *device,
const char *uuid __attribute((unused)),
int major __attribute((unused)),
int minor __attribute((unused)),
- void **unused __attribute((unused)))
+ void **priv_ptr __attribute((unused)),
+ void *priv_data __attribute((unused)))
{
int r = 0;
@@ -277,7 +278,7 @@ int unregister_device(const char *device
const char *uuid __attribute((unused)),
int major __attribute((unused)),
int minor __attribute((unused)),
- void **unused __attribute((unused)))
+ void **priv_ptr __attribute((unused)))
{
pthread_mutex_lock(&_register_mutex);
Index: LVM2.02.54-20090928/daemons/dmeventd/plugins/snapshot/dmeventd_snapshot.c
===================================================================
--- LVM2.02.54-20090928.orig/daemons/dmeventd/plugins/snapshot/dmeventd_snapshot.c
+++ LVM2.02.54-20090928/daemons/dmeventd/plugins/snapshot/dmeventd_snapshot.c
@@ -150,7 +150,8 @@ int register_device(const char *device,
const char *uuid __attribute((unused)),
int major __attribute((unused)),
int minor __attribute((unused)),
- void **private)
+ void **private,
+ void *unused __attribute((unused)))
{
int r = 0;
int *percent_warning = (int*)private;
Index: LVM2.02.54-20090928/lib/mirror/mirrored.c
===================================================================
--- LVM2.02.54-20090928.orig/lib/mirror/mirrored.c
+++ LVM2.02.54-20090928/lib/mirror/mirrored.c
@@ -27,6 +27,7 @@
#include "activate.h"
#include "sharedlib.h"
#include "str_list.h"
+#include "kdev_t.h"
#ifdef DMEVENTD
# include "libdevmapper-event.h"
@@ -421,7 +422,8 @@ static int _get_mirror_dso_path(struct c
static struct dm_event_handler *_create_dm_event_handler(const char *dmname,
const char *dso,
- enum dm_event_mask mask)
+ enum dm_event_mask mask,
+ const char *private)
{
struct dm_event_handler *dmevh;
@@ -435,6 +437,10 @@ static struct dm_event_handler *_create_
goto fail;
dm_event_handler_set_event_mask(dmevh, mask);
+
+ if (dm_event_handler_set_private(dmevh, private))
+ goto fail;
+
return dmevh;
fail:
@@ -460,7 +466,7 @@ static int _target_monitored(struct lv_s
if (!(name = build_dm_name(vg->cmd->mem, vg->name, lv->name, NULL)))
return_0;
- if (!(dmevh = _create_dm_event_handler(name, dso, DM_EVENT_ALL_ERRORS)))
+ if (!(dmevh = _create_dm_event_handler(name, dso, DM_EVENT_ALL_ERRORS, NULL)))
return_0;
if (dm_event_get_registered_device(dmevh, 0)) {
@@ -479,11 +485,63 @@ static int _target_monitored(struct lv_s
return evmask;
}
+/*
+ * create device list
+ *
+ * dev/sda,8:0;/dev/sdb,8:1;
+ *
+ */
+static char *build_device_list(struct dm_pool *mem, struct volume_group *vg,
+ struct logical_volume *lv)
+{
+ struct pv_list *pvl;
+ size_t len = 1, size;
+ char *devs;
+#define TMP_SIZE 256 /* FIXME: set max device name len */
+ char dummy[TMP_SIZE];
+
+
+ /* count lengths of device string */
+ dm_list_iterate_items(pvl, &vg->pvs) {
+ if (pvl->pv->status & MISSING_PV)
+ continue;
+
+ size = dm_snprintf(dummy, TMP_SIZE, "%s,%u:%u;",
+ pv_dev_name(pvl->pv),
+ (unsigned int)MAJOR(pv_dev(pvl->pv)->dev),
+ (unsigned int)MINOR(pv_dev(pvl->pv)->dev));
+ if (size < 0)
+ return NULL;
+
+ len += size;
+ }
+
+ devs = dm_pool_alloc(mem, len);
+ if (!devs)
+ return NULL;
+
+ memset(devs, 0, len);
+ len = 0;
+
+ /* create device lists like /dev/sda,8:0;/dev/sdb,8:1; */
+ dm_list_iterate_items(pvl, &vg->pvs) {
+ if (pvl->pv->status & MISSING_PV)
+ continue;
+ len += dm_snprintf(devs + len, TMP_SIZE, "%s,%u:%u;",
+ pv_dev_name(pvl->pv),
+ (unsigned int)MAJOR(pv_dev(pvl->pv)->dev),
+ (unsigned int)MINOR(pv_dev(pvl->pv)->dev));
+ }
+
+ return devs;
+#undef TMP_SIZE
+}
+
/* FIXME This gets run while suspended and performs banned operations. */
static int _target_set_events(struct lv_segment *seg,
int evmask __attribute((unused)), int set)
{
- char *dso, *name;
+ char *dso, *name, *devl;
struct logical_volume *lv;
struct volume_group *vg;
struct dm_event_handler *dmevh;
@@ -498,8 +556,14 @@ static int _target_set_events(struct lv_
if (!(name = build_dm_name(vg->cmd->mem, vg->name, lv->name, NULL)))
return_0;
- if (!(dmevh = _create_dm_event_handler(name, dso, DM_EVENT_ALL_ERRORS)))
+ if (!(devl = build_device_list(vg->cmd->mem, vg, lv)))
+ return_0;
+
+ if (!(dmevh = _create_dm_event_handler(name, dso, DM_EVENT_ALL_ERRORS,
+ devl))) {
+ dm_free(devl);
return_0;
+ }
r = set ? dm_event_register_handler(dmevh) : dm_event_unregister_handler(dmevh);
dm_event_handler_destroy(dmevh);
--
Takahiro Yasui
Hitachi Computer Products (America), Inc.
More information about the lvm-devel
mailing list