aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJamie Gritton <jamie@FreeBSD.org>2022-06-29 17:33:05 +0000
committerJamie Gritton <jamie@FreeBSD.org>2022-06-29 17:33:05 +0000
commita9f7455c38c19438d1061227b1fa11d40c5407a6 (patch)
tree4659f2aa0ad6c8081102e8283237f5cb320d2d5f
parentcb91f112a3dc6cb68fe618623f59cee576ce4d14 (diff)
downloadsrc-a9f7455c38c19438d1061227b1fa11d40c5407a6.tar.gz
src-a9f7455c38c19438d1061227b1fa11d40c5407a6.zip
jail: add prison_cleanup() to release resources held by a dying jail
Currently, when a jail starts dying, either by losing its last user reference or by being explicitly killed, osd_jail_call(...PR_METHOD_REMOVE...) is called. Encapsulate this into a function prison_cleanup() that can then do other cleanup.
-rw-r--r--sys/kern/kern_jail.c20
1 files changed, 16 insertions, 4 deletions
diff --git a/sys/kern/kern_jail.c b/sys/kern/kern_jail.c
index 187768b59608..7ef0afabe49d 100644
--- a/sys/kern/kern_jail.c
+++ b/sys/kern/kern_jail.c
@@ -143,6 +143,7 @@ static void prison_complete(void *context, int pending);
static void prison_deref(struct prison *pr, int flags);
static void prison_deref_kill(struct prison *pr, struct prisonlist *freeprison);
static int prison_lock_xlock(struct prison *pr, int flags);
+static void prison_cleanup(struct prison *pr);
static void prison_free_not_last(struct prison *pr);
static void prison_proc_free_not_last(struct prison *pr);
static void prison_set_allow_locked(struct prison *pr, unsigned flag,
@@ -2994,8 +2995,7 @@ prison_deref(struct prison *pr, int flags)
pr->pr_state = PRISON_STATE_DYING;
mtx_unlock(&pr->pr_mtx);
flags &= ~PD_LOCKED;
- (void)osd_jail_call(pr,
- PR_METHOD_REMOVE, NULL);
+ prison_cleanup(pr);
}
}
}
@@ -3150,7 +3150,7 @@ prison_deref_kill(struct prison *pr, struct prisonlist *freeprison)
}
if (!(cpr->pr_flags & PR_REMOVE))
continue;
- (void)osd_jail_call(cpr, PR_METHOD_REMOVE, NULL);
+ prison_cleanup(cpr);
mtx_lock(&cpr->pr_mtx);
cpr->pr_flags &= ~PR_REMOVE;
if (cpr->pr_flags & PR_PERSIST) {
@@ -3186,7 +3186,7 @@ prison_deref_kill(struct prison *pr, struct prisonlist *freeprison)
if (rpr != NULL)
LIST_REMOVE(rpr, pr_sibling);
- (void)osd_jail_call(pr, PR_METHOD_REMOVE, NULL);
+ prison_cleanup(pr);
mtx_lock(&pr->pr_mtx);
if (pr->pr_flags & PR_PERSIST) {
pr->pr_flags &= ~PR_PERSIST;
@@ -3233,6 +3233,18 @@ prison_lock_xlock(struct prison *pr, int flags)
}
/*
+ * Release a prison's resources when it starts dying (when the last user
+ * reference is dropped, or when it is killed).
+ */
+static void
+prison_cleanup(struct prison *pr)
+{
+ sx_assert(&allprison_lock, SA_XLOCKED);
+ mtx_assert(&pr->pr_mtx, MA_NOTOWNED);
+ (void)osd_jail_call(pr, PR_METHOD_REMOVE, NULL);
+}
+
+/*
* Set or clear a permission bit in the pr_allow field, passing restrictions
* (cleared permission) down to child jails.
*/