Module Name:    src
Committed By:   christos
Date:           Thu Nov 16 17:08:07 UTC 2017

Modified Files:
        src/usr.bin/config: defs.h main.c

Log Message:
When deleting orphans detect parent<->child loops and break them.
"active" is not a boolean, use the right comparison.


To generate a diff of this commit:
cvs rdiff -u -r1.99 -r1.100 src/usr.bin/config/defs.h
cvs rdiff -u -r1.91 -r1.92 src/usr.bin/config/main.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/usr.bin/config/defs.h
diff -u src/usr.bin/config/defs.h:1.99 src/usr.bin/config/defs.h:1.100
--- src/usr.bin/config/defs.h:1.99	Thu Jun 15 20:10:09 2017
+++ src/usr.bin/config/defs.h	Thu Nov 16 12:08:07 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: defs.h,v 1.99 2017/06/16 00:10:09 christos Exp $	*/
+/*	$NetBSD: defs.h,v 1.100 2017/11/16 17:08:07 christos Exp $	*/
 
 /*
  * Copyright (c) 1992, 1993
@@ -264,6 +264,8 @@ struct pspec {
 struct devbase {
 	const char *d_name;		/* e.g., "sd" */
 	TAILQ_ENTRY(devbase) d_next;
+	int 	d_level;
+	struct devbase *d_levelparent;
 	int	d_isdef;		/* set once properly defined */
 	int	d_ispseudo;		/* is a pseudo-device */
 	devmajor_t d_major;		/* used for "root on sd0", e.g. */

Index: src/usr.bin/config/main.c
diff -u src/usr.bin/config/main.c:1.91 src/usr.bin/config/main.c:1.92
--- src/usr.bin/config/main.c:1.91	Sun Sep  4 20:40:28 2016
+++ src/usr.bin/config/main.c	Thu Nov 16 12:08:07 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: main.c,v 1.91 2016/09/05 00:40:28 sevan Exp $	*/
+/*	$NetBSD: main.c,v 1.92 2017/11/16 17:08:07 christos Exp $	*/
 
 /*
  * Copyright (c) 1992, 1993
@@ -45,7 +45,7 @@
 #endif
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: main.c,v 1.91 2016/09/05 00:40:28 sevan Exp $");
+__RCSID("$NetBSD: main.c,v 1.92 2017/11/16 17:08:07 christos Exp $");
 
 #ifndef MAKE_BOOTSTRAP
 #include <sys/cdefs.h>
@@ -1868,6 +1868,15 @@ check_dead_devi(const char *key, void *v
 	return 0;
 }
 
+static int
+is_orphan_loop(const struct devbase *d, const struct devbase *p)
+{
+
+	for (; p && d != p; p = p->d_levelparent)
+		continue;
+	return d == p;
+}
+
 static void
 do_kill_orphans(struct devbase *d, struct attr *at, struct devbase *parent,
     int state)
@@ -1879,6 +1888,9 @@ do_kill_orphans(struct devbase *d, struc
 	struct pspec *p;
 	int active = 0;
 
+	if (d->d_levelparent == NULL)
+		d->d_levelparent = parent;
+
 	/*
 	 * 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
@@ -1938,9 +1950,9 @@ do_kill_orphans(struct devbase *d, struc
 		/*
 		 * If we've been there but have made no change, stop.
 		 */
-		if (seen && !active)
+		if (seen && active != DEVI_ACTIVE)
 			return;
-		if (!active) {
+		if (active != DEVI_ACTIVE) {
 			struct cdd_params cdd = { d, at, parent };
 			/* Look for a matching dead devi */
 			if (ht_enumerate(deaddevitab, check_dead_devi, &cdd) &&
@@ -1963,9 +1975,15 @@ do_kill_orphans(struct devbase *d, struc
 
 	for (al = d->d_attrs; al != NULL; al = al->al_next) {
 		a = al->al_this;
-		for (nv1 = a->a_devs; nv1 != NULL; nv1 = nv1->nv_next)
+		for (nv1 = a->a_devs; nv1 != NULL; nv1 = nv1->nv_next) {
+			if (is_orphan_loop(nv1->nv_ptr, d)) {
+				if (d->d_level++ > 1)
+					continue;
+			}
 			do_kill_orphans(nv1->nv_ptr, a, d, active);
+		}
 	}
+	d->d_levelparent = NULL;
 }
 
 static int

Reply via email to