Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 03 Sep 2001 11:28:16 +0300
From:      Maxim Sobolev <sobomax@FreeBSD.org>
To:        Poul-Henning Kamp <phk@critter.freebsd.dk>
Cc:        current@FreeBSD.org
Subject:   Re: Junior Kernel Hacker task: Get rid of NCCD constant.
Message-ID:  <3B933F20.8E93FDF9@FreeBSD.org>
References:  <1932.999492571@critter>

next in thread | previous in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format.
--------------4C8CE2CD7293DF8D444DE7F1
Content-Type: text/plain; charset=koi8-r
Content-Transfer-Encoding: 7bit

Poul-Henning Kamp wrote:

> can you send me the patch again ?  I get .rej files when I try
> to apply it to -current...

OOPS, sorry I forgot about -bB in my .cvsrc file - they are convinient when reading others' diffs, but apparently can do
bad things when you are submitting your own diffs to someone else. Mea culpa...

Attached please find regenerated diffs.

-Maxim

>
> Poul-Henning
>
> In message <3B8F8194.1CC1DAE3@FreeBSD.org>, Maxim Sobolev writes:
> >This is a multi-part message in MIME format.
> >--------------E528F773298029521D660E0A
> >Content-Type: text/plain; charset=x-user-defined
> >Content-Transfer-Encoding: 7bit
> >
> >Poul-Henning Kamp wrote:
> >
> >> Assignment:
> >>
> >> There is no reason for the NCCD constant to exist anymore.
> >>
> >> The CCD driver already has cloning support but CCDs "softc"
> >> structure is statically allocated for NCCD devices.
> >>
> >> Change the CCD driver to dynamically allocate memory as needed,
> >> the MD driver can be used as example as the overall morphology
> >> of the two drivers are the same.
> >
> >See attached patch. Due to the fact that statically allocated array was
> >replaced with queue(9) list, it became big PITA to use kvm in the ccdconfig(8)
> >utility, so in addition I've replaced kvm with ioctl interface, which
> >simplifies things and allows to lift sugid bit from it (I bet rwatson and other
> >trusted folks would like that ;) Also I've converted function prototypes into
> >single style (deK&Rified them), because most of them were affected by the my
> >changes anyway.
> >
> >I would like to hear comments and suggestions.
> >
> >Truly yours,
> >
> >Maxim "Jr. Kernel Hacker" Sobolev

--------------4C8CE2CD7293DF8D444DE7F1
Content-Type: text/plain; charset=koi8-r;
 name="ccd.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="ccd.diff"

Index: sys/sys/ccdvar.h
===================================================================
RCS file: /home/ncvs/src/sys/sys/ccdvar.h,v
retrieving revision 1.11
diff -d -u -r1.11 ccdvar.h
--- sys/sys/ccdvar.h	2000/01/16 09:25:05	1.11
+++ sys/sys/ccdvar.h	2001/09/03 08:19:24
@@ -86,19 +86,6 @@
  */
 
 /*
- * A concatenated disk is described at initialization time by this structure.
- */
-struct ccddevice {
-	int		ccd_unit;	/* logical unit of this ccd */
-	int		ccd_interleave;	/* interleave (DEV_BSIZE blocks) */
-	int		ccd_flags;	/* misc. information */
-	int		ccd_dk;		/* disk number */
-	struct vnode	**ccd_vpp;	/* array of component vnodes */
-	char		**ccd_cpp;	/* array of component pathnames */
-	int		ccd_ndev;	/* number of component devices */
-};
-
-/*
  * This structure is used to configure a ccd via ioctl(2).
  */
 struct ccd_ioctl {
@@ -110,12 +97,6 @@
 	size_t	ccio_size;		/* (returned) size of ccd */
 };
 
-/* ccd_flags */
-#define	CCDF_SWAP	0x01	/* interleave should be dmmax */
-#define CCDF_UNIFORM	0x02	/* use LCCD of sizes for uniform interleave */
-#define CCDF_MIRROR	0x04	/* use mirroring */
-#define CCDF_PARITY	0x08	/* use parity (RAID level 5) */
-
 /* Mask of user-settable ccd flags. */
 #define CCDF_USERMASK	(CCDF_SWAP|CCDF_UNIFORM|CCDF_MIRROR|CCDF_PARITY)
 
@@ -175,10 +156,13 @@
 };
 
 /*
- * A concatenated disk is described after initialization by this structure.
+ * A concatenated disk is described by this structure.
  */
-struct ccd_softc {
+struct ccd_s {
+	LIST_ENTRY(ccd_s) list;
+
 	int		 sc_unit;		/* logical unit number */
+	struct vnode	 **sc_vpp;		/* array of component vnodes */
 	int		 sc_flags;		/* flags */
 	int		 sc_cflags;		/* configuration flags */
 	size_t		 sc_size;		/* size of ccd */
@@ -195,10 +179,14 @@
 };
 
 /* sc_flags */
-#define CCDF_INITED	0x01	/* unit has been initialized */
-#define CCDF_WLABEL	0x02	/* label area is writable */
-#define CCDF_LABELLING	0x04	/* unit is currently being labelled */
-#define CCDF_WANTED	0x40	/* someone is waiting to obtain a lock */
+#define CCDF_SWAP	0x01	/* interleave should be dmmax */
+#define CCDF_UNIFORM	0x02	/* use LCCD of sizes for uniform interleave */
+#define CCDF_MIRROR	0x04	/* use mirroring */
+#define CCDF_PARITY	0x08	/* use parity (RAID level 5) */
+#define CCDF_INITED	0x10	/* unit has been initialized */
+#define CCDF_WLABEL	0x20	/* label area is writable */
+#define CCDF_LABELLING	0x40	/* unit is currently being labelled */
+#define CCDF_WANTED	0x60	/* someone is waiting to obtain a lock */
 #define CCDF_LOCKED	0x80	/* unit is locked */
 
 /*
@@ -210,3 +198,15 @@
  */
 #define CCDIOCSET	_IOWR('F', 16, struct ccd_ioctl)   /* enable ccd */
 #define CCDIOCCLR	_IOW('F', 17, struct ccd_ioctl)    /* disable ccd */
+
+struct ccdconf {
+	int		 size;		/* sizeof of buffer below */
+	struct ccd_s	 *buffer;	/* pointer to a configuration array */
+};
+#define CCDCONFINFO	_IOWR('F', 19, struct ccdconf)     /* get config */
+
+struct ccdcpps {
+	int		size;
+	char		*buffer;
+};
+#define CCDCPPINFO	_IOWR('F', 20, struct ccdcpps)	   /* get components */
Index: sys/dev/ccd/ccd.c
===================================================================
RCS file: /home/ncvs/src/sys/dev/ccd/ccd.c,v
retrieving revision 1.91
diff -d -u -r1.91 ccd.c
--- sys/dev/ccd/ccd.c	2001/05/08 09:10:27	1.91
+++ sys/dev/ccd/ccd.c	2001/09/03 08:19:24
@@ -87,8 +87,6 @@
  *	Moffett Field, CA 94035
  */
 
-#include "ccd.h"
-
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/kernel.h>
@@ -108,6 +106,8 @@
 
 #include <sys/ccdvar.h>
 
+MALLOC_DEFINE(M_CCD, "CCD driver", "Concatenated Disk driver");
+
 #if defined(CCDDEBUG) && !defined(DEBUG)
 #define DEBUG
 #endif
@@ -121,7 +121,6 @@
 static int ccddebug = CCDB_FOLLOW | CCDB_INIT | CCDB_IO | CCDB_LABEL |
     CCDB_VNODE;
 SYSCTL_INT(_debug, OID_AUTO, ccddebug, CTLFLAG_RW, &ccddebug, 0, "");
-#undef DEBUG
 #endif
 
 #define	ccdunit(x)	dkunit(x)
@@ -157,6 +156,10 @@
 #define CCDLABELDEV(dev)	\
 	(makedev(major((dev)), dkmakeminor(ccdunit((dev)), 0, RAW_PART)))
 
+/* convinient macros for often-used statements */
+#define IS_ALLOCATED(unit)	(ccdfind(unit) != NULL)
+#define IS_INITED(cs)		(((cs)->sc_flags & CCDF_INITED) != 0)
+
 static d_open_t ccdopen;
 static d_close_t ccdclose;
 static d_strategy_t ccdstrategy;
@@ -183,36 +186,38 @@
 	/* psize */	ccdsize,
 	/* flags */	D_DISK,
 };
