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

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