From owner-svn-src-projects@FreeBSD.ORG Sun Jan 30 07:49:45 2011 Return-Path: Delivered-To: svn-src-projects@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 524E7106566C; Sun, 30 Jan 2011 07:49:45 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 428558FC1E; Sun, 30 Jan 2011 07:49:45 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id p0U7njq6061935; Sun, 30 Jan 2011 07:49:45 GMT (envelope-from mav@svn.freebsd.org) Received: (from mav@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id p0U7njnC061933; Sun, 30 Jan 2011 07:49:45 GMT (envelope-from mav@svn.freebsd.org) Message-Id: <201101300749.p0U7njnC061933@svn.freebsd.org> From: Alexander Motin Date: Sun, 30 Jan 2011 07:49:45 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org X-SVN-Group: projects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r218083 - projects/graid/head/sys/geom/raid X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 30 Jan 2011 07:49:45 -0000 Author: mav Date: Sun Jan 30 07:49:44 2011 New Revision: 218083 URL: http://svn.freebsd.org/changeset/base/218083 Log: Implement delayed until last provider close node destruction. Use it on system shutdown to gracefully stop rebuild and other processes and close lower level providers, allowing them do the same. Modified: projects/graid/head/sys/geom/raid/g_raid.c Modified: projects/graid/head/sys/geom/raid/g_raid.c ============================================================================== --- projects/graid/head/sys/geom/raid/g_raid.c Sun Jan 30 02:17:47 2011 (r218082) +++ projects/graid/head/sys/geom/raid/g_raid.c Sun Jan 30 07:49:44 2011 (r218083) @@ -92,7 +92,7 @@ LIST_HEAD(, g_raid_tr_class) g_raid_tr_c LIST_HEAD(, g_raid_volume) g_raid_volumes = LIST_HEAD_INITIALIZER(g_raid_volumes); -//static eventhandler_tag g_raid_pre_sync = NULL; +static eventhandler_tag g_raid_pre_sync = NULL; static int g_raid_started = 0; static int g_raid_destroy_geom(struct gctl_req *req, struct g_class *mp, @@ -1212,7 +1212,7 @@ process: vol->v_timeout(vol, vol->v_to_arg); } } - if (sc->sc_stopping != 0) + if (sc->sc_stopping == G_RAID_DESTROY_HARD) g_raid_destroy_node(sc, 1); /* May not return. */ } } @@ -1441,9 +1441,9 @@ g_raid_update_disk(struct g_raid_disk *d static int g_raid_access(struct g_provider *pp, int acr, int acw, int ace) { - struct g_raid_volume *vol; + struct g_raid_volume *vol, *vol1; struct g_raid_softc *sc; - int dcr, dcw, dce; + int dcr, dcw, dce, opens, error = 0; g_topology_assert(); G_RAID_DEBUG(2, "Access request for %s: r%dw%de%d.", pp->name, acr, @@ -1460,14 +1460,35 @@ g_raid_access(struct g_provider *pp, int g_topology_unlock(); sx_xlock(&sc->sc_lock); + /* Deny new opens while dying. */ + if (sc->sc_stopping != 0 && (acr > 0 || acw > 0 || ace > 0)) { + error = ENXIO; + goto out; + } // if (dcw == 0 && !vol->v_idle) // g_raid_idle(vol, dcw); vol->v_provider_open += acr + acw + ace; + /* Handle delayed node destruction. */ + if (sc->sc_stopping == G_RAID_DESTROY_DELAYED && + vol->v_provider_open == 0) { + /* Count open volumes. */ + opens = 0; + TAILQ_FOREACH(vol1, &sc->sc_volumes, v_next) { + if (vol1->v_provider_open != 0) + opens++; + } + if (opens == 0) { + sc->sc_stopping = G_RAID_DESTROY_HARD; + g_raid_event_send(sc, 0, 0); /* Wake up worker. */ + } + } + /* Handle open volume destruction. */ if (vol->v_stopping && vol->v_provider_open == 0) g_raid_destroy_volume(vol); +out: sx_xunlock(&sc->sc_lock); g_topology_lock(); - return (0); + return (error); } struct g_raid_softc * @@ -1612,7 +1633,7 @@ g_raid_destroy_node(struct g_raid_softc struct g_raid_disk *disk, *tmpd; int error = 0; - sc->sc_stopping = 1; + sc->sc_stopping = G_RAID_DESTROY_HARD; TAILQ_FOREACH_SAFE(vol, &sc->sc_volumes, v_next, tmpv) { if (g_raid_destroy_volume(vol)) error = EBUSY; @@ -1698,7 +1719,7 @@ g_raid_destroy_volume(struct g_raid_volu } G_RAID_DEBUG(2, "Volume %s destroyed.", vol->v_name); free(vol, M_RAID); - if (sc->sc_stopping) + if (sc->sc_stopping == G_RAID_DESTROY_HARD) g_raid_event_send(sc, 0, 0); /* Wake up worker. */ return (0); } @@ -1760,7 +1781,7 @@ g_raid_destroy(struct g_raid_softc *sc, G_RAID_DEBUG(1, "Node %s will be destroyed on last close.", sc->sc_name); -// sc->sc_stopping = 1; + sc->sc_stopping = G_RAID_DESTROY_DELAYED; return (EBUSY); case G_RAID_DESTROY_HARD: G_RAID_DEBUG(1, @@ -1770,7 +1791,7 @@ g_raid_destroy(struct g_raid_softc *sc, } /* Mark node for destruction. */ - sc->sc_stopping = 1; + sc->sc_stopping = G_RAID_DESTROY_HARD; /* Wake up worker to let it selfdestruct. */ g_raid_event_send(sc, 0, 0); /* Sleep until node destroyed. */ @@ -1970,7 +1991,6 @@ g_raid_dumpconf(struct sbuf *sb, const c } } -#if 0 static void g_raid_shutdown_pre_sync(void *arg, int howto) { @@ -1996,16 +2016,15 @@ g_raid_shutdown_pre_sync(void *arg, int g_topology_unlock(); PICKUP_GIANT(); } -#endif static void g_raid_init(struct g_class *mp) { -// g_raid_pre_sync = EVENTHANDLER_REGISTER(shutdown_pre_sync, -// g_raid_shutdown_pre_sync, mp, SHUTDOWN_PRI_FIRST); -// if (g_raid_pre_sync == NULL) -// G_RAID_DEBUG(0, "Warning! Cannot register shutdown event."); + g_raid_pre_sync = EVENTHANDLER_REGISTER(shutdown_pre_sync, + g_raid_shutdown_pre_sync, mp, SHUTDOWN_PRI_FIRST); + if (g_raid_pre_sync == NULL) + G_RAID_DEBUG(0, "Warning! Cannot register shutdown event."); g_raid_started = 1; } @@ -2013,8 +2032,8 @@ static void g_raid_fini(struct g_class *mp) { -// if (g_raid_pre_sync != NULL) -// EVENTHANDLER_DEREGISTER(shutdown_pre_sync, g_raid_pre_sync); + if (g_raid_pre_sync != NULL) + EVENTHANDLER_DEREGISTER(shutdown_pre_sync, g_raid_pre_sync); g_raid_started = 0; }