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 <[EMAIL PROTECTED]>, 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
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>

Reply via email to