shithub: riscv

Download patch

ref: 08d6b0f043f30d85033aacce63fbd9985f3e5325
parent: 21a599743e037628fbf6e43f6014f007704414e4
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sun Dec 1 12:57:14 EST 2019

kernel: improve diagnostics by reversing the roles of Proc.parentpid and Proc.parent

for better system diagnostics, we *ALWAYS* want to record the parent
pid of a user process, regardless of if the child will post a wait
record on exit or not.

for that, we reverse the roles of Proc.parent and Proc.parentpid so
Proc.parentpid will always be set on rfork() and the Proc.parent
pointer will point to the parent's Proc structure or is set to nil
when no wait record should be posted on exit (RFNOWAIT flag).

this means that we can get the pid of the original parent process
from /proc, regardless of the the child having rforked with the
RFNOWAIT flag. this improves the output of pstree(1) somewhat if
the parent is still alive. note that theres no guarantee that the
parent pid is still valid.

the conditions are unchanged:

a user process that will post wait record has:

up->kp == 0 && up->parent != nil && up->parent->pid == up->parentpid

the boot process is:

up->kp == 0 && up->parent == nil && up->parentpid == 0

and kproc's have:

up->kp != 0 && up->parent == nil && up->parentpid == 0

--- a/sys/src/9/port/proc.c
+++ b/sys/src/9/port/proc.c
@@ -1130,7 +1130,14 @@
 	 * if not a kernel process and have a parent,
 	 * do some housekeeping.
 	 */
-	if(up->kp == 0 && up->parentpid != 0) {
+	if(up->kp)
+		goto Nowait;
+
+	p = up->parent;
+	if(p != nil){
+		if(p->pid != up->parentpid || p->state == Broken)
+			goto Nowait;
+
 		wq = smalloc(sizeof(Waitq));
 		wq->w.pid = up->pid;
 		utime = up->time[TUser] + up->time[TCUser];
@@ -1143,7 +1150,6 @@
 		else
 			wq->w.msg[0] = '\0';
 
-		p = up->parent;
 		lock(&p->exl);
 		/*
 		 * Check that parent is still alive.
@@ -1171,12 +1177,13 @@
 		if(wq != nil)
 			free(wq);
 	}
-	else if(up->kp == 0 && up->parent == nil){
+	else if(up->parentpid == 0){
 		if(exitstr == nil)
 			exitstr = "unknown";
 		panic("boot process died: %s", exitstr);
 	}
 
+Nowait:
 	if(!freemem)
 		addbroken(up);
 
--- a/sys/src/9/port/sysproc.c
+++ b/sys/src/9/port/sysproc.c
@@ -181,9 +181,9 @@
 	 */
 	forkchild(p, up->dbgreg);
 
-	p->parent = up;
+	p->parentpid = up->pid;
 	if((flag&RFNOWAIT) == 0){
-		p->parentpid = up->pid;
+		p->parent = up;
 		lock(&up->exl);
 		up->nchild++;
 		unlock(&up->exl);