[PATCH RESEND] multipathd: check and cleanup zombie paths

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

 



The same LUN have been exported to the host from different lun
number twice, each time create multipath for this lun, after
second time the multipath might have zombie paths which devices
doesn't actually exist.

Check zombie paths:
If a failed path have the same wwid with an active path, but its
sg_id.lun are not equal to this active path. This failed path
might be a zombie path(a lun can't be exported from a different
lun number to a host at the same time).

cleanup zombie paths:
delete the zombie paths' device from sysfs, which will clean up
the zombie paths both in kernel and userspace.

Signed-off-by: Chongyun Wu <wu.chongyun@xxxxxxx>
---
   multipathd/main.c |   42 ++++++++++++++++++++++++++++++++++++++++++
   1 file changed, 42 insertions(+)

diff --git a/multipathd/main.c b/multipathd/main.c
index 27cf234..e74a448 100644
--- a/multipathd/main.c
+++ b/multipathd/main.c
@@ -1511,6 +1511,44 @@ void repair_path(struct path * pp)
   	LOG_MSG(1, checker_message(&pp->checker));
   }

+void try_cleanup_zombie_path(struct vectors *vecs, struct path *pp)
+{
+	struct path *pp_tmp;
+	unsigned int i;
+	struct config *conf;
+	int path_state;
+	const char delete[] = "1";
+
+	/*check if this given path is a zombie path*/
+	vector_foreach_slot(vecs->pathvec, pp_tmp, i) {
+		if ((strcmp(pp_tmp->wwid, pp->wwid) == 0) &&
+			(pp_tmp->state == PATH_UP)) {
+			/*to get the state again to avoid getting
+			 *the old state
+			 */
+			conf = get_multipath_config();
+			path_state = get_state(pp_tmp, conf, 1);
+			put_multipath_config(conf);
+
+			if ((path_state == PATH_UP) &&
+				(pp_tmp->sg_id.lun != pp->sg_id.lun)) {
+				/*
+				 * The given path is a failed path,
+				 * found a active path with the same wwid and
+				 * it's sg_id.lun isn't equal to the given path,
+				 * that means that the given is a zombie path!
+				 * Clean up zombie path then.
+				 */
+				condlog(2, "clean up zombie path %s(%s)",
+					pp->dev, pp->wwid);
+				sysfs_attr_set_value(pp->udev, "device/delete",
+						delete, strlen(delete));
+				break;
+			}
+		}
+	}
+}
+
   /*
    * Returns '1' if the path has been checked, '-1' if it was blacklisted
    * and '0' otherwise
@@ -1580,6 +1618,10 @@ check_path (struct vectors * vecs, struct path *
pp, int ticks)
   		newstate = PATH_DOWN;
   	}

+	if (newstate == PATH_DOWN) {
+		try_cleanup_zombie_path(vecs, pp);
+	}
+
   	if (newstate == PATH_WILD || newstate == PATH_UNCHECKED) {
   		condlog(2, "%s: unusable path", pp->dev);
   		conf = get_multipath_config();
-- 
1.7.9.5

--
dm-devel mailing list
dm-devel@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/dm-devel



[Index of Archives]     [DM Crypt]     [Fedora Desktop]     [ATA RAID]     [Fedora Marketing]     [Fedora Packaging]     [Fedora SELinux]     [Yosemite Discussion]     [KDE Users]     [Fedora Docs]

  Powered by Linux