Fri Jan 22 18:19:54 2016 UTC ()
Prevent interface deletion from running into an infinite loop when altq closes.
$ cat /etc/altq.conf
interface ppp0 bandwidth 10M priq
class priq ppp0 high_class_ppp NULL priority 1
class priq ppp0 low_class_ppp NULL priority 0 default
filter ppp0 high_class_ppp 0 0 0 0 1
$ ifconfig ppp0 create
$ /etc/rc.d/altqd onestart
$ ifconfig ppp0 destroy
$ pkill altqd
XXX: pullup-7


(christos)
diff -r1.24 -r1.25 src/sys/altq/altq_hfsc.c
diff -r1.7 -r1.8 src/sys/altq/altq_jobs.c
diff -r1.21 -r1.22 src/sys/altq/altq_priq.c

cvs diff -r1.24 -r1.25 src/sys/altq/altq_hfsc.c (expand / switch to context diff)
--- src/sys/altq/altq_hfsc.c 2008/06/18 09:06:27 1.24
+++ src/sys/altq/altq_hfsc.c 2016/01/22 18:19:54 1.25
@@ -1,4 +1,4 @@
-/*	$NetBSD: altq_hfsc.c,v 1.24 2008/06/18 09:06:27 yamt Exp $	*/
+/*	$NetBSD: altq_hfsc.c,v 1.25 2016/01/22 18:19:54 christos Exp $	*/
 /*	$KAME: altq_hfsc.c,v 1.26 2005/04/13 03:44:24 suz Exp $	*/
 
 /*
@@ -43,7 +43,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: altq_hfsc.c,v 1.24 2008/06/18 09:06:27 yamt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: altq_hfsc.c,v 1.25 2016/01/22 18:19:54 christos Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_altq.h"
@@ -146,7 +146,7 @@
 
 #ifdef ALTQ3_COMPAT
 static struct hfsc_if *hfsc_attach(struct ifaltq *, u_int);
-static int hfsc_detach(struct hfsc_if *);
+static void hfsc_detach(struct hfsc_if *);
 static int hfsc_class_modify(struct hfsc_class *, struct service_curve *,
     struct service_curve *, struct service_curve *);
 
@@ -1727,7 +1727,7 @@
 	return (hif);
 }
 
-static int
+static void
 hfsc_detach(struct hfsc_if *hif)
 {
 	(void)hfsc_clear_interface(hif);
@@ -1750,8 +1750,6 @@
 	ellist_destroy(hif->hif_eligible);
 
 	free(hif, M_DEVBUF);
-
-	return (0);
 }
 
 static int
@@ -1880,21 +1878,24 @@
     struct lwp *l)
 {
 	struct hfsc_if *hif;
-	int err, error = 0;
 
 	while ((hif = hif_list) != NULL) {
 		/* destroy all */
 		if (ALTQ_IS_ENABLED(hif->hif_ifq))
 			altq_disable(hif->hif_ifq);
 
-		err = altq_detach(hif->hif_ifq);
-		if (err == 0)
-			err = hfsc_detach(hif);
-		if (err != 0 && error == 0)
-			error = err;
+		int error = altq_detach(hif->hif_ifq);
+		switch (error) {
+		case 0:
+		case ENXIO:	/* already disabled */
+			break;
+		default:
+			return error;
+		}
+		hfsc_detach(hif);
 	}
 
-	return error;
+	return 0;
 }
 
 int
@@ -2015,7 +2016,7 @@
 	if ((error = altq_attach(&ifp->if_snd, ALTQT_HFSC, hif,
 				 hfsc_enqueue, hfsc_dequeue, hfsc_request,
 				 &hif->hif_classifier, acc_classify)) != 0)
-		(void)hfsc_detach(hif);
+		hfsc_detach(hif);
 
 	return (error);
 }
@@ -2035,7 +2036,8 @@
 	if ((error = altq_detach(hif->hif_ifq)))
 		return (error);
 
-	return hfsc_detach(hif);
+	hfsc_detach(hif);
+	return 0;
 }
 
 static int

cvs diff -r1.7 -r1.8 src/sys/altq/altq_jobs.c (expand / switch to context diff)
--- src/sys/altq/altq_jobs.c 2014/08/18 03:14:12 1.7
+++ src/sys/altq/altq_jobs.c 2016/01/22 18:19:54 1.8
@@ -1,4 +1,4 @@
-/*	$NetBSD: altq_jobs.c,v 1.7 2014/08/18 03:14:12 riastradh Exp $	*/
+/*	$NetBSD: altq_jobs.c,v 1.8 2016/01/22 18:19:54 christos Exp $	*/
 /*	$KAME: altq_jobs.c,v 1.11 2005/04/13 03:44:25 suz Exp $	*/
 /*
  * Copyright (c) 2001, the Rector and Board of Visitors of the
@@ -59,7 +59,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: altq_jobs.c,v 1.7 2014/08/18 03:14:12 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: altq_jobs.c,v 1.8 2016/01/22 18:19:54 christos Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_altq.h"
@@ -96,7 +96,7 @@
  * function prototypes
  */
 static struct jobs_if *jobs_attach(struct ifaltq *, u_int, u_int, u_int);
