Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 17 Mar 2005 13:01:47 +1100 (EST)
From:      Bruce Evans <bde@zeta.org.au>
To:        John Baldwin <jhb@freebsd.org>
Cc:        freebsd-arch@freebsd.org
Subject:   Re: System processes recognition.
Message-ID:  <20050317124633.M72560@delplex.bde.org>
In-Reply-To: <200503161748.02353.jhb@FreeBSD.org>
References:  <20050315125136.GH9291@darkness.comp.waw.pl> <200503161748.02353.jhb@FreeBSD.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On Wed, 16 Mar 2005, John Baldwin wrote:

> On Tuesday 15 March 2005 07:51 am, Pawel Jakub Dawidek wrote:
>> I found, that there is no way to know if the given process is a system
>> (kernel) process or not:
>> ...
>> The easiest way to fix it, is to add P_KTHREAD flag to the swapper, I
>> think:
>>
>> --- init_main.c	17 Feb 2005 10:00:09 -0000	1.255
>> +++ init_main.c	15 Mar 2005 12:48:04 -0000
>> @@ -365,7 +365,7 @@ proc0_init(void *dummy __unused)
>>  	session0.s_leader = p;
>>
>>  	p->p_sysent = &null_sysvec;
>> -	p->p_flag = P_SYSTEM;
>> +	p->p_flag = P_SYSTEM | P_KTHREAD;
>>  	p->p_sflag = PS_INMEM;
>>  	p->p_state = PRS_NORMAL;
>>  	knlist_init(&p->p_klist, &p->p_mtx);
>>
>> Opinions?
>
> I think this is ok.  Ask bde@, he might say that P_SYSTEM should be removed
> from init.  (Can't remember if he is in favor of that or not.)

P_SYSTEM for init is bogus since it breaks at least procfs for init.
procfs may need to be disabled for init for security reasons, but it
shouldn't be disabled unconditionally.  I mainly noticed /proc/1/map
not existing.

There should be flags like P_KTHREAD as needed to make the properties
of init independent.

I use the following patches to mostly just remove the setting of P_SYSTEM
for init.

%%%
Index: init_main.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/init_main.c,v
retrieving revision 1.243
diff -u -2 -r1.243 init_main.c
--- init_main.c	16 Jun 2004 00:26:29 -0000	1.243
+++ init_main.c	16 Jun 2004 05:56:22 -0000
@@ -697,8 +686,8 @@
  		panic("cannot fork init: %d\n", error);
  	KASSERT(initproc->p_pid == 1, ("create_init: initproc->p_pid != 1"));
-	/* divorce init's credentials from the kernel's */
+
+	/* Divorce init's credentials from the kernel's. */
  	newcred = crget();
  	PROC_LOCK(initproc);
-	initproc->p_flag |= P_SYSTEM;
  	oldcred = initproc->p_ucred;
  	crcopy(newcred, oldcred);
@@ -710,7 +699,5 @@
  	crfree(oldcred);
  	cred_update_thread(FIRST_THREAD_IN_PROC(initproc));
-	mtx_lock_spin(&sched_lock);
-	initproc->p_sflag |= PS_INMEM;
-	mtx_unlock_spin(&sched_lock);
+
  	cpu_set_fork_handler(FIRST_THREAD_IN_PROC(initproc), start_init, NULL);
  }
Index: kern_sig.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/kern_sig.c,v
retrieving revision 1.281
diff -u -2 -r1.281 kern_sig.c
--- kern_sig.c	11 Jun 2004 11:16:23 -0000	1.281
+++ kern_sig.c	2 Oct 2004 13:36:09 -0000
@@ -360,5 +348,5 @@
  				 * is forbidden to set SA_NOCLDWAIT.
  				 */
-				if (p->p_pid == 1)
+				if (p == initproc)
  					ps->ps_flag &= ~PS_NOCLDWAIT;
  				else
@@ -1312,5 +1297,5 @@
  		LIST_FOREACH(p, &allproc, p_list) {
  			PROC_LOCK(p);
-			if (p->p_pid <= 1 || p->p_flag & P_SYSTEM ||
+			if (p == initproc || p->p_flag & P_SYSTEM ||
  			    p == td->td_proc) {
  				PROC_UNLOCK(p);
@@ -1343,5 +1328,5 @@
  		LIST_FOREACH(p, &pgrp->pg_members, p_pglist) {
  			PROC_LOCK(p); 
-			if (p->p_pid <= 1 || p->p_flag & P_SYSTEM) {
+			if (p == initproc || p->p_flag & P_SYSTEM) {
  				PROC_UNLOCK(p);
  				continue;
@@ -2127,5 +2153,5 @@
  			 * Don't take default actions on system processes.
  			 */
-			if (p->p_pid <= 1) {
+			if (p == initproc || p->p_flag & P_SYSTEM) {
  #ifdef DIAGNOSTIC
  				/*
%%%

PS_INMEM should be inherited on fork() like it is for other user processes.
I think it is always set after fork, so setting it in the above never
did anything; in particular it never forced init to stay in memory, but
setting P_SYSTEM did that and forced PS_INMEM to stay set as a side
effect.

All tests of P_SYSTEM need to be looked at to see if they affect init.
I could only find the ones above that are close to being problems.
Since they already had a separate (slightly wrong) test for init, they
don't need to be changed; however, the tests are bogus if P_SYSTEM is
set for init.  (p->p_pid <= 1) is also satisfied for pid 0, but the
P_SYSTEM part of the tests always succeeds for pid 0.

Bruce



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20050317124633.M72560>