Hello all.
This patch actually consists of three parts, logically organized
one-by-one down there:
1. Add BIOCLISTCONTROLLERS ioctl to bio(4), allowing to enumerate all
registered controllers.
2. Add "-A" flag to bioctl(8) that enumerates all volumes accessible by
bio(4), and make this default behavior when no command parameters given.
3. Add such output of bioctl to daily(8), just before "disks:" subpart.
Feedback and, hopefully, commits are welcome. :) Especially
ioctl-related part needs to be reviewed, I'm surely missed something.
But it works. :)
--
Best wishes,
Vadim Zhukov
A: Because it messes up the order in which people normally read text.
Q: Why is top-posting such a bad thing?
A: Top-posting.
Q: What is the most annoying thing in e-mail?
Index: sys/dev/biovar.h
===================================================================
RCS file: /cvs/src/sys/dev/biovar.h,v
retrieving revision 1.39
diff -u -p -r1.39 biovar.h
--- sys/dev/biovar.h 14 Apr 2011 02:41:40 -0000 1.39
+++ sys/dev/biovar.h 14 May 2011 16:30:54 -0000
@@ -221,6 +221,17 @@ struct bioc_installboot {
void *bb_bootldr;
u_int32_t bb_bootblk_size;
u_int32_t bb_bootldr_size;
+};
+
+#define BIOCLISTCONTROLLERS _IOWR('B', 42, struct bioc_controllerlist)
+struct bioc_controller {
+ char bc_xname[16];
+};
+struct bioc_controllerlist {
+ /* max number of bioc_controller structs to fit in bcl_devs */
+ u_int32_t bcl_size;
+ /* pointer to destination buffer */
+ struct bioc_controller *bcl_list;
};
/* kernel and userspace defines */
Index: sys/dev/bio.c
===================================================================
RCS file: /cvs/src/sys/dev/bio.c,v
retrieving revision 1.12
diff -u -p -r1.12 bio.c
--- sys/dev/bio.c 22 Jan 2010 21:56:04 -0000 1.12
+++ sys/dev/bio.c 14 May 2011 16:30:54 -0000
@@ -74,7 +74,10 @@ bioioctl(dev_t dev, u_long cmd, caddr_t
{
struct bio_locate *locate;
struct bio_common *common;
+ struct bio_mapping *bm;
+ struct bioc_controllerlist *clist;
char name[16];
+ u_int32_t i;
int error;
switch (cmd) {
@@ -102,6 +105,26 @@ bioioctl(dev_t dev, u_long cmd, caddr_t
return (ENOENT);
return (bio_delegate_ioctl(
(struct bio_mapping *)common->bc_cookie, cmd, addr));
+
+ case BIOCLISTCONTROLLERS:
+ clist = (struct bioc_controllerlist *)addr;
+ i = 0;
+ error = 0;
+ LIST_FOREACH(bm, &bios, bm_link) {
+ if (clist->bcl_list == NULL)
+ goto next_controller;
+ if (i >= clist->bcl_size) {
+ error = ENOMEM;
+ goto next_controller;
+ }
+ copyoutstr(bm->bm_dev->dv_xname,
+ clist->bcl_list[i].bc_xname,
+ sizeof(bm->bm_dev->dv_xname), NULL);
+next_controller:
+ i++;
+ }
+ clist->bcl_size = i;
+ return (error);
default:
return (ENXIO);
Index: share/man/man4/bio.4
===================================================================
RCS file: /cvs/src/share/man/man4/bio.4,v
retrieving revision 1.29
diff -u -p -r1.29 bio.4
--- share/man/man4/bio.4 23 Aug 2010 00:58:49 -0000 1.29
+++ share/man/man4/bio.4 14 May 2011 16:30:54 -0000
@@ -147,6 +147,12 @@ Remove system disk (if present) and disa
volume.
.It Dv BIOCDISCIPLINE
Dispatch a discipline specific ioctl.
+.It Dv BIOCLISTCONTROLLERS
+Return list of all disk controllers registered in
+.Nm .
+Those names are suitable for
+.Dv BIOCLOCATE .
+Remember that there could be no volumes and disks on those controllers.
.El
.Sh FILES
.Bl -tag -width /dev/bio -compact
Index: sbin/bioctl/bioctl.c
===================================================================
RCS file: /cvs/src/sbin/bioctl/bioctl.c,v
retrieving revision 1.99
diff -u -p -r1.99 bioctl.c
--- sbin/bioctl/bioctl.c 4 Apr 2011 15:22:31 -0000 1.99
+++ sbin/bioctl/bioctl.c 14 May 2011 16:30:54 -0000
@@ -57,7 +57,6 @@ struct locator {
void usage(void);
const char *str2locator(const char *, struct locator *);
-void cleanup(void);
int bio_parse_devlist(char *, dev_t *);
void bio_kdf_derive(struct sr_crypto_kdfinfo *,
struct sr_crypto_kdf_pbkdf2 *, char *, int);
@@ -65,7 +64,8 @@ void bio_kdf_generate(struct sr_crypto
void derive_key_pkcs(int, u_int8_t *, size_t, u_int8_t *,
size_t, char *, int);
-void bio_inq(char *);
+void bio_listall(void);
+void bio_inq(char *, int);
void bio_alarm(char *);
int bio_getvolbyname(char *);
void bio_setstate(char *, int, char *);
@@ -104,12 +104,17 @@ main(int argc, char *argv[])
u_int16_t cr_level = 0;
int biodev = 0;
- if (argc < 2)
- usage();
+ if (argc < 2) {
+ bio_listall();
+ return 0;
+ }
- while ((ch = getopt(argc, argv, "a:b:C:c:dH:hik:l:Pp:qr:R:svu:")) !=
+ while ((ch = getopt(argc, argv, "Aa:b:C:c:dH:hik:l:Pp:qr:R:svu:")) !=
-1) {
switch (ch) {
+ case 'A': /* list all volumes */
+ bio_listall();
+ return 0;
case 'a': /* alarm */
func |= BIOC_ALARM;
al_arg = optarg;
@@ -192,6 +197,9 @@ main(int argc, char *argv[])
argc -= optind;
argv += optind;
+ if (func != 0 || argc != 0)
+ usage();
+
if (argc != 1 || (changepass && func != 0))
usage();
@@ -222,7 +230,7 @@ main(int argc, char *argv[])
} else if (changepass && !biodev) {
bio_changepass(devicename);
} else if (func & BIOC_INQ) {
- bio_inq(devicename);
+ bio_inq(devicename, 1);
} else if (func == BIOC_ALARM) {
bio_alarm(al_arg);
} else if (func == BIOC_BLINK) {
@@ -250,17 +258,18 @@ usage(void)
extern char *__progname;
fprintf(stderr,
- "usage: %s [-hiqv] [-a alarm-function] "
+ "usage: %1$s [-A]\n"
+ " %1$s [-hiqv] [-a alarm-function] "
"[-b channel:target[.lun]]\n"
"\t[-H channel:target[.lun]] "
"[-R device | channel:target[.lun]\n"
"\t[-u channel:target[.lun]] "
"device\n"
- " %s [-dhiPqsv] "
+ " %1$s [-dhiPqsv] "
"[-C flag[,flag,...]] [-c raidlevel] [-k keydisk]\n"
"\t[-l special[,special,...]] [-p passfile]\n"
"\t[-R device | channel:target[.lun] [-r rounds] "
- "device\n", __progname, __progname);
+ "device\n", __progname);
exit(1);
}
@@ -296,15 +305,51 @@ str2locator(const char *string, struct l
}
void
-bio_inq(char *name)
+bio_listall(void)
+{
+ struct bioc_controllerlist cl;
+ int rv;
+
+ memset(&cl, 0, sizeof(cl));
+
+ devh = open("/dev/bio", O_RDONLY);
+ if (devh == -1)
+ err(1, "Can't open %s", "/dev/bio");
+
+ rv = ioctl(devh, BIOCLISTCONTROLLERS, &cl);
+ if (rv == -1)
+ err(1, "BIOCLISTCONTROLLERS");
+ if (cl.bcl_size == 0)
+ return;
+
+ cl.bcl_list = calloc(cl.bcl_size, sizeof(struct bioc_controller));
+ if (cl.bcl_list == NULL)
+ err(1, "calloc");
+ rv = ioctl(devh, BIOCLISTCONTROLLERS, &cl);
+ if (rv == -1)
+ err(1, "BIOCLISTCONTROLLERS");
+ while (cl.bcl_size--) {
+ bl.bl_name = cl.bcl_list[cl.bcl_size].bc_xname;
+ rv = ioctl(devh, BIOCLOCATE, &bl);
+ if (rv == -1)
+ errx(1, "Can't locate %s device via %s",
+ bl.bl_name, "/dev/bio");
+ bio_inq(NULL, 0);
+ }
+ free(cl.bcl_list);
+}
+
+void
+bio_inq(char *name, int fallback)
{
char *status, size[64], scsiname[16], volname[32];
char percent[10], seconds[20];
- int rv, i, d, volheader, hotspare, unused;
+ int rv, i, d, hotspare, unused;
char encname[16], serial[32];
struct bioc_disk bd;
struct bioc_inq bi;
struct bioc_vol bv;
+ static int volheader = 0;
memset(&bi, 0, sizeof(bi));
@@ -312,14 +357,14 @@ bio_inq(char *name)
rv = ioctl(devh, BIOCINQ, &bi);
if (rv == -1) {
- if (errno == ENOTTY)
- bio_diskinq(name);
- else
+ if (errno == ENOTTY) {
+ if (fallback)
+ bio_diskinq(name);
+ } else
err(1, "BIOCINQ");
return;
}
- volheader = 0;
for (i = 0; i < bi.bi_novol; i++) {
memset(&bv, 0, sizeof(bv));
bv.bv_cookie = bl.bl_cookie;
Index: sbin/bioctl/bioctl.8
===================================================================
RCS file: /cvs/src/sbin/bioctl/bioctl.8,v
retrieving revision 1.84
diff -u -p -r1.84 bioctl.8
--- sbin/bioctl/bioctl.8 22 Dec 2010 16:25:32 -0000 1.84
+++ sbin/bioctl/bioctl.8 14 May 2011 16:30:54 -0000
@@ -32,6 +32,10 @@
.Sh SYNOPSIS
.Nm bioctl
.Bk -words
+.Op Fl A
+.Ek
+.Nm bioctl
+.Bk -words
.Op Fl hiqv
.Op Fl a Ar alarm-function
.Op Fl b Ar channel:target[.lun]
@@ -40,7 +44,6 @@
.Op Fl u Ar channel:target[.lun]
.Ar device
.Ek
-.Pp
.Nm bioctl
.Bk -words
.Op Fl dhiPqsv
@@ -82,6 +85,11 @@ device (e.g. softraid0).
.Pp
The options for RAID controllers are as follows:
.Bl -tag -width Ds
+.It Fl A
+List all volumes on all devices registered in
+.Xr bio 4 .
+This is the default behavior when no flags are given on command line.
+When this flag is specified, all other command parameters get ignored.
.It Fl a Ar alarm-function
Control the RAID card's alarm functionality, if supported.
.Ar alarm-function
Index: etc/daily
===================================================================
RCS file: /cvs/src/etc/daily,v
retrieving revision 1.71
diff -u -p -r1.71 daily
--- etc/daily 23 Apr 2011 19:35:53 -0000 1.71
+++ etc/daily 14 May 2011 16:30:54 -0000
@@ -135,6 +135,8 @@ done
next_part "Checking subsystem status:"
if [ "X$VERBOSESTATUS" != X0 ]; then
echo ""
+ echo "RAID:"
+ bioctl
echo "disks:"
df -kl
echo ""