Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/usr.bin/config Allow multiple attachments methods to the sam...



details:   https://anonhg.NetBSD.org/src/rev/b03080d5ecbe
branches:  trunk
changeset: 827921:b03080d5ecbe
user:      christos <christos%NetBSD.org@localhost>
date:      Sat Nov 18 18:44:20 2017 +0000

description:
Allow multiple attachments methods to the same child+parent combination:

    foo* at bar? with baz
    foo* at bar? with barf

Do this by scanning the list of iba's and allocating a new cfparent for
each. Keep track of the shared parent+child combinations by using the
same id for them.

diffstat:

 usr.bin/config/defs.h     |    5 +-
 usr.bin/config/mkioconf.c |    8 +-
 usr.bin/config/sem.c      |  283 ++++++++++++++++++++++++---------------------
 3 files changed, 159 insertions(+), 137 deletions(-)

diffs (truncated from 426 to 300 lines):

diff -r 3f3e660d7214 -r b03080d5ecbe usr.bin/config/defs.h
--- a/usr.bin/config/defs.h     Sat Nov 18 18:41:44 2017 +0000
+++ b/usr.bin/config/defs.h     Sat Nov 18 18:44:20 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: defs.h,v 1.100 2017/11/16 17:08:07 christos Exp $      */
+/*     $NetBSD: defs.h,v 1.101 2017/11/18 18:44:20 christos Exp $      */
 
 /*
  * Copyright (c) 1992, 1993
@@ -107,7 +107,7 @@
  * The next two lines define the current version of the config(1) binary,
  * and the minimum version of the configuration files it supports.
  */
-#define CONFIG_VERSION         20170615
+#define CONFIG_VERSION         20171118
 #define CONFIG_MINVERSION      0
 
 /*
@@ -234,6 +234,7 @@
        struct  devbase *p_atdev;       /* optional parent device base */
        int     p_atunit;               /* optional parent device unit */
        struct  nvlist *p_devs;         /* children using it */
+       struct  deva *p_deva;           /* attribute */
        int     p_inst;                 /* parent spec instance */
        int     p_active;               /* parent spec is actively used */
 };
diff -r 3f3e660d7214 -r b03080d5ecbe usr.bin/config/mkioconf.c
--- a/usr.bin/config/mkioconf.c Sat Nov 18 18:41:44 2017 +0000
+++ b/usr.bin/config/mkioconf.c Sat Nov 18 18:44:20 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: mkioconf.c,v 1.33 2015/11/12 14:38:21 pooka Exp $      */
+/*     $NetBSD: mkioconf.c,v 1.34 2017/11/18 18:44:20 christos Exp $   */
 
 /*
  * Copyright (c) 1992, 1993
@@ -45,7 +45,7 @@
 #endif
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: mkioconf.c,v 1.33 2015/11/12 14:38:21 pooka Exp $");
+__RCSID("$NetBSD: mkioconf.c,v 1.34 2017/11/18 18:44:20 christos Exp $");
 
 #include <sys/param.h>
 #include <err.h>
@@ -338,11 +338,15 @@
 emitparents(FILE *fp)
 {
        struct pspec *p;
+       int inst = -1;
 
        NEWLINE;
        TAILQ_FOREACH(p, &allpspecs, p_list) {
                if (p->p_devs == NULL || p->p_active != DEVI_ACTIVE)
                        continue;
+               if (inst == p->p_inst)
+                       continue;
+               inst = p->p_inst;
                fprintf(fp,
                    "static const struct cfparent pspec%d = {\n", p->p_inst);
                fprintf(fp, "\t\"%s\", ", p->p_iattr->a_name);
diff -r 3f3e660d7214 -r b03080d5ecbe usr.bin/config/sem.c
--- a/usr.bin/config/sem.c      Sat Nov 18 18:41:44 2017 +0000
+++ b/usr.bin/config/sem.c      Sat Nov 18 18:44:20 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: sem.c,v 1.78 2017/11/18 18:41:44 christos Exp $        */
+/*     $NetBSD: sem.c,v 1.79 2017/11/18 18:44:20 christos Exp $        */
 
 /*
  * Copyright (c) 1992, 1993
@@ -45,7 +45,7 @@
 #endif
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: sem.c,v 1.78 2017/11/18 18:41:44 christos Exp $");
+__RCSID("$NetBSD: sem.c,v 1.79 2017/11/18 18:44:20 christos Exp $");
 
 #include <sys/param.h>
 #include <ctype.h>
@@ -79,7 +79,8 @@
 static struct nvlist *addtoattr(struct nvlist *, struct devbase *);
 static int resolve(struct nvlist **, const char *, const char *,
                   struct nvlist *, int);
-static struct pspec *getpspec(struct attr *, struct devbase *, int);
+static struct pspec *getpspec(struct attr *, struct devbase *, int,
+    struct deva *);
 static struct devi *newdevi(const char *, int, struct devbase *d);
 static struct devi *getdevi(const char *);
 static void remove_devi(struct devi *);
@@ -641,7 +642,6 @@
        struct nvlist *nv;
        struct attrlist *al;
        struct attr *a;
-       struct deva *da;
 
        if (dev == &errdev)
                goto bad;
@@ -699,14 +699,16 @@
                if (a == &errattr)
                        continue;               /* already complained */
 
