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 ""

Reply via email to