aboutsummaryrefslogtreecommitdiff
path: root/sys/geom/mirror/g_mirror_ctl.c
diff options
context:
space:
mode:
authorPawel Jakub Dawidek <pjd@FreeBSD.org>2006-11-01 22:51:49 +0000
committerPawel Jakub Dawidek <pjd@FreeBSD.org>2006-11-01 22:51:49 +0000
commit501250ba603416801fab0c9808279d2f54fcb648 (patch)
tree97b3734a2b0b5f3ef52ead534f66a992a2f04c67 /sys/geom/mirror/g_mirror_ctl.c
parentaee5398c294c637aec69daf583cf55db009ffdce (diff)
downloadsrc-501250ba603416801fab0c9808279d2f54fcb648.tar.gz
src-501250ba603416801fab0c9808279d2f54fcb648.zip
Now, that we have gjournal in the tree add possibility to configure
gmirror and graid3 in a way that it is not resynchronized after a power failure or system crash. It is safe when gjournal is running on top of gmirror/graid3.
Notes
Notes: svn path=/head/; revision=163888
Diffstat (limited to 'sys/geom/mirror/g_mirror_ctl.c')
-rw-r--r--sys/geom/mirror/g_mirror_ctl.c32
1 files changed, 30 insertions, 2 deletions
diff --git a/sys/geom/mirror/g_mirror_ctl.c b/sys/geom/mirror/g_mirror_ctl.c
index 957878209755..27e58ceb31c2 100644
--- a/sys/geom/mirror/g_mirror_ctl.c
+++ b/sys/geom/mirror/g_mirror_ctl.c
@@ -97,7 +97,8 @@ g_mirror_ctl_configure(struct gctl_req *req, struct g_class *mp)
intmax_t *slicep;
uint32_t slice;
uint8_t balance;
- int *nargs, *autosync, *noautosync, *hardcode, *dynamic, do_sync = 0;
+ int *autosync, *noautosync, *failsync, *nofailsync, *hardcode, *dynamic;
+ int *nargs, do_sync = 0, dirty = 1;
nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs));
if (nargs == NULL) {
@@ -128,6 +129,16 @@ g_mirror_ctl_configure(struct gctl_req *req, struct g_class *mp)
gctl_error(req, "No '%s' argument.", "noautosync");
return;
}
+ failsync = gctl_get_paraml(req, "failsync", sizeof(*failsync));
+ if (failsync == NULL) {
+ gctl_error(req, "No '%s' argument.", "failsync");
+ return;
+ }
+ nofailsync = gctl_get_paraml(req, "nofailsync", sizeof(*nofailsync));
+ if (nofailsync == NULL) {
+ gctl_error(req, "No '%s' argument.", "nofailsync");
+ return;
+ }
hardcode = gctl_get_paraml(req, "hardcode", sizeof(*hardcode));
if (hardcode == NULL) {
gctl_error(req, "No '%s' argument.", "hardcode");
@@ -143,6 +154,11 @@ g_mirror_ctl_configure(struct gctl_req *req, struct g_class *mp)
"noautosync");
return;
}
+ if (*failsync && *nofailsync) {
+ gctl_error(req, "'%s' and '%s' specified.", "failsync",
+ "nofailsync");
+ return;
+ }
if (*hardcode && *dynamic) {
gctl_error(req, "'%s' and '%s' specified.", "hardcode",
"dynamic");
@@ -180,7 +196,8 @@ g_mirror_ctl_configure(struct gctl_req *req, struct g_class *mp)
return;
}
if (sc->sc_balance == balance && sc->sc_slice == slice && !*autosync &&
- !*noautosync && !*hardcode && !*dynamic) {
+ !*noautosync && !*failsync && !*nofailsync && !*hardcode &&
+ !*dynamic) {
sx_xunlock(&sc->sc_lock);
gctl_error(req, "Nothing has changed.");
return;
@@ -196,6 +213,15 @@ g_mirror_ctl_configure(struct gctl_req *req, struct g_class *mp)
if (*noautosync)
sc->sc_flags |= G_MIRROR_DEVICE_FLAG_NOAUTOSYNC;
}
+ if ((sc->sc_flags & G_MIRROR_DEVICE_FLAG_NOFAILSYNC) != 0) {
+ if (*failsync)
+ sc->sc_flags &= ~G_MIRROR_DEVICE_FLAG_NOFAILSYNC;
+ } else {
+ if (*nofailsync) {
+ sc->sc_flags |= G_MIRROR_DEVICE_FLAG_NOFAILSYNC;
+ dirty = 0;
+ }
+ }
LIST_FOREACH(disk, &sc->sc_disks, d_next) {
if (do_sync) {
if (disk->d_state == G_MIRROR_DISK_STATE_SYNCHRONIZING)
@@ -205,6 +231,8 @@ g_mirror_ctl_configure(struct gctl_req *req, struct g_class *mp)
disk->d_flags |= G_MIRROR_DISK_FLAG_HARDCODED;
else if (*dynamic)
disk->d_flags &= ~G_MIRROR_DISK_FLAG_HARDCODED;
+ if (!dirty)
+ disk->d_flags &= ~G_MIRROR_DISK_FLAG_DIRTY;
g_mirror_update_metadata(disk);
if (do_sync) {
if (disk->d_state == G_MIRROR_DISK_STATE_STALE) {