+#if 0
                /*
                 * Make sure that an attachment spec doesn't
                 * already say how to attach to this attribute.
                 */
-               for (da = dev->d_ahead; da != NULL; da = da->d_bsame)
+               for (struct deva *da = dev->d_ahead; da; da = da->d_bsame)
                        if (onlist(da->d_atlist, a))
                                cfgerror("attach at `%s' already done by `%s'",
                                     a ? a->a_name : "root", da->d_name);
+#endif
 
                if (a == NULL) {
                        ht_insert(devroottab, dev->d_name, dev);
@@ -1158,6 +1160,83 @@
        return (i);
 }
 
+static struct attr *
+finddevattr(const char *name, const char *at, struct devbase *ib,
+    struct devbase **ab, int *atunit)
+{
+       const char *cp;
+       char atbuf[NAMESIZE];
+       struct attrlist *al;
+       struct attr *attr;
+
+       if (at == NULL) {
+               *ab = NULL;
+               *atunit = -1;
+               return &errattr;        /* a convenient "empty" attr */
+       }
+       if (split(at, strlen(at), atbuf, sizeof atbuf, atunit)) {
+               cfgerror("invalid attachment name `%s'", at);
+               /* (void)getdevi(name); -- ??? */
+               return NULL;
+       }
+
+       /*
+        * Devices can attach to two types of things: Attributes,
+        * and other devices (which have the appropriate attributes
+        * to allow attachment).
+        *
+        * (1) If we're attached to an attribute, then we don't need
+        *     look at the parent base device to see what attributes
+        *     it has, and make sure that we can attach to them.    
+        *
+        * (2) If we're attached to a real device (i.e. named in
+        *     the config file), we want to remember that so that
+        *     at cross-check time, if the device we're attached to
+        *     is missing but other devices which also provide the
+        *     attribute are present, we don't get a false "OK."
+        *
+        * (3) If the thing we're attached to is an attribute
+        *     but is actually named in the config file, we still
+        *     have to remember its devbase.
+        */
+       cp = intern(atbuf);
+
+       /* Figure out parent's devbase, to satisfy case (3). */
+       *ab = ht_lookup(devbasetab, cp);
+
+       /* Find out if it's an attribute. */
+       attr = ht_lookup(attrtab, cp);
+
+       /* Make sure we're _really_ attached to the attr.  Case (1). */
+       if (attr != NULL && onlist(attr->a_devs, ib))
+               return attr;
+
+       /*
+        * Else a real device, and not just an attribute.  Case (2).
+        *
+        * Have to work a bit harder to see whether we have
+        * something like "tg0 at esp0" (where esp is merely
+        * not an attribute) or "tg0 at nonesuch0" (where
+        * nonesuch is not even a device).
+        */
+       if (*ab == NULL) {
+               cfgerror("%s at %s: `%s' unknown", name, at, atbuf);
+               return NULL;
+       }
+
+       /*
+        * See if the named parent carries an attribute
+        * that allows it to supervise device ib.
+        */
+       for (al = (*ab)->d_attrs; al != NULL; al = al->al_next) {
+               attr = al->al_this;
+               if (onlist(attr->a_devs, ib))
+                       return attr;
+       }
+       cfgerror("`%s' cannot attach to `%s'", ib->d_name, atbuf);
+       return NULL;
+}
+
 /*
  * Add the named device as attaching to the named attribute (or perhaps
  * another device instead) plus unit number.
@@ -1170,137 +1249,68 @@
        struct attr *attr;      /* attribute that allows attach */
        struct devbase *ib;     /* i->i_base */
        struct devbase *ab;     /* not NULL => at another dev */