-static int jobs_detach(struct jobs_if *);
+static void jobs_detach(struct jobs_if *);
 static int jobs_clear_interface(struct jobs_if *);
 static int jobs_request(struct ifaltq *, int, void *);
 static void jobs_purge(struct jobs_if *);
@@ -184,7 +184,7 @@
 	return (jif);
 }
 
-static int
+static void
 jobs_detach(struct jobs_if *jif)
 {
 	(void)jobs_clear_interface(jif);
@@ -203,7 +203,6 @@
 		ASSERT(p != NULL);
 	}
 	free(jif, M_DEVBUF);
-	return (0);
 }
 
 /*
@@ -1837,18 +1836,21 @@
     struct lwp *l)
 {
 	struct jobs_if *jif;
-	int err, error = 0;
 
 	while ((jif = jif_list) != NULL) {
 		/* destroy all */
 		if (ALTQ_IS_ENABLED(jif->jif_ifq))
 			altq_disable(jif->jif_ifq);
 
-		err = altq_detach(jif->jif_ifq);
-		if (err == 0)
-			err = jobs_detach(jif);
-		if (err != 0 && error == 0)
-			error = err;
+		int error = altq_detach(pif->pif_ifq);
+		switch (error) {
+		case 0:
+		case ENXIO:	/* already disabled */
+			break;
+		default:
+			return error;
+		}
+		jobs_detach(jif);
 	}
 
 	return error;
@@ -1971,7 +1973,7 @@
 	if ((error = altq_attach(&ifp->if_snd, ALTQT_JOBS, jif,
 				 jobs_enqueue, jobs_dequeue, jobs_request,
 				 &jif->jif_classifier, acc_classify)) != 0)
-		(void)jobs_detach(jif);
+		jobs_detach(jif);
 
 	return (error);
 }
@@ -1991,7 +1993,8 @@
 	if ((error = altq_detach(jif->jif_ifq)))
 		return (error);
 
-	return jobs_detach(jif);
+	jobs_detach(jif);
+	return 0;
 }
 
 static int

cvs diff -r1.21 -r1.22 src/sys/altq/altq_priq.c (expand / switch to context diff)
--- src/sys/altq/altq_priq.c 2009/03/14 15:35:58 1.21
+++ src/sys/altq/altq_priq.c 2016/01/22 18:19:54 1.22
@@ -1,4 +1,4 @@
-/*	$NetBSD: altq_priq.c,v 1.21 2009/03/14 15:35:58 dsl Exp $	*/
+/*	$NetBSD: altq_priq.c,v 1.22 2016/01/22 18:19:54 christos Exp $	*/
 /*	$KAME: altq_priq.c,v 1.13 2005/04/13 03:44:25 suz Exp $	*/
 /*
  * Copyright (C) 2000-2003
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: altq_priq.c,v 1.21 2009/03/14 15:35:58 dsl Exp $");
+__KERNEL_RCSID(0, "$NetBSD: altq_priq.c,v 1.22 2016/01/22 18:19:54 christos Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_altq.h"
@@ -68,7 +68,7 @@
  */
 #ifdef ALTQ3_COMPAT
 static struct priq_if *priq_attach(struct ifaltq *, u_int);
-static int priq_detach(struct priq_if *);
+static void priq_detach(struct priq_if *);
 #endif
 static int priq_clear_interface(struct priq_if *);
 static int priq_request(struct ifaltq *, int, void *);
@@ -648,7 +648,7 @@
 	return (pif);
 }
 
-static int
+static void
 priq_detach(struct priq_if *pif)
 {
 	(void)priq_clear_interface(pif);
@@ -668,7 +668,6 @@
 	}
 
 	free(pif, M_DEVBUF);
-	return (0);
 }
 
 /*
@@ -687,21 +686,24 @@
     struct lwp *l)
 {
 	struct priq_if *pif;
-	int err, error = 0;
 
 	while ((pif = pif_list) != NULL) {
 		/* destroy all */
 		if (ALTQ_IS_ENABLED(pif->pif_ifq))
 			altq_disable(pif->pif_ifq);
 
-		err = altq_detach(pif->pif_ifq);
-		if (err == 0)
-			err = priq_detach(pif);
-		if (err != 0 && error == 0)
-			error = err;
+		int error = altq_detach(pif->pif_ifq);
+		switch (error) {
+		case 0:
+		case ENXIO:	/* already disabled */
+			break;
+		default:
+			return error;
+		}
+		priq_detach(pif);
 	}
 
-	return error;
+	return 0;
 }
 
 int
@@ -821,7 +823,7 @@
 	if ((error = altq_attach(&ifp->if_snd, ALTQT_PRIQ, pif,
 				 priq_enqueue, priq_dequeue, priq_request,
 				 &pif->pif_classifier, acc_classify)) != 0)
-		(void)priq_detach(pif);
+		priq_detach(pif);
 
 	return (error);
 }
@@ -841,7 +843,8 @@
 	if ((error = altq_detach(pif->pif_ifq)))
 		return (error);
 
-	return priq_detach(pif);
+	priq_detach(pif);
+	return 0;
 }
 
 static int