System processes recognition.
Bruce Evans
bde at zeta.org.au
Wed Mar 16 18:01:59 PST 2005
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
More information about the freebsd-arch
mailing list