PM cleanup: merge exit and coredump paths

This commit is contained in:
David van Moolenbroek 2009-07-08 17:16:53 +00:00
parent 5e173f55f5
commit 67d986f882
8 changed files with 127 additions and 259 deletions

View File

@ -162,7 +162,7 @@ int result;
/* Use SIGILL signal that something went wrong */ /* Use SIGILL signal that something went wrong */
rmp->mp_sigstatus = SIGILL; rmp->mp_sigstatus = SIGILL;
pm_exit(rmp, 0, FALSE /*!for_trace*/); exit_proc(rmp, 0, PM_EXIT);
return; return;
} }
setreply(rmp-mproc, result); setreply(rmp-mproc, result);

View File

@ -7,11 +7,12 @@
* exits first, it continues to occupy a slot until the parent does a WAIT. * exits first, it continues to occupy a slot until the parent does a WAIT.
* *
* The entry points into this file are: * The entry points into this file are:
* do_fork: perform the FORK system call * do_fork: perform the FORK system call
* do_pm_exit: perform the EXIT system call (by calling pm_exit()) * do_fork_nb: special nonblocking version of FORK, for RS
* pm_exit: actually do the exiting * do_exit: perform the EXIT system call (by calling exit_proc())
* do_wait: perform the WAITPID or WAIT system call * exit_proc: actually do the exiting, and tell FS about it
* tell_parent: tell parent about the death of a child * exit_restart: continue exiting a process after FS has replied
* do_waitpid: perform the WAITPID or WAIT system call
*/ */
#include "pm.h" #include "pm.h"
@ -26,7 +27,9 @@
#define LAST_FEW 2 /* last few slots reserved for superuser */ #define LAST_FEW 2 /* last few slots reserved for superuser */
FORWARD _PROTOTYPE (void cleanup, (register struct mproc *child) ); FORWARD _PROTOTYPE (void zombify, (struct mproc *rmp) );
FORWARD _PROTOTYPE (void tell_parent, (struct mproc *child) );
FORWARD _PROTOTYPE (void cleanup, (register struct mproc *rmp) );
/*===========================================================================* /*===========================================================================*
* do_fork * * do_fork *
@ -173,35 +176,45 @@ PUBLIC int do_fork_nb()
} }
/*===========================================================================* /*===========================================================================*
* do_pm_exit * * do_exit *
*===========================================================================*/ *===========================================================================*/
PUBLIC int do_pm_exit() PUBLIC int do_exit()
{ {
/* Perform the exit(status) system call. The real work is done by pm_exit(), /* Perform the exit(status) system call. The real work is done by exit_proc(),
* which is also called when a process is killed by a signal. * which is also called when a process is killed by a signal.
*/ */
pm_exit(mp, m_in.status, FALSE /*!for_trace*/); exit_proc(mp, m_in.status, PM_EXIT);
return(SUSPEND); /* can't communicate from beyond the grave */ return(SUSPEND); /* can't communicate from beyond the grave */
} }
/*===========================================================================* /*===========================================================================*
* pm_exit * * exit_proc *
*===========================================================================*/ *===========================================================================*/
PUBLIC void pm_exit(rmp, exit_status, for_trace) PUBLIC void exit_proc(rmp, exit_status, exit_type)
register struct mproc *rmp; /* pointer to the process to be terminated */ register struct mproc *rmp; /* pointer to the process to be terminated */
int exit_status; /* the process' exit status (for parent) */ int exit_status; /* the process' exit status (for parent) */
int for_trace; int exit_type; /* one of PM_EXIT, PM_EXIT_TR, PM_DUMPCORE */
{ {
/* A process is done. Release most of the process' possessions. If its /* A process is done. Release most of the process' possessions. If its
* parent is waiting, release the rest, else keep the process slot and * parent is waiting, release the rest, else keep the process slot and
* become a zombie. * become a zombie.
*/ */
register int proc_nr, proc_nr_e; register int proc_nr, proc_nr_e;
int parent_waiting, right_child, r; int parent_waiting, r;
pid_t pidarg, procgrp; pid_t procgrp;
struct mproc *p_mp; struct mproc *p_mp;
clock_t user_time, sys_time; clock_t user_time, sys_time;
/* Do not create core files for set uid execution */
if (exit_type == PM_DUMPCORE && rmp->mp_realuid != rmp->mp_effuid)
exit_type = PM_EXIT;
/* System processes are destroyed before informing FS, meaning that FS can
* not get their CPU state, so we can't generate a coredump for them either.
*/
if (exit_type == PM_DUMPCORE && (rmp->mp_flags & PRIV_PROC))
exit_type = PM_EXIT;
proc_nr = (int) (rmp - mproc); /* get process slot number */ proc_nr = (int) (rmp - mproc); /* get process slot number */
proc_nr_e = rmp->mp_endpoint; proc_nr_e = rmp->mp_endpoint;
@ -213,7 +226,7 @@ int for_trace;
/* Do accounting: fetch usage times and accumulate at parent. */ /* Do accounting: fetch usage times and accumulate at parent. */
if((r=sys_times(proc_nr_e, &user_time, &sys_time, NULL)) != OK) if((r=sys_times(proc_nr_e, &user_time, &sys_time, NULL)) != OK)
panic(__FILE__,"pm_exit: sys_times failed", r); panic(__FILE__,"exit_proc: sys_times failed", r);
p_mp = &mproc[rmp->mp_parent]; /* process' parent */ p_mp = &mproc[rmp->mp_parent]; /* process' parent */
p_mp->mp_child_utime += user_time + rmp->mp_child_utime; /* add user time */ p_mp->mp_child_utime += user_time + rmp->mp_child_utime; /* add user time */
@ -227,7 +240,7 @@ int for_trace;
*/ */
sys_nice(proc_nr_e, PRIO_STOP); /* stop the process */ sys_nice(proc_nr_e, PRIO_STOP); /* stop the process */
if((r=vm_willexit(proc_nr_e)) != OK) { if((r=vm_willexit(proc_nr_e)) != OK) {
panic(__FILE__, "pm_exit: vm_willexit failed", r); panic(__FILE__, "exit_proc: vm_willexit failed", r);
} }
if (proc_nr_e == INIT_PROC_NR) if (proc_nr_e == INIT_PROC_NR)
@ -240,16 +253,16 @@ int for_trace;
{ {
/* Tell FS about the exiting process. */ /* Tell FS about the exiting process. */
if (rmp->mp_fs_call != PM_IDLE) if (rmp->mp_fs_call != PM_IDLE)
panic(__FILE__, "pm_exit: not idle", rmp->mp_fs_call); panic(__FILE__, "exit_proc: not idle", rmp->mp_fs_call);
rmp->mp_fs_call= (for_trace ? PM_EXIT_TR : PM_EXIT); rmp->mp_fs_call= exit_type;
r= notify(FS_PROC_NR); r= notify(FS_PROC_NR);
if (r != OK) panic(__FILE__, "pm_exit: unable to notify FS", r); if (r != OK) panic(__FILE__, "exit_proc: unable to notify FS", r);
if (rmp->mp_flags & PRIV_PROC) if (rmp->mp_flags & PRIV_PROC)
{ {
/* destroy system processes without waiting for FS */ /* destroy system processes without waiting for FS */
if((r= sys_exit(rmp->mp_endpoint)) != OK) if((r= sys_exit(rmp->mp_endpoint)) != OK)
panic(__FILE__, "pm_exit: sys_exit failed", r); panic(__FILE__, "exit_proc: sys_exit failed", r);
} }
} }
else else
@ -264,18 +277,12 @@ int for_trace;
/* Keep the process around until FS is finished with it. */ /* Keep the process around until FS is finished with it. */
rmp->mp_exitstatus = (char) exit_status; rmp->mp_exitstatus = (char) exit_status;
pidarg = p_mp->mp_wpid; /* who's being waited for? */
parent_waiting = p_mp->mp_flags & WAITING;
right_child = /* child meets one of the 3 tests? */
(pidarg == -1 || pidarg == rmp->mp_pid || -pidarg == rmp->mp_procgrp);
if (parent_waiting && right_child) { /* For normal exits, try to notify the parent as soon as possible.
tell_parent(rmp); /* tell parent */ * For core dumps, notify the parent only once the core dump has been made.
} else { */
rmp->mp_flags &= (IN_USE|PRIV_PROC|HAS_DMA); if (exit_type != PM_DUMPCORE)
rmp->mp_flags |= ZOMBIE; /* parent not waiting, zombify child */ zombify(rmp);
sig_proc(p_mp, SIGCHLD); /* send parent a "child died" signal */
}
/* If the process has children, disinherit them. INIT is the new parent. */ /* If the process has children, disinherit them. INIT is the new parent. */
for (rmp = &mproc[0]; rmp < &mproc[NR_PROCS]; rmp++) { for (rmp = &mproc[0]; rmp < &mproc[NR_PROCS]; rmp++) {
@ -284,9 +291,11 @@ int for_trace;
rmp->mp_parent = INIT_PROC_NR; rmp->mp_parent = INIT_PROC_NR;
parent_waiting = mproc[INIT_PROC_NR].mp_flags & WAITING; parent_waiting = mproc[INIT_PROC_NR].mp_flags & WAITING;
if (parent_waiting && (rmp->mp_flags & ZOMBIE) && if (parent_waiting && (rmp->mp_flags & ZOMBIE) &&
!(rmp->mp_flags & TOLD_PARENT) && !(rmp->mp_flags & TOLD_PARENT)) {
rmp->mp_fs_call != PM_EXIT) { tell_parent(rmp);
cleanup(rmp);
if (rmp->mp_fs_call == PM_IDLE)
cleanup(rmp);
} }
} }
} }
@ -295,6 +304,46 @@ int for_trace;
if (procgrp != 0) check_sig(-procgrp, SIGHUP); if (procgrp != 0) check_sig(-procgrp, SIGHUP);
} }
/*===========================================================================*
* exit_restart *
*===========================================================================*/
PUBLIC void exit_restart(rmp, reply_type)
struct mproc *rmp; /* pointer to the process being terminated */
int reply_type; /* one of PM_EXIT_REPLY(_TR), PM_CORE_REPLY */
{
/* FS replied to our exit or coredump request. Perform the second half of the
* exit code.
*/
int r;
/* For core dumps, now is the right time to try to contact the parent. */
if (reply_type == PM_CORE_REPLY)
zombify(rmp);
if (!(rmp->mp_flags & PRIV_PROC))
{
/* destroy the (user) process */
if((r=sys_exit(rmp->mp_endpoint)) != OK)
panic(__FILE__, "exit_restart: sys_exit failed", r);
}
/* Release the memory occupied by the child. */
if((r=vm_exit(rmp->mp_endpoint)) != OK) {
panic(__FILE__, "exit_restart: vm_exit failed", r);
}
if (reply_type == PM_EXIT_REPLY_TR && rmp->mp_parent != INIT_PROC_NR)
{
/* Wake up the parent, completing the ptrace(T_EXIT) call */
mproc[rmp->mp_parent].mp_reply.reply_trace = 0;
setreply(rmp->mp_parent, OK);
}
/* Clean up if the parent has collected the exit status */
if (rmp->mp_flags & TOLD_PARENT)
cleanup(rmp);
}
/*===========================================================================* /*===========================================================================*
* do_waitpid * * do_waitpid *
*===========================================================================*/ *===========================================================================*/
@ -305,7 +354,7 @@ PUBLIC int do_waitpid()
* really wait. * really wait.
* A process calling WAIT never gets a reply in the usual way at the end * A process calling WAIT never gets a reply in the usual way at the end
* of the main loop (unless WNOHANG is set or no qualifying child exists). * of the main loop (unless WNOHANG is set or no qualifying child exists).
* If a child has already exited, the routine cleanup() sends the reply * If a child has already exited, the routine tell_parent() sends the reply
* to awaken the caller. * to awaken the caller.
* Both WAIT and WAITPID are handled by this code. * Both WAIT and WAITPID are handled by this code.
*/ */
@ -335,7 +384,7 @@ PUBLIC int do_waitpid()
/* This child meets the pid test and has exited. */ /* This child meets the pid test and has exited. */
tell_parent(rp); /* this child has already exited */ tell_parent(rp); /* this child has already exited */
if (rp->mp_fs_call == PM_IDLE) if (rp->mp_fs_call == PM_IDLE)
real_cleanup(rp); cleanup(rp);
return(SUSPEND); return(SUSPEND);
} }
if ((rp->mp_flags & STOPPED) && rp->mp_sigstatus) { if ((rp->mp_flags & STOPPED) && rp->mp_sigstatus) {
@ -363,27 +412,40 @@ PUBLIC int do_waitpid()
} }
/*===========================================================================* /*===========================================================================*
* cleanup * * zombify *
*===========================================================================*/ *===========================================================================*/
PRIVATE void cleanup(child) PRIVATE void zombify(rmp)
register struct mproc *child; /* tells which process is exiting */ struct mproc *rmp;
{ {
/* Finish off the exit of a process. The process has exited or been killed /* Zombify a process. If the parent is waiting, notify it immediately.
* by a signal, and its parent is waiting. * Otherwise, send a SIGCHLD signal to the parent.
*/ */
struct mproc *p_mp;
int parent_waiting, right_child;
pid_t pidarg;
if (child->mp_fs_call != PM_IDLE) if (rmp->mp_flags & ZOMBIE)
panic(__FILE__, "cleanup: not idle", child->mp_fs_call); panic(__FILE__, "zombify: process was already a zombie", NO_NUM);
tell_parent(child); rmp->mp_flags &= (IN_USE|PRIV_PROC|HAS_DMA);
real_cleanup(child); rmp->mp_flags |= ZOMBIE;
p_mp = &mproc[rmp->mp_parent];
pidarg = p_mp->mp_wpid; /* who's being waited for? */
parent_waiting = p_mp->mp_flags & WAITING;
right_child = /* child meets one of the 3 tests? */
(pidarg == -1 || pidarg == rmp->mp_pid || -pidarg == rmp->mp_procgrp);
if (parent_waiting && right_child)
tell_parent(rmp); /* tell parent */
else
sig_proc(p_mp, SIGCHLD); /* send parent a "child died" signal */
} }
/*===========================================================================* /*===========================================================================*
* tell_parent * * tell_parent *
*===========================================================================*/ *===========================================================================*/
PUBLIC void tell_parent(child) PRIVATE void tell_parent(child)
register struct mproc *child; /* tells which process is exiting */ register struct mproc *child; /* tells which process is exiting */
{ {
int exitstatus, mp_parent; int exitstatus, mp_parent;
@ -405,9 +467,9 @@ register struct mproc *child; /* tells which process is exiting */
} }
/*===========================================================================* /*===========================================================================*
* real_cleanup * * cleanup *
*===========================================================================*/ *===========================================================================*/
PUBLIC void real_cleanup(rmp) PRIVATE void cleanup(rmp)
register struct mproc *rmp; /* tells which process is exiting */ register struct mproc *rmp; /* tells which process is exiting */
{ {
/* Release the process table entry and reinitialize some field. */ /* Release the process table entry and reinitialize some field. */

View File

@ -596,34 +596,7 @@ message *m_ptr;
/* Call is finished */ /* Call is finished */
rmp->mp_fs_call= PM_IDLE; rmp->mp_fs_call= PM_IDLE;
if (!(rmp->mp_flags & PRIV_PROC)) exit_restart(rmp, m_ptr->m_type);
{
/* destroy the (user) process */
if((r=sys_exit(proc_e)) != OK)
{
panic(__FILE__,
"PM_EXIT_REPLY: sys_exit failed", r);
}
}
/* Release the memory occupied by the child. */
if((s=vm_exit(rmp->mp_endpoint)) != OK) {
panic(__FILE__, "vm_exit() failed", s);
}
if (m_ptr->m_type == PM_EXIT_REPLY_TR &&
rmp->mp_parent != INIT_PROC_NR)
{
/* Wake up the parent */
mproc[rmp->mp_parent].mp_reply.reply_trace = 0;
setreply(rmp->mp_parent, OK);
}
/* Clean up if the parent has collected the exit
* status
*/
if (rmp->mp_flags & TOLD_PARENT)
real_cleanup(rmp);
break; break;
@ -675,10 +648,6 @@ message *m_ptr;
case PM_CORE_REPLY: case PM_CORE_REPLY:
{ {
int parent_waiting, right_child;
pid_t pidarg;
struct mproc *p_mp;
proc_e= m_ptr->PM_CORE_PROC; proc_e= m_ptr->PM_CORE_PROC;
if (pm_isokendpt(proc_e, &proc_n) != OK) if (pm_isokendpt(proc_e, &proc_n) != OK)
{ {
@ -694,43 +663,7 @@ message *m_ptr;
/* Call is finished */ /* Call is finished */
rmp->mp_fs_call= PM_IDLE; rmp->mp_fs_call= PM_IDLE;
p_mp = &mproc[rmp->mp_parent]; /* process' parent */ exit_restart(rmp, m_ptr->m_type);
pidarg = p_mp->mp_wpid; /* who's being waited for? */
parent_waiting = p_mp->mp_flags & WAITING;
right_child = /* child meets one of the 3 tests? */
(pidarg == -1 || pidarg == rmp->mp_pid ||
-pidarg == rmp->mp_procgrp);
if (parent_waiting && right_child) {
tell_parent(rmp); /* tell parent */
} else {
/* parent not waiting, zombify child */
rmp->mp_flags &= (IN_USE|PRIV_PROC|HAS_DMA);
rmp->mp_flags |= ZOMBIE;
/* send parent a "child died" signal */
sig_proc(p_mp, SIGCHLD);
}
if (!(rmp->mp_flags & PRIV_PROC))
{
/* destroy the (user) process */
if((r=sys_exit(proc_e)) != OK)
{
panic(__FILE__,
"PM_CORE_REPLY: sys_exit failed", r);
}
}
/* Release the memory occupied by the child. */
if((s=vm_exit(rmp->mp_endpoint)) != OK) {
panic(__FILE__, "vm_exit() failed", s);
}
/* Clean up if the parent has collected the exit
* status
*/
if (rmp->mp_flags & TOLD_PARENT)
real_cleanup(rmp);
break; break;
} }

View File

@ -33,12 +33,11 @@ _PROTOTYPE( void exec_restart, (struct mproc *rmp, int result) );
/* forkexit.c */ /* forkexit.c */
_PROTOTYPE( int do_fork, (void) ); _PROTOTYPE( int do_fork, (void) );
_PROTOTYPE( int do_fork_nb, (void) ); _PROTOTYPE( int do_fork_nb, (void) );
_PROTOTYPE( int do_pm_exit, (void) ); _PROTOTYPE( int do_exit, (void) );
_PROTOTYPE( int do_waitpid, (void) ); _PROTOTYPE( int do_waitpid, (void) );
_PROTOTYPE( void pm_exit, (struct mproc *rmp, int exit_status, _PROTOTYPE( void exit_proc, (struct mproc *rmp, int exit_status,
int for_trace) ); int exit_type) );
_PROTOTYPE (void tell_parent, (struct mproc *child) ); _PROTOTYPE( void exit_restart, (struct mproc *rmp, int reply_type) );
_PROTOTYPE( void real_cleanup, (struct mproc *rmp) );
/* getset.c */ /* getset.c */
_PROTOTYPE( int do_getset, (void) ); _PROTOTYPE( int do_getset, (void) );

View File

@ -34,7 +34,6 @@
#include "mproc.h" #include "mproc.h"
#include "param.h" #include "param.h"
FORWARD _PROTOTYPE( int dump_core, (struct mproc *rmp) );
FORWARD _PROTOTYPE( void unpause, (int pro, int for_trace) ); FORWARD _PROTOTYPE( void unpause, (int pro, int for_trace) );
FORWARD _PROTOTYPE( void handle_ksig, (int proc_nr, sigset_t sig_map) ); FORWARD _PROTOTYPE( void handle_ksig, (int proc_nr, sigset_t sig_map) );
FORWARD _PROTOTYPE( void cause_sigalrm, (struct timer *tp) ); FORWARD _PROTOTYPE( void cause_sigalrm, (struct timer *tp) );
@ -422,6 +421,7 @@ int signo; /* signal to send to process (1 to _NSIG) */
int s; int s;
int slot; int slot;
int sigflags; int sigflags;
int exit_type;
slot = (int) (rmp - mproc); slot = (int) (rmp - mproc);
if ((rmp->mp_flags & (IN_USE | ZOMBIE)) != IN_USE) { if ((rmp->mp_flags & (IN_USE | ZOMBIE)) != IN_USE) {
@ -520,16 +520,13 @@ doterminate:
} }
rmp->mp_sigstatus = (char) signo; rmp->mp_sigstatus = (char) signo;
exit_type = PM_EXIT;
if (sigismember(&core_sset, signo) && slot != FS_PROC_NR) { if (sigismember(&core_sset, signo) && slot != FS_PROC_NR) {
printf("PM: signal %d for %d / %s\n", signo, rmp->mp_pid, rmp->mp_name); printf("PM: coredump signal %d for %d / %s\n", signo, rmp->mp_pid,
s= dump_core(rmp); rmp->mp_name);
if (s == SUSPEND) { exit_type = PM_DUMPCORE;
return;
}
/* Not dumping core, just call exit */
} }
pm_exit(rmp, 0, FALSE /*!for_trace*/); /* terminate process */ exit_proc(rmp, 0, exit_type); /* terminate process */
} }
/*===========================================================================* /*===========================================================================*
@ -669,124 +666,3 @@ int for_trace; /* for tracing */
r= notify(FS_PROC_NR); r= notify(FS_PROC_NR);
if (r != OK) panic("pm", "unpause: unable to notify FS", r); if (r != OK) panic("pm", "unpause: unable to notify FS", r);
} }
/*===========================================================================*
* dump_core *
*===========================================================================*/
PRIVATE int dump_core(rmp)
register struct mproc *rmp; /* whose core is to be dumped */
{
/* Make a core dump on the file "core", if possible. */
int r, proc_nr, proc_nr_e, parent_waiting;
pid_t procgrp;
#if 0
vir_bytes current_sp;
#endif
struct mproc *p_mp;
clock_t user_time, sys_time;
printf("dumpcore for %d / %s\n", rmp->mp_pid, rmp->mp_name);
/* Do not create core files for set uid execution */
if (rmp->mp_realuid != rmp->mp_effuid) return OK;
/* Make sure the stack segment is up to date.
* We don't want adjust() to fail unless current_sp is preposterous,
* but it might fail due to safety checking. Also, we don't really want
* the adjust() for sending a signal to fail due to safety checking.
* Maybe make SAFETY_BYTES a parameter.
*/
#if 0
if ((r= get_stack_ptr(rmp->mp_endpoint, &current_sp)) != OK)
panic(__FILE__,"couldn't get new stack pointer (for core)", r);
adjust(rmp, rmp->mp_seg[D].mem_len, current_sp);
#endif
/* Tell FS about the exiting process. */
if (rmp->mp_fs_call != PM_IDLE)
panic(__FILE__, "dump_core: not idle", rmp->mp_fs_call);
rmp->mp_fs_call= PM_DUMPCORE;
r= notify(FS_PROC_NR);
if (r != OK) panic(__FILE__, "dump_core: unable to notify FS", r);
/* Also perform most of the normal exit processing. Informing the parent
* has to wait until we know whether the coredump was successful or not.
*/
proc_nr = (int) (rmp - mproc); /* get process slot number */
proc_nr_e = rmp->mp_endpoint;
/* Remember a session leader's process group. */
procgrp = (rmp->mp_pid == mp->mp_procgrp) ? mp->mp_procgrp : 0;
/* If the exited process has a timer pending, kill it. */
if (rmp->mp_flags & ALARM_ON) set_alarm(proc_nr_e, (unsigned) 0);
/* Do accounting: fetch usage times and accumulate at parent. */
if((r=sys_times(proc_nr_e, &user_time, &sys_time, NULL)) != OK)
panic(__FILE__,"dump_core: sys_times failed", r);
p_mp = &mproc[rmp->mp_parent]; /* process' parent */
p_mp->mp_child_utime += user_time + rmp->mp_child_utime; /* add user time */
p_mp->mp_child_stime += sys_time + rmp->mp_child_stime; /* add system time */
/* Tell the kernel the process is no longer runnable to prevent it from
* being scheduled in between the following steps. Then tell FS that it
* the process has exited and finally, clean up the process at the kernel.
* This order is important so that FS can tell drivers to cancel requests
* such as copying to/ from the exiting process, before it is gone.
*/
sys_nice(proc_nr_e, PRIO_STOP); /* stop the process */
if((r=vm_willexit(proc_nr_e)) != OK) {
panic(__FILE__,"dump_core: vm_willexit failed", r);
}
if(proc_nr_e != FS_PROC_NR) /* if it is not FS that is exiting.. */
{
if (rmp->mp_flags & PRIV_PROC)
{
/* destroy system processes without waiting for FS */
if((r= sys_exit(rmp->mp_endpoint)) != OK)
panic(__FILE__, "dump_core: sys_exit failed", r);
/* Just send a SIGCHLD. Dealing with waidpid is too complicated
* here.
*/
p_mp = &mproc[rmp->mp_parent]; /* process' parent */
sig_proc(p_mp, SIGCHLD);
/* Zombify to avoid calling sys_endksig */
rmp->mp_flags |= ZOMBIE;
}
}
else
{
printf("PM: FS died\n");
return SUSPEND;
}
/* Pending reply messages for the dead process cannot be delivered. */
rmp->mp_flags &= ~REPLY;
/* Keep the process around until FS is finished with it. */
/* If the process has children, disinherit them. INIT is the new parent. */
for (rmp = &mproc[0]; rmp < &mproc[NR_PROCS]; rmp++) {
if (rmp->mp_flags & IN_USE && rmp->mp_parent == proc_nr) {
/* 'rmp' now points to a child to be disinherited. */
rmp->mp_parent = INIT_PROC_NR;
parent_waiting = mproc[INIT_PROC_NR].mp_flags & WAITING;
if (parent_waiting && (rmp->mp_flags & ZOMBIE))
{
tell_parent(rmp);
real_cleanup(rmp);
}
}
}
/* Send a hangup to the process' process group if it was a session leader. */
if (procgrp != 0) check_sig(-procgrp, SIGHUP);
return SUSPEND;
}

