PERFORCE change 20981 for review
Robert Watson
rwatson at freebsd.org
Tue Nov 12 00:41:19 GMT 2002
http://perforce.freebsd.org/chv.cgi?CH=20981
Change 20981 by rwatson at 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 at trustedbsd.org
with "unsubscribe trustedbsd-cvs" in the body of the message
More information about the trustedbsd-cvs
mailing list