Blame SOURCES/0256-RHBZ-1672175-retry-no-fd-paths.patch

4ae388
---
4ae388
 libmultipath/discovery.c   |   10 ++++++--
4ae388
 libmultipath/structs.h     |    1 
4ae388
 libmultipath/structs_vec.c |    4 ++-
4ae388
 multipathd/main.c          |   52 ++++++++++++++++++++++++++++++++-------------
4ae388
 4 files changed, 49 insertions(+), 18 deletions(-)
4ae388
4ae388
Index: multipath-tools-130222/libmultipath/discovery.c
4ae388
===================================================================
4ae388
--- multipath-tools-130222.orig/libmultipath/discovery.c
4ae388
+++ multipath-tools-130222/libmultipath/discovery.c
4ae388
@@ -1425,10 +1425,13 @@ pathinfo (struct path *pp, vector hwtabl
4ae388
 		pp->fd = open(udev_device_get_devnode(pp->udev), O_RDONLY);
4ae388
 
4ae388
 	if (pp->fd < 0) {
4ae388
+		pp->missing_udev_info = INFO_REINIT;
4ae388
 		condlog(4, "Couldn't open node for %s: %s",
4ae388
 			pp->dev, strerror(errno));
4ae388
 		goto blank;
4ae388
 	}
4ae388
+	if (pp->missing_udev_info == INFO_REINIT)
4ae388
+		pp->missing_udev_info = INFO_OK;
4ae388
 
4ae388
 	if (mask & DI_SERIAL)
4ae388
 		get_geometry(pp);
4ae388
@@ -1443,8 +1446,11 @@ pathinfo (struct path *pp, vector hwtabl
4ae388
 
4ae388
 	if (mask & DI_CHECKER) {
4ae388
 		if (path_state == PATH_UP) {
4ae388
-			pp->chkrstate = pp->state = get_state(pp, 0,
4ae388
-							      path_state);
4ae388
+			int newstate = get_state(pp, 0, path_state);
4ae388
+			if (newstate != PATH_PENDING ||
4ae388
+			    pp->state == PATH_UNCHECKED ||
4ae388
+			    pp->state == PATH_WILD)
4ae388
+				pp->chkrstate = pp->state = newstate;
4ae388
 			if (pp->state == PATH_UNCHECKED ||
4ae388
 			    pp->state == PATH_WILD)
4ae388
 				goto blank;
4ae388
Index: multipath-tools-130222/libmultipath/structs.h
4ae388
===================================================================
4ae388
--- multipath-tools-130222.orig/libmultipath/structs.h
4ae388
+++ multipath-tools-130222/libmultipath/structs.h
4ae388
@@ -184,6 +184,7 @@ enum marginal_path_states {
4ae388
 
4ae388
 enum missing_udev_info_states {
4ae388
 	INFO_OK,
4ae388
+	INFO_REINIT,
4ae388
 	INFO_MISSING,
4ae388
 	INFO_REQUESTED,
4ae388
 };
4ae388
Index: multipath-tools-130222/multipathd/main.c
4ae388
===================================================================
4ae388
--- multipath-tools-130222.orig/multipathd/main.c
4ae388
+++ multipath-tools-130222/multipathd/main.c
4ae388
@@ -1381,7 +1381,7 @@ int update_path_groups(struct multipath
4ae388
 	return 0;
4ae388
 }
4ae388
 
4ae388
-void
4ae388
+int
4ae388
 check_path (struct vectors * vecs, struct path * pp)
4ae388
 {
4ae388
 	int newstate;
4ae388
@@ -1390,19 +1390,20 @@ check_path (struct vectors * vecs, struc
4ae388
 	int disable_reinstate = 0;
4ae388
 	int oldchkrstate = pp->chkrstate;
4ae388
 
4ae388
-	if (!pp->mpp && (pp->missing_udev_info != INFO_MISSING ||
4ae388
-			 pp->retriggers >= conf->retrigger_tries))
4ae388
-		return;
4ae388
+	if (!pp->mpp && pp->missing_udev_info != INFO_REINIT &&
4ae388
+	    (pp->missing_udev_info != INFO_MISSING ||
4ae388
+	     pp->retriggers >= conf->retrigger_tries))
4ae388
+		return 0;
4ae388
 
4ae388
 	if (pp->tick && --pp->tick)
4ae388
-		return; /* don't check this path yet */
4ae388
+		return 0; /* don't check this path yet */
4ae388
 
4ae388
-	if (!pp->mpp) {
4ae388
+	if (!pp->mpp && pp->missing_udev_info == INFO_MISSING) {
4ae388
 		pp->missing_udev_info = INFO_REQUESTED;
4ae388
 		pp->retriggers++;
4ae388
 		sysfs_attr_set_value(pp->udev, "uevent", "change",
4ae388
 				     strlen("change"));
4ae388
-		return;
4ae388
+		return 0;
4ae388
 	}
4ae388
 
4ae388
 	/*
4ae388
@@ -1412,6 +1413,21 @@ check_path (struct vectors * vecs, struc
4ae388
 	pp->tick = conf->checkint;
4ae388
 
4ae388
 	newstate = path_offline(pp);
4ae388
+	if (!pp->mpp) {
4ae388
+		if (newstate == PATH_UP &&
4ae388
+		    pp->missing_udev_info == INFO_REINIT) {
4ae388
+			int ret;
4ae388
+			condlog(3, "%s: add missing path", pp->dev);
4ae388
+			ret = pathinfo(pp, conf->hwtable,
4ae388
+				       DI_ALL | DI_BLACKLIST);
4ae388
+			if (ret == PATHINFO_OK && strlen(pp->wwid)) {
4ae388
+				ev_add_path(pp, vecs);
4ae388
+				pp->tick = 1;
4ae388
+			} else if (ret == PATHINFO_SKIPPED)
4ae388
+				return -1;
4ae388
+		}
4ae388
+		return 0;
4ae388
+	}
4ae388
 	if (newstate == PATH_UP)
4ae388
 		newstate = get_state(pp, 1, newstate);
4ae388
 	else
4ae388
@@ -1426,7 +1442,7 @@ check_path (struct vectors * vecs, struc
4ae388
 	if (newstate == PATH_WILD || newstate == PATH_UNCHECKED) {
4ae388
 		condlog(2, "%s: unusable path", pp->dev);
4ae388
 		pathinfo(pp, conf->hwtable, 0);
4ae388
-		return;
4ae388
+		return 0;
4ae388
 	}
4ae388
 	/*
4ae388
 	 * Async IO in flight. Keep the previous path state
4ae388
@@ -1434,7 +1450,7 @@ check_path (struct vectors * vecs, struc
4ae388
 	 */
4ae388
 	if (newstate == PATH_PENDING) {
4ae388
 		pp->tick = 1;
4ae388
-		return;
4ae388
+		return 0;
4ae388
 	}
4ae388
 	/*
4ae388
 	 * Synchronize with kernel state
4ae388
@@ -1446,7 +1462,7 @@ check_path (struct vectors * vecs, struc
4ae388
 	}
4ae388
 	/* if update_multipath_strings orphaned the path, quit early */
4ae388
 	if (!pp->mpp)
4ae388
-		return;
4ae388
+		return 0;
4ae388
 
4ae388
 	if ((newstate == PATH_UP || newstate == PATH_GHOST) &&
4ae388
 	    pp->io_err_disable_reinstate && need_io_err_check(pp)) {
4ae388
@@ -1456,7 +1472,7 @@ check_path (struct vectors * vecs, struc
4ae388
 		 * be recoverd in time
4ae388
 		 */
4ae388
 		pp->tick = 1;
4ae388
-		return;
4ae388
+		return 0;
4ae388
 	}
4ae388
 
4ae388
 	if ((newstate == PATH_UP || newstate == PATH_GHOST) &&
4ae388
@@ -1464,7 +1480,7 @@ check_path (struct vectors * vecs, struc
4ae388
 		if (pp->mpp && pp->mpp->nr_active > 0) {
4ae388
 			pp->state = PATH_DELAYED;
4ae388
 			pp->wait_checks--;
4ae388
-			return;
4ae388
+			return 0;
4ae388
 		} else
4ae388
 			pp->wait_checks = 0;
4ae388
 	}
4ae388
@@ -1512,7 +1528,7 @@ check_path (struct vectors * vecs, struc
4ae388
 			pp->mpp->failback_tick = 0;
4ae388
 
4ae388
 			pp->mpp->stat_path_failures++;
4ae388
-			return;
4ae388
+			return 0;
4ae388
 		}
4ae388
 
4ae388
 		if(newstate == PATH_UP || newstate == PATH_GHOST){
4ae388
@@ -1594,7 +1610,7 @@ check_path (struct vectors * vecs, struc
4ae388
 
4ae388
 
4ae388
 	if (pp->mpp->wait_for_udev)
4ae388
-		return;
4ae388
+		return 0;
4ae388
 	/*
4ae388
 	 * path prio refreshing
4ae388
 	 */
4ae388
@@ -1613,6 +1629,7 @@ check_path (struct vectors * vecs, struc
4ae388
 			 (chkr_new_path_up && followover_should_failback(pp)))
4ae388
 			switch_pathgroup(pp->mpp);
4ae388
 	}
4ae388
+	return 0;
4ae388
 }
4ae388
 
4ae388
 static void *
4ae388
@@ -1642,7 +1659,12 @@ checkerloop (void *ap)
4ae388
 
4ae388
 		if (vecs->pathvec) {
4ae388
 			vector_foreach_slot (vecs->pathvec, pp, i) {
4ae388
-				check_path(vecs, pp);
4ae388
+				int rc = check_path(vecs, pp);
4ae388
+				if (rc < 0) {
4ae388
+					vector_del_slot(vecs->pathvec, i);
4ae388
+					free_path(pp);
4ae388
+					i--;
4ae388
+				}
4ae388
 			}
4ae388
 		}
4ae388
 		if (vecs->mpvec) {
4ae388
Index: multipath-tools-130222/libmultipath/structs_vec.c
4ae388
===================================================================
4ae388
--- multipath-tools-130222.orig/libmultipath/structs_vec.c
4ae388
+++ multipath-tools-130222/libmultipath/structs_vec.c
4ae388
@@ -274,9 +274,11 @@ void sync_paths(struct multipath *mpp, v
4ae388
 			}
4ae388
 		}
4ae388
 		if (!found) {
4ae388
-			condlog(3, "%s dropped path %s", mpp->alias, pp->dev);
4ae388
+			condlog(2, "%s dropped path %s", mpp->alias, pp->dev);
4ae388
 			vector_del_slot(mpp->paths, i--);
4ae388
 			orphan_path(pp);
4ae388
+			memset(pp->wwid, 0, WWID_SIZE);
4ae388
+			pp->missing_udev_info = INFO_REINIT;
4ae388
 		}
4ae388
 	}
4ae388
 	update_mpp_paths(mpp, pathvec);