Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 07 May 2003 00:01:04 -0700
From:      Terry Lambert <tlambert2@mindspring.com>
To:        Igor Sysoev <is@rambler-co.ru>
Cc:        freebsd-arch@freebsd.org
Subject:   Re: rfork(RFPROC|RFMEM)
Message-ID:  <3EB8AF30.B25A18CD@mindspring.com>
References:  <Pine.BSF.4.21.0305062342570.68150-100000@is>

next in thread | previous in thread | raw e-mail | index | archive | help
Igor Sysoev wrote:
> >It only does that if at least one of a set of flags is not
> >set; I don't see where you think EINVAL is coming from.
> 
> It's recent changes 1.182 in 5.0 and 1.72.2.12 in 4.8 in kern_fork.c.
> Now rfork() requires RFTHREAD to be set if RFPROC is set.

I still don't see it.  I'm looking at 1.197:

        if ((uap->flags & (RFPROC | RFTHREAD | RFFDG | RFCFDG)) ==
            RFPROC)
                return(EINVAL);

The only thing this does is prevent you from using RFPROC without
at least one of the other flags.


> >But in any case, if RFTHREAD makes something work for you,
> >then by all means use it.  It should not be implied, and
> >it should not be required by documentation, since, as you
> >noticed reading the code, all it does is associate sibling
> >threads under a parent for killing and advisory locking.
> 
> Well, but I think this change should be documented.
> Right now rfork(RFPROC|RFMEM) returns EINVAL and rfork_thread(2) causes
> segmentation fault because it does not handle errors correctly.

I wish you had said these were your flags earlier; I have been
(incorrectly) assuming you were passing in one of the existing
RF*FDG flags, and as a result, that you had rolled your own
"helper" code.  So, with that in mind...

This is correct behaviour.  You must set a flag in the set of
(RFTHREAD | RFFDG | RFCFDG) when you set RFPROC.  It could be
rewritten (less efficiently) as:

        if ((uap->flags & RFPROC) == RFPROC &&
	    (uap_flags & (RFTHREAD | RFFDG | RFCFDG)) == 0)
                return(EINVAL);

...Basically, if you use RFPROC, you have to do something about
the file descriptor table, so that it's in one of 3 states:

	RFTHREAD	I know the open file table is shared, so
			I will act accordingly (I promise to
			communicate state between processes so
			that if one closes a file, the other
			does not attempt to use it).

	RFFDG		I want the file table copied, so that if
			one process screws it up, it won't break
			the other processes (I promise to very
			carefully examine all the descriptors I
			think are still open to see if they were
			closed on me by the O_EXCL bit having
			been set before rfork() was called).

	RFCFDG		I want the file table cleared, so that
			the new process starts out with a clean
			slate

Maybe it would be more correct to seperate RFTHREAD into an
RFSFDG and a seperate RFTHREAD, for the P_WEXIT/SIGKILL stuff.

But the bottom line is that this is not a bug, it's a change
to a system interface that no one realized was being used.

Worst case, the interface should be versioned, but I think
that's overkill.  You might want to #ifdef out the "if"
statement, as a local hack.


> >My point was that the only code that uses it without RFTHREAD
> >successfully is probably about two years old, and was never
> >committed to the tree as part of a threads library.  You
> 
> Yes, I belive it, rfork(RFPROC|RFMEM) runs on FreeBSD-4.3.

You could just correct the code to pass the flag to the helper
function; this is probably the correct thing to do.


> >would need to check the mailing list archives for "Jason Evans"
> >and "John Dyson", in combination with "rfork", to find the code
> >that "fixes" needing RFTHREAD.
> 
> RFTHREAD got to be required recently.

It changed an implied bit into a real bit.  Personally, I prefer
real bits.

Probably, though it should be seperated, since the RFTHREAD side
effect in fork1() doesn't happen if you don't want it to... I
don't personally see it as something undesirable, though it might
surprise someone who expects to explicitly shutdown their own
rfork'ed processes, and finds them disappeared... that would
still leave you in the same boat, though.

-- Terry



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?3EB8AF30.B25A18CD>