On Tue, Mar 18, 2025 at 03:17:33PM +0100, Andreas Schwab wrote: > On Mär 18 2025, Daniel P. Berrangé wrote: > > > 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 ? > > For an emulation performance isn't a thing, what we need is accuracy. > The current issue I have right now is that the MozillaFirefox package > fails to build because posix_spawn behaves unexpectedly. > > https://build.opensuse.org/package/live_build_log/openSUSE:Factory:RISCV/MozillaFirefox/standard/riscv64 > > [ 666s] 4:55.15 Traceback (most recent call last): > [ 666s] 4:55.16 File > "/home/abuild/rpmbuild/BUILD/MozillaFirefox-136.0.1-build/firefox-136.0.1/security/nss/./coreconf/werror.py", > line 80, in <module> > [ 666s] 4:55.16 main() > [ 666s] 4:55.16 ~~~~^^ > [ 666s] 4:55.16 File > "/home/abuild/rpmbuild/BUILD/MozillaFirefox-136.0.1-build/firefox-136.0.1/security/nss/./coreconf/werror.py", > line 10, in main > [ 666s] 4:55.16 cc_is_clang = 'clang' in subprocess.check_output( > [ 666s] 4:55.16 ~~~~~~~~~~~~~~~~~~~~~~~^ > [ 666s] 4:55.16 [cc, '--version'], universal_newlines=True, > stderr=sink) > [ 666s] 4:55.16 > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ > [ 666s] 4:55.16 File "/usr/lib64/python3.13/subprocess.py", line 474, in > check_output > [ 666s] 4:55.16 return run(*popenargs, stdout=PIPE, timeout=timeout, > check=True, > [ 666s] 4:55.16 > ~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ > [ 666s] 4:55.17 **kwargs).stdout > [ 666s] 4:55.17 ^^^^^^^^^ > [ 666s] 4:55.17 File "/usr/lib64/python3.13/subprocess.py", line 579, in > run > [ 666s] 4:55.17 raise CalledProcessError(retcode, process.args, > [ 666s] 4:55.17 output=stdout, stderr=stderr) > [ 666s] 4:55.17 subprocess.CalledProcessError: Command '['/usr/bin/ccache > /usr/bin/gcc', '--version']' returned non-zero exit status 127. > > A real posix_spawn would have set errno to ENOENT.
I look at how the errno is propagated. In glibc, they have a struct on the stack of the parent into which the child will write the errno. This relies on the the vfork() semantics of sharing of pages, and thus breaks when we use fork() that makes the pages copy-on-write - the child writes the errno, but the parent will never see it. In musl, they create a pipe and the child writes the errno in the pipe which the parent then reads, so they're seemingly not relying on the sharing of pages and appears to work under QEMU's impl. I don't see an attractive workaround to make glibc's impl compatible with QEMU, without making QEMU fully use VFORK, with the risk that entails. Wonder if its worth enquiring if glibc would be interested in following musl's approach to make it more emulation friendly for QEMU ? 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 :|