Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 22 Feb 2001 14:31:29 -0500 (EST)
From:      Robert Watson <rwatson@freebsd.org>
To:        Dima Dorfman <dima@unixfreak.org>
Cc:        freebsd-hackers@freebsd.org, phk@freebsd.org
Subject:   Re: Listing configured md(4) devices
Message-ID:  <Pine.NEB.3.96L.1010222142758.49833G-100000@fledge.watson.org>
In-Reply-To: <20010222080512.3DCF23E0C@bazooka.unixfreak.org>

next in thread | previous in thread | raw e-mail | index | archive | help

The only comments I really had on this were:

1) Your comment about vnode->name mapping is correct, there is no way to
turn a vnode pointer into an absolute path meaningful to the caller. There
are countless reasons why believing this is possible is a bad idea, and we
keep having to hit people with sticks to remind them that this is the
case.  :-)

2) I'm not sure I like the strncmp(.., "md", 2) stuff, as that means that
it would also match any other device name that might begin with md, which
potentially might not be provided by the md driver.  This is currently (I
suspect) hypothetical as we don't have any other drivers beginning with
md, but it would be nice not to preclude that in the future.  Restricting
all possible disk device names to two letters, of which the second is
always d, is not a scalable approach.  That said, writing an easy matching
function without that assumption probably isn't all that easy, either.
Don't know what the right answer is, so I'm just saying I'm not sure I
like it, not saying, change it. :-)

Robert N M Watson             FreeBSD Core Team, TrustedBSD Project
robert@fledge.watson.org      NAI Labs, Safeport Network Services

On Thu, 22 Feb 2001, Dima Dorfman wrote:

> 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
> 					dima@unixfreak.org
> 
> 
> 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 majordomo@FreeBSD.org
> with "unsubscribe freebsd-hackers" in the body of the message
> 


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.NEB.3.96L.1010222142758.49833G-100000>