There’s something fishy when running the tests. If you comment out the “setns” and “pivot-root” tests, you’ll see that syscalls.log reads this:
--8<---------------cut here---------------start------------->8--- %%%% Starting test syscalls Group begin: syscalls Test begin: test-name: "mount, ENOENT" source-file: "tests/syscalls.scm" source-line: 34 source-form: (test-equal "mount, ENOENT" ENOENT (catch (quote system-error) (lambda () (mount "/dev/null" "/does-not-exist" "ext2") #f) (compose system-error-errno list))) [...] Test begin: test-name: "clone" source-file: "tests/syscalls.scm" source-line: 86 source-form: (test-assert "clone" (match (clone (logior CLONE_NEWUSER SIGCHLD)) (0 (primitive-exit 42)) (pid (and (not (equal? (readlink (user-namespace pid)) (readlink (user-namespace (getpid))))) (match (waitpid pid) ((_ . status) (= 42 (status:exit-val status)))))))) %%%% Starting test syscalls Group begin: syscalls Test begin: test-name: "mount, ENOENT" source-file: "tests/syscalls.scm" source-line: 34 source-form: (test-equal "mount, ENOENT" ENOENT (catch (quote system-error) (lambda () (mount "/dev/null" "/does-not-exist" "ext2") #f) (compose system-error-errno list))) [...] Group end: syscalls # of expected passes 14 --8<---------------cut here---------------end--------------->8--- Notice the second “Starting test syscalls” in the middle of the “clone” test. So it looks as though the child process started execution from the beginning of the file, yet somehow finished as expected (there’s only one occurrence of “Group end”.) Ideas? Another issue is the return value of ‘getpid’ in the child process, which is the PID of the parent process as I reported earlier. This issue is actually documented in clone(2): Versions of the GNU C library that include the NPTL threading library contain a wrapper function for getpid(2) that performs caching of PIDs. This caching relies on support in the glibc wrapper for clone(), but as currently implemented, the cache may not be up to date in some circumstances. I wonder if there are other parts of libc state that may be broken after a raw ‘clone’. This may be fine if we call ‘exec’ soon after ‘clone’, but otherwise could be problematic–e.g., for ‘call-with-container’. Perhaps we’ll have to revisit the syscall vs. wrapper choice? Ludo’.