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>