aboutsummaryrefslogtreecommitdiff
path: root/sbin/gvinum/gvinum.c
diff options
context:
space:
mode:
authorLukas Ertl <le@FreeBSD.org>2004-11-26 12:31:36 +0000
committerLukas Ertl <le@FreeBSD.org>2004-11-26 12:31:36 +0000
commit997337fd20178ba41cb07f88e19b1366c1ccddba (patch)
tree73b2f06a9c68badfecce3952b7fda1b373c9d6b5 /sbin/gvinum/gvinum.c
parent3514b3b581ca57f23eecca891b04fa1d5591417e (diff)
downloadsrc-997337fd20178ba41cb07f88e19b1366c1ccddba.tar.gz
src-997337fd20178ba41cb07f88e19b1366c1ccddba.zip
Implement 'setstate' to allow setting the state of drives and subdisks
for debugging and emergency purposes.
Notes
Notes: svn path=/head/; revision=138112
Diffstat (limited to 'sbin/gvinum/gvinum.c')
-rw-r--r--sbin/gvinum/gvinum.c58
1 files changed, 58 insertions, 0 deletions
diff --git a/sbin/gvinum/gvinum.c b/sbin/gvinum/gvinum.c
index 524a08ebbab2..bb3166c6ff64 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"))