+static LIST_HEAD(, ccd_s) ccd_softc_list = LIST_HEAD_INITIALIZER(&ccd_softc_list);
+
+static struct ccd_s *ccdfind(int);
+static struct ccd_s *ccdnew(int);
+static int ccddestroy(struct ccd_s *, struct proc *);
 
 /* called during module initialization */
-static	void ccdattach __P((void));
-static	int ccd_modevent __P((module_t, int, void *));
+static void ccdattach(void);
+static int ccd_modevent(module_t, int, void *);
 
 /* called by biodone() at interrupt time */
-static	void ccdiodone __P((struct bio *bp));
+static void ccdiodone(struct bio *bp);
 
-static	void ccdstart __P((struct ccd_softc *, struct bio *));
-static	void ccdinterleave __P((struct ccd_softc *, int));
-static	void ccdintr __P((struct ccd_softc *, struct bio *));
-static	int ccdinit __P((struct ccddevice *, char **, struct proc *));
-static	int ccdlookup __P((char *, struct proc *p, struct vnode **));
-static	void ccdbuffer __P((struct ccdbuf **ret, struct ccd_softc *,
-		struct bio *, daddr_t, caddr_t, long));
-static	void ccdgetdisklabel __P((dev_t));
-static	void ccdmakedisklabel __P((struct ccd_softc *));
-static	int ccdlock __P((struct ccd_softc *));
-static	void ccdunlock __P((struct ccd_softc *));
+static void ccdstart(struct ccd_s *, struct bio *);
+static void ccdinterleave(struct ccd_s *, int);
+static void ccdintr(struct ccd_s *, struct bio *);
+static int ccdinit(struct ccd_s *, char **, struct proc *);
+static int ccdlookup(char *, struct proc *p, struct vnode **);
+static void ccdbuffer(struct ccdbuf **ret, struct ccd_s *,
+		      struct bio *, daddr_t, caddr_t, long);
+static void ccdgetdisklabel(dev_t);
+static void ccdmakedisklabel(struct ccd_s *);
+static int ccdlock(struct ccd_s *);
+static void ccdunlock(struct ccd_s *);
 
 #ifdef DEBUG
-static	void printiinfo __P((struct ccdiinfo *));
+static void printiinfo(struct ccdiinfo *);
 #endif
 
 /* Non-private for the benefit of libkvm. */
