aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sbin/mdconfig/mdconfig.810
-rw-r--r--sbin/mdconfig/mdconfig.c134
-rw-r--r--sys/dev/md/md.c32
-rw-r--r--sys/sys/mdioctl.h3
4 files changed, 165 insertions, 14 deletions
diff --git a/sbin/mdconfig/mdconfig.8 b/sbin/mdconfig/mdconfig.8
index 3df260390f2d..09fbf44b6f3f 100644
--- a/sbin/mdconfig/mdconfig.8
+++ b/sbin/mdconfig/mdconfig.8
@@ -61,6 +61,9 @@
.Nm
.Fl d
.Fl u Ar unit
+.Nm
+.Fl l
+.Op Fl u Ar unit
.Sh DESCRIPTION
The
.Nm
@@ -92,6 +95,13 @@ swapspace is used to back this memory disk.
.El
.It Fl f Ar file
Filename to use for the vnode type memory disk.
+.It Fl l
+List information about configured
+.Xr md 4
+devices. If the
+.Fl u
+option is used in conjuction with this, the output is limited to
+information on the specified device.
.It Fl s Ar size
Size of the memory disk.
.Ar Size
diff --git a/sbin/mdconfig/mdconfig.c b/sbin/mdconfig/mdconfig.c
index 079be71d8670..3bcd7b259489 100644
--- a/sbin/mdconfig/mdconfig.c
+++ b/sbin/mdconfig/mdconfig.c
@@ -21,10 +21,16 @@
#include <sys/module.h>
#include <sys/linker.h>
#include <sys/mdioctl.h>
+#include <sys/sysctl.h>
+#include <sys/queue.h>
+
+int intcmp(const void *, const void *);
+int list(const int);
+int query(const int, const int);
struct md_ioctl mdio;
-enum {UNSET, ATTACH, DETACH} action = UNSET;
+enum {UNSET, ATTACH, DETACH, LIST} action = UNSET;
void mdmaybeload(void);
@@ -34,6 +40,7 @@ usage()
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");
@@ -48,7 +55,7 @@ main(int argc, char **argv)
int cmdline = 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) {
@@ -65,6 +72,13 @@ main(int argc, char **argv)
mdio.md_options = MD_AUTOUNIT;
cmdline = 3;
break;
+ case 'l':
+ if (cmdline != 0)
+ usage();
+ action = LIST;
+ mdio.md_options = MD_AUTOUNIT;
+ cmdline = 3;
+ break;
case 't':
if (cmdline != 1)
usage();
@@ -132,10 +146,9 @@ main(int argc, char **argv)
usage();
if (!strncmp(optarg, "/dev/", 5))
optarg += 5;
- if (!strncmp(optarg, "md", 2))
+ if (!strncmp(optarg, MD_NAME, sizeof(MD_NAME) - 1))
optarg += 2;
mdio.md_unit = strtoul(optarg, NULL, 0);
- mdio.md_unit = strtoul(optarg, NULL, 0);
mdio.md_options &= ~MD_AUTOUNIT;
break;
default:
@@ -144,20 +157,121 @@ main(int argc, char **argv)
}
mdmaybeload();
- fd = open("/dev/mdctl", O_RDWR, 0);
+ fd = open("/dev/" MDCTL_NAME, O_RDWR, 0);
if (fd < 0)
- err(1, "open(/dev/mdctl)");
- if (action == ATTACH) {
+ err(1, "open(/dev/%s)", MDCTL_NAME);
+ if (action == LIST) {
+ if (mdio.md_options & MD_AUTOUNIT)
+ list(fd);
+ else
+ query(fd, mdio.md_unit);
+ } else if (action == ATTACH) {
i = ioctl(fd, MDIOCATTACH, &mdio);
+ if (i < 0)
+ err(1, "ioctl(/dev/%s)", MDCTL_NAME);
} else {
if (mdio.md_options & MD_AUTOUNIT)
usage();
i = ioctl(fd, MDIOCDETACH, &mdio);
+ if (i < 0)
+ err(1, "ioctl(/dev/%s)", MDCTL_NAME);
}
- if (i < 0)
- err(1, "ioctl(/dev/mdctl)");
if (mdio.md_options & MD_AUTOUNIT)
- printf("md%d\n", mdio.md_unit);
+ printf("%s%d\n", MD_NAME, mdio.md_unit);
+ close (fd);
+ return (0);
+}
+
+int
+intcmp(const void *a, const void *b)
+{
+
+ return (*(int *)a - *(int *)b);
+}
+
+struct dl {
+ int unit;
+ SLIST_ENTRY(dl) slist;
+};
+
+SLIST_HEAD(, dl) dlist = SLIST_HEAD_INITIALIZER(&dlist);
+
+int
+list(const int fd)
+{
+ char *disklist, *p, *p2, *p3;
+ int unit, dll;
+ struct dl *dp, *di, *dn;
+
+ 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;
+ (p2 = strsep(&p, " ")) != NULL;) {
+ if (strncmp(p2, MD_NAME, sizeof(MD_NAME) - 1) != 0)
+ continue;
+ p2 += 2;
+ unit = strtoul(p2, &p3, 10);
+ if (p2 == p3)
+ continue;
+ dp = calloc(sizeof *dp, 1);
+ dp->unit = unit;
+ dn = SLIST_FIRST(&dlist);
+ if (dn == NULL || dn->unit > unit) {
+ SLIST_INSERT_HEAD(&dlist, dp, slist);
+ } else {
+ SLIST_FOREACH(di, &dlist, slist) {
+ dn = SLIST_NEXT(di, slist);
+ if (dn == NULL || dn->unit > unit) {
+ SLIST_INSERT_AFTER(di, dp, slist);
+ break;
+ }
+ }
+ }
+ }
+ SLIST_FOREACH(di, &dlist, slist)
+ query(fd, di->unit);
+ while (!SLIST_EMPTY(&dlist)) {
+ di = SLIST_FIRST(&dlist);
+ SLIST_REMOVE_HEAD(&dlist, slist);
+ free(di);
+ }
+ free(disklist);
+ return (0);
+}
+
+int
+query(const int fd, const int unit)
+{
+
+ mdio.md_unit = unit;
+
+ if (ioctl(fd, MDIOCQUERY, &mdio) < 0)
+ err(1, "ioctl(/dev/%s)", MDCTL_NAME);
+
+ switch (mdio.md_type) {
+ case MD_MALLOC:
+ (void)printf("%s%d\tmalloc\t%d KBytes\n", MD_NAME,
+ mdio.md_unit, mdio.md_size / 2);
+ break;
+ case MD_PRELOAD:
+ (void)printf("%s%d\tpreload\t%d KBytes\n", MD_NAME,
+ mdio.md_unit, mdio.md_size / 2);
+ break;
+ case MD_SWAP:
+ (void)printf("%s%d\tswap\t%d KBytes\n", MD_NAME,
+ mdio.md_unit, mdio.md_size / 2);
+ break;
+ case MD_VNODE:
+ (void)printf("%s%d\tvnode\t%d KBytes\n", MD_NAME,
+ mdio.md_unit, mdio.md_size / 2);
+ break;
+ }
+
return (0);
}
diff --git a/sys/dev/md/md.c b/sys/dev/md/md.c
index 48ff0b35f57c..dc53517a2591 100644
--- a/sys/dev/md/md.c
+++ b/sys/dev/md/md.c
@@ -133,7 +133,7 @@ static struct cdevsw md_cdevsw = {
/* poll */ nopoll,
/* mmap */ nommap,
/* strategy */ mdstrategy,
- /* name */ "md",
+ /* name */ MD_NAME,
/* maj */ CDEV_MAJOR,
/* dump */ nodump,
/* psize */ nopsize,
@@ -149,7 +149,7 @@ static struct cdevsw mdctl_cdevsw = {
/* poll */ nopoll,
/* mmap */ nommap,
/* strategy */ nostrategy,
- /* name */ "md",
+ /* name */ MD_NAME,
/* maj */ CDEV_MAJOR
};
@@ -533,7 +533,7 @@ mdinit(struct md_s *sc)
{
bioq_init(&sc->bio_queue);
- devstat_add_entry(&sc->stats, "md", sc->unit, sc->secsize,
+ devstat_add_entry(&sc->stats, MD_NAME, sc->unit, sc->secsize,
DEVSTAT_NO_ORDERED_TAGS,
DEVSTAT_TYPE_DIRECT | DEVSTAT_TYPE_IF_OTHER,
DEVSTAT_PRIORITY_OTHER);
@@ -608,7 +608,7 @@ mdcreate_malloc(struct md_ioctl *mdio)
for (u = 0; u < sc->nsect; u++)
MALLOC(sc->secp[u], u_char *, DEV_BSIZE, M_MDSECT, M_WAITOK | M_ZERO);
}
- printf("md%d: Malloc disk\n", sc->unit);
+ printf("%s%d: Malloc disk\n", MD_NAME, sc->unit);
mdinit(sc);
return (0);
}
@@ -833,6 +833,30 @@ mdctlioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
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);
};
diff --git a/sys/sys/mdioctl.h b/sys/sys/mdioctl.h
index 1507e6f2d714..6ebda6b8dfaf 100644
--- a/sys/sys/mdioctl.h
+++ b/sys/sys/mdioctl.h
@@ -64,6 +64,8 @@ struct md_ioctl {
int pad[100]; /* padding for future ideas */
};
+#define MD_NAME "md"
+#define MDCTL_NAME "mdctl"
#define MDIOVERSION 1
/*
@@ -75,6 +77,7 @@ struct md_ioctl {
#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 */