-       struct attrlist *al;
        struct deva *iba;       /* devbase attachment used */
-       const char *cp;
+       struct deva *lastiba;
        int atunit;
-       char atbuf[NAMESIZE];
-       int hit;
+
+       lastiba = NULL;
+       if ((i = getdevi(name)) == NULL)
+               goto bad;
+       ib = i->i_base;
+       iba = NULL;
+       p = NULL;
+       attr = finddevattr(name, at, ib, &ab, &atunit);
+       if (attr == NULL) {
+               i->i_active = DEVI_BROKEN;
+               goto bad;
+       }
 
-       ab = NULL;
-       iba = NULL;
-       if (at == NULL) {
-               /* "at root" */
-               p = NULL;
-               if ((i = getdevi(name)) == NULL)
+       for (lastiba = ib->d_ahead; lastiba; lastiba = iba->d_bsame) {
+               for (iba = lastiba; iba != NULL; iba = iba->d_bsame)
+                       if (onlist(iba->d_atlist,
+                           attr == &errattr ? NULL : attr))
+                               break;
+
+               if (iba == NULL) {
+                       if (lastiba != ib->d_ahead)
+                               goto bad;
+                       if (attr != &errattr) {
+                               panic("adddev: can't figure out attachment");
+                       } else {
+                               cfgerror("`%s' cannot attach to the root",
+                                   ib->d_name);
+                               i->i_active = DEVI_BROKEN;
+                       }
+               }
+               // get a new one if it is not the first time
+               if (lastiba != ib->d_ahead && (i = getdevi(name)) == NULL)
                        goto bad;
-               /*
-                * Must warn about i_unit > 0 later, after taking care of
-                * the STAR cases (we could do non-star's here but why
-                * bother?).  Make sure this device can be at root.
-                */
-               ib = i->i_base;
-               hit = 0;
-               for (iba = ib->d_ahead; iba != NULL; iba = iba->d_bsame)
-                       if (onlist(iba->d_atlist, NULL)) {
-                               hit = 1;
-                               break;
-                       }
-               if (!hit) {
-                       cfgerror("`%s' cannot attach to the root", ib->d_name);
+
+               if (attr != &errattr) {
+                       /*
+                        * Find the parent spec.  If a matching one has not
+                        * yet been created, create one.
+                        *
+                        * XXX: This creates multiple pspecs that look the
+                        * same in the config file and could be merged.
+                        */
+                       p = getpspec(attr, ab, atunit, iba);
+                       p->p_devs = newnv(NULL, NULL, i, 0, p->p_devs);
+               }
+
+               if ((i->i_locs = fixloc(name, attr, loclist)) == NULL) {
                        i->i_active = DEVI_BROKEN;
                        goto bad;
                }
-               attr = &errattr;        /* a convenient "empty" attr */
-       } else {
-               if (split(at, strlen(at), atbuf, sizeof atbuf, &atunit)) {
-                       cfgerror("invalid attachment name `%s'", at);
-                       /* (void)getdevi(name); -- ??? */
-                       goto bad;
-               }
-               if ((i = getdevi(name)) == NULL)
-                       goto bad;
-               ib = i->i_base;
-
-               /*
-                * Devices can attach to two types of things: Attributes,
-                * and other devices (which have the appropriate attributes
-                * to allow attachment).
-                *
-                * (1) If we're attached to an attribute, then we don't need
-                *     look at the parent base device to see what attributes
-                *     it has, and make sure that we can attach to them.    
-                *
-                * (2) If we're attached to a real device (i.e. named in



Home | Main Index | Thread Index | Old Index