-struct	ccd_softc *ccd_softc;
-struct	ccddevice *ccddevs;
-struct	ccdbuf *ccdfreebufs;
-static	int numccdfreebufs;
-static	int numccd = 0;
+struct ccdbuf *ccdfreebufs;
+static int numccdfreebufs;
 
 /*
  * getccdbuf() -	Allocate and zero a ccd buffer.
@@ -281,6 +286,47 @@
 #define CCD_OFFSET 16
 #endif
 
+static struct ccd_s *
+ccdfind(int unit)
+{
+	struct ccd_s *sc = NULL;
+
+	/* XXX: LOCK(unique unit numbers) */
+	LIST_FOREACH(sc, &ccd_softc_list, list) {
+		if (sc->sc_unit == unit)
+			break;
+	}
+	/* XXX: UNLOCK(unique unit numbers) */
+	return ((sc == NULL) || (sc->sc_unit != unit) ? NULL : sc);
+}
+
+static struct ccd_s *
+ccdnew(int unit)
+{
+	struct ccd_s *sc;
+
+	/* XXX: LOCK(unique unit numbers) */
+	if (IS_ALLOCATED(unit) || unit > DKMAXUNIT)
+		return (NULL);
+
+	MALLOC(sc, struct ccd_s *, sizeof(*sc), M_CCD, M_WAITOK | M_ZERO);
+	sc->sc_unit = unit;
+	LIST_INSERT_HEAD(&ccd_softc_list, sc, list);
+	/* XXX: UNLOCK(unique unit numbers) */
+	return (sc);
+}
+
+static int
+ccddestroy(struct ccd_s *sc, struct proc *p)
+{
+
+	/* XXX: LOCK(unique unit numbers) */
+	LIST_REMOVE(sc, list);
+	/* XXX: UNLOCK(unique unit numbers) */
+	FREE(sc, M_CCD);
+	return (0);
+}
+
 static void
 ccd_clone(void *arg, char *name, int namelen, dev_t *dev)
 {
@@ -292,8 +338,6 @@
 	i = dev_stdclone(name, &s, "ccd", &u);
 	if (i != 2)
 		return;
-	if (u >= numccd)
-		return;
 	if (*s < 'a' || *s > 'h')
 		return;
 	if (s[1] != '\0')
@@ -304,48 +348,19 @@
 
 /*
  * Called by main() during pseudo-device attachment.  All we need
- * to do is allocate enough space for devices to be configured later, and
- * add devsw entries.
+ * to do is to add devsw entries.
  */
 static void
 ccdattach()
 {
-	int i;
-	int num = NCCD;
-
-	if (num > 1)
-		printf("ccd0-%d: Concatenated disk drivers\n", num-1);
-	else
-		printf("ccd0: Concatenated disk driver\n");
-
-	ccd_softc = (struct ccd_softc *)malloc(num * sizeof(struct ccd_softc),
-	    M_DEVBUF, M_NOWAIT);
-	ccddevs = (struct ccddevice *)malloc(num * sizeof(struct ccddevice),
-	    M_DEVBUF, M_NOWAIT);
-	if ((ccd_softc == NULL) || (ccddevs == NULL)) {
-		printf("WARNING: no memory for concatenated disks\n");
-		if (ccd_softc != NULL)
-			free(ccd_softc, M_DEVBUF);
-		if (ccddevs != NULL)
-			free(ccddevs, M_DEVBUF);
-		return;
-	}
-	numccd = num;
-	bzero(ccd_softc, num * sizeof(struct ccd_softc));
-	bzero(ccddevs, num * sizeof(struct ccddevice));
+	printf("ccd0: Concatenated disk driver\n");
 
 	cdevsw_add(&ccd_cdevsw);
-	/* XXX: is this necessary? */
-	for (i = 0; i < numccd; ++i) 
-		ccddevs[i].ccd_dk = -1;
 	EVENTHANDLER_REGISTER(dev_clone, ccd_clone, 0, 1000);
 }
 
 static int
-ccd_modevent(mod, type, data)
-	module_t mod;
-	int type;
-	void *data;
+ccd_modevent(module_t mod, int type, void *data)
 {
 	int error = 0;
 
@@ -368,12 +383,8 @@
 DEV_MODULE(ccd, ccd_modevent, NULL);
 
 static int
-ccdinit(ccd, cpaths, p)
-	struct ccddevice *ccd;
-	char **cpaths;
-	struct proc *p;
+ccdinit(struct ccd_s *cs, char **cpaths, struct proc *p)
 {
-	struct ccd_softc *cs = &ccd_softc[ccd->ccd_unit];
 	struct ccdcinfo *ci = NULL;	/* XXX */
 	size_t size;
 	int ix;
@@ -387,12 +398,10 @@
 
 #ifdef DEBUG
 	if (ccddebug & (CCDB_FOLLOW|CCDB_INIT))
-		printf("ccdinit: unit %d\n", ccd->ccd_unit);
+		printf("ccdinit: unit %d\n", cs->sc_unit);
 #endif
 
 	cs->sc_size = 0;
-	cs->sc_ileave = ccd->ccd_interleave;
-	cs->sc_nccdisks = ccd->ccd_ndev;
 
 	/* Allocate space for the component info. */
 	cs->sc_cinfo = malloc(cs->sc_nccdisks * sizeof(struct ccdcinfo),
@@ -405,7 +414,7 @@
 	maxsecsize = 0;
 	minsize = 0;
 	for (ix = 0; ix < cs->sc_nccdisks; ix++) {
-		vp = ccd->ccd_vpp[ix];
+		vp = cs->sc_vpp[ix];
 		ci = &cs->sc_cinfo[ix];
 		ci->ci_vp = vp;
 
@@ -418,7 +427,7 @@
 #ifdef DEBUG
 			if (ccddebug & (CCDB_FOLLOW|CCDB_INIT))
 				printf("ccd%d: can't copy path, error = %d\n",
-				    ccd->ccd_unit, error);
+				    cs->sc_unit, error);
 #endif
 			goto fail;
 		}
@@ -435,7 +444,7 @@
 #ifdef DEBUG
 			if (ccddebug & (CCDB_FOLLOW|CCDB_INIT))
 				 printf("ccd%d: %s: ioctl failed, error = %d\n",
-				     ccd->ccd_unit, ci->ci_path, error);
+				     cs->sc_unit, ci->ci_path, error);
 #endif
 			goto fail;
 		}
@@ -448,7 +457,7 @@
 #ifdef DEBUG
 			if (ccddebug & (CCDB_FOLLOW|CCDB_INIT))
 				printf("ccd%d: %s: incorrect partition type\n",
-				    ccd->ccd_unit, ci->ci_path);
+				    cs->sc_unit, ci->ci_path);
 #endif
 			error = EFTYPE;
 			goto fail;
@@ -466,7 +475,7 @@
 #ifdef DEBUG
 			if (ccddebug & (CCDB_FOLLOW|CCDB_INIT))
 				printf("ccd%d: %s: size == 0\n",
-				    ccd->ccd_unit, ci->ci_path);
+				    cs->sc_unit, ci->ci_path);
 #endif
 			error = ENODEV;
 			goto fail;
@@ -487,7 +496,7 @@
 #ifdef DEBUG
 		if (ccddebug & (CCDB_FOLLOW|CCDB_INIT))
 			printf("ccd%d: interleave must be at least %d\n",
-			    ccd->ccd_unit, (maxsecsize / DEV_BSIZE));
+			    cs->sc_unit, (maxsecsize / DEV_BSIZE));
 #endif
 		error = EINVAL;
 		goto fail;
@@ -502,12 +511,12 @@
 	 * overall size.  Half the space is lost when CCDF_MIRROR is
 	 * specified.  One disk is lost when CCDF_PARITY is specified.
 	 */
