diff options
author | le <le@FreeBSD.org> | 2004-11-26 12:31:36 +0000 |
---|---|---|
committer | le <le@FreeBSD.org> | 2004-11-26 12:31:36 +0000 |
commit | c2bd948f6822dbbdb059d792f1e6150a26618d4f (patch) | |
tree | 73b2f06a9c68badfecce3952b7fda1b373c9d6b5 /sbin | |
parent | 1ce692dc6551a683467623fc437c34f027de50d1 (diff) | |
download | FreeBSD-src-c2bd948f6822dbbdb059d792f1e6150a26618d4f.zip FreeBSD-src-c2bd948f6822dbbdb059d792f1e6150a26618d4f.tar.gz |
Implement 'setstate' to allow setting the state of drives and subdisks
for debugging and emergency purposes.
Diffstat (limited to 'sbin')
-rw-r--r-- | sbin/gvinum/gvinum.c | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/sbin/gvinum/gvinum.c b/sbin/gvinum/gvinum.c index 524a08e..bb3166c 100644 --- a/sbin/gvinum/gvinum.c +++ b/sbin/gvinum/gvinum.c @@ -59,6 +59,7 @@ void gvinum_parityop(int, char **, int); void gvinum_printconfig(int, char **); void gvinum_rm(int, char **); void gvinum_saveconfig(void); +void gvinum_setstate(int, char **); void gvinum_start(int, char **); void gvinum_stop(int, char **); void parseline(int, char **); @@ -482,6 +483,61 @@ gvinum_init(int argc, char **argv) } void +gvinum_setstate(int argc, char **argv) +{ + struct gctl_req *req; + int flags, i; + const char *errstr; + + flags = 0; + + optreset = 1; + optind = 1; + + while ((i = getopt(argc, argv, "f")) != -1) { + switch (i) { + case 'f': + flags |= GV_FLAG_F; + break; + case '?': + default: + warn("invalid flag: %c", i); + return; + } + } + + argc -= optind; + argv += optind; + + if (argc != 2) { + warnx("usage: setstate [-f] <state> <obj>"); + return; + } + + /* + * XXX: This hack is needed to avoid tripping over (now) invalid + * 'classic' vinum states and will go away later. + */ + if (strcmp(argv[0], "up") && strcmp(argv[0], "down") && + strcmp(argv[0], "stale")) { + warnx("invalid state '%s'", argv[0]); + return; + } + + req = gctl_get_handle(); + gctl_ro_param(req, "class", -1, "VINUM"); + gctl_ro_param(req, "verb", -1, "setstate"); + gctl_ro_param(req, "state", -1, argv[0]); + gctl_ro_param(req, "object", -1, argv[1]); + gctl_ro_param(req, "flags", sizeof(int), &flags); + + errstr = gctl_issue(req); + if (errstr != NULL) + warnx("%s", errstr); + gctl_free(req); +} + +void gvinum_list(int argc, char **argv) { struct gctl_req *req; @@ -801,6 +857,8 @@ parseline(int argc, char **argv) gvinum_rm(argc, argv); else if (!strcmp(argv[0], "saveconfig")) gvinum_saveconfig(); + else if (!strcmp(argv[0], "setstate")) + gvinum_setstate(argc, argv); else if (!strcmp(argv[0], "start")) gvinum_start(argc, argv); else if (!strcmp(argv[0], "stop")) |