git: 06dcf1499bf5 - stable/13 - MFC jail: add prison_cleanup() to release resources held by a dying jail

From: Jamie Gritton <jamie_at_FreeBSD.org>
Date: Sun, 03 Jul 2022 19:25:27 UTC
The branch stable/13 has been updated by jamie:

URL: https://cgit.FreeBSD.org/src/commit/?id=06dcf1499bf5d194bd89a7e37d50df80d8c3c609

commit 06dcf1499bf5d194bd89a7e37d50df80d8c3c609
Author:     Jamie Gritton <jamie@FreeBSD.org>
AuthorDate: 2022-06-29 17:33:05 +0000
Commit:     Jamie Gritton <jamie@FreeBSD.org>
CommitDate: 2022-07-03 19:24:49 +0000

    MFC 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.
    
    (cherry picked from commit a9f7455c38c19438d1061227b1fa11d40c5407a6)
---
 sys/kern/kern_jail.c | 20 ++++++++++++++++----
 1 file changed, 16 insertions(+), 4 deletions(-)

diff --git a/sys/kern/kern_jail.c b/sys/kern/kern_jail.c
index c86c945b3807..43e101176a71 100644
--- a/sys/kern/kern_jail.c
+++ b/sys/kern/kern_jail.c
@@ -142,6 +142,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,
@@ -2776,8 +2777,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);
 				}
 			}
 		}
@@ -2932,7 +2932,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) {
@@ -2968,7 +2968,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;
@@ -3014,6 +3014,18 @@ prison_lock_xlock(struct prison *pr, int flags)
 	return 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.