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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 David van Moolenbroek
						David van Moolenbroek