Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 11 Nov 2002 16:41:19 -0800 (PST)
From:      Robert Watson <rwatson@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 20981 for review
Message-ID:  <200211120041.gAC0fJAV012669@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=20981

Change 20981 by rwatson@rwatson_tislabs on 2002/11/11 16:41:03

	Introduce a condition variable to avoid returning EBUSY when
	the MAC policy list is busy during a load or unload attempt.
	We assert no locks held during the cv wait, meaning we should
	be fairly deadlock-safe.  Because of the cv model and busy
	count, it's possible for a cv waiter waiting for exclusive
	access to the policy list to be starved by active and
	long-lived access control/labeling events.  For now, we
	accept that as a necessary tradeoff.
	
	Largely extracted from: amigus_mac_userland

Affected files ...

.. //depot/projects/trustedbsd/mac/sys/kern/kern_mac.c#356 edit

Differences ...

==== //depot/projects/trustedbsd/mac/sys/kern/kern_mac.c#356 (text+ko) ====

@@ -46,6 +46,7 @@
 #include "opt_devfs.h"
 
 #include <sys/param.h>
+#include <sys/condvar.h>
 #include <sys/extattr.h>
 #include <sys/imgact.h>
 #include <sys/kernel.h>
@@ -233,12 +234,14 @@
  * and that this is not yet done for relabel requests.
  */
 static struct mtx mac_policy_list_lock;
+static struct cv mac_policy_list_not_busy;
 static LIST_HEAD(, mac_policy_conf) mac_policy_list;
 static int mac_policy_list_busy;
 
 #define	MAC_POLICY_LIST_LOCKINIT() do {					\
 	mtx_init(&mac_policy_list_lock, "mac_policy_list_lock", NULL,	\
 	    MTX_DEF);							\
+	cv_init(&mac_policy_list_not_busy, "mac_policy_list_not_busy");	\
 } while (0)
 
 #define	MAC_POLICY_LIST_LOCK() do {					\
@@ -249,6 +252,14 @@
 	mtx_unlock(&mac_policy_list_lock);				\
 } while (0)
 
+#define	MAC_POLICY_LIST_EXCLUSIVE() do {				\
+	WITNESS_SLEEP(1, NULL);						\
+	mtx_lock(&mac_policy_list_lock);				\
+	while (mac_policy_list_busy != 0)				\
+		cv_wait(&mac_policy_list_not_busy,			\
+		    &mac_policy_list_lock);				\
+} while (0)
+
 #define	MAC_POLICY_LIST_BUSY() do {					\
 	MAC_POLICY_LIST_LOCK();						\
 	mac_policy_list_busy++;						\
@@ -258,8 +269,9 @@
 #define	MAC_POLICY_LIST_UNBUSY() do {					\
 	MAC_POLICY_LIST_LOCK();						\
 	mac_policy_list_busy--;						\
-	if (mac_policy_list_busy < 0)					\
-		panic("Extra mac_policy_list_busy--");			\
+	KASSERT(mac_policy_list_busy >= 0, ("MAC_POLICY_LIST_LOCK"));	\
+	if (mac_policy_list_busy == 0)					\
+		cv_signal(&mac_policy_list_not_busy);			\
 	MAC_POLICY_LIST_UNLOCK();					\
 } while (0)
 
@@ -474,11 +486,7 @@
 	struct mac_policy_conf *tmpc;
 	int slot;
 
-	MAC_POLICY_LIST_LOCK();
-	if (mac_policy_list_busy > 0) {
-		MAC_POLICY_LIST_UNLOCK();
-		return (EBUSY);
-	}
+	MAC_POLICY_LIST_EXCLUSIVE();
 	LIST_FOREACH(tmpc, &mac_policy_list, mpc_list) {
 		if (strcmp(tmpc->mpc_name, mpc->mpc_name) == 0) {
 			MAC_POLICY_LIST_UNLOCK();
@@ -518,7 +526,7 @@
 	 * to see if we did the run-time registration, and if not,
 	 * silently succeed.
 	 */
-	MAC_POLICY_LIST_LOCK();
+	MAC_POLICY_LIST_EXCLUSIVE();
 	if ((mpc->mpc_runtime_flags & MPC_RUNTIME_FLAG_REGISTERED) == 0) {
 		MAC_POLICY_LIST_UNLOCK();
 		return (0);
@@ -540,23 +548,14 @@
 		MAC_POLICY_LIST_UNLOCK();
 		return (EBUSY);
 	}
-	/*
-	 * Right now, we EBUSY if the list is in use.  In the future,
-	 * for reliability reasons, we might want to sleep and wakeup
-	 * later to try again.
-	 */
-	if (mac_policy_list_busy > 0) {
-		MAC_POLICY_LIST_UNLOCK();
-		return (EBUSY);
-	}
 	if (mpc->mpc_ops->mpo_destroy != NULL)
 		(*(mpc->mpc_ops->mpo_destroy))(mpc);
 
 	LIST_REMOVE(mpc, mpc_list);
+	mpc->mpc_runtime_flags &= ~MPC_RUNTIME_FLAG_REGISTERED;
+
 	MAC_POLICY_LIST_UNLOCK();
 
-	mpc->mpc_runtime_flags &= ~MPC_RUNTIME_FLAG_REGISTERED;
-
 	printf("Security policy unload: %s (%s)\n", mpc->mpc_fullname,
 	    mpc->mpc_name);
 

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe p4-projects" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200211120041.gAC0fJAV012669>