o Keep track of negated devices in deaddevitab
o Rework do_kill_orphans() to use that information and mark explicitely orphaned devices (i.e., the ones whose missing ancestor has been negated) o Make a distinction between erroneous orphans and explicit orphans. Error out on the former, ignore the later (but print a warning when -v is used) Yes, now config(1) will actually stop if you comment out a parent. That should help people still hoping adjustkernel is relevant these days :)
This commit is contained in:
parent
09bc805fb6
commit
7aa6070d4e
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: defs.h,v 1.3 2005/09/30 22:36:20 cube Exp $ */
|
||||
/* $NetBSD: defs.h,v 1.4 2005/10/01 23:30:37 cube Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1992, 1993
|
||||
|
@ -243,7 +243,10 @@ struct devi {
|
|||
const char **i_locs; /* locators (as given by pspec's iattr) */
|
||||
int i_cfflags; /* flags from config line */
|
||||
int i_lineno; /* line # in config, for later errors */
|
||||
int i_active; /* instance is not orphaned in any way */
|
||||
int i_active;
|
||||
#define DEVI_ORPHAN 0 /* instance has no active parent */
|
||||
#define DEVI_ACTIVE 1 /* instance has an active parent */
|
||||
#define DEVI_IGNORED 2 /* instance's parent has been removed */
|
||||
|
||||
/* created during packing or ioconf.c generation */
|
||||
short i_collapsed; /* set => this alias no longer needed */
|
||||
|
@ -367,6 +370,7 @@ struct hashtab *devbasetab; /* devbase lookup */
|
|||
struct hashtab *devroottab; /* attach at root lookup */
|
||||
struct hashtab *devatab; /* devbase attachment lookup */
|
||||
struct hashtab *devitab; /* device instance lookup */
|
||||
struct hashtab *deaddevitab; /* removed instances lookup */
|
||||
struct hashtab *selecttab; /* selects things that are "optional foo" */
|
||||
struct hashtab *needcnttab; /* retains names marked "needs-count" */
|
||||
struct hashtab *opttab; /* table of configured options */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: main.c,v 1.2 2005/09/30 22:36:20 cube Exp $ */
|
||||
/* $NetBSD: main.c,v 1.3 2005/10/01 23:30:37 cube Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1992, 1993
|
||||
|
@ -104,8 +104,12 @@ static int badstar(void);
|
|||
int main(int, char **);
|
||||
static int mksymlinks(void);
|
||||
static int mkident(void);
|
||||
static int devbase_has_dead_instances(const char *, void *, void *);
|
||||
static int devbase_has_any_instance(struct devbase *, int, int);
|
||||
static int check_dead_devi(const char *, void *, void *);
|
||||
static void kill_orphans(void);
|
||||
static void do_kill_orphans(struct devbase *, struct attr *, struct devbase *);
|
||||
static void do_kill_orphans(struct devbase *, struct attr *,
|
||||
struct devbase *, int);
|
||||
static int kill_orphans_cb(const char *, void *, void *);
|
||||
static int cfcrosscheck(struct config *, const char *, struct nvlist *);
|
||||
static const char *strtolower(const char *);
|
||||
|
@ -254,6 +258,7 @@ main(int argc, char **argv)
|
|||
devroottab = ht_new();
|
||||
devatab = ht_new();
|
||||
devitab = ht_new();
|
||||
deaddevitab = ht_new();
|
||||
selecttab = ht_new();
|
||||
needcnttab = ht_new();
|
||||
opttab = ht_new();
|
||||
|
@ -347,7 +352,8 @@ main(int argc, char **argv)
|
|||
/*
|
||||
* Select devices and pseudo devices and their attributes
|
||||
*/
|
||||
fixdevis();
|
||||
if (fixdevis())
|
||||
stop();
|
||||
|
||||
/*
|
||||
* Deal with option dependencies.
|
||||
|
@ -996,7 +1002,7 @@ deva_has_instances(struct deva *deva, int unit)
|
|||
struct devi *i;
|
||||
|
||||
for (i = deva->d_ihead; i != NULL; i = i->i_asame)
|
||||
if (i->i_active &&
|
||||
if (i->i_active == DEVI_ACTIVE &&
|
||||
(unit == WILD || unit == i->i_unit || i->i_unit == STAR))
|
||||
return (1);
|
||||
return (0);
|
||||
|
@ -1477,25 +1483,127 @@ extract_config(const char *kname, const char *cname, int cfd)
|
|||
return found;
|
||||
}
|
||||
|
||||
struct dhdi_params {
|
||||
struct devbase *d;
|
||||
int unit;
|
||||
};
|
||||
|
||||
static int
|
||||
devbase_has_dead_instances(const char *key, void *value, void *aux)
|
||||
{
|
||||
struct devi *i = value;
|
||||
struct dhdi_params *dhdi = aux;
|
||||
|
||||
if (i->i_base == dhdi->d &&
|
||||
(dhdi->unit == WILD || dhdi->unit == i->i_unit ||
|
||||
i->i_unit == STAR))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is almost the same as devbase_has_instances, except it
|
||||
* may have special considerations regarding ignored instances.
|
||||
*/
|
||||
|
||||
static int
|
||||
devbase_has_any_instance(struct devbase *dev, int unit, int state)
|
||||
{
|
||||
struct deva *da;
|
||||
struct devi *i;
|
||||
|
||||
if (dev->d_ispseudo) {
|
||||
if (dev->d_ihead != NULL)
|
||||
return 1;
|
||||
else if (state == DEVI_IGNORED)
|
||||
return (ht_lookup(deaddevitab, dev->d_name) != NULL);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (da = dev->d_ahead; da != NULL; da = da->d_bsame)
|
||||
for (i = da->d_ihead; i != NULL; i = i->i_asame)
|
||||
if ((i->i_active == DEVI_ACTIVE ||
|
||||
i->i_active == state) &&
|
||||
(unit == WILD || unit == i->i_unit ||
|
||||
i->i_unit == STAR))
|
||||
return 1;
|
||||
|
||||
if (state == DEVI_IGNORED) {
|
||||
struct dhdi_params dhdi = { dev, unit };
|
||||
/* also check dead devices */
|
||||
return ht_enumerate(deaddevitab, devbase_has_dead_instances,
|
||||
&dhdi);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* check_dead_devi(), used with ht_enumerate, checks if any of the removed
|
||||
* device instances would have been a valid instance considering the devbase,
|
||||
* the parent device and the interface attribute.
|
||||
*
|
||||
* In other words, for a non-active device, it checks if children would be
|
||||
* actual orphans or the result of a negative statement in the config file.
|
||||
*/
|
||||
|
||||
struct cdd_params {
|
||||
struct devbase *d;
|
||||
struct attr *at;
|
||||
struct devbase *parent;
|
||||
};
|
||||
|
||||
static int
|
||||
check_dead_devi(const char *key, void *value, void *aux)
|
||||
{
|
||||
struct cdd_params *cdd = aux;
|
||||
struct devi *i = value;
|
||||
struct pspec *p = i->i_pspec;
|
||||
|
||||
if (i->i_base != cdd->d)
|
||||
return 0;
|
||||
|
||||
if ((p == NULL && cdd->at == NULL) ||
|
||||
(p != NULL && p->p_iattr == cdd->at &&
|
||||
(p->p_atdev == NULL || p->p_atdev == cdd->parent))) {
|
||||
if (p != NULL &&
|
||||
!devbase_has_any_instance(cdd->parent, p->p_atunit,
|
||||
DEVI_IGNORED))
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
do_kill_orphans(struct devbase *d, struct attr *at, struct devbase *parent)
|
||||
do_kill_orphans(struct devbase *d, struct attr *at, struct devbase *parent,
|
||||
int state)
|
||||
{
|
||||
struct nvlist *nv, *nv1;
|
||||
struct attr *a;
|
||||
struct devi *i, *j = NULL;
|
||||
struct pspec *p;
|
||||
int active = 0;
|
||||
|
||||
/*
|
||||
* A pseudo-device will always attach at root, and if it has an
|
||||
* instance (it cannot have more than one), it is enough to consider
|
||||
* it active, as there is no real attachment.
|
||||
*
|
||||
* A pseudo device can never be marked DEVI_IGNORED.
|
||||
*/
|
||||
if (d->d_ispseudo) {
|
||||
if (d->d_ihead == NULL)
|
||||
return;
|
||||
d->d_ihead->i_active = 1;
|
||||
if (d->d_ihead != NULL)
|
||||
d->d_ihead->i_active = active = DEVI_ACTIVE;
|
||||
else {
|
||||
if (ht_lookup(deaddevitab, d->d_name) != NULL)
|
||||
active = DEVI_IGNORED;
|
||||
else
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
int active = 0;
|
||||
for (i = d->d_ihead; i != NULL; i = i->i_bsame) {
|
||||
for (j = i; j != NULL; j = j->i_alias) {
|
||||
p = j->i_pspec;
|
||||
|
@ -1504,8 +1612,8 @@ do_kill_orphans(struct devbase *d, struct attr *at, struct devbase *parent)
|
|||
(p->p_atdev == NULL ||
|
||||
p->p_atdev == parent))) {
|
||||
if (p != NULL &&
|
||||
!devbase_has_instances(parent,
|
||||
p->p_atunit))
|
||||
!devbase_has_any_instance(parent,
|
||||
p->p_atunit, state))
|
||||
continue;
|
||||
/*
|
||||
* There are Fry-like devices which can
|
||||
|
@ -1515,33 +1623,45 @@ do_kill_orphans(struct devbase *d, struct attr *at, struct devbase *parent)
|
|||
* an instance for one reason or
|
||||
* another, stop there.
|
||||
*/
|
||||
if (j->i_active)
|
||||
if (j->i_active == DEVI_ACTIVE ||
|
||||
j->i_active == state)
|
||||
/*
|
||||
* Device has already been
|
||||
* seen
|
||||
*/
|
||||
return;
|
||||
j->i_active = active = 1;
|
||||
j->i_active = active = state;
|
||||
if (p != NULL)
|
||||
p->p_active = 1;
|
||||
p->p_active = state;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!active)
|
||||
return;
|
||||
if (!active) {
|
||||
struct cdd_params cdd = { d, at, parent };
|
||||
/* Look for a matching dead devi */
|
||||
if (ht_enumerate(deaddevitab, check_dead_devi, &cdd))
|
||||
/*
|
||||
* That device had its instances removed.
|
||||
* Continue the loop marking descendants
|
||||
* with DEVI_IGNORED instead of DEVI_ACTIVE.
|
||||
*/
|
||||
active = DEVI_IGNORED;
|
||||
else
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
for (nv = d->d_attrs; nv != NULL; nv = nv->nv_next) {
|
||||
a = nv->nv_ptr;
|
||||
for (nv1 = a->a_devs; nv1 != NULL; nv1 = nv1->nv_next)
|
||||
do_kill_orphans(nv1->nv_ptr, a, d);
|
||||
do_kill_orphans(nv1->nv_ptr, a, d, active);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
kill_orphans_cb(const char *key, void *value, void *aux)
|
||||
{
|
||||
do_kill_orphans((struct devbase *)value, NULL, NULL);
|
||||
do_kill_orphans((struct devbase *)value, NULL, NULL, DEVI_ACTIVE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: mkioconf.c,v 1.4 2005/09/30 22:36:20 cube Exp $ */
|
||||
/* $NetBSD: mkioconf.c,v 1.5 2005/10/01 23:30:37 cube Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1992, 1993
|
||||
|
@ -359,7 +359,7 @@ emitparents(FILE *fp)
|
|||
|
||||
NEWLINE;
|
||||
TAILQ_FOREACH(p, &allpspecs, p_list) {
|
||||
if (p->p_devs == NULL || !p->p_active)
|
||||
if (p->p_devs == NULL || p->p_active != DEVI_ACTIVE)
|
||||
continue;
|
||||
if (fprintf(fp,
|
||||
"static const struct cfparent pspec%d = {\n", p->p_inst) < 0)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: pack.c,v 1.2 2005/09/30 22:36:20 cube Exp $ */
|
||||
/* $NetBSD: pack.c,v 1.3 2005/10/01 23:30:37 cube Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1992, 1993
|
||||
|
@ -115,7 +115,7 @@ pack(void)
|
|||
*/
|
||||
locspace = 0;
|
||||
TAILQ_FOREACH(i, &alldevi, i_next) {
|
||||
if (!i->i_active || i->i_collapsed)
|
||||
if (!i->i_active == DEVI_ACTIVE || i->i_collapsed)
|
||||
continue;
|
||||
if ((p = i->i_pspec) == NULL)
|
||||
continue;
|
||||
|
@ -186,7 +186,7 @@ packdevi(void)
|
|||
for (i = d->d_ihead; i != NULL; i = i->i_bsame) {
|
||||
m = n;
|
||||
for (l = i; l != NULL; l = l->i_alias) {
|
||||
if (!l->i_active)
|
||||
if (l->i_active != DEVI_ACTIVE)
|
||||
continue;
|
||||
l->i_locoff = -1;
|
||||
/* try to find an equivalent for l */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: sem.c,v 1.7 2005/09/30 22:51:46 cube Exp $ */
|
||||
/* $NetBSD: sem.c,v 1.8 2005/10/01 23:30:37 cube Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1992, 1993
|
||||
|
@ -88,6 +88,7 @@ static const char *major2name(int);
|
|||
static int dev2major(struct devbase *);
|
||||
|
||||
extern const char *yyfile;
|
||||
extern int vflag;
|
||||
|
||||
void
|
||||
initsem(void)
|
||||
|
@ -877,7 +878,7 @@ newdevi(const char *name, int unit, struct devbase *d)
|
|||
i->i_locs = NULL;
|
||||
i->i_cfflags = 0;
|
||||
i->i_lineno = currentline();
|
||||
i->i_active = 0;
|
||||
i->i_active = DEVI_ORPHAN; /* Proper analysis comes later */
|
||||
if (unit >= d->d_umax)
|
||||
d->d_umax = unit + 1;
|
||||
return (i);
|
||||
|
@ -1181,7 +1182,19 @@ remove_devi(struct devi *i)
|
|||
*/
|
||||
TAILQ_REMOVE(&alldevi, i, i_next);
|
||||
ndevi--;
|
||||
free(i);
|
||||
/*
|
||||
* Put it in deaddevitab
|
||||
*/
|
||||
i->i_alias = NULL;
|
||||
f = ht_lookup(deaddevitab, i->i_name);
|
||||
if (f == NULL) {
|
||||
if (ht_insert(deaddevitab, i->i_name, i))
|
||||
panic("remove_devi(%s) - can't add to deaddevitab",
|
||||
i->i_name);
|
||||
} else {
|
||||
for (j = f; j->i_alias != NULL; j = j->i_alias);
|
||||
j->i_alias = i;
|
||||
}
|
||||
/*
|
||||
* - reconstuct d->d_umax
|
||||
*/
|
||||
|
@ -1343,7 +1356,7 @@ addpseudo(const char *name, int number)
|
|||
panic("addpseudo(%s)", name);
|
||||
/* Useful to retrieve the instance from the devbase */
|
||||
d->d_ihead = i;
|
||||
i->i_active = 1;
|
||||
i->i_active = DEVI_ACTIVE;
|
||||
TAILQ_INSERT_TAIL(&allpseudo, i, i_next);
|
||||
}
|
||||
|
||||
|
@ -1367,9 +1380,12 @@ delpseudo(const char *name)
|
|||
return;
|
||||
}
|
||||
d->d_umax = 0; /* clear neads-count entries */
|
||||
d->d_ihead = NULL; /* make sure it won't be considered active */
|
||||
TAILQ_REMOVE(&allpseudo, i, i_next);
|
||||
if (ht_remove(devitab, name))
|
||||
panic("delpseudo(%s) - can't remove from devitab", name);
|
||||
if (ht_insert(deaddevitab, name, i))
|
||||
panic("delpseudo(%s) - can't add to deaddevitab", name);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1408,28 +1424,38 @@ adddevm(const char *name, int cmajor, int bmajor, struct nvlist *options)
|
|||
maxbdevm = MAX(maxbdevm, dm->dm_bmajor);
|
||||
}
|
||||
|
||||
void
|
||||
int
|
||||
fixdevis(void)
|
||||
{
|
||||
struct devi *i;
|
||||
int error = 0;
|
||||
|
||||
TAILQ_FOREACH(i, &alldevi, i_next)
|
||||
if (i->i_active)
|
||||
if (i->i_active == DEVI_ACTIVE)
|
||||
selectbase(i->i_base, i->i_atdeva);
|
||||
else
|
||||
else if (i->i_active == DEVI_ORPHAN) {
|
||||
/*
|
||||
* At this point, we can't have instances for which
|
||||
* i_at or i_pspec are NULL.
|
||||
*/
|
||||
++error;
|
||||
(void)fprintf(stderr,
|
||||
"%s:%d: `%s at %s' is orphaned"
|
||||
" (%s `%s' found)\n", conffile, i->i_lineno,
|
||||
i->i_name, i->i_at, i->i_pspec->p_atunit == WILD ?
|
||||
"nothing matching" : "no", i->i_at);
|
||||
} else if (vflag && i->i_active == DEVI_IGNORED)
|
||||
(void)fprintf(stderr, "%s:%d: ignoring explicitely"
|
||||
" orphaned instance `%s at %s'\n", conffile,
|
||||
i->i_lineno, i->i_name, i->i_at);
|
||||
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
TAILQ_FOREACH(i, &allpseudo, i_next)
|
||||
if (i->i_active)
|
||||
if (i->i_active == DEVI_ACTIVE)
|
||||
selectbase(i->i_base, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: sem.h,v 1.2 2005/09/30 22:51:46 cube Exp $ */
|
||||
/* $NetBSD: sem.h,v 1.3 2005/10/01 23:30:37 cube Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1992, 1993
|
||||
|
@ -65,7 +65,7 @@ void deldev(const char *);
|
|||
void addpseudo(const char *, int);
|
||||
void delpseudo(const char *);
|
||||
void adddevm(const char *, int, int, struct nvlist *);
|
||||
void fixdevis(void);
|
||||
int fixdevis(void);
|
||||
const char *ref(const char *);
|
||||
const char *starref(const char *);
|
||||
const char *wildref(const char *);
|
||||
|
|
Loading…
Reference in New Issue