libstore/build: drop cgroups experimental feature
We drop it to re-introduce it via the concept of build context which will control in which cgroup a certain build should be spawned. Change-Id: I4b4705d768129a6d7c0f061dc2163ba116088b18 Signed-off-by: Raito Bezarius <raito@lix.systems>
This commit is contained in:
@@ -16,7 +16,6 @@
|
||||
#include "lix/libutil/result.hh"
|
||||
#include "lix/libutil/topo-sort.hh"
|
||||
#include "lix/libutil/json.hh"
|
||||
#include "lix/libutil/cgroup.hh"
|
||||
#include "lix/libstore/build/personality.hh"
|
||||
#include "lix/libutil/namespaces.hh"
|
||||
#include "lix/libstore/build/child.hh"
|
||||
@@ -403,57 +402,8 @@ void LocalDerivationGoal::cleanupPostOutputsRegisteredModeNonCheck()
|
||||
|
||||
kj::Promise<Result<void>> LocalDerivationGoal::startBuilder()
|
||||
try {
|
||||
if ((buildUser && buildUser->getUIDCount() != 1)
|
||||
#if __linux__
|
||||
|| settings.useCgroups
|
||||
#endif
|
||||
)
|
||||
{
|
||||
#if __linux__
|
||||
experimentalFeatureSettings.require(Xp::Cgroups);
|
||||
|
||||
auto cgroupFS = getCgroupFS();
|
||||
if (!cgroupFS)
|
||||
throw Error("cannot determine the cgroups file system");
|
||||
|
||||
auto ourCgroups = getCgroups("/proc/self/cgroup");
|
||||
auto ourCgroup = ourCgroups[""];
|
||||
if (ourCgroup == "")
|
||||
throw Error("cannot determine cgroup name from /proc/self/cgroup");
|
||||
|
||||
auto ourCgroupPath = canonPath(*cgroupFS + "/" + ourCgroup);
|
||||
|
||||
if (!pathExists(ourCgroupPath))
|
||||
throw Error("expected cgroup directory '%s'", ourCgroupPath);
|
||||
|
||||
static std::atomic<unsigned int> counter{0};
|
||||
|
||||
cgroup = buildUser
|
||||
? fmt("%s/nix-build-uid-%d", ourCgroupPath, buildUser->getUID())
|
||||
: fmt("%s/nix-build-pid-%d-%d", ourCgroupPath, getpid(), counter++);
|
||||
|
||||
debug("using cgroup '%s'", *cgroup);
|
||||
|
||||
/* When using a build user, record the cgroup we used for that
|
||||
user so that if we got interrupted previously, we can kill
|
||||
any left-over cgroup first. */
|
||||
if (buildUser) {
|
||||
auto cgroupsDir = settings.nixStateDir + "/cgroups";
|
||||
createDirs(cgroupsDir);
|
||||
|
||||
auto cgroupFile = fmt("%s/%d", cgroupsDir, buildUser->getUID());
|
||||
|
||||
if (pathExists(cgroupFile)) {
|
||||
auto prevCgroup = readFile(cgroupFile);
|
||||
destroyCgroup(prevCgroup);
|
||||
}
|
||||
|
||||
writeFile(cgroupFile, *cgroup);
|
||||
}
|
||||
|
||||
#else
|
||||
if (buildUser && buildUser->getUIDCount() != 1) {
|
||||
throw Error("cgroups are not supported on this platform");
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Make sure that no other processes are executing under the
|
||||
@@ -823,7 +773,6 @@ try {
|
||||
co_return result::current_exception();
|
||||
}
|
||||
|
||||
|
||||
Pid LocalDerivationGoal::startChild(std::function<void()> openSlave) {
|
||||
return startProcess([&]() {
|
||||
openSlave();
|
||||
|
||||
@@ -21,11 +21,6 @@ struct LocalDerivationGoal : public DerivationGoal
|
||||
*/
|
||||
Pid pid;
|
||||
|
||||
/**
|
||||
* The cgroup of the builder, if any.
|
||||
*/
|
||||
std::optional<Path> cgroup;
|
||||
|
||||
/**
|
||||
* The temporary directory.
|
||||
*/
|
||||
@@ -238,8 +233,7 @@ struct LocalDerivationGoal : public DerivationGoal
|
||||
void killChild() override final;
|
||||
|
||||
/**
|
||||
* Kill any processes running under the build user UID or in the
|
||||
* cgroup of the build.
|
||||
* Kill any processes running under the build user UID.
|
||||
*/
|
||||
virtual void killSandbox(bool getStats);
|
||||
|
||||
|
||||
@@ -108,7 +108,6 @@ libstore_setting_definitions = files(
|
||||
'settings/timeout.md',
|
||||
'settings/trusted-public-keys.md',
|
||||
'settings/trusted-substituters.md',
|
||||
'settings/use-cgroups.md',
|
||||
'settings/use-sqlite-wal.md',
|
||||
'settings/use-xdg-base-directories.md',
|
||||
# keep-sorted end
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
#include "lix/libstore/build/worker.hh"
|
||||
#include "lix/libutil/cgroup.hh"
|
||||
#include "lix/libutil/finally.hh"
|
||||
#include "lix/libstore/gc-store.hh"
|
||||
#include "lix/libutil/signals.hh"
|
||||
@@ -819,15 +818,6 @@ void LinuxLocalDerivationGoal::prepareSandbox()
|
||||
for (auto & i : drv->outputsAndPaths(worker.store)) {
|
||||
pathsInChroot.erase(worker.store.printStorePath(i.second.second));
|
||||
}
|
||||
|
||||
if (cgroup) {
|
||||
if (mkdir(cgroup->c_str(), 0755) != 0)
|
||||
throw SysError("creating cgroup '%s'", *cgroup);
|
||||
chownToBuilder(*cgroup);
|
||||
chownToBuilder(*cgroup + "/cgroup.procs");
|
||||
chownToBuilder(*cgroup + "/cgroup.threads");
|
||||
//chownToBuilder(*cgroup + "/cgroup.subtree_control");
|
||||
}
|
||||
}
|
||||
|
||||
Pid LinuxLocalDerivationGoal::startChild(std::function<void()> openSlave)
|
||||
@@ -967,10 +957,6 @@ Pid LinuxLocalDerivationGoal::startChild(std::function<void()> openSlave)
|
||||
"nixbld:!:%1%:\n"
|
||||
"nogroup:x:65534:\n", sandboxGid()));
|
||||
|
||||
/* Move the child into its own cgroup. */
|
||||
if (cgroup)
|
||||
writeFile(*cgroup + "/cgroup.procs", fmt("%d", pid.get()));
|
||||
|
||||
/* Signal the builder that we've updated its user namespace. */
|
||||
writeFull(userNamespaceSync.writeSide.get(), "1");
|
||||
|
||||
@@ -979,13 +965,7 @@ Pid LinuxLocalDerivationGoal::startChild(std::function<void()> openSlave)
|
||||
|
||||
void LinuxLocalDerivationGoal::killSandbox(bool getStats)
|
||||
{
|
||||
if (cgroup) {
|
||||
auto stats = destroyCgroup(*cgroup);
|
||||
if (getStats) {
|
||||
buildResult.cpuUser = stats.cpuUser;
|
||||
buildResult.cpuSystem = stats.cpuSystem;
|
||||
}
|
||||
} else if (!useChroot) {
|
||||
if (!useChroot) {
|
||||
/* Linux sandboxes use PID namespaces, which ensure that processes cannot escape from a build.
|
||||
Therefore, we don't need to kill all processes belonging to the build user.
|
||||
This avoids processes unrelated to the build being killed, thus avoiding: https://git.lix.systems/lix-project/lix/issues/667 */
|
||||
|
||||
@@ -40,14 +40,13 @@ private:
|
||||
void prepareSandbox() override;
|
||||
|
||||
/**
|
||||
* Start child process in new namespaces and cgroup,
|
||||
* Start child process in new namespaces,
|
||||
* create /etc/passwd and /etc/group based on discovered uid/gid
|
||||
*/
|
||||
Pid startChild(std::function<void()> openSlave) override;
|
||||
|
||||
/**
|
||||
* Kill all processes by build user, possibly using a reused
|
||||
* cgroup if we have one
|
||||
* Kill all processes by build user.
|
||||
*/
|
||||
void killSandbox(bool getStatus) override;
|
||||
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
---
|
||||
name: use-cgroups
|
||||
internalName: useCgroups
|
||||
platforms: [linux]
|
||||
type: bool
|
||||
default: false
|
||||
experimentalFeature: cgroups
|
||||
---
|
||||
Whether to execute builds inside cgroups.
|
||||
|
||||
Cgroups are required and enabled automatically for derivations
|
||||
that require the `uid-range` system feature.
|
||||
@@ -1,6 +0,0 @@
|
||||
---
|
||||
name: cgroups
|
||||
internalName: Cgroups
|
||||
---
|
||||
Allows Nix to execute builds inside cgroups. See
|
||||
the [`use-cgroups`](../command-ref/conf-file.md#conf-use-cgroups) setting for details.
|
||||
@@ -142,7 +142,6 @@ libutil_headers = files(
|
||||
experimental_feature_definitions = files(
|
||||
# keep-sorted start
|
||||
'experimental-features/auto-allocate-uids.md',
|
||||
'experimental-features/cgroups.md',
|
||||
'experimental-features/coerce-integers.md',
|
||||
'experimental-features/daemon-trust-override.md',
|
||||
'experimental-features/fetch-closure.md',
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
nix.settings.substituters = lib.mkForce [ ];
|
||||
nix.extraOptions =
|
||||
''
|
||||
extra-experimental-features = nix-command auto-allocate-uids cgroups
|
||||
extra-experimental-features = nix-command auto-allocate-uids
|
||||
extra-system-features = uid-range
|
||||
'';
|
||||
nix.nixPath = [ "nixpkgs=${nixpkgs}" ];
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
{ name, uidRange ? false }:
|
||||
|
||||
with import <nixpkgs> {};
|
||||
|
||||
runCommand name
|
||||
{ requiredSystemFeatures = if uidRange then ["uid-range"] else [];
|
||||
}
|
||||
"id; id > $out"
|
||||
@@ -1,80 +0,0 @@
|
||||
{ nixpkgs }:
|
||||
|
||||
let
|
||||
|
||||
machine = { config, pkgs, ... }:
|
||||
{
|
||||
system.stateVersion = "22.05";
|
||||
boot.isContainer = true;
|
||||
systemd.services.console-getty.enable = false;
|
||||
networking.dhcpcd.enable = false;
|
||||
|
||||
services.httpd = {
|
||||
enable = true;
|
||||
adminAddr = "nixos@example.org";
|
||||
};
|
||||
|
||||
systemd.services.test = {
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [ "httpd.service" ];
|
||||
script = ''
|
||||
source /.env
|
||||
echo "Hello World" > $out/msg
|
||||
ls -lR /dev > $out/dev
|
||||
${pkgs.curl}/bin/curl -sS --fail http://localhost/ > $out/page.html
|
||||
'';
|
||||
unitConfig = {
|
||||
FailureAction = "exit-force";
|
||||
FailureActionExitStatus = 42;
|
||||
SuccessAction = "exit-force";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
cfg = (import (nixpkgs + "/nixos/lib/eval-config.nix") {
|
||||
modules = [ machine ];
|
||||
system = "x86_64-linux";
|
||||
});
|
||||
|
||||
config = cfg.config;
|
||||
|
||||
in
|
||||
|
||||
with cfg._module.args.pkgs;
|
||||
|
||||
runCommand "test"
|
||||
{ buildInputs = [ config.system.path ];
|
||||
requiredSystemFeatures = [ "uid-range" ];
|
||||
toplevel = config.system.build.toplevel;
|
||||
}
|
||||
''
|
||||
root=$(pwd)/root
|
||||
mkdir -p $root $root/etc
|
||||
|
||||
export > $root/.env
|
||||
|
||||
# Make /run a tmpfs to shut up a systemd warning.
|
||||
mkdir /run
|
||||
mount -t tmpfs none /run
|
||||
|
||||
mount -t cgroup2 none /sys/fs/cgroup
|
||||
|
||||
mkdir -p $out
|
||||
|
||||
chmod +w /etc
|
||||
touch /etc/os-release
|
||||
echo a5ea3f98dedc0278b6f3cc8c37eeaeac > /etc/machine-id
|
||||
|
||||
SYSTEMD_NSPAWN_UNIFIED_HIERARCHY=1 \
|
||||
${config.systemd.package}/bin/systemd-nspawn \
|
||||
--keep-unit \
|
||||
-M ${config.networking.hostName} -D "$root" \
|
||||
--register=no \
|
||||
--resolv-conf=off \
|
||||
--bind-ro=/nix/store \
|
||||
--bind=$out \
|
||||
--bind=/proc:/run/host/proc \
|
||||
--bind=/sys:/run/host/sys \
|
||||
--private-network \
|
||||
$toplevel/init
|
||||
''
|
||||
@@ -150,8 +150,6 @@ in
|
||||
|
||||
tarballFlakes = runNixOSTestFor "x86_64-linux" ./tarball-flakes.nix;
|
||||
|
||||
containers = runNixOSTestFor "x86_64-linux" ./containers/containers.nix;
|
||||
|
||||
setuid = lib.genAttrs
|
||||
["i686-linux" "x86_64-linux"]
|
||||
(system: runNixOSTestFor system ./setuid/setuid.nix);
|
||||
|
||||
Reference in New Issue
Block a user