On Tue, Mar 18, 2025 at 01:06:17PM +0000, Peter Maydell wrote:
> On Tue, 18 Mar 2025 at 12:43, Daniel P. Berrangé <berra...@redhat.com> wrote:
> >
> > On Tue, Mar 18, 2025 at 01:34:57PM +0100, Andreas Schwab wrote:
> > > On Mär 18 2025, Daniel P. Berrangé wrote:
> > >
> > > > Whereever practical, it is preferrable to check a discrete feature
> > > > or behaviour in a functional way, rather than matching on "is it QEMU"
> > >
> > > Do you know a way to detect support for CLONE_VFORK that isn't too
> > > expensive?
> >
> > No, but I feel like the right thing in this particular case is to look
> > at improving our vfork impl. The current impl is incredibly crude and
> > acknowledged by the original author
> >
> >   commit 436d124b7d538b1fd9cf72edf17770664c309856
> >   Author: Andrzej Zaborowski <balr...@gmail.com>
> >   Date:   Sun Sep 21 02:39:45 2008 +0000
> >
> >     Band-aid vfork() emulation (Kirill Shutemov).
> >
> > I can see why they did it that way, but I'm feeling like it ought to
> > be possible to do a better special case vfork impl ni QEMU instead of
> > overloading the fork() impl.
> 
> The difficulty with vfork() (and, more generally, with various of
> the clone() syscall flag combinations) is that because we use the
> host libc we are restricted to the thread/process creation options
> that that libc permits: which is only fork() and pthread_create().
> vfork() wants "create a new process like fork with its own file
> descriptors, signal handlers, etc, but share all the memory space with
> the parent", and the host libc just doesn't provide us with the tools
> to do that. (We can't call the host vfork() because we wouldn't be
> abiding by the rules it imposes, like "don't return from the function
> that called vfork".)
> 
> If we were implemented as a usermode emulator that sat on the raw
> kernel syscalls, we could directly call the clone syscall and
> use that to provide at least a wider range of the possible clone
> flag options; but our dependency on libc means we have to avoid
> doing things that would confuse it.

I guess I'm not seeing how libc is blocking us in this respect ?
The clone() syscall wrapper is exposed by glibc at least, and it
is possible to call it, albeit with some caveats that we might
miss any logic glibc has around its fork() wrapper. The spec
requires that any child must immediately call execve after vfrok
so I'm wondering just what risk of confusion we would have in
practice ?

> For vfork in particular, we could I guess do something like:
>  * use real fork() to create child process
>  * parent process arranges to wait until child process exits
>    (via waitpid or equivalent) or it tells us it's about to exec
>  * we make all the guest memory be mapped read-only in the child
>    process, so we can trap writes and tell the parent about them
>    so it can update its copy of the memory.
>    (Sadly since we can't guaranteedly get control on termination
>    events for the child before it really terminates, we can't
>    do this memory-transfer in bulk at the end; otherwise we'd
>    behave wrongly for the "child process gets SIGKILLed" case.)

That would get the synchronization behaviour of Linux vfork,
but I'm not sure it'd get the performance benefits (of avoiding
page table copying) which is what  Andreas mentioned as the
desired thing ?

With regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|


Reply via email to