-	if (ccd->ccd_flags & CCDF_UNIFORM) {
+	if (cs->sc_flags & CCDF_UNIFORM) {
 		for (ci = cs->sc_cinfo;
 		     ci < &cs->sc_cinfo[cs->sc_nccdisks]; ci++) {
 			ci->ci_size = minsize;
 		}
-		if (ccd->ccd_flags & CCDF_MIRROR) {
+		if (cs->sc_flags & CCDF_MIRROR) {
 			/*
 			 * Check to see if an even number of components
 			 * have been specified.  The interleave must also
@@ -515,21 +524,21 @@
 			 * guarentee the topology.
 			 */
 			if (cs->sc_nccdisks % 2) {
-				printf("ccd%d: mirroring requires an even number of disks\n", ccd->ccd_unit );
+				printf("ccd%d: mirroring requires an even number of disks\n", cs->sc_unit );
 				error = EINVAL;
 				goto fail;
 			}
 			if (cs->sc_ileave == 0) {
-				printf("ccd%d: an interleave must be specified when mirroring\n", ccd->ccd_unit);
+				printf("ccd%d: an interleave must be specified when mirroring\n", cs->sc_unit);
 				error = EINVAL;
 				goto fail;
 			}
 			cs->sc_size = (cs->sc_nccdisks/2) * minsize;
-		} else if (ccd->ccd_flags & CCDF_PARITY) {
+		} else if (cs->sc_flags & CCDF_PARITY) {
 			cs->sc_size = (cs->sc_nccdisks-1) * minsize;
 		} else {
 			if (cs->sc_ileave == 0) {
-				printf("ccd%d: an interleave must be specified when using parity\n", ccd->ccd_unit);
+				printf("ccd%d: an interleave must be specified when using parity\n", cs->sc_unit);
 				error = EINVAL;
 				goto fail;
 			}
@@ -540,7 +549,7 @@
 	/*
 	 * Construct the interleave table.
 	 */
-	ccdinterleave(cs, ccd->ccd_unit);
+	ccdinterleave(cs, cs->sc_unit);
 
 	/*
 	 * Create pseudo-geometry based on 1MB cylinders.  It's
@@ -554,14 +563,13 @@
 	/*
 	 * Add an devstat entry for this device.
 	 */
-	devstat_add_entry(&cs->device_stats, "ccd", ccd->ccd_unit,
+	devstat_add_entry(&cs->device_stats, "ccd", cs->sc_unit,
 			  ccg->ccg_secsize, DEVSTAT_ALL_SUPPORTED,
 			  DEVSTAT_TYPE_STORARRAY |DEVSTAT_TYPE_IF_OTHER,
 			  DEVSTAT_PRIORITY_ARRAY);
 
 	cs->sc_flags |= CCDF_INITED;
-	cs->sc_cflags = ccd->ccd_flags;	/* So we can find out later... */
-	cs->sc_unit = ccd->ccd_unit;
+	cs->sc_cflags = cs->sc_flags;	/* So we can find out later... */
 	return (0);
 fail:
 	while (ci > cs->sc_cinfo) {
@@ -573,9 +581,7 @@
 }
 
 static void
-ccdinterleave(cs, unit)
-	struct ccd_softc *cs;
-	int unit;
+ccdinterleave(struct ccd_s *cs, int unit)
 {
 	struct ccdcinfo *ci, *smallci;
 	struct ccdiinfo *ii;
@@ -697,13 +703,10 @@
 
 /* ARGSUSED */
 static int
-ccdopen(dev, flags, fmt, p)
-	dev_t dev;
-	int flags, fmt;
-	struct proc *p;
+ccdopen(dev_t dev, int flags, int fmt, struct proc *p)
 {
 	int unit = ccdunit(dev);
-	struct ccd_softc *cs;
+	struct ccd_s *cs;
 	struct disklabel *lp;
 	int error = 0, part, pmask;
 
@@ -711,9 +714,8 @@
 	if (ccddebug & CCDB_FOLLOW)
 		printf("ccdopen(%p, %x)\n", dev, flags);
 #endif
-	if (unit >= numccd)
-		return (ENXIO);
-	cs = &ccd_softc[unit];
+
+	cs = IS_ALLOCATED(unit) ? ccdfind(unit) : ccdnew(unit);
 
 	if ((error = ccdlock(cs)) != 0)
 		return (error);
@@ -728,7 +730,7 @@
 	 * open partitions.  If not, then it's safe to update
 	 * the in-core disklabel.
 	 */
-	if ((cs->sc_flags & CCDF_INITED) && (cs->sc_openmask == 0))
+	if (IS_INITED(cs) && (cs->sc_openmask == 0))
 		ccdgetdisklabel(dev);
 
 	/* Check that the partition exists. */
@@ -746,13 +748,10 @@
 
 /* ARGSUSED */
 static int
-ccdclose(dev, flags, fmt, p)
-	dev_t dev;
-	int flags, fmt;
-	struct proc *p;
+ccdclose(dev_t dev, int flags, int fmt, struct proc *p)
 {
 	int unit = ccdunit(dev);
-	struct ccd_softc *cs;
+	struct ccd_s *cs;
 	int error = 0, part;
 
 #ifdef DEBUG
@@ -760,9 +759,9 @@
 		printf("ccdclose(%p, %x)\n", dev, flags);
 #endif
 
-	if (unit >= numccd)
+	if (!IS_ALLOCATED(unit))
 		return (ENXIO);
-	cs = &ccd_softc[unit];
+	cs = ccdfind(unit);
 
 	if ((error = ccdlock(cs)) != 0)
 		return (error);
@@ -771,16 +770,19 @@
 
 	/* ...that much closer to allowing unconfiguration... */
 	cs->sc_openmask &= ~(1 << part);
-	ccdunlock(cs);
+	/* collect "garbage" if possible */
+	if (!IS_INITED(cs) && (cs->sc_flags & CCDF_WANTED) == 0)
+		ccddestroy(cs, p);
+	else
+		ccdunlock(cs);
 	return (0);
 }
 
 static void
-ccdstrategy(bp)
-	struct bio *bp;
+ccdstrategy(struct bio *bp)
 {
 	int unit = ccdunit(bp->bio_dev);
-	struct ccd_softc *cs = &ccd_softc[unit];
+	struct ccd_s *cs = ccdfind(unit);
 	int s;
 	int wlabel;
 	struct disklabel *lp;
@@ -789,7 +791,7 @@
 	if (ccddebug & CCDB_FOLLOW)
 		printf("ccdstrategy(%p): unit %d\n", bp, unit);
 #endif
-	if ((cs->sc_flags & CCDF_INITED) == 0) {
+	if (!IS_INITED(cs)) {
 		biofinish(bp, NULL, ENXIO);
 		return;
 	}
@@ -854,9 +856,7 @@
 }
 
 static void
-ccdstart(cs, bp)
-	struct ccd_softc *cs;
-	struct bio *bp;
+ccdstart(struct ccd_s *cs, struct bio *bp)
 {
 	long bcount, rcount;
 	struct ccdbuf *cbp[4];
@@ -930,13 +930,7 @@
  * Build a component buffer header.
  */
 static void
-ccdbuffer(cb, cs, bp, bn, addr, bcount)
-	struct ccdbuf **cb;
-	struct ccd_softc *cs;
-	struct bio *bp;
-	daddr_t bn;
-	caddr_t addr;
-	long bcount;
+ccdbuffer(struct ccdbuf **cb, struct ccd_s *cs, struct bio *bp, daddr_t bn, caddr_t addr, long bcount)
 {
 	struct ccdcinfo *ci, *ci2 = NULL;	/* XXX */
 	struct ccdbuf *cbp;
@@ -1073,7 +1067,7 @@
 	 * context for ccdiodone
 	 */
 	cbp->cb_obp = bp;
-	cbp->cb_unit = cs - ccd_softc;
+	cbp->cb_unit = cs->sc_unit;
 	cbp->cb_comp = ci - cs->sc_cinfo;
 
 #ifdef DEBUG
@@ -1104,9 +1098,7 @@
 }
 
 static void
-ccdintr(cs, bp)
-	struct ccd_softc *cs;
-	struct bio *bp;
+ccdintr(struct ccd_s *cs, struct bio *bp)
 {
 #ifdef DEBUG
 	if (ccddebug & CCDB_FOLLOW)
@@ -1126,8 +1118,7 @@
  * take a ccd interrupt.
  */
 static void
-ccdiodone(ibp)
-	struct bio *ibp;
+ccdiodone(struct bio *ibp)
 {
 	struct ccdbuf *cbp = (struct ccdbuf *)ibp;
 	struct bio *bp = cbp->cb_obp;
@@ -1157,7 +1148,7 @@
 	if (cbp->cb_buf.bio_flags & BIO_ERROR) {
 		const char *msg = "";
 
-		if ((ccd_softc[unit].sc_cflags & CCDF_MIRROR) &&
+		if ((ccdfind(unit)->sc_cflags & CCDF_MIRROR) &&
 		    (cbp->cb_buf.bio_cmd == BIO_READ) &&
 		    (cbp->cb_pflags & CCDPF_MIRROR_DONE) == 0) {
 			/*
@@ -1166,7 +1157,7 @@
 			 * are doing a scan we do not keep hitting the
 			 * bad disk first.
 			 */
-			struct ccd_softc *cs = &ccd_softc[unit];
+			struct ccd_s *cs = ccdfind(unit);
 
 			msg = ", trying other disk";
 			cs->sc_pick = 1 - cs->sc_pick;
@@ -1190,7 +1181,7 @@
 	 * we free the second I/O without initiating it.
 	 */
 
-	if (ccd_softc[unit].sc_cflags & CCDF_MIRROR) {
+	if (ccdfind(unit)->sc_cflags & CCDF_MIRROR) {
 		if (cbp->cb_buf.bio_cmd == BIO_WRITE) {
 			/*
 			 * When writing, handshake with the second buffer
@@ -1244,36 +1235,28 @@
 	if (bp->bio_resid < 0)
 		panic("ccdiodone: count");
 	if (bp->bio_resid == 0)
-		ccdintr(&ccd_softc[unit], bp);
+		ccdintr(ccdfind(unit), bp);
 	splx(s);
 }
 
 static int
-ccdioctl(dev, cmd, data, flag, p)
-	dev_t dev;
-	u_long cmd;
-	caddr_t data;
-	int flag;
-	struct proc *p;
+ccdioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
 {
 	int unit = ccdunit(dev);
 	int i, j, lookedup = 0, error = 0;
 	int part, pmask, s;
-	struct ccd_softc *cs;
+	struct ccd_s *cs;
 	struct ccd_ioctl *ccio = (struct ccd_ioctl *)data;
-	struct ccddevice ccd;
 	char **cpp;
 	struct vnode **vpp;
 
-	if (unit >= numccd)
+	if (!IS_ALLOCATED(unit))
 		return (ENXIO);
-	cs = &ccd_softc[unit];
-
-	bzero(&ccd, sizeof(ccd));
+	cs = ccdfind(unit);
 
 	switch (cmd) {
 	case CCDIOCSET:
-		if (cs->sc_flags & CCDF_INITED)
+		if (IS_INITED(cs))
 			return (EBUSY);
 
 		if ((flag & FWRITE) == 0)
@@ -1283,9 +1266,8 @@
 			return (error);
 
 		/* Fill in some important bits. */
-		ccd.ccd_unit = unit;
-		ccd.ccd_interleave = ccio->ccio_ileave;
-		if (ccd.ccd_interleave == 0 &&
+		cs->sc_ileave = ccio->ccio_ileave;
+		if (cs->sc_ileave == 0 &&
 		    ((ccio->ccio_flags & CCDF_MIRROR) ||
 		     (ccio->ccio_flags & CCDF_PARITY))) {
 			printf("ccd%d: disabling mirror/parity, interleave is 0\n", unit);
@@ -1302,7 +1284,7 @@
 			       unit);
 			ccio->ccio_flags |= CCDF_UNIFORM;
 		}
-		ccd.ccd_flags = ccio->ccio_flags & CCDF_USERMASK;
+		cs->sc_flags = ccio->ccio_flags & CCDF_USERMASK;
 
 		/*
 		 * Allocate space for and copy in the array of
@@ -1345,18 +1327,24 @@
 			}
 			++lookedup;
 		}
-		ccd.ccd_cpp = cpp;
-		ccd.ccd_vpp = vpp;
-		ccd.ccd_ndev = ccio->ccio_ndisks;
+		cs->sc_vpp = vpp;
+		cs->sc_nccdisks = ccio->ccio_ndisks;
 
 		/*
 		 * Initialize the ccd.  Fills in the softc for us.
 		 */
-		if ((error = ccdinit(&ccd, cpp, p)) != 0) {
+		if ((error = ccdinit(cs, cpp, p)) != 0) {
 			for (j = 0; j < lookedup; ++j)
 				(void)vn_close(vpp[j], FREAD|FWRITE,
 				    p->p_ucred, p);
-			bzero(&ccd_softc[unit], sizeof(struct ccd_softc));
+			/*
+			 * We can't ccddestroy() cs just yet, because nothing
+			 * prevents user-level app to do another ioctl()
+			 * without closing the device first, therefore
+			 * declare unit null and void and let ccdclose()
+			 * destroy it when it is safe to do so.
+			 */
+			cs->sc_flags &= (CCDF_WANTED | CCDF_LOCKED);
 			free(vpp, M_DEVBUF);
 			free(cpp, M_DEVBUF);
 			ccdunlock(cs);
@@ -1367,7 +1355,6 @@
 		 * The ccd has been successfully initialized, so
 		 * we can place it into the array and read the disklabel.
 		 */
-		bcopy(&ccd, &ccddevs[unit], sizeof(ccd));
 		ccio->ccio_unit = unit;
 		ccio->ccio_size = cs->sc_size;
 		ccdgetdisklabel(dev);
@@ -1377,7 +1364,7 @@
 		break;
 
 	case CCDIOCCLR:
-		if ((cs->sc_flags & CCDF_INITED) == 0)
+		if (!IS_INITED(cs))
 			return (ENXIO);
 
 		if ((flag & FWRITE) == 0)
@@ -1394,9 +1381,8 @@
 			return (EBUSY);
 		}
 
-		/*
-		 * Free ccd_softc information and clear entry.
-		 */
+		/* Declare unit null and void (reset all flags) */
+		cs->sc_flags &= (CCDF_WANTED | CCDF_LOCKED);
 
 		/* Close the components and free their pathnames. */
 		for (i = 0; i < cs->sc_nccdisks; ++i) {
@@ -1422,38 +1408,93 @@
 		/* Free component info and interleave table. */
 		free(cs->sc_cinfo, M_DEVBUF);
 		free(cs->sc_itable, M_DEVBUF);
-		cs->sc_flags &= ~CCDF_INITED;
-
-		/*
-		 * Free ccddevice information and clear entry.
-		 */
-		free(ccddevs[unit].ccd_cpp, M_DEVBUF);
-		free(ccddevs[unit].ccd_vpp, M_DEVBUF);
-		ccd.ccd_dk = -1;
-		bcopy(&ccd, &ccddevs[unit], sizeof(ccd));
+		free(cs->sc_vpp, M_DEVBUF);
 
-		/*
-		 * And remove the devstat entry.
-		 */
+		/* And remove the devstat entry. */
 		devstat_remove_entry(&cs->device_stats);
 
 		/* This must be atomic. */
 		s = splhigh();
 		ccdunlock(cs);
-		bzero(cs, sizeof(struct ccd_softc));
 		splx(s);
 
 		break;
 
+	case CCDCONFINFO:
+		{
+			int ninit = 0;
+			struct ccdconf *conf = (struct ccdconf *)data;
+			struct ccd_s *tmpcs;
+			struct ccd_s *ubuf = conf->buffer;
+
+			/* XXX: LOCK(unique unit numbers) */
+			LIST_FOREACH(tmpcs, &ccd_softc_list, list)
+				if (IS_INITED(tmpcs))
+					ninit++;
+
+			if (conf->size == 0) {
+				conf->size = sizeof(struct ccd_s) * ninit;
+				break;
+			} else if ((conf->size / sizeof(struct ccd_s) != ninit) ||
+			    (conf->size % sizeof(struct ccd_s) != 0)) {
+				/* XXX: UNLOCK(unique unit numbers) */
+				return (EINVAL);
+			}
+
+			ubuf += ninit;
+			LIST_FOREACH(tmpcs, &ccd_softc_list, list) {
+				if (!IS_INITED(tmpcs))
+					continue;
+				error = copyout(tmpcs, --ubuf,
+				    sizeof(struct ccd_s));
+				if (error != 0)
+					/* XXX: UNLOCK(unique unit numbers) */
+					return (error);
+			}
+			/* XXX: UNLOCK(unique unit numbers) */
+		}
+		break;
+
+	case CCDCPPINFO:
+		if (!IS_INITED(cs))
+			return (ENXIO);
+
+		{
+			int len = 0;
+			struct ccdcpps *cpps = (struct ccdcpps *)data;
+			char *ubuf = cpps->buffer;
+
+
+			for (i = 0; i < cs->sc_nccdisks; ++i)
+				len += cs->sc_cinfo[i].ci_pathlen;
+
+			if (cpps->size == 0) {
+				cpps->size = len;
+				break;
+			} else if (cpps->size != len) {
+				return (EINVAL);
+			}
+
+			for (i = 0; i < cs->sc_nccdisks; ++i) {
+				len = cs->sc_cinfo[i].ci_pathlen;
+				error = copyout(cs->sc_cinfo[i].ci_path, ubuf,
+				    len);
+				if (error != 0)
+					return (error);
+				ubuf += len;
+			}
+		}
+		break;
+
 	case DIOCGDINFO:
-		if ((cs->sc_flags & CCDF_INITED) == 0)
+		if (!IS_INITED(cs))
 			return (ENXIO);
 
 		*(struct disklabel *)data = cs->sc_label;
 		break;
 
 	case DIOCGPART:
-		if ((cs->sc_flags & CCDF_INITED) == 0)
+		if (!IS_INITED(cs))
 			return (ENXIO);
 
 		((struct partinfo *)data)->disklab = &cs->sc_label;
@@ -1463,7 +1504,7 @@
 
 	case DIOCWDINFO:
 	case DIOCSDINFO:
-		if ((cs->sc_flags & CCDF_INITED) == 0)
+		if (!IS_INITED(cs))
 			return (ENXIO);
 
 		if ((flag & FWRITE) == 0)
@@ -1491,7 +1532,7 @@
 		break;
 
 	case DIOCWLABEL:
-		if ((cs->sc_flags & CCDF_INITED) == 0)
+		if (!IS_INITED(cs))
 			return (ENXIO);
 
 		if ((flag & FWRITE) == 0)
@@ -1510,19 +1551,18 @@
 }
 
 static int
-ccdsize(dev)
-	dev_t dev;
+ccdsize(dev_t dev)
 {
-	struct ccd_softc *cs;
+	struct ccd_s *cs;
 	int part, size;
 
 	if (ccdopen(dev, 0, S_IFCHR, curproc))
 		return (-1);
 
-	cs = &ccd_softc[ccdunit(dev)];
+	cs = ccdfind(ccdunit(dev));
 	part = ccdpart(dev);
 
-	if ((cs->sc_flags & CCDF_INITED) == 0)
+	if (!IS_INITED(cs))
 		return (-1);
 
 	if (cs->sc_label.d_partitions[part].p_fstype != FS_SWAP)
@@ -1537,8 +1577,7 @@
 }
 
 static int
-ccddump(dev)
-	dev_t dev;
+ccddump(dev_t dev)
 {
 
 	/* Not implemented. */
@@ -1551,10 +1590,7 @@
  * set *vpp to the file's vnode.
  */
 static int
-ccdlookup(path, p, vpp)
-	char *path;
-	struct proc *p;
-	struct vnode **vpp;	/* result */
+ccdlookup(char *path, struct proc *p, struct vnode **vpp)
 {
 	struct nameidata nd;
 	struct vnode *vp;
@@ -1564,7 +1600,7 @@
 	flags = FREAD | FWRITE;
 	if ((error = vn_open(&nd, &flags, 0)) != 0) {
 #ifdef DEBUG
-		if (ccddebug & CCDB_FOLLOW|CCDB_INIT)
+		if (ccddebug & (CCDB_FOLLOW|CCDB_INIT))
 			printf("ccdlookup: vn_open error = %d\n", error);
 #endif
 		return (error);
@@ -1601,11 +1637,10 @@
  * up.
  */
 static void
-ccdgetdisklabel(dev)
-	dev_t dev;
+ccdgetdisklabel(dev_t dev)
 {
 	int unit = ccdunit(dev);
-	struct ccd_softc *cs = &ccd_softc[unit];
+	struct ccd_s *cs = ccdfind(unit);
 	char *errstring;
 	struct disklabel *lp = &cs->sc_label;
 	struct ccdgeom *ccg = &cs->sc_geom;
@@ -1658,8 +1693,7 @@
  * that a disklabel isn't present.
  */
 static void
-ccdmakedisklabel(cs)
-	struct ccd_softc *cs;
+ccdmakedisklabel(struct ccd_s *cs)
 {
 	struct disklabel *lp = &cs->sc_label;
 
@@ -1679,8 +1713,7 @@
  * Several drivers do this; it should be abstracted and made MP-safe.
  */
 static int
-ccdlock(cs)
-	struct ccd_softc *cs;
+ccdlock(struct ccd_s *cs)
 {
 	int error;
 
@@ -1697,8 +1730,7 @@
  * Unlock and wake up any waiters.
  */
 static void
-ccdunlock(cs)
-	struct ccd_softc *cs;
+ccdunlock(struct ccd_s *cs)
 {
 
 	cs->sc_flags &= ~CCDF_LOCKED;
@@ -1710,8 +1742,7 @@
 
 #ifdef DEBUG
 static void
-printiinfo(ii)
-	struct ccdiinfo *ii;
+printiinfo(struct ccdiinfo *ii)
 {
 	int ix, i;
 
Index: sbin/ccdconfig/Makefile
===================================================================
RCS file: /home/ncvs/src/sbin/ccdconfig/Makefile,v
retrieving revision 1.5
diff -d -u -r1.5 Makefile
--- sbin/ccdconfig/Makefile	2001/05/18 13:41:24	1.5
+++ sbin/ccdconfig/Makefile	2001/09/03 08:19:24
@@ -3,9 +3,4 @@
 PROG=	ccdconfig
 MAN=	ccdconfig.8
 
-LDADD+=		-lkvm
-DPADD+=		${LIBKVM}
-BINGRP=		kmem
-BINMODE=	2555
-
 .include <bsd.prog.mk>
Index: sbin/ccdconfig/ccdconfig.8
===================================================================
RCS file: /home/ncvs/src/sbin/ccdconfig/ccdconfig.8,v
retrieving revision 1.17
diff -d -u -r1.17 ccdconfig.8
--- sbin/ccdconfig/ccdconfig.8	2001/07/15 07:49:06	1.17
+++ sbin/ccdconfig/ccdconfig.8	2001/09/03 08:19:25
@@ -61,8 +61,6 @@
 .Op Fl f Ar config_file
 .Nm
 .Fl g
-.Op Fl M Ar core
-.Op Fl N Ar system
 .Op Ar ccd Op Ar ...
 .Sh DESCRIPTION
 .Nm Ccdconfig
@@ -86,16 +84,6 @@
 Dump the current ccd configuration in a format suitable for use as the
 ccd configuration file.  If no arguments are specified, every configured
 ccd is dumped.  Otherwise, the configuration of each listed ccd is dumped.
-.It Fl M Ar core
-Extract values associated with the name list from
-.Pa core
-instead of the default
-.Pa /dev/mem .
-.It Fl N Ar system
-Use
-.Ar system
-as the kernel instead of the running kernel (as determined from
-.Xr getbootfile 3 ) .
 .It Fl u
 Unconfigure a ccd.
 .It Fl U
Index: sbin/ccdconfig/ccdconfig.c
===================================================================
RCS file: /home/ncvs/src/sbin/ccdconfig/ccdconfig.c,v
retrieving revision 1.20
diff -d -u -r1.20 ccdconfig.c
--- sbin/ccdconfig/ccdconfig.c	2001/08/31 16:26:34	1.20
+++ sbin/ccdconfig/ccdconfig.c	2001/09/03 08:19:25
@@ -46,7 +46,6 @@
 #include <err.h>
 #include <errno.h>
 #include <fcntl.h>
-#include <kvm.h>
 #include <limits.h>
 #include <paths.h>
 #include <stdio.h>
@@ -63,9 +62,6 @@
 static	int verbose = 0;
 static	char *ccdconf = _PATH_CCDCONF;
 
-static	char *core = NULL;
-static	char *kernel = NULL;
-
 struct	flagval {
 	char	*fv_flag;
 	int	fv_val;
@@ -77,14 +73,6 @@
 	{ NULL,			0 },
 };
 
-static	struct nlist nl[] = {
-	{ "_ccd_softc" },
-#define SYM_CCDSOFTC		0
-	{ "_numccd" },
-#define SYM_NUMCCD		1
-	{ NULL },
-};
-
 #define CCD_CONFIG		0	/* configure a device */
 #define CCD_CONFIGALL		1	/* configure all devices */
 #define CCD_UNCONFIG		2	/* unconfigure a device */
@@ -99,7 +87,7 @@
 static	int getmaxpartitions __P((void));
 static	int getrawpartition __P((void));
 static	int flags_to_val __P((char *));
-static	void print_ccd_info __P((struct ccd_softc *, kvm_t *));
+static	void print_ccd_info __P((struct ccd_s *));
 static	char *resolve_ccdname __P((char *));
 static	void usage __P((void));
 
@@ -130,14 +118,6 @@
 			action = CCD_DUMP;
 			break;
 
-		case 'M':
-			core = optarg;
-			break;
-
-		case 'N':
-			kernel = optarg;
-			break;
-
 		case 'u':
 			action = CCD_UNCONFIG;
 			++options;
@@ -162,15 +142,6 @@
 	if (options > 1)
 		usage();
 
-	/*
-	 * Discard setgid privileges if not the running kernel so that bad
-	 * guys can't print interesting stuff from kernel memory.
-	 */
-	if (core != NULL || kernel != NULL || action != CCD_DUMP) {
-		setegid(getgid());
-		setgid(getgid());
-	}
-
 	if (modfind("ccd") < 0) {
 		/* Not present in kernel, try loading it */
 		if (kldload("ccd") < 0 || modfind("ccd") < 0)
@@ -476,6 +447,14 @@
 			cp = "CCDIOCCLR";
 			break;
 
+		case CCDCONFINFO:
+			cp = "CCDCONFINFO";
+			break;
+
+		case CCDCPPINFO:
+			cp = "CCDCPPINFO";
+			break;
+
 		default:
 			cp = "unknown";
 		}
@@ -486,78 +465,44 @@
 	return (0);
 }
 
-#define KVM_ABORT(kd, str) {						\
-	(void)kvm_close((kd));						\
-	warnx("%s", (str));							\
-	warnx("%s", kvm_geterr((kd)));					\
-	return (1);							\
-}
-
 static int
 dump_ccd(argc, argv)
 	int argc;
 	char **argv;
 {
-	char errbuf[_POSIX2_LINE_MAX], *ccd, *cp;
-	struct ccd_softc *cs, *kcs;
-	size_t readsize;
+	char *ccd, *cp;
 	int i, error, numccd, numconfiged = 0;
-	kvm_t *kd;
-
-	bzero(errbuf, sizeof(errbuf));
+	struct ccdconf conf;
 
-	if ((kd = kvm_openfiles(kernel, core, NULL, O_RDONLY,
-	    errbuf)) == NULL) {
-		warnx("can't open kvm: %s", errbuf);
+	/*
+	 * Read the ccd configuration data from the kernel and dump
+	 * it to stdout.
+	 */
+	if ((ccd = resolve_ccdname("ccd0")) == NULL) {		/* XXX */
+		warnx("invalid ccd name: %s", cp);
 		return (1);
 	}
-	setegid(getgid());
-	setgid(getgid());
-
-	if (kvm_nlist(kd, nl))
-		KVM_ABORT(kd, "ccd-related symbols not available");
-
-	/* Check to see how many ccds are currently configured. */
-	if (kvm_read(kd, nl[SYM_NUMCCD].n_value, (char *)&numccd,
-	    sizeof(numccd)) != sizeof(numccd))
-		KVM_ABORT(kd, "can't determine number of configured ccds");
-
-	if (numccd == 0) {
-		printf("ccd driver in kernel, but is uninitialized\n");
-		goto done;
+	conf.size = 0;
+	if (do_io(ccd, CCDCONFINFO, (struct ccd_ioctl *) &conf))
+		return (1);
+	if (conf.size == 0) {
+		printf("no concatenated disks configured\n");
+		return (0);
 	}
-
 	/* Allocate space for the configuration data. */
-	readsize = numccd * sizeof(struct ccd_softc);
-	if ((cs = malloc(readsize)) == NULL) {
+	conf.buffer = alloca(conf.size);
+	if (conf.buffer == NULL) {
 		warnx("no memory for configuration data");
-		goto bad;
+		return (1);
 	}
-	bzero(cs, readsize);
+	if (do_io(ccd, CCDCONFINFO, (struct ccd_ioctl *) &conf))
+		return (1);
 
-	/*
-	 * Read the ccd configuration data from the kernel and dump
-	 * it to stdout.
-	 */
-	if (kvm_read(kd, nl[SYM_CCDSOFTC].n_value, (char *)&kcs,
-	    sizeof(kcs)) != sizeof(kcs)) {
-		free(cs);
-		KVM_ABORT(kd, "can't find pointer to configuration data");
-	}
-	if (kvm_read(kd, (u_long)kcs, (char *)cs, readsize) != readsize) {
-		free(cs);
-		KVM_ABORT(kd, "can't read configuration data");
-	}
+	numconfiged = conf.size / sizeof(struct ccd_s);
 
 	if (argc == 0) {
-		for (i = 0; i < numccd; ++i)
-			if (cs[i].sc_flags & CCDF_INITED) {
-				++numconfiged;
-				print_ccd_info(&cs[i], kd);
-			}
-
-		if (numconfiged == 0)
-			printf("no concatenated disks configured\n");
+		for (i = 0; i < numconfiged; i++)
+			print_ccd_info(&(conf.buffer[i]));
 	} else {
 		while (argc) {
 			cp = *argv++; --argc;
@@ -565,85 +510,88 @@
 				warnx("invalid ccd name: %s", cp);
 				continue;
 			}
-			if ((error = pathtounit(ccd, &i)) != 0) {
+			if ((error = pathtounit(ccd, &numccd)) != 0) {
 				warnx("%s: %s", ccd, strerror(error));
 				continue;
 			}
-			if (i >= numccd) {
-				warnx("ccd%d not configured", i);
+			error = 1;
+			for (i = 0; i < numconfiged; i++) {
+				if (conf.buffer[i].sc_unit == numccd) {
+					print_ccd_info(&(conf.buffer[i]));
+					error = 0;
+					break;
+				}
+			}
+			if (error) {
+				warnx("ccd%d not configured", numccd);
 				continue;
 			}
-			if (cs[i].sc_flags & CCDF_INITED)
-				print_ccd_info(&cs[i], kd);
-			else
-				printf("ccd%d not configured\n", i);
 		}
-	}
-
-	free(cs);
+	}	
 
- done:
-	(void)kvm_close(kd);
 	return (0);
-
- bad:
-	(void)kvm_close(kd);
-	return (1);
 }
 
 static void
-print_ccd_info(cs, kd)
-	struct ccd_softc *cs;
-	kvm_t *kd;
+print_ccd_info(cs)
+	struct ccd_s *cs;
 {
+	char *cp, *ccd;
 	static int header_printed = 0;
-	struct ccdcinfo *cip;
-	size_t readsize;
-	char path[MAXPATHLEN];
-	int i;
+	struct ccdcpps cpps;
 
+	/* Print out header if necessary*/
 	if (header_printed == 0 && verbose) {
 		printf("# ccd\t\tileave\tflags\tcompnent devices\n");
 		header_printed = 1;
 	}
 
-	readsize = cs->sc_nccdisks * sizeof(struct ccdcinfo);
-	if ((cip = malloc(readsize)) == NULL) {
-		warn("ccd%d: can't allocate memory for component info",
-		    cs->sc_unit);
-		return;
-	}
-	bzero(cip, readsize);
-
 	/* Dump out softc information. */
 	printf("ccd%d\t\t%d\t%d\t", cs->sc_unit, cs->sc_ileave,
 	    cs->sc_cflags & CCDF_USERMASK);
 	fflush(stdout);
 
 	/* Read in the component info. */
-	if (kvm_read(kd, (u_long)cs->sc_cinfo, (char *)cip,
-	    readsize) != readsize) {
+	asprintf(&cp, "%s%d", cs->device_stats.device_name,
+	    cs->device_stats.unit_number);
+	if (cp == NULL) {
+		printf("\n");
+		warn("ccd%d: can't allocate memory",
+		    cs->sc_unit);
+		return;
+	}
+
+	if ((ccd = resolve_ccdname(cp)) == NULL) {
 		printf("\n");
+		warnx("can't read component info: invalid ccd name: %s", cp);
+		return;
+	}
+	cpps.size = 0;
+	if (do_io(ccd, CCDCPPINFO, (struct ccd_ioctl *) &cpps)) {
+		printf("\n");
 		warnx("can't read component info");
-		warnx("%s", kvm_geterr(kd));
-		goto done;
+		return;
+	}
+	cpps.buffer = alloca(cpps.size);
+	if (cpps.buffer == NULL) {
+		printf("\n");
+		warn("ccd%d: can't allocate memory for component info",
+		    cs->sc_unit);
+		return;
+	}
+	if (do_io(ccd, CCDCPPINFO, (struct ccd_ioctl *) &cpps)) {
+		printf("\n");
+		warnx("can't read component info");
+		return;
 	}
 
-	/* Read component pathname and display component info. */
-	for (i = 0; i < cs->sc_nccdisks; ++i) {
-		if (kvm_read(kd, (u_long)cip[i].ci_path, (char *)path,
-		    cip[i].ci_pathlen) != cip[i].ci_pathlen) {
-			printf("\n");
-			warnx("can't read component pathname");
-			warnx("%s", kvm_geterr(kd));
-			goto done;
-		}
-		printf((i + 1 < cs->sc_nccdisks) ? "%s " : "%s\n", path);
+	/* Display component info. */
+	for (cp = cpps.buffer; cp - cpps.buffer < cpps.size; cp += strlen(cp) + 1) {
+		printf((cp + strlen(cp) + 1) < (cpps.buffer + cpps.size) ?
+		    "%s " : "%s\n", cp);
 		fflush(stdout);
 	}
-
- done:
-	free(cip);
+	return;
 }
 
 static int
@@ -725,7 +673,7 @@
 		"       ccdconfig -C [-v] [-f config_file]",
 		"       ccdconfig -u [-v] ccd [...]",
 		"       ccdconfig -U [-v] [-f config_file]",
-		"       ccdconfig -g [-M core] [-N system] [ccd [...]]");
+		"       ccdconfig -g [ccd [...]]");
 	exit(1);
 }
 
Index: sys/modules/ccd/Makefile
===================================================================
RCS file: /home/ncvs/src/sys/modules/ccd/Makefile,v
retrieving revision 1.14
diff -d -u -r1.14 Makefile
--- sys/modules/ccd/Makefile	2001/01/06 13:59:42	1.14
+++ sys/modules/ccd/Makefile	2001/09/03 08:19:26
@@ -3,13 +3,7 @@
 .PATH: ${.CURDIR}/../../dev/ccd
 
 KMOD=	ccd
-SRCS=	ccd.c ccd.h vnode_if.h
+SRCS=	ccd.c vnode_if.h
 NOMAN=
-
-NCCD?=		4
-CLEANFILES=	ccd.h
-
-ccd.h:
-	echo "#define NCCD ${NCCD}" > ccd.h
 
 .include <bsd.kmod.mk>

--------------4C8CE2CD7293DF8D444DE7F1--


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




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?3B933F20.8E93FDF9>