summaryrefslogtreecommitdiff
path: root/sbin
diff options
context:
space:
mode:
authorMarco Peereboom <marco@cvs.openbsd.org>2005-08-18 04:49:53 +0000
committerMarco Peereboom <marco@cvs.openbsd.org>2005-08-18 04:49:53 +0000
commit4eb64979878c88021ad286c154decd88cdb5fd8e (patch)
tree547762decd40704f43cb991b555de411199fb59f /sbin
parent554d489dce3a2e3c280f90fb15459a80f14ade1a (diff)
Add "create hot spare" ok dlg@
Diffstat (limited to 'sbin')
-rw-r--r--sbin/bioctl/bioctl.86
-rw-r--r--sbin/bioctl/bioctl.c80
2 files changed, 81 insertions, 5 deletions
diff --git a/sbin/bioctl/bioctl.8 b/sbin/bioctl/bioctl.8
index 901cf0f137f..8fc4aa53371 100644
--- a/sbin/bioctl/bioctl.8
+++ b/sbin/bioctl/bioctl.8
@@ -1,4 +1,4 @@
-.\" $OpenBSD: bioctl.8,v 1.25 2005/08/09 08:11:33 jmc Exp $
+.\" $OpenBSD: bioctl.8,v 1.26 2005/08/18 04:49:52 marco Exp $
.\"
.\" Copyright (c) 2004, 2005 Marco Peereboom
.\"
@@ -34,6 +34,7 @@
.Bk -words
.Op Fl Dhiv
.Op Fl a Ar alarm-function
+.Op Fl H Ar channel:target[.lun]
.Ar device
.Ek
.Sh DESCRIPTION
@@ -64,6 +65,9 @@ or by the first letter only
(e.g. -a e).
.It Fl D
Enable debug output.
+.It Fl H Ar channel:target[.lun]
+Make a hot spare out of disk channel:target[.lun] on the specified controller
+(e.g. bioctl -H 0:15)
.It Fl h
Where neccessary, produce "human-readable" output.
Use unit suffixes: Byte, Kilobyte, Megabyte,
diff --git a/sbin/bioctl/bioctl.c b/sbin/bioctl/bioctl.c
index 9bed55fcbcd..3032555664b 100644
--- a/sbin/bioctl/bioctl.c
+++ b/sbin/bioctl/bioctl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: bioctl.c,v 1.30 2005/08/17 06:31:01 marco Exp $ */
+/* $OpenBSD: bioctl.c,v 1.31 2005/08/18 04:49:52 marco Exp $ */
/*
* Copyright (c) 2004, 2005 Marco Peereboom
@@ -45,11 +45,22 @@
#include <ctype.h>
#include <util.h>
+#define CT_SEP ':'
+#define TL_SEP '.'
+
+struct locator {
+ int channel;
+ int target;
+ int lun;
+};
+
void usage(void);
+int str2locator(const char *, struct locator *);
void cleanup(void);
void bio_inq(char *);
void bio_alarm(char *);
+void bio_setstate(char *);
/* globals */
const char *bio_device = "/dev/bio";
@@ -74,7 +85,7 @@ main(int argc, char *argv[])
if (argc < 2)
usage();
- while ((ch = getopt(argc, argv, "ha:Div")) != -1) {
+ while ((ch = getopt(argc, argv, "H:ha:Div")) != -1) {
switch (ch) {
case 'a': /* alarm */
func |= BIOC_ALARM;
@@ -83,6 +94,10 @@ main(int argc, char *argv[])
case 'D': /* debug */
debug = 1;
break;
+ case 'H': /* set hotspare */
+ func |= BIOC_SETSTATE;
+ al_arg = optarg;
+ break;
case 'h':
human = 1;
break;
@@ -137,6 +152,8 @@ main(int argc, char *argv[])
bio_inq(sd_dev);
} else if (func == BIOC_ALARM) {
bio_alarm(al_arg);
+ } else if (func == BIOC_SETSTATE) {
+ bio_setstate(al_arg);
}
return (0);
@@ -148,10 +165,42 @@ usage(void)
extern char *__progname;
fprintf(stderr,
- "usage: %s [-Dhiv] [-a alarm-function] device\n", __progname);
+ "usage: %s [-Dhiv] [-a alarm-function] [-H channel:target[.lun]] "
+ "device\n", __progname);
exit(1);
}
+int
+str2locator(const char *string, struct locator *location)
+{
+ char *targ, *lun;
+
+ targ = strchr(string, CT_SEP);
+ if (targ == NULL)
+ return (-1);
+
+ *targ++ = '\0';
+
+ lun = strchr(targ, TL_SEP);
+ if (lun != NULL) {
+ *lun++ = '\0';
+ location->lun = strtonum(lun, 0, 256 /* XXX */, NULL);
+ if (errno)
+ return (-1);
+ } else
+ location->lun = 0;
+
+ location->target = strtonum(targ, 0, 256 /* XXX */, NULL);
+ if (errno)
+ return (-1);
+
+ location->channel = strtonum(string, 0, 256 /* XXX */, NULL);
+ if (errno)
+ return (-1);
+
+ return (0);
+}
+
void
bio_inq(char *name)
{
@@ -338,7 +387,7 @@ bio_alarm(char *arg)
rv = ioctl(devh, BIOCALARM, &ba);
if (rv == -1) {
- warnx("bioc_ioctl() call failed");
+ warnx("bioc_ioctl(ALARM) call failed");
return;
}
@@ -348,3 +397,26 @@ bio_alarm(char *arg)
}
}
+
+void bio_setstate(char *arg)
+{
+ int rv;
+ struct bioc_setstate bs;
+ struct locator location;
+
+ if (str2locator(arg, &location) != 0)
+ errx(1, "invalid channel:target[.lun]");
+
+
+ bs.bs_cookie = bl.bl_cookie;
+ bs.bs_status = BIOC_SSHOTSPARE;
+ bs.bs_channel = location.channel;
+ bs.bs_target = location.target;
+ bs.bs_lun = location.lun;
+
+ rv = ioctl(devh, BIOCSETSTATE, &bs);
+ if (rv == -1) {
+ warnx("bioc_ioctl(BIOCSETSTATE) call failed");
+ return;
+ }
+}