Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/usr.sbin/config Add support for specifiying attribute depend...
details: https://anonhg.NetBSD.org/src/rev/a0397c431b52
branches: trunk
changeset: 538005:a0397c431b52
user: thorpej <thorpej%NetBSD.org@localhost>
date: Wed Oct 09 20:17:00 2002 +0000
description:
Add support for specifiying attribute dependencies on attributes. This
allows for the following:
define foo
define bar { }: foo
device foobar: bar
An instance of "foobar" will select "bar", which will in turn select
"foo" due to "bar"'s dependency on "foo".
Circular dependencies are not allowed, and a dependency may also not
be an interface attribute.
diffstat:
usr.sbin/config/defs.h | 4 +-
usr.sbin/config/gram.y | 7 ++-
usr.sbin/config/sem.c | 79 ++++++++++++++++++++++++++++++++++++++++++++-----
usr.sbin/config/sem.h | 5 +-
4 files changed, 81 insertions(+), 14 deletions(-)
diffs (210 lines):
diff -r 5f7df4c06f55 -r a0397c431b52 usr.sbin/config/defs.h
--- a/usr.sbin/config/defs.h Wed Oct 09 19:58:35 2002 +0000
+++ b/usr.sbin/config/defs.h Wed Oct 09 20:17:00 2002 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: defs.h,v 1.7 2002/09/26 04:07:36 thorpej Exp $ */
+/* $NetBSD: defs.h,v 1.8 2002/10/09 20:17:00 thorpej Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -153,6 +153,8 @@
int a_loclen; /* length of above list */
struct nvlist *a_devs; /* children */
struct nvlist *a_refs; /* parents */
+ struct nvlist *a_deps; /* we depend on these other attrs */
+ int a_expanding; /* to detect cycles in attr graph */
};
/*
diff -r 5f7df4c06f55 -r a0397c431b52 usr.sbin/config/gram.y
--- a/usr.sbin/config/gram.y Wed Oct 09 19:58:35 2002 +0000
+++ b/usr.sbin/config/gram.y Wed Oct 09 20:17:00 2002 +0000
@@ -1,5 +1,5 @@
%{
-/* $NetBSD: gram.y,v 1.36 2002/09/11 06:20:09 enami Exp $ */
+/* $NetBSD: gram.y,v 1.37 2002/10/09 20:17:00 thorpej Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -266,9 +266,10 @@
device_major { do_devsw = 1; } |
include |
prefix |
- DEVCLASS WORD { (void)defattr($2, NULL, 1); } |
+ DEVCLASS WORD { (void)defattr($2, NULL, NULL, 1); } |
DEFFS fsoptfile_opt deffses { deffilesystem($2, $3); } |
- DEFINE WORD interface_opt { (void)defattr($2, $3, 0); } |
+ DEFINE WORD interface_opt attrs_opt
+ { (void)defattr($2, $3, $4, 0); } |
DEFOPT optfile_opt defopts defoptdeps
{ defoption($2, $3, $4); } |
DEFFLAG optfile_opt defopts defoptdeps
diff -r 5f7df4c06f55 -r a0397c431b52 usr.sbin/config/sem.c
--- a/usr.sbin/config/sem.c Wed Oct 09 19:58:35 2002 +0000
+++ b/usr.sbin/config/sem.c Wed Oct 09 20:17:00 2002 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: sem.c,v 1.33 2002/09/26 04:07:36 thorpej Exp $ */
+/* $NetBSD: sem.c,v 1.34 2002/10/09 20:17:00 thorpej Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -180,20 +180,41 @@
}
/*
- * Define an attribute, optionally with an interface (a locator list).
+ * Define an attribute, optionally with an interface (a locator list)
+ * and a set of attribute-dependencies.
+ *
+ * Attribute dependencies MAY NOT be interface attributes.
+ *
* Since an empty locator list is logically different from "no interface",
* all locator lists include a dummy head node, which we discard here.
*/
int
-defattr(const char *name, struct nvlist *locs, int devclass)
+defattr(const char *name, struct nvlist *locs, struct nvlist *deps,
+ int devclass)
{
- struct attr *a;
+ struct attr *a, *dep;
struct nvlist *nv;
int len;
if (locs != NULL && devclass)
panic("defattr(%s): locators and devclass", name);
+ if (deps != NULL && devclass)
+ panic("defattr(%s): dependencies and devclass", name);
+
+ /*
+ * If this attribute depends on any others, make sure none of
+ * the dependencies are interface attributes.
+ */
+ for (nv = deps; nv != NULL; nv = nv->nv_next) {
+ dep = nv->nv_ptr;
+ if (dep->a_iattr) {
+ error("`%s' dependency `%s' is an interface attribute",
+ name, dep->a_name);
+ return (1);
+ }
+ }
+
a = emalloc(sizeof *a);
if (ht_insert(attrtab, name, a)) {
free(a);
@@ -235,6 +256,12 @@
a->a_loclen = len;
a->a_devs = NULL;
a->a_refs = NULL;
+ a->a_deps = deps;
+ a->a_expanding = 0;
+
+ /* Expand the attribute to check for cycles in the graph. */
+ expandattr(a, NULL);
+
return (0);
}
@@ -315,7 +342,7 @@
if (loclist != NULL) {
nv = loclist;
loclist = NULL; /* defattr disposes of them for us */
- if (defattr(dev->d_name, nv, 0))
+ if (defattr(dev->d_name, nv, NULL, 0))
goto bad;
attrs = newnv(dev->d_name, NULL, getattr(dev->d_name), 0,
attrs);
@@ -540,6 +567,36 @@
}
/*
+ * Recursively expand an attribute and its dependencies, checking for
+ * cycles, and invoking a callback for each attribute found.
+ */
+void
+expandattr(struct attr *a, void (*callback)(struct attr *))
+{
+ struct nvlist *nv;
+ struct attr *dep;
+
+ if (a->a_expanding) {
+ error("circular dependency on attribute `%s'", a->a_name);
+ return;
+ }
+
+ a->a_expanding = 1;
+
+ /* First expand all of this attribute's dependencies. */
+ for (nv = a->a_deps; nv != NULL; nv = nv->nv_next) {
+ dep = nv->nv_ptr;
+ expandattr(dep, callback);
+ }
+
+ /* ...and now invoke the callback for ourself. */
+ if (callback != NULL)
+ (*callback)(a);
+
+ a->a_expanding = 0;
+}
+
+/*
* Set the major device number for a device, so that it can be used
* as a root/dumps "on" device in a configuration.
*/
@@ -1230,6 +1287,13 @@
return (0);
}
+static void
+selectattr(struct attr *a)
+{
+
+ (void)ht_insert(selecttab, a->a_name, (char *)a->a_name);
+}
+
/*
* We have an instance of the base foo, so select it and all its
* attributes for "optional foo".
@@ -1243,14 +1307,13 @@
(void)ht_insert(selecttab, d->d_name, (char *)d->d_name);
for (nv = d->d_attrs; nv != NULL; nv = nv->nv_next) {
a = nv->nv_ptr;
- (void)ht_insert(selecttab, a->a_name, (char *)a->a_name);
+ expandattr(a, selectattr);
}
if (da != NULL) {
(void)ht_insert(selecttab, da->d_name, (char *)da->d_name);
for (nv = da->d_attrs; nv != NULL; nv = nv->nv_next) {
a = nv->nv_ptr;
- (void)ht_insert(selecttab, a->a_name,
- (char *)a->a_name);
+ expandattr(a, selectattr);
}
}
}
diff -r 5f7df4c06f55 -r a0397c431b52 usr.sbin/config/sem.h
--- a/usr.sbin/config/sem.h Wed Oct 09 19:58:35 2002 +0000
+++ b/usr.sbin/config/sem.h Wed Oct 09 20:17:00 2002 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: sem.h,v 1.15 2002/09/06 13:18:43 gehenna Exp $ */
+/* $NetBSD: sem.h,v 1.16 2002/10/09 20:17:00 thorpej Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -49,13 +49,14 @@
void setdefmaxusers(int, int, int);
void setmaxusers(int);
void setident(const char *);
-int defattr(const char *, struct nvlist *, int);
+int defattr(const char *, struct nvlist *, struct nvlist *, int);
void defdev(struct devbase *, struct nvlist *, struct nvlist *, int);
void defdevattach(struct deva *, struct devbase *, struct nvlist *,
struct nvlist *);
struct devbase *getdevbase(const char *);
struct deva *getdevattach(const char *);
struct attr *getattr(const char *);
+void expandattr(struct attr *, void (*)(struct attr *));
void setmajor(struct devbase *, int);
void addconf(struct config *);
void setconf(struct nvlist **, const char *, struct nvlist *);
Home |
Main Index |
Thread Index |
Old Index