[device-mapper-multipath/f17] device-mapper-multipath-0.4.9-23 Add 0024-RH-libudev-monitor.patch Resolves: BZ #805493

Benjamin Marzinski bmarzins at fedoraproject.org
Mon Apr 30 22:38:48 UTC 2012


commit c0b04511d54b03c01ebd1c27b645790ecadd1973
Author: Benjamin Marzinski <bmarzins at redhat.com>
Date:   Mon Apr 30 11:42:27 2012 -0500

    device-mapper-multipath-0.4.9-23
    Add 0024-RH-libudev-monitor.patch
    Resolves: BZ #805493

 0024-RH-libudev-monitor.patch |  205 +++++++++++++++++++++++++++++++++++++++++
 device-mapper-multipath.spec  |    7 +-
 2 files changed, 211 insertions(+), 1 deletions(-)
---
diff --git a/0024-RH-libudev-monitor.patch b/0024-RH-libudev-monitor.patch
new file mode 100644
index 0000000..b092779
--- /dev/null
+++ b/0024-RH-libudev-monitor.patch
@@ -0,0 +1,205 @@
+---
+ libmultipath/Makefile |    2 
+ libmultipath/uevent.c |  151 ++++++++++++++++++++++++++++++++++++++++++++------
+ 2 files changed, 134 insertions(+), 19 deletions(-)
+
+Index: multipath-tools-120123/libmultipath/Makefile
+===================================================================
+--- multipath-tools-120123.orig/libmultipath/Makefile
++++ multipath-tools-120123/libmultipath/Makefile
+@@ -7,7 +7,7 @@ include ../Makefile.inc
+ SONAME=0
+ DEVLIB = libmultipath.so
+ LIBS = $(DEVLIB).$(SONAME)
+-LIBDEPS = -lpthread -ldl -ldevmapper
++LIBDEPS = -lpthread -ldl -ldevmapper -ludev
+ 
+ OBJS = memory.o parser.o vector.o devmapper.o callout.o \
+        hwtable.o blacklist.o util.o dmparser.o config.o \
+Index: multipath-tools-120123/libmultipath/uevent.c
+===================================================================
+--- multipath-tools-120123.orig/libmultipath/uevent.c
++++ multipath-tools-120123/libmultipath/uevent.c
+@@ -39,6 +39,7 @@
+ #include <pthread.h>
+ #include <limits.h>
+ #include <sys/mman.h>
++#include <libudev.h>
+ #include <errno.h>
+ 
+ #include "memory.h"
+@@ -161,7 +162,7 @@ int uevent_dispatch(int (*uev_trigger)(s
+ 	return 0;
+ }
+ 
+-int uevent_listen(void)
++int failback_listen(void)
+ {
+ 	int sock;
+ 	struct sockaddr_nl snl;
+@@ -173,20 +174,6 @@ int uevent_listen(void)
+ 	int rcvszsz = sizeof(rcvsz);
+ 	unsigned int *prcvszsz = (unsigned int *)&rcvszsz;
+ 	const int feature_on = 1;
+-
+-	/*
+-	 * Queue uevents for service by dedicated thread so that the uevent
+-	 * listening thread does not block on multipathd locks (vecs->lock)
+-	 * thereby not getting to empty the socket's receive buffer queue
+-	 * often enough.
+-	 */
+-	INIT_LIST_HEAD(&uevq);
+-
+-	pthread_mutex_init(uevq_lockp, NULL);
+-	pthread_cond_init(uev_condp, NULL);
+-
+-	pthread_cleanup_push(uevq_stop, NULL);
+-
+ 	/*
+ 	 * First check whether we have a udev socket
+ 	 */
+@@ -382,13 +369,141 @@ int uevent_listen(void)
+ 
+ exit:
+ 	close(sock);
++	return 1;
++}
+ 
+-	pthread_cleanup_pop(1);
++int uevent_listen(void)
++{
++	int err;
++	struct udev *udev = NULL;
++	struct udev_monitor *monitor = NULL;
++	int fd, socket_flags;
++	int need_failback = 0;
++	/*
++	 * Queue uevents for service by dedicated thread so that the uevent
++	 * listening thread does not block on multipathd locks (vecs->lock)
++	 * thereby not getting to empty the socket's receive buffer queue
++	 * often enough.
++	 */
++	INIT_LIST_HEAD(&uevq);
++
++	pthread_mutex_init(uevq_lockp, NULL);
++	pthread_cond_init(uev_condp, NULL);
++	pthread_cleanup_push(uevq_stop, NULL);
++
++	udev = udev_new();
++	if (!udev) {
++		condlog(2, "failed to create udev context");
++		need_failback = 1;
++		goto out;
++	}
++	monitor = udev_monitor_new_from_netlink(udev, "udev");
++	if (!monitor) {
++		condlog(2, "failed to create udev monitor");
++		need_failback = 1;
++		goto out;
++	}
++	if (udev_monitor_set_receive_buffer_size(monitor, 128 * 1024 * 1024))
++		condlog(2, "failed to increase buffer size");
++	fd = udev_monitor_get_fd(monitor);
++	socket_flags = fcntl(fd, F_GETFL);
++	if (socket_flags < 0) {
++		condlog(2, "failed to get monitor socket flags : %s",
++			strerror(errno));
++		need_failback = 1;
++		goto out;
++	}
++	if (fcntl(fd, F_SETFL, socket_flags & ~O_NONBLOCK) < 0) {
++		condlog(2, "failed to set monitor socket flags : %s",
++			strerror(errno));
++		need_failback = 1;
++		goto out;
++	}
++	err = udev_monitor_filter_add_match_subsystem_devtype(monitor, "block",
++							      NULL);
++	if (err)
++		condlog(2, "failed to create filter : %s\n", strerror(-err));
++	err = udev_monitor_enable_receiving(monitor);
++	if (err) {
++		condlog(2, "failed to enable receiving : %s\n", strerror(-err));
++		need_failback = 1;
++		goto out;
++	}
++	while (1) {
++		int i = 0;
++		char *pos, *end;
++		struct uevent *uev;
++		struct udev_device *dev;
++                struct udev_list_entry *list_entry;
++
++		dev = udev_monitor_receive_device(monitor);
++		if (!dev) {
++			condlog(0, "failed getting udev device");
++			continue;
++		}
+ 
++		uev = alloc_uevent();
++		if (!uev) {
++			condlog(1, "lost uevent, oom");
++			continue;
++		}
++		pos = uev->buffer;
++		end = pos + HOTPLUG_BUFFER_SIZE + OBJECT_SIZE - 1;
++		udev_list_entry_foreach(list_entry, udev_device_get_properties_list_entry(dev)) {
++			const char *name, *value;
++			int bytes;
++
++			name = udev_list_entry_get_name(list_entry);
++			value = udev_list_entry_get_value(list_entry);
++			bytes = snprintf(pos, end - pos, "%s=%s", name,
++					value);
++			if (pos + bytes >= end) {
++				condlog(2, "buffer overflow for uevent");
++				break;
++			}
++			uev->envp[i] = pos;
++			pos += bytes;
++			*pos = '\0';
++			pos++;
++			if (strcmp(name, "DEVPATH") == 0)
++				uev->devpath = uev->envp[i] + 8;
++			if (strcmp(name, "ACTION") == 0)
++				uev->action = uev->envp[i] + 7;
++			i++;
++			if (i == HOTPLUG_NUM_ENVP - 1)
++				break;
++		}
++		udev_device_unref(dev);
++		uev->envp[i] = NULL;
++
++		condlog(3, "uevent '%s' from '%s'", uev->action, uev->devpath);
++		uev->kernel = strrchr(uev->devpath, '/');
++		if (uev->kernel)
++			uev->kernel++;
++
++		/* print payload environment */
++		for (i = 0; uev->envp[i] != NULL; i++)
++			condlog(5, "%s", uev->envp[i]);
++
++		/*
++ 		 * Queue uevent and poke service pthread.
++ 		 */
++		pthread_mutex_lock(uevq_lockp);
++		list_add_tail(&uev->node, &uevq);
++		pthread_cond_signal(uev_condp);
++		pthread_mutex_unlock(uevq_lockp);
++	}
++out:
++	if (monitor)
++		udev_monitor_unref(monitor);
++	if (udev)
++		udev_unref(udev);
++	if (need_failback)
++		err = failback_listen();
++	pthread_cleanup_pop(1);
+ 	pthread_mutex_destroy(uevq_lockp);
+ 	pthread_cond_destroy(uev_condp);
+-
+-	return 1;
++	return err;
+ }
+ 
+ extern int
diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec
index 59570ef..e7817cf 100644
--- a/device-mapper-multipath.spec
+++ b/device-mapper-multipath.spec
@@ -1,7 +1,7 @@
 Summary: Tools to manage multipath devices using device-mapper
 Name: device-mapper-multipath
 Version: 0.4.9
-Release: 22%{?dist}
+Release: 23%{?dist}
 License: GPL+
 Group: System Environment/Base
 URL: http://christophe.varoqui.free.fr/
@@ -31,6 +31,7 @@ Patch0020: 0020-RH-dont-remove-map-twice.patch
 Patch0021: 0021-RH-validate-guid-partitions.patch
 Patch0022: 0022-RH-adjust-messages.patch
 Patch0023: 0023-RH-manpage-update.patch
+Patch0024: 0024-RH-libudev-monitor.patch
 
 # runtime
 Requires: %{name}-libs = %{version}-%{release}
@@ -106,6 +107,7 @@ kpartx manages partition creation and removal for device-mapper devices.
 %patch0021 -p1
 %patch0022 -p1
 %patch0023 -p1
+%patch0024 -p1
 cp %{SOURCE1} .
 
 %build
@@ -196,6 +198,9 @@ bin/systemctl --no-reload enable multipathd.service >/dev/null 2>&1 ||:
 %{_mandir}/man8/kpartx.8.gz
 
 %changelog
+* Mon Apr 30 2012 Benjamin Marzinski <bmarzins at redhat.com> 0.4.9-23
+- Add 0024-RH-libudev-monitor.patch
+
 * Fri Feb 10 2012 Benjamin Marzinski <bmarzins at redhat.com> 0.4.9-22
 - Add 0012-RH-update-on-show-topology.patch
 - Add 0013-RH-manpage-update.patch


More information about the scm-commits mailing list