/*
* Service the uevent queue.
*/
-static void *
-uevq_thread(void * et)
+int uevent_dispatch(int (*uev_trigger)(struct uevent *, void * trigger_data),
+ void * trigger_data)
{
+ my_uev_trigger = uev_trigger;
+ my_trigger_data = trigger_data;
+
mlockall(MCL_CURRENT | MCL_FUTURE);
while (1) {
break;
service_uevq(&uevq_tmp);
}
- return NULL;
+ condlog(3, "Terminating uev service queue");
+ return 0;
}
-int uevent_listen(int (*uev_trigger)(struct uevent *, void * trigger_data),
- void * trigger_data)
+int uevent_listen(void)
{
int sock;
struct sockaddr_nl snl;
int rcvsz = 0;
int rcvszsz = sizeof(rcvsz);
unsigned int *prcvszsz = (unsigned int *)&rcvszsz;
- pthread_attr_t attr;
const int feature_on = 1;
- my_uev_trigger = uev_trigger;
- my_trigger_data = trigger_data;
-
/*
* Queue uevents for service by dedicated thread so that the uevent
* listening thread does not block on multipathd locks (vecs->lock)
pthread_cond_init(uev_condp, NULL);
pthread_cleanup_push(uevq_stop, NULL);
- setup_thread_attr(&attr, 64 * 1024, 0);
- pthread_create(&uevq_thr, &attr, uevq_thread, NULL);
/*
* First check whether we have a udev socket
block_signal(SIGUSR1, NULL);
block_signal(SIGHUP, NULL);
- if (uevent_listen(&uev_trigger, ap))
- fprintf(stderr, "error starting uevent listener");
+ if (uevent_listen())
+ condlog(0, "error starting uevent listener");
return NULL;
}
static void *
+uevqloop (void * ap)
+{
+ block_signal(SIGUSR1, NULL);
+ block_signal(SIGHUP, NULL);
+
+ if (uevent_dispatch(&uev_trigger, ap))
+ condlog(0, "error starting uevent dispatcher");
+
+ return NULL;
+}
+static void *
uxlsnrloop (void * ap)
{
block_signal(SIGUSR1, NULL);
static int
child (void * param)
{
- pthread_t check_thr, uevent_thr, uxlsnr_thr;
+ pthread_t check_thr, uevent_thr, uxlsnr_thr, uevq_thr;
pthread_attr_t log_attr, misc_attr;
struct vectors * vecs;
struct multipath * mpp;
int i;
+ int rc;
mlockall(MCL_CURRENT | MCL_FUTURE);
conf->daemon = 1;
udev_set_sync_support(0);
/*
+ * Start uevent listener early to catch events
+ */
+ if ((rc = pthread_create(&uevent_thr, &misc_attr, ueventloop, vecs))) {
+ condlog(0, "failed to create uevent thread: %d", rc);
+ exit(1);
+ }
+ /*
* fetch and configure both paths and multipaths
*/
+ lock(vecs->lock);
if (configure(vecs, 1)) {
+ unlock(vecs->lock);
condlog(0, "failure during configuration");
exit(1);
}
+ unlock(vecs->lock);
+
/*
* start threads
*/
- pthread_create(&check_thr, &misc_attr, checkerloop, vecs);
- pthread_create(&uevent_thr, &misc_attr, ueventloop, vecs);
- pthread_create(&uxlsnr_thr, &misc_attr, uxlsnrloop, vecs);
+ if ((rc = pthread_create(&check_thr, &misc_attr, checkerloop, vecs))) {
+ condlog(0,"failed to create checker loop thread: %d", rc);
+ exit(1);
+ }
+ if ((rc = pthread_create(&uxlsnr_thr, &misc_attr, uxlsnrloop, vecs))) {
+ condlog(0, "failed to create cli listener: %d", rc);
+ exit(1);
+ }
+ if ((rc = pthread_create(&uevq_thr, &misc_attr, uevqloop, vecs))) {
+ condlog(0, "failed to create uevent dispatcher: %d", rc);
+ exit(1);
+ }
pthread_attr_destroy(&misc_attr);
pthread_mutex_lock(&exit_mutex);
pthread_cancel(check_thr);
pthread_cancel(uevent_thr);
pthread_cancel(uxlsnr_thr);
+ pthread_cancel(uevq_thr);
sysfs_cleanup();