[multipath] remove dead maps
authorChristophe Varoqui <root@xa-s05.(none)>
Mon, 3 Oct 2005 15:46:24 +0000 (17:46 +0200)
committerChristophe Varoqui <root@xa-s05.(none)>
Mon, 3 Oct 2005 15:46:24 +0000 (17:46 +0200)
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
libmultipath/structs.h
multipath/main.c

index 1a8ae3f..7cb489f 100644 (file)
@@ -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;
index 6f917a8..4ed3bd0 100644 (file)
@@ -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);
index 7bfdeee..63ec981 100644 (file)
@@ -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;
 }