Use clone3 / CLONE_INTO_CGROUP on Linux

Use clone3 / CLONE_INTO_CGROUP to have the Linux kernel create the process in the
correct cgroup rather than move the process into the cgroup after it is created.
This commit is contained in:
Jeffrey C. Ollie
2024-06-07 23:48:03 -06:00
parent 0d94fb61c9
commit e6f97c28f8
3 changed files with 74 additions and 9 deletions

View File

@@ -19,6 +19,7 @@ const Command = @This();
const std = @import("std");
const builtin = @import("builtin");
const internal_os = @import("os/main.zig");
const termio = @import("termio.zig");
const windows = internal_os.windows;
const TempDir = internal_os.TempDir;
const mem = std.mem;
@@ -32,6 +33,8 @@ const EnvMap = std.process.EnvMap;
const PreExecFn = fn (*Command) void;
const log = std.log.scoped(.command);
/// Path to the command to run. This must be an absolute path. This
/// library does not do PATH lookup.
path: []const u8,
@@ -61,6 +64,8 @@ stderr: ?File = null,
/// exec process takes over, such as signal handlers, setsid, setuid, etc.
pre_exec: ?*const PreExecFn = null,
linux_cgroup: termio.Options.LinuxCgroup = termio.Options.linux_cgroup_default,
/// If set, then the process will be created attached to this pseudo console.
/// `stdin`, `stdout`, and `stderr` will be ignored if set.
pseudo_console: if (builtin.os.tag == .windows) ?windows.exp.HPCON else void =
@@ -133,8 +138,11 @@ fn startPosix(self: *Command, arena: Allocator) !void {
else
@compileError("missing env vars");
// Fork
const pid = try posix.fork();
const pid: linux.pid_t = switch (builtin.os.tag) {
.linux => if (self.linux_cgroup) |cgroup| try internal_os.cgroup.cloneInto(cgroup) else try posix.fork(),
else => try posix.fork(),
};
if (pid != 0) {
// Parent, return immediately.
self.pid = @intCast(pid);