File multipath-tools-start-waitevent-checker of Package multipath-tools

commit 87c1022e90d55b76fa6f13fd6f90e1a59c8130f3
Author: Hannes Reinecke <hare@suse.de>
Date:   Mon Feb 9 14:04:25 2009 +0100

    multipathd is not starting waitevent checker for single paths
    
    After multipathd was started, any SCSI disks that would be added afterwards
    would not trigger multipathd to create a waitevent thread.
    
    The waitevent thread listens for kernel's offline/online events and thoroughly
    checks what the kernel sees with what multipathd thinks and if something is
    off,
    whacks multipathd to the right state.
    
    For devices which did not have a kernel device mapper helper (hp_sw, rdac,
    etc) and only have one single path, when the link experiences a momentary blib
    with I/O on it the path would be marked as failed _only_ by the kernel. This
    event
    would _not_ be propagated to multipathd (b/c it did not have a waitevent thread
    create). Multipathd would only do the path checker which would provide a
    PATH_UP event (rightly so - as the path would only be down for a second or so).
    However, the device mapper path group would be marked as failed, and any
    incoming I/O would be blocked (if queue_if_no_path was set) or fail.
    
    The end result was the multipathd would think everything was peachy while the
    kernel would be failing (or queueing) the I/O to the multipath device.
    
    References: bnc#473841
    
    Signed-off-by: Hannes Reinecke <hare@suse.de>

diff --git a/multipathd/main.c b/multipathd/main.c
index 7b46f2d..71acc05 100644
--- a/multipathd/main.c
+++ b/multipathd/main.c
@@ -339,6 +339,7 @@ ev_add_path (char * devname, struct vectors * vecs)
 	struct path * pp;
 	char empty_buff[WWID_SIZE] = {0};
 	char params[PARAMS_SIZE] = {0};
+	int start_waiter = 0;
 
 	pp = find_path_by_dev(vecs->pathvec, devname);
 
@@ -387,8 +388,14 @@ rescan:
 	}
 	else {
 		condlog(4,"%s: creating new map", pp->dev);
-		if ((mpp = add_map_with_path(vecs, pp, 1)))
+		if ((mpp = add_map_with_path(vecs, pp, 1))) {
 			mpp->action = ACT_CREATE;
+			/*
+			 * We don't depend on ACT_CREATE, as domap will
+			 * set it to ACT_NOTHING when complete.
+			 */
+			start_waiter = 1;
+		}
 		else
 			return 1; /* leave path added to pathvec */
 	}
@@ -429,7 +436,8 @@ rescan:
 
 	sync_map_state(mpp);
 
-	if (mpp->action == ACT_CREATE &&
+	if ((mpp->action == ACT_CREATE ||
+	     (mpp->action == ACT_NOTHING && start_waiter && !mpp->waiter)) &&
 	    start_waiter_thread(mpp, vecs))
 			goto out;
 
openSUSE Build Service is sponsored by