View File

@ -15,7 +15,7 @@ char core_name[] = "core"; /* file name where core images are produced */
_PROTOTYPE (int (*call_vec[]), (void) ) = { _PROTOTYPE (int (*call_vec[]), (void) ) = {
no_sys, /* 0 = unused */ no_sys, /* 0 = unused */
do_pm_exit, /* 1 = exit */ do_exit, /* 1 = exit */
do_fork, /* 2 = fork */ do_fork, /* 2 = fork */
no_sys, /* 3 = read */ no_sys, /* 3 = read */
no_sys, /* 4 = write */ no_sys, /* 4 = write */

View File

@ -112,7 +112,7 @@ PUBLIC int do_trace()
switch (m_in.request) { switch (m_in.request) {
case T_EXIT: /* exit */ case T_EXIT: /* exit */
pm_exit(child, (int) m_in.data, TRUE /*for_trace*/); exit_proc(child, (int) m_in.data, PM_EXIT_TR);
/* Do not reply to the caller until FS has processed the exit /* Do not reply to the caller until FS has processed the exit
* request. * request.
*/ */

View File

@ -3,11 +3,9 @@
* The entry points are: * The entry points are:
* find_param: look up a boot monitor parameter * find_param: look up a boot monitor parameter
* get_free_pid: get a free process or group id * get_free_pid: get a free process or group id
* allowed: see if an access is permitted
* no_sys: called for invalid system call numbers * no_sys: called for invalid system call numbers
* panic: PM has run aground of a fatal error
* get_stack_ptr: get stack pointer of given process
* proc_from_pid: return process pointer from pid number * proc_from_pid: return process pointer from pid number
* pm_isokendpt: check the validity of an endpoint
*/ */
#include "pm.h" #include "pm.h"