Re: Is this a bug in the fork() code?
* John Baldwin <[EMAIL PROTECTED]> [011218 18:41] wrote: > > Actually, it's a bit worse than that. The parent process will sleep on itself > waiting to be woken up, but when the child exits, it will wake up init > (p->p_pptr) not the waiting process, so if you do a rfork(..., RFNOWAIT | > RFPPWAIT); then the parent process will hang and never return. > > Perhaps fork1() should return EINVAL if both flags are set. > Good idea. -- -Alfred Perlstein [[EMAIL PROTECTED]] 'Instead of asking why a piece of software is using "1970s technology," start asking why software is ignoring 30 years of accumulated wisdom.' http://www.morons.org/rants/gpl-harmful.php3 To Unsubscribe: send mail to [EMAIL PROTECTED] with "unsubscribe freebsd-current" in the body of the message
Re: Is this a bug in the fork() code?
On 19-Dec-01 Alfred Perlstein wrote: > * Julian Elischer <[EMAIL PROTECTED]> [011218 18:20] wrote: >> >> now, what is to say that the process has not exitted by this stage, and >> been reeped by init (on SMP) >> particularly since between the two is: >> >> /* >> * Preserve synchronization semantics of vfork. If waiting for >> * child to exec or exit, set P_PPWAIT on child, and sleep on our >> * proc (in case of exit). >> */ >> PROC_LOCK(p2); >> while (p2->p_flag & P_PPWAIT) >> msleep(p1, &p2->p_mtx, PWAIT, "ppwait", 0); >> PROC_UNLOCK(p2); >> >> It may be that due to some semantics of teh fork calls >> you cannot have P_PPWAIT and a process queued to run on the other >> processor while reparented to init(1) but I can't see it.. >> the result would be that the return value MIGHT be teh pid >> of a totally different process if the proc structure had been re-used. >> >> Alternatively I could have some good weed here... > > That's not possible, since the parent is waiting the kernel will > not reparent unless the parent exits, which it doesn't because it's > waiting for the child. > > You owe the Oracle a large bong rip. Look at RFNOWAIT silly. It forces a parent to init during fork1() itself. -- John Baldwin <[EMAIL PROTECTED]> <>< http://www.FreeBSD.org/~jhb/ "Power Users Use the Power to Serve!" - http://www.FreeBSD.org/ To Unsubscribe: send mail to [EMAIL PROTECTED] with "unsubscribe freebsd-current" in the body of the message
RE: Is this a bug in the fork() code?
On 19-Dec-01 John Baldwin wrote: >> It may be that due to some semantics of teh fork calls >> you cannot have P_PPWAIT and a process queued to run on the other >> processor while reparented to init(1) but I can't see it.. >> the result would be that the return value MIGHT be teh pid >> of a totally different process if the proc structure had been re-used. >> >> Alternatively I could have some good weed here... > > Note that fork1() is only called indirectly from syscalls. The only one for > which this can happen is if someone does rfork(.., RFNOWAIT | RFPPWAIT). > If someone does this, then they know what they are doing and realize that > init > will harvest the child before they get the pid back and thus that the pid > should be ignored. > > Note that neither fork() nor vfork() can end up in this case. Only a > masochist > using rfork() and asking for this case will get it. Actually, it's a bit worse than that. The parent process will sleep on itself waiting to be woken up, but when the child exits, it will wake up init (p->p_pptr) not the waiting process, so if you do a rfork(..., RFNOWAIT | RFPPWAIT); then the parent process will hang and never return. Perhaps fork1() should return EINVAL if both flags are set. What with preemption for interrupts and what not, RFNOWAIT could potentially always return an invalid pid though I think if the child process exits and the proc is reused prior to the original parent being resumed. Not sure how you want to fix this. Even if you return the right pid, that pid could be reused by some other process potentially, so going to extra work to return the right pid in that case would still be returning an invalid pid since the child has exited and been harvested by init already. -- John Baldwin <[EMAIL PROTECTED]> <>< http://www.FreeBSD.org/~jhb/ "Power Users Use the Power to Serve!" - http://www.FreeBSD.org/ To Unsubscribe: send mail to [EMAIL PROTECTED] with "unsubscribe freebsd-current" in the body of the message
RE: Is this a bug in the fork() code?
On 19-Dec-01 Julian Elischer wrote: > Near the end of fork1(): > /* > * If RFSTOPPED not requested, make child runnable and add to > * run queue. > */ > microtime(&(p2->p_stats->p_start)); > p2->p_acflag = AFORK; > if ((flags & RFSTOPPED) == 0) { > mtx_lock_spin(&sched_lock); > p2->p_stat = SRUN; /* XXXKSE */ > setrunqueue(td2); > mtx_unlock_spin(&sched_lock); > } > > > > note that it may have made itself only a child of init. > > > later at the very end of fork1(): > > /* > * Return child proc pointer to parent. > */ > *procp = p2; > return (0); > } > > > > now, what is to say that the process has not exitted by this stage, and > been reeped by init (on SMP) > particularly since between the two is: > > /* > * Preserve synchronization semantics of vfork. If waiting for > * child to exec or exit, set P_PPWAIT on child, and sleep on our > * proc (in case of exit). > */ > PROC_LOCK(p2); > while (p2->p_flag & P_PPWAIT) > msleep(p1, &p2->p_mtx, PWAIT, "ppwait", 0); > PROC_UNLOCK(p2); > > It may be that due to some semantics of teh fork calls > you cannot have P_PPWAIT and a process queued to run on the other > processor while reparented to init(1) but I can't see it.. > the result would be that the return value MIGHT be teh pid > of a totally different process if the proc structure had been re-used. > > Alternatively I could have some good weed here... Note that fork1() is only called indirectly from syscalls. The only one for which this can happen is if someone does rfork(.., RFNOWAIT | RFPPWAIT). If someone does this, then they know what they are doing and realize that init will harvest the child before they get the pid back and thus that the pid should be ignored. Note that neither fork() nor vfork() can end up in this case. Only a masochist using rfork() and asking for this case will get it. -- John Baldwin <[EMAIL PROTECTED]> <>< http://www.FreeBSD.org/~jhb/ "Power Users Use the Power to Serve!" - http://www.FreeBSD.org/ To Unsubscribe: send mail to [EMAIL PROTECTED] with "unsubscribe freebsd-current" in the body of the message
Re: Is this a bug in the fork() code?
* Julian Elischer <[EMAIL PROTECTED]> [011218 18:20] wrote: > > now, what is to say that the process has not exitted by this stage, and > been reeped by init (on SMP) > particularly since between the two is: > > /* > * Preserve synchronization semantics of vfork. If waiting for > * child to exec or exit, set P_PPWAIT on child, and sleep on our > * proc (in case of exit). > */ > PROC_LOCK(p2); > while (p2->p_flag & P_PPWAIT) > msleep(p1, &p2->p_mtx, PWAIT, "ppwait", 0); > PROC_UNLOCK(p2); > > It may be that due to some semantics of teh fork calls > you cannot have P_PPWAIT and a process queued to run on the other > processor while reparented to init(1) but I can't see it.. > the result would be that the return value MIGHT be teh pid > of a totally different process if the proc structure had been re-used. > > Alternatively I could have some good weed here... That's not possible, since the parent is waiting the kernel will not reparent unless the parent exits, which it doesn't because it's waiting for the child. You owe the Oracle a large bong rip. -- -Alfred Perlstein [[EMAIL PROTECTED]] 'Instead of asking why a piece of software is using "1970s technology," start asking why software is ignoring 30 years of accumulated wisdom.' http://www.morons.org/rants/gpl-harmful.php3 To Unsubscribe: send mail to [EMAIL PROTECTED] with "unsubscribe freebsd-current" in the body of the message
Is this a bug in the fork() code?
Near the end of fork1(): /* * If RFSTOPPED not requested, make child runnable and add to * run queue. */ microtime(&(p2->p_stats->p_start)); p2->p_acflag = AFORK; if ((flags & RFSTOPPED) == 0) { mtx_lock_spin(&sched_lock); p2->p_stat = SRUN; /* XXXKSE */ setrunqueue(td2); mtx_unlock_spin(&sched_lock); } note that it may have made itself only a child of init. later at the very end of fork1(): /* * Return child proc pointer to parent. */ *procp = p2; return (0); } now, what is to say that the process has not exitted by this stage, and been reeped by init (on SMP) particularly since between the two is: /* * Preserve synchronization semantics of vfork. If waiting for * child to exec or exit, set P_PPWAIT on child, and sleep on our * proc (in case of exit). */ PROC_LOCK(p2); while (p2->p_flag & P_PPWAIT) msleep(p1, &p2->p_mtx, PWAIT, "ppwait", 0); PROC_UNLOCK(p2); It may be that due to some semantics of teh fork calls you cannot have P_PPWAIT and a process queued to run on the other processor while reparented to init(1) but I can't see it.. the result would be that the return value MIGHT be teh pid of a totally different process if the proc structure had been re-used. Alternatively I could have some good weed here... To Unsubscribe: send mail to [EMAIL PROTECTED] with "unsubscribe freebsd-current" in the body of the message