From owner-p4-projects@FreeBSD.ORG Fri Jan 5 00:26:32 2007 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id A871B16A412; Fri, 5 Jan 2007 00:26:32 +0000 (UTC) X-Original-To: perforce@freebsd.org Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 6EDAE16A407 for ; Fri, 5 Jan 2007 00:26:32 +0000 (UTC) (envelope-from mjacob@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [69.147.83.41]) by mx1.freebsd.org (Postfix) with ESMTP id 55D1B13C459 for ; Fri, 5 Jan 2007 00:26:32 +0000 (UTC) (envelope-from mjacob@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.6/8.13.6) with ESMTP id l050QW5f065985 for ; Fri, 5 Jan 2007 00:26:32 GMT (envelope-from mjacob@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.6/8.13.4/Submit) id l050QWDk065982 for perforce@freebsd.org; Fri, 5 Jan 2007 00:26:32 GMT (envelope-from mjacob@freebsd.org) Date: Fri, 5 Jan 2007 00:26:32 GMT Message-Id: <200701050026.l050QWDk065982@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to mjacob@freebsd.org using -f From: Matt Jacob To: Perforce Change Reviews Cc: Subject: PERFORCE change 112505 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 05 Jan 2007 00:26:33 -0000 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 */