[PATCH] Improve LinuxThreads compatibility in rfork()

Petr Salinger Petr.Salinger at seznam.cz
Mon Jul 11 13:50:46 UTC 2011


>> This patch made by Petr Salinger improves compatibility with
>> LinuxThreads in rfork() syscall.  The Linux clone() implementation
>> allows specifying the signal sent to parent when child terminates
>> (instead of SIGCHLD).
>>
>> As the threading implementation in Debian GNU/kFreeBSD is
>> LinuxThreads-based, we had to diverge from upstream kFreeBSD ABI and
>> implement this extension.
>>
>> I hope it is acceptable for you to use the same encoding, this way we
>> would archieve ABI compatibility to run Debian GNU/kFreeBSD inside a
>> chroot/jail on top of a FreeBSD system.
>>
>> Thanks for considering
>>
>> --
>> Robert Millan
>
>> --- a/sys/kern/kern_fork.c
>> +++ b/sys/kern/kern_fork.c
>> @@ -477,7 +477,13 @@
>>  		p2->p_sigacts = newsigacts;
>>  	}
>>  	if (flags & RFLINUXTHPN)
>> -	        p2->p_sigparent = SIGUSR1;
>> +	{
>> +		int sig;
>> +		sig = RFTHPNSIGNUM(flags);
>> +	        if (sig == 0) sig = SIGUSR1;
>> +	        if (sig == SIGCHLD) sig = 0;
>> +	        p2->p_sigparent = sig;
>> +	}
>>  	else
>>  	        p2->p_sigparent = SIGCHLD;
>>
>> --- a/sys/sys/unistd.h
>> +++ b/sys/sys/unistd.h
>> @@ -182,6 +182,10 @@
>>  #define	RFHIGHPID	(1<<18)	/* use a pid higher than 10 (idleproc) */
>>  #define	RFPPWAIT	(1<<31)	/* parent sleeps until child exits (vfork) */
>>  #define	RFKERNELONLY	(RFSTOPPED | RFHIGHPID | RFPPWAIT)
>> +#define RFTHPNSHIFT	24	/* reserve bits 24-30 */
>> +#define RFTHPNMASK	0x7F    /* for compatibility with linuxthreads/clone()   */
>> +				/* allow to specify  "clone exit parent notification" signal */
>> +#define RFTHPNSIGNUM(flags)	(((flags) >> RFTHPNSHIFT) & RFTHPNMASK)
>>
>>  #endif /* __BSD_VISIBLE */
>>
> I looked at this patch some time ago already.
>
> Can you, please, describe the reasoning behind the
>> +	        if (sig == SIGCHLD) sig = 0;
> line ?

The main reason is backward compatibility.
The original FreeBSD code allows only to select between
SIGUSR1 or SIGCHLD signals.

The our extension changes meaning of RFLINUXTHPN to select signal based on 
bits 24-30 of passed flags instead of using SIGUSR1 every time.

When the passed "signal" number is zero, it should behave identically
on plain FreeBSD and in our environment, therefore SIGUSR1 is selected.
The assumption is (have been) that (yet) undefined bits are zero.
That way we are backward compatible with original FreeBSD.

We still need an alternative way to select "none signal is sent"
after child exit (under linux #0 is used).

The SIGCHLD can be "selected" (also on original FreeBSD) by not specifying 
RFLINUXTHPN, therefore combination of RFLINUXTHPN and passed "signal" 
number SIGCHLD is (have been) used for "none signal".

BTW, the opposite side is in

http://anonscm.debian.org/viewvc/glibc-bsd/trunk/glibc-ports/kfreebsd/clone.c?view=markup

Petr


More information about the freebsd-hackers mailing list