Hello phk and -hackers

With md(4)'s great autounit feature, it's becoming harder to keep
track of md(4) devices.  Without autounit, you pretty much knew what
was what since you had to specify the unit number; with autounit,
things like `make release` configure an arbitrary unit without telling
you what it is, or even letting you change it (which isn't really
necessary).

jhb recently suggested that a way to get a list of active md(4)
devices and the way they were configured (size, type, etc.) would be a
nice remedy to the problem describe above (see "doFS.sh should obey
MDDEVICE if available" on -current a few weeks back).

I've come up with a relatively short patch to implement this.  It adds
a new ioctl, MDIOCQUERY, to get information on a configured md(4)
device (it returns a filled in md_ioctl structure modulo md_file,
which, I think, can't be obtained without explicitly storing the path
during cofiguration (i.e., you can't derive a path from a vnode)), and
uses the 'kern.disks' sysctl to find out which devices are currently
configured.  With it, `mdconfig -l` will list all devices and their
configurations, and `mdconfig -d -u <x>` will print information on the
device specified.

Comments?  Suggestions?

Thanks

                                        Dima Dorfman
                                        [EMAIL PROTECTED]


Index: sys/dev/md/md.c
===================================================================
RCS file: /st/src/FreeBSD/src/sys/dev/md/md.c,v
retrieving revision 1.23
diff -u -r1.23 md.c
--- sys/dev/md/md.c     2001/01/28 20:55:55     1.23
+++ sys/dev/md/md.c     2001/02/21 08:27:08
@@ -829,6 +829,30 @@
                default:
                        return (EOPNOTSUPP);
                }
+       case MDIOCQUERY:
+               sc = mdfind(mdio->md_unit);
+               if (sc == NULL)
+                       return (ENOENT);
+               mdio->md_type = sc->type;
+               mdio->md_options = sc->flags;
+               switch (sc->type) {
+               case MD_MALLOC:
+                       mdio->md_size = sc->nsect;
+                       break;
+               case MD_PRELOAD:
+                       mdio->md_size = sc->nsect;
+                       (u_char *)(uintptr_t)mdio->md_base = sc->pl_ptr;
+                       break;
+               case MD_SWAP:
+                       mdio->md_size = sc->nsect * (PAGE_SIZE / DEV_BSIZE);
+                       break;
+               case MD_VNODE:
+                       mdio->md_size = sc->nsect;
+                       /* XXX fill this in */
+                       mdio->md_file = NULL; 
+                       break;
+               }
+               return (0);
        default:
                return (ENOIOCTL);
        };
Index: sys/sys/mdioctl.h
===================================================================
RCS file: /st/src/FreeBSD/src/sys/sys/mdioctl.h,v
retrieving revision 1.7
diff -u -r1.7 mdioctl.h
--- sys/sys/mdioctl.h   2001/01/01 23:08:26     1.7
+++ sys/sys/mdioctl.h   2001/02/21 08:27:08
@@ -75,6 +75,7 @@
 
 #define MDIOCATTACH    _IOWR('m', 0, struct md_ioctl)  /* attach disk */
 #define MDIOCDETACH    _IOWR('m', 1, struct md_ioctl)  /* detach disk */
+#define MDIOCQUERY     _IOWR('m', 2, struct md_ioctl)  /* query status */
 
 #define MD_CLUSTER     0x01    /* Don't cluster */
 #define MD_RESERVE     0x02    /* Pre-reserve swap */
Index: sbin/mdconfig/mdconfig.c
===================================================================
RCS file: /st/src/FreeBSD/src/sbin/mdconfig/mdconfig.c,v
retrieving revision 1.6
diff -u -r1.6 mdconfig.c
--- sbin/mdconfig/mdconfig.c    2001/01/31 08:41:18     1.6
+++ sbin/mdconfig/mdconfig.c    2001/02/21 08:27:08
@@ -19,7 +19,12 @@
 #include <sys/ioctl.h>
 #include <sys/param.h>
 #include <sys/mdioctl.h>
+#include <sys/sysctl.h>
 
+int     intcmp(const void *, const void *);
+int     list(void);
+int     query(const int);
+
 struct md_ioctl mdio;
 
 enum {UNSET, ATTACH, DETACH} action = UNSET;
@@ -30,6 +35,7 @@
        fprintf(stderr, "Usage:\n");
        fprintf(stderr, "\tmdconfig -a -t type [-o [no]option]... [ -f file] [-s size] 
[-u unit]\n");
        fprintf(stderr, "\tmdconfig -d -u unit\n");
+       fprintf(stderr, "\tmdconfig -l [-u unit]\n");
        fprintf(stderr, "\t\ttype = {malloc, preload, vnode, swap}\n");
        fprintf(stderr, "\t\toption = {cluster, compress, reserve, autounit}\n");
        fprintf(stderr, "\t\tsize = %%d (512 byte blocks), %%dk (kB), %%dm (MB) or 
%%dg (GB)\n");
@@ -41,10 +47,10 @@
 {
        int ch, fd, i;
        char *p;
-       int cmdline = 0;
+       int cmdline = 0, haveunit = 0;
 
        for (;;) {
-               ch = getopt(argc, argv, "ab:df:o:s:t:u:");
+               ch = getopt(argc, argv, "ab:df:lo:s:t:u:");
                if (ch == -1)
                        break;
                switch (ch) {
@@ -86,6 +92,11 @@
                                usage();
                        mdio.md_file = optarg;
                        break;
+               case 'l':
+                       if (cmdline != 0)
+                               usage();
+                       cmdline = 4;
+                       break;
                case 'o':
                        if (cmdline != 2)
                                usage();
@@ -124,7 +135,7 @@
                                errx(1, "Unknown suffix on -s argument");
                        break;
                case 'u':
-                       if (cmdline != 2 && cmdline != 3)
+                       if (cmdline != 2 && cmdline != 3 && cmdline != 4)
                                usage();
                        if (!strncmp(optarg, "/dev/", 5))
                                optarg += 5;
@@ -133,12 +144,30 @@
                        mdio.md_unit = strtoul(optarg, NULL, 0);
                        mdio.md_unit = strtoul(optarg, NULL, 0);
                        mdio.md_options &= ~MD_AUTOUNIT;
+                       haveunit = 1;
                        break;
                default:
                        usage();
                }
        }
 
+       switch (cmdline)
+       {
+       case 0:
+               usage();
+               /* NOTREACHED */
+       case 1:
+       case 2:
+       case 3:
+               break;
+       case 4:
+               if (haveunit)
+                       return (query(mdio.md_unit));
+               else
+                       return (list());
+               break;
+       }
+
        fd = open("/dev/mdctl", O_RDWR, 0);
        if (fd < 0)
                err(1, "open(/dev/mdctl)");
@@ -156,3 +185,75 @@
        return (0);
 }
 
+int
+intcmp(const void *a, const void *b)
+{
+
+       return (*(int *)a - *(int *)b);
+}
+
+int
+list(void)
+{
+       char *disklist, *p, *p2;
+       int dll;                /* disklist length */
+       int mds[512], *mdsp, mdsc, i;
+
+       if (sysctlbyname("kern.disks", NULL, &dll, NULL, NULL) == -1)
+               err(1, "sysctlbyname: kern.disks");
+       if ( (disklist = malloc(dll)) == NULL)
+               err(1, "malloc");
+       if (sysctlbyname("kern.disks", disklist, &dll, NULL, NULL) == -1)
+               err(1, "sysctlbyname: kern.disks");
+
+       for (p = disklist, mdsp = mds, mdsc = 0;
+            (p2 = strsep(&p, " ")) != NULL;) {
+               if (strncmp(p2, "md", 2) != 0)
+                       continue;
+               p2 += 2;
+               *mdsp = strtoul(p2, NULL, 10);
+               mdsc++;
+               if (++mdsp >= &mds[sizeof(mds)])
+                       break;
+       }
+       qsort(mds, mdsc, sizeof(int), intcmp);
+       for (i = 0; i < mdsc; i++)
+               query(mds[i]);
+
+       free(disklist);
+       return (0);
+}
+
+int
+query(const int unit)
+{
+       int fd;
+
+       mdio.md_unit = unit;
+       if ( (fd = open("/dev/mdctl", O_RDWR)) < 0)
+               err(1, "open(/dev/mdctl)");
+       if (ioctl(fd, MDIOCQUERY, &mdio) < 0)
+               err(1, "ioctl(/dev/mdctl)");
+       close(fd);
+
+       switch (mdio.md_type) {
+       case MD_MALLOC:
+               (void)printf("md%d\tmalloc\t%d KBytes\n",
+                   mdio.md_unit, mdio.md_size / 2);
+               break;
+       case MD_PRELOAD:
+               (void)printf("md%d\tpreload\t%d KBytes\n",
+                   mdio.md_unit, mdio.md_size / 2);
+               break;
+       case MD_SWAP:
+               (void)printf("md%d\tswap\t%d KBytes\n",
+                   mdio.md_unit, mdio.md_size / 2);
+               break;
+       case MD_VNODE:
+               (void)printf("md%d\tvnode\t%d KBytes\n",
+                   mdio.md_unit, mdio.md_size / 2);
+               break;
+       }
+
+       return (0);
+}


To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-hackers" in the body of the message

Reply via email to