[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[dm-devel] dm-multipath: nr_active fix



There is some weirdness in the nr_active handling in multipathd, For instance,
whenever you change state to a PATH_DOWN or PATH_SHAKY state, you decrement
the number of active paths, even if you change from PATH_DOWN to PATH_SHAKY.

The attached patch attempts to fix the problem.  It slightly changes how some
of the states are handled.

-Ben
diff -urpN mp-devel-clean/libmultipath/structs_vec.c mp-devel-patched/libmultipath/structs_vec.c
--- mp-devel-clean/libmultipath/structs_vec.c	2006-02-13 11:53:36.000000000 -0600
+++ mp-devel-patched/libmultipath/structs_vec.c	2006-02-16 19:14:18.000000000 -0600
@@ -214,7 +214,7 @@ extern void
 set_no_path_retry(struct multipath *mpp)
 {
 	mpp->retry_tick = 0;
-	mpp->nr_active = pathcount(mpp, PATH_UP);
+	mpp->nr_active = pathcount(mpp, PATH_UP) + pathcount(mpp, PATH_GHOST);
 	select_no_path_retry(mpp);
 
 	switch (mpp->no_path_retry) {
diff -urpN mp-devel-clean/multipathd/main.c mp-devel-patched/multipathd/main.c
--- mp-devel-clean/multipathd/main.c	2006-02-16 12:17:19.000000000 -0600
+++ mp-devel-patched/multipathd/main.c	2006-02-16 19:14:40.000000000 -0600
@@ -282,10 +282,13 @@ update_multipath (struct vectors *vecs, 
 				continue;
 
 			if (pp->state != PATH_DOWN) {
+				int oldstate = pp->state;
 				condlog(2, "%s: mark as failed", pp->dev_t);
 				mpp->stat_path_failures++;
 				pp->state = PATH_DOWN;
-				update_queue_mode_del_path(mpp);
+				if (oldstate == PATH_UP ||
+				    oldstate == PATH_GHOST)
+					update_queue_mode_del_path(mpp);
 
 				/*
 				 * if opportune,
@@ -1032,7 +1035,7 @@ exit_daemon (int status)
 }
 
 static void
-fail_path (struct path * pp)
+fail_path (struct path * pp, int del_active)
 {
 	if (!pp->mpp)
 		return;
@@ -1041,14 +1044,15 @@ fail_path (struct path * pp)
 		 pp->dev_t, pp->mpp->alias);
 
 	dm_fail_path(pp->mpp->alias, pp->dev_t);
-	update_queue_mode_del_path(pp->mpp);
+	if (del_active)
+		update_queue_mode_del_path(pp->mpp);
 }
 
 /*
  * caller must have locked the path list before calling that function
  */
 static void
-reinstate_path (struct path * pp)
+reinstate_path (struct path * pp, int add_active)
 {
 	if (!pp->mpp)
 		return;
@@ -1057,7 +1061,8 @@ reinstate_path (struct path * pp)
 		condlog(0, "%s: reinstate failed", pp->dev_t);
 	else {
 		condlog(2, "%s: reinstated", pp->dev_t);
-		update_queue_mode_add_path(pp->mpp);
+		if (add_active)
+			update_queue_mode_add_path(pp->mpp);
 	}
 }
 
@@ -1191,6 +1196,7 @@ checkerloop (void *ap)
 			}
 
 			if (newstate != pp->state) {
+				int oldstate = pp->state;
 				pp->state = newstate;
 				LOG_MSG(1, checker_message(&pp->checker));
 
@@ -1207,7 +1213,11 @@ checkerloop (void *ap)
 					/*
 					 * proactively fail path in the DM
 					 */
-					fail_path(pp);
+					if (oldstate == PATH_UP ||
+					    oldstate == PATH_GHOST)
+						fail_path(pp, 1);
+					else
+						fail_path(pp, 0);
 
 					/*
 					 * cancel scheduled failback
@@ -1221,7 +1231,11 @@ checkerloop (void *ap)
 				/*
 				 * reinstate this path
 				 */
-				reinstate_path(pp);
+				if (oldstate != PATH_UP &&
+				    oldstate != PATH_GHOST)
+					reinstate_path(pp, 1);
+				else
+					reinstate_path(pp, 0);
 
 				/*
 				 * schedule [defered] failback

[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]