P2_WEXIT: avoid thread_single() for exiting process earlier

before the process itself does thread_single(SINGLE_EXIT).  We cannot
single-thread such process in ALLPROC (external) mode, and properly
detect and report the failure to do so due to the process becoming
zombie is easier to prevent than handle.

In collaboration with:	pho
Reviewed by:	markj
Sponsored by:	The FreeBSD Foundation
MFC after:	2 weeks
Differential revision:	https://reviews.freebsd.org/D35310
This commit is contained in:
Konstantin Belousov 2022-05-05 02:57:26 +03:00
parent 6a02539959
commit d3000939c7
5 changed files with 8 additions and 2 deletions

View File

@ -251,6 +251,8 @@ exit1(struct thread *td, int rval, int signo)
* MUST abort all other threads before proceeding past here.
*/
PROC_LOCK(p);
p->p_flag2 |= P2_WEXIT;
/*
* First check if some other thread or external request got
* here before us. If so, act appropriately: exit or suspend.

View File

@ -3446,7 +3446,7 @@ stop_all_proc(void)
PROC_UNLOCK(p);
continue;
}
if ((p->p_flag & P_WEXIT) != 0) {
if ((p->p_flag2 & P2_WEXIT) != 0) {
seen_exiting = true;
PROC_UNLOCK(p);
continue;

View File

@ -325,7 +325,7 @@ reap_kill_proc(struct thread *td, struct proc *p2, ksiginfo_t *ksi,
res = true;
PROC_LOCK(p2);
if ((p2->p_flag & P_WEXIT) == 0) {
if ((p2->p_flag2 & P2_WEXIT) == 0) {
_PHOLD_LITE(p2);
res = reap_kill_proc_locked(td, p2, ksi, rk, error);
_PRELE(p2);

View File

@ -3406,6 +3406,7 @@ sigexit(struct thread *td, int sig)
struct proc *p = td->td_proc;
PROC_LOCK_ASSERT(p, MA_OWNED);
p->p_flag2 |= P2_WEXIT;
p->p_acflag |= AXSIG;
/*
* We must be single-threading to generate a core dump. This

View File

@ -847,6 +847,9 @@ struct proc {
#define P2_NO_NEW_PRIVS 0x00008000 /* Ignore setuid */
#define P2_WXORX_DISABLE 0x00010000 /* WX mappings enabled */
#define P2_WXORX_ENABLE_EXEC 0x00020000 /* WXORX enabled after exec */
#define P2_WEXIT 0x00040000 /* exit just started, no
external thread_single() is
permitted */
/* Flags protected by proctree_lock, kept in p_treeflags. */
#define P_TREE_ORPHANED 0x00000001 /* Reparented, on orphan list */