diff options
author | ae <ae@FreeBSD.org> | 2013-12-19 22:13:12 +0000 |
---|---|---|
committer | ae <ae@FreeBSD.org> | 2013-12-19 22:13:12 +0000 |
commit | 86d162fb60a778f9693153d552ce23a379a36131 (patch) | |
tree | 91a9f97de159ec615be69a00d674291a5a889a7e /sys/geom | |
parent | f1e34080470d8957d5462be79b29d9629d00a386 (diff) | |
download | FreeBSD-src-86d162fb60a778f9693153d552ce23a379a36131.zip FreeBSD-src-86d162fb60a778f9693153d552ce23a379a36131.tar.gz |
Prevent users from deactivating the last component of a mirror.
PR: 184985
MFC after: 1 week
Diffstat (limited to 'sys/geom')
-rw-r--r-- | sys/geom/mirror/g_mirror_ctl.c | 13 |
1 files changed, 12 insertions, 1 deletions
diff --git a/sys/geom/mirror/g_mirror_ctl.c b/sys/geom/mirror/g_mirror_ctl.c index 1748d7b..29bc56c 100644 --- a/sys/geom/mirror/g_mirror_ctl.c +++ b/sys/geom/mirror/g_mirror_ctl.c @@ -695,7 +695,7 @@ g_mirror_ctl_deactivate(struct gctl_req *req, struct g_class *mp) 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) { @@ -716,6 +716,7 @@ g_mirror_ctl_deactivate(struct gctl_req *req, struct g_class *mp) gctl_error(req, "No such device: %s.", name); 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); @@ -728,6 +729,16 @@ g_mirror_ctl_deactivate(struct gctl_req *req, struct g_class *mp) 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 deactivate the " + "last ACTIVE component %s.", + sc->sc_geom->name, name); + continue; + } + } disk->d_flags |= G_MIRROR_DISK_FLAG_INACTIVE; disk->d_flags &= ~G_MIRROR_DISK_FLAG_FORCE_SYNC; g_mirror_update_metadata(disk); |