PM: add EXITING process flag as stopgap between starting coredump and setting ZOMBIE flag
This commit is contained in:
parent
1450a8ac6d
commit
73c5bbf1a3
|
@ -271,6 +271,11 @@ int exit_type; /* one of PM_EXIT, PM_EXIT_TR, PM_DUMPCORE */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* The process is now officially exiting. The ZOMBIE flag is not enough, as
|
||||||
|
* it is not set here for core dumps - introducing potential race conditions.
|
||||||
|
*/
|
||||||
|
rmp->mp_flags |= EXITING;
|
||||||
|
|
||||||
/* Pending reply messages for the dead process cannot be delivered. */
|
/* Pending reply messages for the dead process cannot be delivered. */
|
||||||
rmp->mp_flags &= ~REPLY;
|
rmp->mp_flags &= ~REPLY;
|
||||||
|
|
||||||
|
@ -290,8 +295,7 @@ int exit_type; /* one of PM_EXIT, PM_EXIT_TR, PM_DUMPCORE */
|
||||||
/* 'rmp' now points to a child to be disinherited. */
|
/* 'rmp' now points to a child to be disinherited. */
|
||||||
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)) {
|
|
||||||
tell_parent(rmp);
|
tell_parent(rmp);
|
||||||
|
|
||||||
if (rmp->mp_fs_call == PM_IDLE)
|
if (rmp->mp_fs_call == PM_IDLE)
|
||||||
|
@ -427,7 +431,7 @@ struct mproc *rmp;
|
||||||
if (rmp->mp_flags & ZOMBIE)
|
if (rmp->mp_flags & ZOMBIE)
|
||||||
panic(__FILE__, "zombify: process was already a zombie", NO_NUM);
|
panic(__FILE__, "zombify: process was already a zombie", NO_NUM);
|
||||||
|
|
||||||
rmp->mp_flags &= (IN_USE|PRIV_PROC);
|
rmp->mp_flags &= (IN_USE|PRIV_PROC|EXITING);
|
||||||
rmp->mp_flags |= ZOMBIE;
|
rmp->mp_flags |= ZOMBIE;
|
||||||
|
|
||||||
p_mp = &mproc[rmp->mp_parent];
|
p_mp = &mproc[rmp->mp_parent];
|
||||||
|
@ -454,6 +458,8 @@ register struct mproc *child; /* tells which process is exiting */
|
||||||
mp_parent= child->mp_parent;
|
mp_parent= child->mp_parent;
|
||||||
if (mp_parent <= 0)
|
if (mp_parent <= 0)
|
||||||
panic(__FILE__, "tell_parent: bad value in mp_parent", mp_parent);
|
panic(__FILE__, "tell_parent: bad value in mp_parent", mp_parent);
|
||||||
|
if(!(child->mp_flags & ZOMBIE))
|
||||||
|
panic(__FILE__, "tell_parent: child not a zombie", NO_NUM);
|
||||||
if(child->mp_flags & TOLD_PARENT)
|
if(child->mp_flags & TOLD_PARENT)
|
||||||
panic(__FILE__, "tell_parent: telling parent again", NO_NUM);
|
panic(__FILE__, "tell_parent: telling parent again", NO_NUM);
|
||||||
parent = &mproc[mp_parent];
|
parent = &mproc[mp_parent];
|
||||||
|
@ -463,6 +469,7 @@ register struct mproc *child; /* tells which process is exiting */
|
||||||
parent->mp_reply.reply_res2 = exitstatus;
|
parent->mp_reply.reply_res2 = exitstatus;
|
||||||
setreply(child->mp_parent, child->mp_pid);
|
setreply(child->mp_parent, child->mp_pid);
|
||||||
parent->mp_flags &= ~WAITING; /* parent no longer waiting */
|
parent->mp_flags &= ~WAITING; /* parent no longer waiting */
|
||||||
|
child->mp_flags &= ~ZOMBIE; /* child no longer a zombie */
|
||||||
child->mp_flags |= TOLD_PARENT; /* avoid informing parent twice */
|
child->mp_flags |= TOLD_PARENT; /* avoid informing parent twice */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -148,9 +148,9 @@ PUBLIC int main()
|
||||||
/* In the meantime, the process may have been killed by a
|
/* In the meantime, the process may have been killed by a
|
||||||
* signal (e.g. if a lethal pending signal was unblocked)
|
* signal (e.g. if a lethal pending signal was unblocked)
|
||||||
* without the PM realizing it. If the slot is no longer in
|
* without the PM realizing it. If the slot is no longer in
|
||||||
* use or just a zombie, don't try to reply.
|
* use or the process is exiting, don't try to reply.
|
||||||
*/
|
*/
|
||||||
if ((rmp->mp_flags & (REPLY | IN_USE | ZOMBIE)) ==
|
if ((rmp->mp_flags & (REPLY | IN_USE | EXITING)) ==
|
||||||
(REPLY | IN_USE)) {
|
(REPLY | IN_USE)) {
|
||||||
s=sendnb(rmp->mp_endpoint, &rmp->mp_reply);
|
s=sendnb(rmp->mp_endpoint, &rmp->mp_reply);
|
||||||
if (s != OK) {
|
if (s != OK) {
|
||||||
|
@ -365,7 +365,7 @@ void checkme(char *str, int line)
|
||||||
int boned = 0;
|
int boned = 0;
|
||||||
int proc_nr;
|
int proc_nr;
|
||||||
for (proc_nr=0, trmp=mproc; proc_nr < NR_PROCS; proc_nr++, trmp++) {
|
for (proc_nr=0, trmp=mproc; proc_nr < NR_PROCS; proc_nr++, trmp++) {
|
||||||
if ((trmp->mp_flags & (REPLY | IN_USE | ZOMBIE)) ==
|
if ((trmp->mp_flags & (REPLY | IN_USE | EXITING)) ==
|
||||||
(REPLY | IN_USE)) {
|
(REPLY | IN_USE)) {
|
||||||
int tp;
|
int tp;
|
||||||
if(pm_isokendpt(trmp->mp_endpoint, &tp) != OK) {
|
if(pm_isokendpt(trmp->mp_endpoint, &tp) != OK) {
|
||||||
|
|
|
@ -343,7 +343,7 @@ PUBLIC int do_getprocnr()
|
||||||
return(s);
|
return(s);
|
||||||
search_key[key_len] = '\0'; /* terminate for safety */
|
search_key[key_len] = '\0'; /* terminate for safety */
|
||||||
for (rmp = &mproc[0]; rmp < &mproc[NR_PROCS]; rmp++) {
|
for (rmp = &mproc[0]; rmp < &mproc[NR_PROCS]; rmp++) {
|
||||||
if (((rmp->mp_flags & (IN_USE | ZOMBIE)) == IN_USE) &&
|
if (((rmp->mp_flags & (IN_USE | EXITING)) == IN_USE) &&
|
||||||
strncmp(rmp->mp_name, search_key, key_len)==0) {
|
strncmp(rmp->mp_name, search_key, key_len)==0) {
|
||||||
mp->mp_reply.endpt = rmp->mp_endpoint;
|
mp->mp_reply.endpt = rmp->mp_endpoint;
|
||||||
printf("PM: name %s result: %d\n", search_key,
|
printf("PM: name %s result: %d\n", search_key,
|
||||||
|
|
|
@ -65,7 +65,7 @@ EXTERN struct mproc {
|
||||||
/* Flag values */
|
/* Flag values */
|
||||||
#define IN_USE 0x001 /* set when 'mproc' slot in use */
|
#define IN_USE 0x001 /* set when 'mproc' slot in use */
|
||||||
#define WAITING 0x002 /* set by WAIT system call */
|
#define WAITING 0x002 /* set by WAIT system call */
|
||||||
#define ZOMBIE 0x004 /* set by EXIT, cleared by WAIT */
|
#define ZOMBIE 0x004 /* waiting for parent to issue WAIT call */
|
||||||
#define PAUSED 0x008 /* set by PAUSE system call */
|
#define PAUSED 0x008 /* set by PAUSE system call */
|
||||||
#define ALARM_ON 0x010 /* set when SIGALRM timer started */
|
#define ALARM_ON 0x010 /* set when SIGALRM timer started */
|
||||||
#define TRACED 0x040 /* set if process is to be traced */
|
#define TRACED 0x040 /* set if process is to be traced */
|
||||||
|
@ -76,6 +76,7 @@ EXTERN struct mproc {
|
||||||
#define PM_SIG_PENDING 0x4000 /* process got a signal while waiting for FS */
|
#define PM_SIG_PENDING 0x4000 /* process got a signal while waiting for FS */
|
||||||
#define PARTIAL_EXEC 0x8000 /* Process got a new map but no content */
|
#define PARTIAL_EXEC 0x8000 /* Process got a new map but no content */
|
||||||
#define TOLD_PARENT 0x10000 /* Parent wait() completed, ZOMBIE off */
|
#define TOLD_PARENT 0x10000 /* Parent wait() completed, ZOMBIE off */
|
||||||
|
#define EXITING 0x20000 /* set by EXIT, process is now exiting */
|
||||||
|
|
||||||
#define NIL_MPROC ((struct mproc *) 0)
|
#define NIL_MPROC ((struct mproc *) 0)
|
||||||
|
|
||||||
|
|
|
@ -230,7 +230,7 @@ PUBLIC int ksig_pending()
|
||||||
/* If the process still exists to the kernel after the signal
|
/* If the process still exists to the kernel after the signal
|
||||||
* has been handled ...
|
* has been handled ...
|
||||||
*/
|
*/
|
||||||
if ((mproc[proc_nr_p].mp_flags & (IN_USE | ZOMBIE)) == IN_USE)
|
if ((mproc[proc_nr_p].mp_flags & (IN_USE | EXITING)) == IN_USE)
|
||||||
{
|
{
|
||||||
if((r=sys_endksig(proc_nr_e)) != OK) /* ... tell kernel it's done */
|
if((r=sys_endksig(proc_nr_e)) != OK) /* ... tell kernel it's done */
|
||||||
panic(__FILE__,"sys_endksig failed", r);
|
panic(__FILE__,"sys_endksig failed", r);
|
||||||
|
@ -256,8 +256,8 @@ sigset_t sig_map;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
rmp = &mproc[proc_nr];
|
rmp = &mproc[proc_nr];
|
||||||
if ((rmp->mp_flags & (IN_USE | ZOMBIE)) != IN_USE) {
|
if ((rmp->mp_flags & (IN_USE | EXITING)) != IN_USE) {
|
||||||
printf("PM: handle_ksig: %d?? zombie / not in use\n", proc_nr_e);
|
printf("PM: handle_ksig: %d?? exiting / not in use\n", proc_nr_e);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
proc_id = rmp->mp_pid;
|
proc_id = rmp->mp_pid;
|
||||||
|
@ -379,7 +379,7 @@ struct timer *tp;
|
||||||
|
|
||||||
rmp = &mproc[proc_nr_n];
|
rmp = &mproc[proc_nr_n];
|
||||||
|
|
||||||
if ((rmp->mp_flags & (IN_USE | ZOMBIE)) != IN_USE) return;
|
if ((rmp->mp_flags & (IN_USE | EXITING)) != IN_USE) return;
|
||||||
if ((rmp->mp_flags & ALARM_ON) == 0) return;
|
if ((rmp->mp_flags & ALARM_ON) == 0) return;
|
||||||
rmp->mp_flags &= ~ALARM_ON;
|
rmp->mp_flags &= ~ALARM_ON;
|
||||||
check_sig(rmp->mp_pid, SIGALRM);
|
check_sig(rmp->mp_pid, SIGALRM);
|
||||||
|
@ -424,9 +424,8 @@ int signo; /* signal to send to process (1 to _NSIG) */
|
||||||
int exit_type;
|
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 | EXITING)) != IN_USE) {
|
||||||
printf("PM: signal %d sent to %s process %d\n",
|
printf("PM: signal %d sent to exiting process %d\n", signo, slot);
|
||||||
signo, (rmp->mp_flags & ZOMBIE) ? "zombie" : "dead", slot);
|
|
||||||
panic(__FILE__,"", NO_NUM);
|
panic(__FILE__,"", NO_NUM);
|
||||||
}
|
}
|
||||||
if (rmp->mp_fs_call != PM_IDLE || rmp->mp_fs_call2 != PM_IDLE)
|
if (rmp->mp_fs_call != PM_IDLE || rmp->mp_fs_call2 != PM_IDLE)
|
||||||
|
@ -557,7 +556,6 @@ int signo; /* signal to send to process (0 to _NSIG) */
|
||||||
error_code = ESRCH;
|
error_code = ESRCH;
|
||||||
for (rmp = &mproc[0]; rmp < &mproc[NR_PROCS]; rmp++) {
|
for (rmp = &mproc[0]; rmp < &mproc[NR_PROCS]; rmp++) {
|
||||||
if (!(rmp->mp_flags & IN_USE)) continue;
|
if (!(rmp->mp_flags & IN_USE)) continue;
|
||||||
if ((rmp->mp_flags & ZOMBIE) && signo != 0) continue;
|
|
||||||
|
|
||||||
/* Check for selection. */
|
/* Check for selection. */
|
||||||
if (proc_id > 0 && proc_id != rmp->mp_pid) continue;
|
if (proc_id > 0 && proc_id != rmp->mp_pid) continue;
|
||||||
|
@ -580,7 +578,7 @@ int signo; /* signal to send to process (0 to _NSIG) */
|
||||||
}
|
}
|
||||||
|
|
||||||
count++;
|
count++;
|
||||||
if (signo == 0) continue;
|
if (signo == 0 || (rmp->mp_flags & EXITING)) continue;
|
||||||
|
|
||||||
/* 'sig_proc' will handle the disposition of the signal. The
|
/* 'sig_proc' will handle the disposition of the signal. The
|
||||||
* signal may be caught, blocked, ignored, or cause process
|
* signal may be caught, blocked, ignored, or cause process
|
||||||
|
@ -592,7 +590,7 @@ int signo; /* signal to send to process (0 to _NSIG) */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If the calling process has killed itself, don't reply. */
|
/* If the calling process has killed itself, don't reply. */
|
||||||
if ((mp->mp_flags & (IN_USE | ZOMBIE)) != IN_USE) return(SUSPEND);
|
if ((mp->mp_flags & (IN_USE | EXITING)) != IN_USE) return(SUSPEND);
|
||||||
return(count > 0 ? OK : error_code);
|
return(count > 0 ? OK : error_code);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -144,7 +144,7 @@ pid_t lpid;
|
||||||
register struct mproc *rmp;
|
register struct mproc *rmp;
|
||||||
|
|
||||||
for (rmp = &mproc[0]; rmp < &mproc[NR_PROCS]; rmp++)
|
for (rmp = &mproc[0]; rmp < &mproc[NR_PROCS]; rmp++)
|
||||||
if ((rmp->mp_flags & (IN_USE | ZOMBIE)) == IN_USE &&
|
if ((rmp->mp_flags & (IN_USE | EXITING)) == IN_USE &&
|
||||||
rmp->mp_pid == lpid) {
|
rmp->mp_pid == lpid) {
|
||||||
return(rmp);
|
return(rmp);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue