Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Evergreen:11.1
multipath-tools
multipath-tools-update-uevent-list-handling
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File multipath-tools-update-uevent-list-handling of Package multipath-tools
From e3d7fba40c566321078442bd63bd8c320d034198 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke <hare@suse.de> Date: Tue, 10 Mar 2009 08:54:40 +0100 Subject: [PATCH] Update uevent list handling list_for_each_safe() is safe against removal, but not addition. So we might run into a list corruption if an event is added when service_uevent() runs. Better approach is to use list_splice_init() here and process the then private list. Plus we reduce lock contention. Signed-off-by: Hannes Reinecke <hare@suse.de> --- libmultipath/uevent.c | 23 ++++++++++++++++------- 1 files changed, 16 insertions(+), 7 deletions(-) diff --git a/libmultipath/uevent.c b/libmultipath/uevent.c index 9bbc317..d832068 100644 --- a/libmultipath/uevent.c +++ b/libmultipath/uevent.c @@ -55,26 +55,29 @@ static void * my_trigger_data; struct uevent * alloc_uevent (void) { - return (struct uevent *)MALLOC(sizeof(struct uevent)); + struct uevent *uev = MALLOC(sizeof(struct uevent)); + + if (uev) + INIT_LIST_HEAD(&uev->node); + + return uev; } /* * Called with uevq_lockp held */ void -service_uevq(void) +service_uevq(struct list_head *tmpq) { struct uevent *uev, *tmp; - list_for_each_entry_safe(uev, tmp, &uevq, node) { + list_for_each_entry_safe(uev, tmp, tmpq, node) { list_del_init(&uev->node); - pthread_mutex_unlock(uevq_lockp); if (my_uev_trigger && my_uev_trigger(uev, my_trigger_data)) condlog(0, "uevent trigger error"); FREE(uev); - pthread_mutex_lock(uevq_lockp); } } @@ -84,9 +87,12 @@ service_uevq(void) static void * uevq_thread(void * et) { + mlockall(MCL_CURRENT | MCL_FUTURE); while (1) { + LIST_HEAD(uevq_tmp); + pthread_mutex_lock(uevq_lockp); /* * Condition signals are unreliable, @@ -95,8 +101,9 @@ uevq_thread(void * et) if (list_empty(&uevq)) { pthread_cond_wait(uev_condp, uevq_lockp); } - service_uevq(); + list_splice_init(&uevq, &uevq_tmp); pthread_mutex_unlock(uevq_lockp); + service_uevq(&uevq_tmp); } } @@ -235,8 +242,10 @@ int uevent_listen(int (*uev_trigger)(struct uevent *, void * trigger_data), continue; } - if ((size_t)buflen > sizeof(buff)-1) + if ((size_t)buflen > sizeof(buff)-1) { + condlog(2, "buffer overflow for received uevent"); buflen = sizeof(buff)-1; + } uev = alloc_uevent(); -- 1.6.0.2
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor