--- libmultipath/uevent.c | 17 ++++++++++++----- libmultipath/uevent.h | 4 +++- multipathd/main.c | 8 +++++--- 3 files changed, 20 insertions(+), 9 deletions(-) Index: multipath-tools-130222/libmultipath/uevent.c =================================================================== --- multipath-tools-130222.orig/libmultipath/uevent.c +++ multipath-tools-130222/libmultipath/uevent.c @@ -47,7 +47,6 @@ #include "list.h" #include "uevent.h" #include "vector.h" -#include "config.h" typedef int (uev_trigger)(struct uevent *, void * trigger_data); @@ -127,11 +126,14 @@ service_uevq(struct list_head *tmpq) static void uevq_stop(void *arg) { + struct udev *udev = arg; + condlog(3, "Stopping uev queue"); pthread_mutex_lock(uevq_lockp); my_uev_trigger = NULL; pthread_cond_signal(uev_condp); pthread_mutex_unlock(uevq_lockp); + udev_unref(udev); } void @@ -399,9 +401,9 @@ exit: return 1; } -int uevent_listen(void) +int uevent_listen(struct udev *udev) { - int err; + int err = 2; struct udev_monitor *monitor = NULL; int fd, socket_flags; int need_failback = 1; @@ -411,9 +413,14 @@ int uevent_listen(void) * thereby not getting to empty the socket's receive buffer queue * often enough. */ - pthread_cleanup_push(uevq_stop, NULL); + if (!udev) { + condlog(1, "no udev context"); + return 1; + } + udev_ref(udev); + pthread_cleanup_push(uevq_stop, udev); - monitor = udev_monitor_new_from_netlink(conf->udev, "udev"); + monitor = udev_monitor_new_from_netlink(udev, "udev"); if (!monitor) { condlog(2, "failed to create udev monitor"); goto out; Index: multipath-tools-130222/libmultipath/uevent.h =================================================================== --- multipath-tools-130222.orig/libmultipath/uevent.h +++ multipath-tools-130222/libmultipath/uevent.h @@ -13,6 +13,8 @@ #define NETLINK_KOBJECT_UEVENT 15 #endif +struct udev; + struct uevent { struct list_head node; struct udev_device *udev; @@ -27,7 +29,7 @@ struct uevent { int is_uevent_busy(void); void setup_thread_attr(pthread_attr_t *attr, size_t stacksize, int detached); -int uevent_listen(void); +int uevent_listen(struct udev *udev); int uevent_dispatch(int (*store_uev)(struct uevent *, void * trigger_data), void * trigger_data); int uevent_get_major(struct uevent *uev); Index: multipath-tools-130222/multipathd/main.c =================================================================== --- multipath-tools-130222.orig/multipathd/main.c +++ multipath-tools-130222/multipathd/main.c @@ -840,7 +840,7 @@ out: static void * ueventloop (void * ap) { - if (uevent_listen()) + if (uevent_listen(udev)) condlog(0, "error starting uevent listener"); return NULL; @@ -1593,7 +1593,7 @@ static int child (void * param) { pthread_t check_thr, uevent_thr, uxlsnr_thr, uevq_thr; - pthread_attr_t log_attr, misc_attr; + pthread_attr_t log_attr, misc_attr, uevent_attr; struct vectors * vecs; struct multipath * mpp; int i; @@ -1606,6 +1606,7 @@ child (void * param) udev = udev_new(); setup_thread_attr(&misc_attr, 64 * 1024, 1); + setup_thread_attr(&uevent_attr, 128 * 1024, 1); setup_thread_attr(&waiter_attr, 32 * 1024, 1); if (logsink) { @@ -1671,10 +1672,11 @@ child (void * param) /* * Start uevent listener early to catch events */ - if ((rc = pthread_create(&uevent_thr, &misc_attr, ueventloop, vecs))) { + if ((rc = pthread_create(&uevent_thr, &uevent_attr, ueventloop, udev))) { condlog(0, "failed to create uevent thread: %d", rc); exit(1); } + pthread_attr_destroy(&uevent_attr); if ((rc = pthread_create(&uxlsnr_thr, &misc_attr, uxlsnrloop, vecs))) { condlog(0, "failed to create cli listener: %d", rc); exit(1);