From 2e0cc67ec829754184dcbebff8078726debd13f7 Mon Sep 17 00:00:00 2001 From: eldritch horrors Date: Wed, 28 Jan 2026 18:49:02 +0100 Subject: [PATCH] libstore: start pasta much earlier starting pasta as soon as we have all namespaces it must be in available lets it start up while we finish creating the sandbox. this may speed up sandbox launches somewhat, but likely not enough to show up in practice. Change-Id: Id6724cbdc48b99284cd7ba7b56c98829d74557c5 --- lix/libstore/platform/linux.cc | 108 +++++++++++++++------------------ 1 file changed, 49 insertions(+), 59 deletions(-) diff --git a/lix/libstore/platform/linux.cc b/lix/libstore/platform/linux.cc index c285771c7..e96afb43b 100644 --- a/lix/libstore/platform/linux.cc +++ b/lix/libstore/platform/linux.cc @@ -1624,68 +1624,10 @@ Pid LinuxLocalDerivationGoal::startChild( return {std::move(userns), std::move(netns)}; }(); - Pid pid = inVFork(/* flags*/ 0, [&]() { - if (prctl(PR_SET_PDEATHSIG, SIGKILL) == -1) - throw SysError("setting death signal"); - - if (dup2(logPTY.get(), STDERR_FILENO) == -1) { - throw SysError("failed to redirect build output to log file"); - } - - /* Migrate the child inside the available control group. */ - if (context.cgroup) { - context.cgroup->adoptProcess(getpid()); - } - - // Drop additional groups here because we can't do it after we're in the - // new user namespace. check `asVFork` for why we use raw syscalls here. - if (syscall(SYS_setgroups, 0, nullptr) == -1) { - if (errno != EPERM) - throw SysError("setgroups failed"); - if (settings.requireDropSupplementaryGroups) - throw Error("setgroups failed. Set the require-drop-supplementary-groups option to false to skip this step."); - } - - if (userns && setns(userns.get(), 0)) { - throw SysError("setns(userNS)"); - } - if (netns && setns(netns.get(), 0)) { - throw SysError("setns(netNS)"); - } - - ProcessOptions options; - options.cloneFlags = - CLONE_NEWPID | CLONE_NEWNS | CLONE_NEWIPC | CLONE_NEWUTS | CLONE_PARENT | SIGCHLD; - - return startProcess( - [&]() { - if (prctl(PR_SET_PDEATHSIG, SIGKILL) == -1) { - throw SysError("setting death signal"); - } - runChild(builder, envStrs, args); - }, - options - ); - }); - if (runPasta()) { // Bring up pasta, for handling FOD networking. We don't let it daemonize // itself for process managements reasons and kill it manually when done. - AutoCloseFD netns(sys::open(fmt("/proc/%i/ns/net", pid.get()), O_RDONLY | O_CLOEXEC)); - if (!netns) { - throw SysError("failed to open netns"); - } - - AutoCloseFD userns; - if (worker.namespaces.user) { - userns = - AutoCloseFD(sys::open(fmt("/proc/%i/ns/user", pid.get()), O_RDONLY | O_CLOEXEC)); - if (!userns) { - throw SysError("failed to open userns"); - } - } - // FIXME ideally we want a notification when pasta exits, but we cannot do // this at present. without such support we need to busy-wait for pasta to // set up the namespace completely and time out after a while for the case @@ -1716,7 +1658,55 @@ Pid LinuxLocalDerivationGoal::startChild( ); } - return pid; + return inVFork(/* flags*/ 0, [&]() { + if (prctl(PR_SET_PDEATHSIG, SIGKILL) == -1) { + throw SysError("setting death signal"); + } + + if (dup2(logPTY.get(), STDERR_FILENO) == -1) { + throw SysError("failed to redirect build output to log file"); + } + + /* Migrate the child inside the available control group. */ + if (context.cgroup) { + context.cgroup->adoptProcess(getpid()); + } + + // Drop additional groups here because we can't do it after we're in the + // new user namespace. check `asVFork` for why we use raw syscalls here. + if (syscall(SYS_setgroups, 0, nullptr) == -1) { + if (errno != EPERM) { + throw SysError("setgroups failed"); + } + if (settings.requireDropSupplementaryGroups) { + throw Error( + "setgroups failed. Set the require-drop-supplementary-groups option to false to skip " + "this step." + ); + } + } + + if (userns && setns(userns.get(), 0)) { + throw SysError("setns(userNS)"); + } + if (netns && setns(netns.get(), 0)) { + throw SysError("setns(netNS)"); + } + + ProcessOptions options; + options.cloneFlags = + CLONE_NEWPID | CLONE_NEWNS | CLONE_NEWIPC | CLONE_NEWUTS | CLONE_PARENT | SIGCHLD; + + return startProcess( + [&]() { + if (prctl(PR_SET_PDEATHSIG, SIGKILL) == -1) { + throw SysError("setting death signal"); + } + runChild(builder, envStrs, args); + }, + options + ); + }); } void LinuxLocalDerivationGoal::cleanupHookFinally()