All of lore.kernel.org
 help / color / mirror / Atom feed
From: Zdenek Kabelac <zkabelac@redhat.com>
To: device-mapper development <dm-devel@redhat.com>
Cc: Christophe Varoqui <christophe.varoqui@gmail.com>
Subject: Re: [PATCH] multipath: enable getting uevents through libudev
Date: Wed, 04 Apr 2012 13:12:45 +0200	[thread overview]
Message-ID: <4F7C2CAD.5060905@redhat.com> (raw)
In-Reply-To: <20120403234221.GM1241@ether.msp.redhat.com>

Dne 4.4.2012 01:42, Benjamin Marzinski napsal(a):
> udev is removing support for RUN+="socket:..." rules. For now, I've kept
> all the existing uevent code, but I've added a new method for getting the
> uevent information using libudev that will be tried first.
>
> Signed-off-by: Benjamin Marzinski<bmarzins@redhat.com>
> ---
>   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,

I'd recommend to validate all input going from libudev agains NULL pointers:

(i.e. look at https://bugzilla.redhat.com/show_bug.cgi?id=809576)

Zdenek

  reply	other threads:[~2012-04-04 11:12 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-04-03 23:42 [PATCH] multipath: enable getting uevents through libudev Benjamin Marzinski
2012-04-04 11:12 ` Zdenek Kabelac [this message]
2012-04-09 20:18   ` Benjamin Marzinski

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=4F7C2CAD.5060905@redhat.com \
    --to=zkabelac@redhat.com \
    --cc=christophe.varoqui@gmail.com \
    --cc=dm-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.