All of lore.kernel.org
 help / color / mirror / Atom feed
From: Takahiro Yasui <tyasui@redhat.com>
To: lvm-devel@redhat.com
Subject: [RFC][PATCH 2/5] add device list registering interface
Date: Tue, 29 Sep 2009 20:28:12 -0400	[thread overview]
Message-ID: <4AC2A61C.6090301@redhat.com> (raw)

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@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.



                 reply	other threads:[~2009-09-30  0:28 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4AC2A61C.6090301@redhat.com \
    --to=tyasui@redhat.com \
    --cc=lvm-devel@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.