From 04114b7eb8687c8060214f2c7f8b2ded2daaf2dc Mon Sep 17 00:00:00 2001 From: Christophe Varoqui Date: Mon, 3 Oct 2005 17:46:24 +0200 Subject: [PATCH] [multipath] remove dead maps A map is considered dead, and thus removed from DM, when all its constituent paths have disappeared from the system (ie sysfs). When all paths fail, we keep the map, hoping some path can come back up. Flush will fail if the map is claimed (mount, ...), notify that. This policy is rather safe, because : - multipath is exec'ed only upon "add path events", so maps can magically disappear - claimed maps cannot disappear This map purge is clearly an interactive maintenance operation. --- libmultipath/structs.c | 18 ++++++++++++++++++ libmultipath/structs.h | 1 + multipath/main.c | 30 ++++++++++++++++++++++++++++++ 3 files changed, 49 insertions(+) diff --git a/libmultipath/structs.c b/libmultipath/structs.c index 1a8ae3f..7cb489f 100644 --- a/libmultipath/structs.c +++ b/libmultipath/structs.c @@ -145,6 +145,24 @@ free_multipath (struct multipath * mpp, int free_paths) } void +drop_multipath (vector mpvec, char * wwid, int free_paths) +{ + int i; + struct multipath * mpp; + + if (!mpvec) + return; + + vector_foreach_slot (mpvec, mpp, i) { + if (!strncmp(mpp->wwid, wwid, WWID_SIZE)) { + free_multipath(mpp, free_paths); + vector_del_slot(mpvec, i); + return; + } + } +} + +void free_multipathvec (vector mpvec, int free_paths) { int i; diff --git a/libmultipath/structs.h b/libmultipath/structs.h index 6f917a8..4ed3bd0 100644 --- a/libmultipath/structs.h +++ b/libmultipath/structs.h @@ -148,6 +148,7 @@ void free_pathvec (vector vec, int free_paths); void free_pathgroup (struct pathgroup * pgp, int free_paths); void free_pgvec (vector pgvec, int free_paths); void free_multipath (struct multipath *, int free_paths); +void drop_multipath (vector mpvec, char * wwid, int free_paths); void free_multipathvec (vector mpvec, int free_paths); int store_path (vector pathvec, struct path * pp); diff --git a/multipath/main.c b/multipath/main.c index 7bfdeee..63ec981 100644 --- a/multipath/main.c +++ b/multipath/main.c @@ -630,6 +630,21 @@ domap (struct multipath * mpp) } static int +deadmap (struct multipath * mpp) +{ + int i, j; + struct pathgroup * pgp; + struct path * pp; + + vector_foreach_slot (mpp->pg, pgp, i) + vector_foreach_slot (pgp->paths, pp, j) + if (strlen(pp->dev)) + return 0; /* alive */ + + return 1; /* dead */ +} + +static int coalesce_paths (vector curmp, vector pathvec) { int k, i; @@ -712,8 +727,23 @@ coalesce_paths (vector curmp, vector pathvec) condlog(3, "action set to %i", mpp->action); domap(mpp); + drop_multipath(curmp, mpp->wwid, KEEP_PATHS); free_multipath(mpp, KEEP_PATHS); } + /* + * Flush maps with only dead paths (ie not in sysfs) + * Keep maps with only failed paths + */ + vector_foreach_slot (curmp, mpp, i) { + if (!deadmap(mpp)) + continue; + + if (dm_flush_map(mpp->alias, DEFAULT_TARGET)) + condlog(2, "remove: %s (dead) failed!", + mpp->alias); + else + condlog(2, "remove: %s (dead)", mpp->alias); + } return 0; } -- 2.7.4