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.
-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(mo nitor, "block",
+ NULL);
+ if (err)
+ condlog(2, "failed to create filter : %s
", strerror(-err));
+ err = udev_monitor_enable_receiving(monitor);
+ if (err) {
+ condlog(2, "failed to enable receiving : %s
", 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;
+ }
--
dm-devel mailing list
dm-devel@redhat.com
https://www.redhat.com/mailman/listinfo/dm-devel
04-16-2012, 06:44 AM
Hannes Reinecke
multipath: enable getting uevents through libudev
On 04/10/2012 06:01 AM, Benjamin Marzinski wrote:
> 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.
>
> This version includes more error checking.
>
Thanks for this. Based on this I did a patchset for replacing the
hand-crafted sysfs code in multipath with calls to libudev.
Will be sending out the patches soon.
(Just as a heads up. so as to spare you some effort :-)
Cheers,
Hannes
--
Dr. Hannes Reinecke zSeries & Storage
hare@suse.de +49 911 74053 688
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: J. Hawn, J. Guild, F. Imendörffer, HRB 16746 (AG Nürnberg)
--
dm-devel mailing list
dm-devel@redhat.com
https://www.redhat.com/mailman/listinfo/dm-devel