Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 5 Jan 2007 00:26:32 GMT
From:      Matt Jacob <mjacob@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 112505 for review
Message-ID:  <200701050026.l050QWDk065982@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=112505

Change 112505 by mjacob@mjexp on 2007/01/05 00:25:37

	A little more tweaking on this toy to finally get it to completely
	clean out dead consumers via posting events.

Affected files ...

.. //depot/projects/mjexp/sys/geom/multipath/g_multipath.c#10 edit
.. //depot/projects/mjexp/sys/geom/multipath/g_multipath.h#5 edit

Differences ...

==== //depot/projects/mjexp/sys/geom/multipath/g_multipath.c#10 (text+ko) ====

@@ -74,6 +74,7 @@
 static void
 g_multipath_orphan(struct g_consumer *cp)
 {
+printf("%s called on %s\n", __FUNCTION__, cp->provider? cp->provider->name : "none");
 	g_topology_assert();
 	g_multipath_destroy(cp->geom);
 }
@@ -104,6 +105,17 @@
 }
 
 static void
+g_mpd(void *arg, int flags __unused)
+{
+	struct g_consumer *cp;
+        g_topology_assert();
+	cp = arg;
+	g_access(cp, -cp->acr, -cp->acw, -cp->ace);
+	g_detach(cp);
+	g_destroy_consumer(cp);
+}
+
+static void
 g_multipath_done(struct bio *bp)
 {
 	struct bio *pbp = bp->bio_parent;
@@ -131,6 +143,8 @@
 		
 	if (dofail) {
 		struct g_consumer *cp = bp->bio_from;
+		struct g_consumer *lcp;
+		struct g_provider *pp = cp->provider;
 
 		/*
 		 * If we had a failure, we have to check first to see
@@ -139,31 +153,44 @@
 		 * a number of failures). If so, we then switch consumers
 		 * to the next available consumer.
 		 */
+		g_topology_lock();
 		if (cp == sc->cp_active) {
-			printf("i/o failure is causing detach of %s from %s\n",
-			    cp->provider->name, gp->name);
-/*
- * XXX: The following two lines are probably wrong due to inflights
- */
-			g_detach(cp);
-        		g_destroy_consumer(cp);
-			sc->cp_active = LIST_FIRST(&gp->consumer);
+			printf("GEOM_MULTIPATH: I/O failure terminates use of "
+			    "%s in %s\n", cp->provider->name, gp->name);
+			cp->index = 1;
+			sc->cp_active = NULL;
+			LIST_FOREACH(lcp, &gp->consumer, consumer) {
+				if (lcp->index == 0) {
+					sc->cp_active = lcp;
+					break;
+				}
+			}
+			if (sc->cp_active == NULL) {
+				printf("GEOM_MULTIPATH: out of providers\n");
+				g_topology_unlock();
+				goto out;
+			}
+			printf("GEOM_MULTIPATH: switching to provider %s\n",
+			    sc->cp_active->provider->name);
+		}
+		g_topology_unlock();
+		if (cp->nend == cp->nstart && pp->nend == pp->nstart) {
+			printf("GEOM_MULTIPATH: old provider %s is now quiet\n",
+			    pp->name);
+			g_post_event(g_mpd, cp, M_NOWAIT, NULL);
 		}
 
 		/*
 		 * If we can fruitfully restart the I/O, do so.
 		 */
 		if (sc->cp_active) {
-			printf("switching to provider %s\n",
-			    sc->cp_active->provider->name);
 			g_destroy_bio(bp);
 			pbp->bio_children--;
 			g_multipath_start(pbp);
 			return;
-		} else {
-			printf("out of providers to try\n");
 		}
 	}
+out:
 	g_std_done(bp);
 }
 
@@ -275,7 +302,7 @@
 		return (error);
 	}
 	cp->private = sc;
-	cp->index = sc->index++;
+	cp->index = 0;
 
 	/*
 	 * Set access permissions on new consumer to match other consumers
@@ -375,7 +402,6 @@
 	g_destroy_consumer(cp);
 	g_destroy_geom(gp);
 	if (error != 0) {
-		printf("%s had error %d reading metadata\n", pp->name, error);
 		return (NULL);
 	}
 	gp = NULL;

==== //depot/projects/mjexp/sys/geom/multipath/g_multipath.h#5 (text+ko) ====

@@ -47,7 +47,6 @@
 	struct g_consumer *	cp_active;
 	char			sc_name[16];
 	char			sc_uuid[40];
-	int			index;
 };
 #endif	/* _KERNEL */
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200701050026.l050QWDk065982>