[PATCH] winsup/cygwin: Protect fork() against dll- and exe-updates.

Corinna Vinschen corinna-cygwin@cygwin.com
Mon Aug 3 20:22:00 GMT 2015

Hi Michael,

On Jul 31 13:32, Michael Haubenwallner wrote:
> Hi Corinna,
> Am 2015-07-29 um 15:22 schrieb Corinna Vinschen:
> > On Jul 28 18:40, Michael Haubenwallner wrote:
> >> On 07/27/2015 09:50 AM, Corinna Vinschen wrote:
> >>> On Jul 24 17:43, Michael Haubenwallner wrote:
> >>>> When starting to port Gentoo Prefix to Cygwin, the first real problem
> >>>> discovered is that fork() does use the original executable's location
> >>> Unfortunately there's some red tape to get over with, first.  We need a
> >>> copyright assignment from you before we can go much further.
> Copyright assignment submitted.

By snail mail or by mail to ges-info AT redhat DOT com?  We didn't
receive a mail yet...

> >>> - /proc is already available as virtual filesystem as on Linux.
> >>>   [blah]
> >>>   Also, using the Windows PID as dir name seems a bit weird, given that
> >>>   the virtual /proc obviously uses the Cygwin PID.  This sounds like a
> >>>   source for confusion.
> For the moment, using Windows PID as directory name is necessary, as the
> Cygwin PID may be shared by multiple Windows processes, which feels like
> it would require more sophisticated setup/cleanup logic.

Yeah, that's a secondary problem for now.

> >> There's no particular reason for /proc/ actually - just came to my mind
> >> first. I've also seen /run/ on recent Linux boxes...
> > 
> > Yeah, /run might be a good option, albeit there may be installations
> > out there already using this path for their own dubious purposes.
> > Reusing a path existing in a cygwin installation by default would
> > avoid collisions.  /var/run perhaps.
> 've updated the patch to use /var/run/wproc/<sid>/<ntpid>/ now,
> where /var/run/wproc/ needs to be created manually for enabling.


> [...]
> >> However, I've been using Interix before - and Cygwin feels faster even
> >> with hardlinks enabled.
> > 
> > FTR: Me too, and I have not the faintest idea why, given that Interix
> > can fork natively while Cygwin has to go to great lengths to emulate it.
> Won't be surprised actually if Interix does similar - just hidden as "native".

Well, afaics they are using the native calls under the hood.  Are you
comparing interix w/ the 64 bit Cygwin by any chance?  Isn't Interix
running in 32 bit and thus under WOW64 only?

> <snip>
> >>  I've tried hardlinks
> >> for loaded dlls mangling the full path into the hardlink's filename, but
> >> encountered different load addresses in the child - most likely due to the
> >> now different dll's filename.
> > 
> > Huh?  That shouldn't happen.  The address is determined by the file's
> > PE/COFF header, not by the name.  However, did you reuse the name field
> > in the dll structure or did you create another name field for the
> > mangled name?  In the first case there may be some checks in dll_init.cc
> > not working.  That's why I said to use an extra field for the mangled
> > name.
> Fixed now. The basename of the loaded dll has to be preserved, so it can
> be found in the child as "already loaded" link-dep of another dll that
> is loaded afterwards.


> > [...]
> > So, here's a question.  What if the directory is only created on
> > first fork?  Given that only few processes actually call fork, shouldn't
> > that speed up typical usage profiles a lot?  Even with `configure' or
> > `make', at least half of the involved processes don't fork.
> Yeah - but how to create the original file-name (in another directory) so it
> does refer to the original inode number, when the original file-name has been
> renamed/unlinked during the upgrade?

A process could open a handle to the file by itself at DLL load time and
just keep it in the dll table until the file is unloaded.  The original
filename is stored at DLL load time anyway.

The real action could then take place at fork time since the handle to
the file is still valid, even after rename/unlink.

> And WTF is ReFS? Is NTFS the next dead horse I'm gonna ride after Interix?

Don't ask.  ReFS is a filesystem designed for "big data".  I don't think
(and really *really* hope) it doesn't replace NTFS any time soon.

> >>> - What about reducing the overhead by implementing some kind of generic
> >>>   exe/dll cache used by all processes?  It would reduce the requirement
> >>>   to cleanup, reduce the footprint of the cache, speed up subsequent
> >>>   forks.
> >>
> >> I'm all for it, but I've no idea of currently available cross-process
> >> mechanisms in cygwin/windows that could help here ...
> > 
> > Yeah, scratching my head myself, but we might want to discuss it
> > nevertheless.  Maybe sombody has a good idea?
> Just found NtCreateFile (CreateOptions=FILE_OPEN_BY_FILE_ID) - but I've not
> found a mechanism yet to re-create a fully useable filesystem entry out of
> the FILE_ID and/or the HMODULE only.

The HMODULE is only the address of the section so, no, there's no way to
do an NtCreateFile with this information alone.  As for the file id, I
never tried NtOpenFile w/ FILE_OPEN_BY_FILE_ID.  The usage description
in the WDK docs is a bit vague, but it does work.  You just have to have
the file id from some earlier call to NtQueryInformationFile.

> <snip>
> > Here's the catch.  What you're doing is a deviation from how Cygwin
> > is trying to operate.  If at all possible, Cygwin applications should
> > run in any environment.  Cygwin is just some "operating system", and
> > despite striving for POSIX compatibility, we can't manage it under all
> > circumstances.
> > 
> > This in turn usually requires porting.  Any application running under
> > multiple OSes has code to make sure differences in the various OSes
> > (and there are lots of them, even between the supposedly POSIX compatible
> > ones) are handled gracefully.
> > 
> > So you'd usually port gentoo prefix to Cygwin, not vice versa.  And
> > to close the loop, your change to Cygwin requires to change the users'
> > environment, plus a noticable slowdown of the entire installation, just
> > to be able to run your application.
> > 
> > I'd expect that gentoo prefix, if there *is* an interest to port it to
> > Cygwin, would try to run under Cygwin as is.  And it should preferredly
> > run under Cygwin in any environment, not only in the environment adding
> > the exe/dll hardlinks.
> > 
> > Do you understand what bugs me?
> I think I do understand - and I do agree for your point of view!
> But still, before trying to work around any issues with the underlying OS,
> I prefer to fix them if possible.

The problem is that it's not a generic fix but one requiring to change
the behaviour of the Cygwin DLL in a way which noticably affects the
entire installation.  The current performance hit is rather cruel, just
so that *one* package works as desired...

> [...]
> Still, for Gentoo Prefix I do prefer to run on "Cygwin" rather than on
> "Windows", even if that feels like nitpicking.

Not as far as I'm concerned.

> > Your patch is rather intrusive.  It's not "simple" as I understand it.
> Was it really myself that called this patch "simple"? ;)

Heh :)


Corinna Vinschen                  Please, send mails regarding Cygwin to
Cygwin Maintainer                 cygwin AT cygwin DOT com
Red Hat
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://cygwin.com/pipermail/cygwin-developers/attachments/20150803/8abd2f20/attachment.sig>

More information about the Cygwin-developers mailing list