diff --git a/handlers.go b/handlers.go index d9d022d8..24053b36 100644 --- a/handlers.go +++ b/handlers.go @@ -109,10 +109,6 @@ var JailerConfigValidationHandler = Handler{ return fmt.Errorf("UID must be specified when using jailer mode") } - if m.Cfg.JailerCfg.NumaNode == nil { - return fmt.Errorf("ID must be specified when using jailer mode") - } - return nil }, } diff --git a/jailer.go b/jailer.go index e261fae6..14b83acf 100644 --- a/jailer.go +++ b/jailer.go @@ -86,6 +86,9 @@ type JailerConfig struct { // CgroupVersion is the version of the cgroup filesystem to use. CgroupVersion string + // CgroupArgs are the cgroup arguments to pass to the jailer. + CgroupArgs []string + // Stdout specifies the IO writer for STDOUT to use when spawning the jailer. Stdout io.Writer // Stderr specifies the IO writer for STDERR to use when spawning the jailer. @@ -102,7 +105,6 @@ type JailerCommandBuilder struct { uid int gid int execFile string - node int // optional params chrootBaseDir string @@ -110,6 +112,8 @@ type JailerCommandBuilder struct { daemonize bool firecrackerArgs []string cgroupVersion string + cgroupArgs []string + node *int stdin io.Reader stdout io.Writer @@ -139,9 +143,15 @@ func (b JailerCommandBuilder) Args() []string { args = append(args, "--gid", strconv.Itoa(b.gid)) args = append(args, "--exec-file", b.execFile) - if cpulist := getNumaCpuset(b.node); len(cpulist) > 0 { - args = append(args, "--cgroup", fmt.Sprintf("cpuset.mems=%d", b.node)) - args = append(args, "--cgroup", fmt.Sprintf("cpuset.cpus=%s", cpulist)) + for _, cgroupArg := range b.cgroupArgs { + args = append(args, "--cgroup", cgroupArg) + } + + if b.node != nil { + if cpulist := getNumaCpuset(*b.node); len(cpulist) > 0 { + args = append(args, "--cgroup", fmt.Sprintf("cpuset.mems=%d", *b.node)) + args = append(args, "--cgroup", fmt.Sprintf("cpuset.cpus=%s", cpulist)) + } } if len(b.cgroupVersion) > 0 { @@ -208,7 +218,14 @@ func (b JailerCommandBuilder) WithExecFile(path string) JailerCommandBuilder { // WithNumaNode uses the specfied node for the jailer. This represents the numa // node that the process will get assigned to. func (b JailerCommandBuilder) WithNumaNode(node int) JailerCommandBuilder { - b.node = node + b.node = &node + return b +} + +// WithCgroupArgs will set the specified cgroup args to the builder. This +// represents the cgroup settings that the process will get assigned. +func (b JailerCommandBuilder) WithCgroupArgs(cgroupArgs ...string) JailerCommandBuilder { + b.cgroupArgs = cgroupArgs return b } @@ -344,11 +361,11 @@ func jail(ctx context.Context, m *Machine, cfg *Config) error { WithID(cfg.JailerCfg.ID). WithUID(*cfg.JailerCfg.UID). WithGID(*cfg.JailerCfg.GID). - WithNumaNode(*cfg.JailerCfg.NumaNode). WithExecFile(cfg.JailerCfg.ExecFile). WithChrootBaseDir(cfg.JailerCfg.ChrootBaseDir). WithDaemonize(cfg.JailerCfg.Daemonize). WithCgroupVersion(cfg.JailerCfg.CgroupVersion). + WithCgroupArgs(cfg.JailerCfg.CgroupArgs...). WithFirecrackerArgs(fcArgs...). WithStdout(stdout). WithStderr(stderr) @@ -365,6 +382,10 @@ func jail(ctx context.Context, m *Machine, cfg *Config) error { builder = builder.WithStdin(stdin) } + if cfg.JailerCfg.NumaNode != nil { + builder = builder.WithNumaNode(*cfg.JailerCfg.NumaNode) + } + m.cmd = builder.Build(ctx) if err := cfg.JailerCfg.ChrootStrategy.AdaptHandlers(&m.Handlers); err != nil { diff --git a/jailer_test.go b/jailer_test.go index 7c7017bc..ce323475 100644 --- a/jailer_test.go +++ b/jailer_test.go @@ -34,7 +34,6 @@ func TestJailerBuilder(t *testing.T) { ID: "my-test-id", UID: Int(123), GID: Int(100), - NumaNode: Int(0), ChrootStrategy: NewNaiveChrootStrategy("kernel-image-path"), ExecFile: "/path/to/firecracker", }, @@ -48,10 +47,6 @@ func TestJailerBuilder(t *testing.T) { "100", "--exec-file", "/path/to/firecracker", - "--cgroup", - "cpuset.mems=0", - "--cgroup", - fmt.Sprintf("cpuset.cpus=%s", getNumaCpuset(0)), }, expectedSockPath: filepath.Join( defaultJailerPath, @@ -67,7 +62,6 @@ func TestJailerBuilder(t *testing.T) { ID: "my-test-id", UID: Int(123), GID: Int(100), - NumaNode: Int(0), ChrootStrategy: NewNaiveChrootStrategy("kernel-image-path"), ExecFile: "/path/to/firecracker", JailerBinary: "imprisoner", @@ -82,10 +76,6 @@ func TestJailerBuilder(t *testing.T) { "100", "--exec-file", "/path/to/firecracker", - "--cgroup", - "cpuset.mems=0", - "--cgroup", - fmt.Sprintf("cpuset.cpus=%s", getNumaCpuset(0)), }, expectedSockPath: filepath.Join( defaultJailerPath, @@ -108,6 +98,7 @@ func TestJailerBuilder(t *testing.T) { ChrootBaseDir: "/tmp", JailerBinary: "/path/to/the/jailer", CgroupVersion: "2", + CgroupArgs: []string{"cpu.weight=200"}, }, expectedArgs: []string{ "/path/to/the/jailer", @@ -120,6 +111,8 @@ func TestJailerBuilder(t *testing.T) { "--exec-file", "/path/to/firecracker", "--cgroup", + "cpu.weight=200", + "--cgroup", "cpuset.mems=0", "--cgroup", fmt.Sprintf("cpuset.cpus=%s", getNumaCpuset(0)), @@ -145,10 +138,17 @@ func TestJailerBuilder(t *testing.T) { WithID(c.jailerCfg.ID). WithUID(IntValue(c.jailerCfg.UID)). WithGID(IntValue(c.jailerCfg.GID)). - WithNumaNode(IntValue(c.jailerCfg.NumaNode)). WithCgroupVersion(c.jailerCfg.CgroupVersion). WithExecFile(c.jailerCfg.ExecFile) + if c.jailerCfg.NumaNode != nil { + b = b.WithNumaNode(IntValue(c.jailerCfg.NumaNode)) + } + + if len(c.jailerCfg.CgroupArgs) > 0 { + b = b.WithCgroupArgs(c.jailerCfg.CgroupArgs...) + } + if len(c.jailerCfg.JailerBinary) > 0 { b = b.WithBin(c.jailerCfg.JailerBinary) } @@ -188,7 +188,6 @@ func TestJail(t *testing.T) { ID: "my-test-id", UID: Int(123), GID: Int(100), - NumaNode: Int(0), ChrootStrategy: NewNaiveChrootStrategy("kernel-image-path"), ExecFile: "/path/to/firecracker", }, @@ -202,10 +201,6 @@ func TestJail(t *testing.T) { "100", "--exec-file", "/path/to/firecracker", - "--cgroup", - "cpuset.mems=0", - "--cgroup", - fmt.Sprintf("cpuset.cpus=%s", getNumaCpuset(0)), "--", "--no-seccomp", "--api-sock", @@ -225,7 +220,6 @@ func TestJail(t *testing.T) { ID: "my-test-id", UID: Int(123), GID: Int(100), - NumaNode: Int(0), ChrootStrategy: NewNaiveChrootStrategy("kernel-image-path"), ExecFile: "/path/to/firecracker", JailerBinary: "imprisoner", @@ -240,10 +234,6 @@ func TestJail(t *testing.T) { "100", "--exec-file", "/path/to/firecracker", - "--cgroup", - "cpuset.mems=0", - "--cgroup", - fmt.Sprintf("cpuset.cpus=%s", getNumaCpuset(0)), "--", "--no-seccomp", "--api-sock", @@ -270,6 +260,7 @@ func TestJail(t *testing.T) { ChrootBaseDir: "/tmp", JailerBinary: "/path/to/the/jailer", CgroupVersion: "2", + CgroupArgs: []string{"cpu.weight=200"}, }, expectedArgs: []string{ "/path/to/the/jailer", @@ -282,6 +273,8 @@ func TestJail(t *testing.T) { "--exec-file", "/path/to/firecracker", "--cgroup", + "cpu.weight=200", + "--cgroup", "cpuset.mems=0", "--cgroup", fmt.Sprintf("cpuset.cpus=%s", getNumaCpuset(0)),