svn commit: r235968 - stable/9/sys/geom/mirror
Andrey V. Elsukov
ae at FreeBSD.org
Fri May 25 04:26:15 UTC 2012
Author: ae
Date: Fri May 25 04:26:14 2012
New Revision: 235968
URL: http://svn.freebsd.org/changeset/base/235968
Log:
MFC r235599:
Introduce new device flag G_MIRROR_DEVICE_FLAG_TASTING. It should
protect geom from destroying while it is tasting.
MFC r235600:
Prevent removing of the last active component from a mirror.
PR: kern/154860
Reviewed by: pjd
Tested by: Eugene Grosbein
Modified:
stable/9/sys/geom/mirror/g_mirror.c
stable/9/sys/geom/mirror/g_mirror.h
stable/9/sys/geom/mirror/g_mirror_ctl.c
Directory Properties:
stable/9/sys/ (props changed)
Modified: stable/9/sys/geom/mirror/g_mirror.c
==============================================================================
--- stable/9/sys/geom/mirror/g_mirror.c Fri May 25 03:46:56 2012 (r235967)
+++ stable/9/sys/geom/mirror/g_mirror.c Fri May 25 04:26:14 2012 (r235968)
@@ -1692,6 +1692,8 @@ g_mirror_can_destroy(struct g_mirror_sof
gp = sc->sc_geom;
if (gp->softc == NULL)
return (1);
+ if ((sc->sc_flags & G_MIRROR_DEVICE_FLAG_TASTING) != 0)
+ return (0);
LIST_FOREACH(cp, &gp->consumer, consumer) {
if (g_mirror_is_busy(sc, cp))
return (0);
@@ -3053,6 +3055,7 @@ g_mirror_taste(struct g_class *mp, struc
G_MIRROR_DEBUG(1, "Adding disk %s to %s.", pp->name, gp->name);
g_topology_unlock();
sx_xlock(&sc->sc_lock);
+ sc->sc_flags |= G_MIRROR_DEVICE_FLAG_TASTING;
error = g_mirror_add_disk(sc, pp, &md);
if (error != 0) {
G_MIRROR_DEBUG(0, "Cannot add disk %s to %s (error=%d).",
@@ -3065,6 +3068,12 @@ g_mirror_taste(struct g_class *mp, struc
}
gp = NULL;
}
+ sc->sc_flags &= ~G_MIRROR_DEVICE_FLAG_TASTING;
+ if ((sc->sc_flags & G_MIRROR_DEVICE_FLAG_DESTROY) != 0) {
+ g_mirror_destroy(sc, G_MIRROR_DESTROY_HARD);
+ g_topology_lock();
+ return (NULL);
+ }
sx_xunlock(&sc->sc_lock);
g_topology_lock();
return (gp);
Modified: stable/9/sys/geom/mirror/g_mirror.h
==============================================================================
--- stable/9/sys/geom/mirror/g_mirror.h Fri May 25 03:46:56 2012 (r235967)
+++ stable/9/sys/geom/mirror/g_mirror.h Fri May 25 04:26:14 2012 (r235968)
@@ -157,6 +157,7 @@ struct g_mirror_event {
#define G_MIRROR_DEVICE_FLAG_DESTROY 0x0100000000000000ULL
#define G_MIRROR_DEVICE_FLAG_WAIT 0x0200000000000000ULL
#define G_MIRROR_DEVICE_FLAG_DESTROYING 0x0400000000000000ULL
+#define G_MIRROR_DEVICE_FLAG_TASTING 0x0800000000000000ULL
#define G_MIRROR_DEVICE_STATE_STARTING 0
#define G_MIRROR_DEVICE_STATE_RUNNING 1
Modified: stable/9/sys/geom/mirror/g_mirror_ctl.c
==============================================================================
--- stable/9/sys/geom/mirror/g_mirror_ctl.c Fri May 25 03:46:56 2012 (r235967)
+++ stable/9/sys/geom/mirror/g_mirror_ctl.c Fri May 25 04:26:14 2012 (r235968)
@@ -560,7 +560,7 @@ g_mirror_ctl_remove(struct gctl_req *req
const char *name;
char param[16];
int *nargs;
- u_int i;
+ u_int i, active;
nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs));
if (nargs == NULL) {
@@ -587,6 +587,7 @@ g_mirror_ctl_remove(struct gctl_req *req
"first.");
return;
}
+ active = g_mirror_ndisks(sc, G_MIRROR_DISK_STATE_ACTIVE);
for (i = 1; i < (u_int)*nargs; i++) {
snprintf(param, sizeof(param), "arg%u", i);
name = gctl_get_asciiparam(req, param);
@@ -599,6 +600,16 @@ g_mirror_ctl_remove(struct gctl_req *req
gctl_error(req, "No such provider: %s.", name);
continue;
}
+ if (disk->d_state == G_MIRROR_DISK_STATE_ACTIVE) {
+ if (active > 1)
+ active--;
+ else {
+ gctl_error(req, "%s: Can't remove the last "
+ "ACTIVE component %s.", sc->sc_geom->name,
+ name);
+ continue;
+ }
+ }
g_mirror_event_send(disk, G_MIRROR_DISK_STATE_DESTROY,
G_MIRROR_EVENT_DONTWAIT);
}
More information about the svn-src-stable-9
mailing list