Skip to content

Commit

Permalink
linuxcontainer: allow restrict usage of CPU and CPU set
Browse files Browse the repository at this point in the history
- change cpuRate to int and 1000 means 1 CPU 100%
  • Loading branch information
criyle committed Oct 31, 2021
1 parent 7f0b066 commit d8581a0
Show file tree
Hide file tree
Showing 17 changed files with 238 additions and 216 deletions.
2 changes: 2 additions & 0 deletions README.cn.md
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,8 @@ interface Cmd {
memoryLimit?: number; // 内存限制,单位 byte
stackLimit?: number; // 栈内存限制,单位 byte
procLimit?: number; // 线程数量限制
cpuRateLimit?: number; // 仅 Linux,CPU 使用率限制,1000 等于单核 100%
cpuSetLimit?: string; // 仅 Linux,限制 CPU 使用,使用方式和 cpuset cgroup 相同 (例如,`0` 表示限制仅使用第一个核)
strictMemoryLimit?: boolean; // 开启严格内存限制 (仅 Linux,设置 rlimit 内存限制)

// 在执行程序之前复制进容器的文件列表
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,8 @@ interface Cmd {
memoryLimit?: number; // byte
stackLimit?: number; // byte (N/A on windows, macOS cannot set over 32M)
procLimit?: number;
cpuRateLimit?: number; // limit cpu usage (1000 equals 1 cpu)
cpuSetLimit?: string; // Linux only: set the cpuSet for cgroup
strictMemoryLimit?: boolean; // Linux only: use stricter memory limit (+ rlimit_data when cgroup enabled)

// copy the correspond file to the container dst path
Expand Down
3 changes: 2 additions & 1 deletion cmd/executorserver/grpc_executor/grpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,8 @@ func convertPBCmd(c *pb.Request_CmdType, srcPrefix string) (cm worker.Cmd, strea
MemoryLimit: envexec.Size(c.GetMemoryLimit()),
StackLimit: envexec.Size(c.GetStackLimit()),
ProcLimit: c.GetProcLimit(),
CPURateLimit: c.GetCPURateLimit(),
CPURateLimit: c.GetCpuRateLimit(),
CPUSetLimit: c.GetCpuSetLimit(),
StrictMemoryLimit: c.GetStrictMemoryLimit(),
CopyOut: convertCopyOut(c.GetCopyOut()),
CopyOutCached: convertCopyOut(c.GetCopyOutCached()),
Expand Down
18 changes: 10 additions & 8 deletions cmd/executorserver/model/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,15 @@ type Cmd struct {
Files []*CmdFile `json:"files,omitempty"`
TTY bool `json:"tty,omitempty"`

CPULimit uint64 `json:"cpuLimit"`
RealCPULimit uint64 `json:"realCpuLimit"`
ClockLimit uint64 `json:"clockLimit"`
MemoryLimit uint64 `json:"memoryLimit"`
StackLimit uint64 `json:"stackLimit"`
ProcLimit uint64 `json:"procLimit"`
CPURateLimit float64 `json:"cpuRateLimit"`
StrictMemoryLimit bool `json:"strictMemoryLimit"`
CPULimit uint64 `json:"cpuLimit"`
RealCPULimit uint64 `json:"realCpuLimit"`
ClockLimit uint64 `json:"clockLimit"`
MemoryLimit uint64 `json:"memoryLimit"`
StackLimit uint64 `json:"stackLimit"`
ProcLimit uint64 `json:"procLimit"`
CPURateLimit uint64 `json:"cpuRateLimit"`
CPUSetLimit string `json:"cpuSetLimit"`
StrictMemoryLimit bool `json:"strictMemoryLimit"`

CopyIn map[string]CmdFile `json:"copyIn"`

Expand Down Expand Up @@ -246,6 +247,7 @@ func convertCmd(c Cmd, srcPrefix string) (worker.Cmd, error) {
StackLimit: envexec.Size(c.StackLimit),
ProcLimit: c.ProcLimit,
CPURateLimit: c.CPURateLimit,
CPUSetLimit: c.CPUSetLimit,
StrictMemoryLimit: c.StrictMemoryLimit,
CopyOut: convertCopyOut(c.CopyOut),
CopyOutCached: convertCopyOut(c.CopyOutCached),
Expand Down
5 changes: 1 addition & 4 deletions env/env_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,10 +98,7 @@ func NewBuilder(c Config) (pool.EnvBuilder, error) {
ContainerUID: cUID,
ContainerGID: cGID,
}
cgb := cgroup.NewBuilder(c.CgroupPrefix).WithCPUAcct().WithMemory().WithPids()
if c.Cpuset != "" {
cgb = cgb.WithCPUSet()
}
cgb := cgroup.NewBuilder(c.CgroupPrefix).WithCPUAcct().WithMemory().WithPids().WithCPUSet()
if c.EnableCPURate {
cgb = cgb.WithCPU()
}
Expand Down
4 changes: 2 additions & 2 deletions env/linuxcontainer/cgroup_wrapper_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ type wCgroup struct {
cfsPeriod time.Duration
}

func (c *wCgroup) SetCPURate(s float64) error {
func (c *wCgroup) SetCPURate(s uint64) error {
if err := c.cg.SetCPUCfsPeriod(uint64(c.cfsPeriod.Microseconds())); err != nil {
return err
}
quota := time.Duration(float64(c.cfsPeriod) * s)
quota := time.Duration(uint64(c.cfsPeriod) * s / 1000)
return c.cg.SetCPUCfsQuota(uint64(quota.Microseconds()))
}

Expand Down
2 changes: 1 addition & 1 deletion env/linuxcontainer/cgrouppool_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ type Cgroup interface {
SetCpuset(string) error
SetMemoryLimit(envexec.Size) error
SetProcLimit(uint64) error
SetCPURate(float64) error
SetCPURate(uint64) error // 1000 as 1

CPUUsage() (time.Duration, error)
MemoryUsage() (envexec.Size, error)
Expand Down
8 changes: 6 additions & 2 deletions env/linuxcontainer/environment_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,12 @@ func (c *environ) Open(path string, flags int, perm os.FileMode) (*os.File, erro
}

func (c *environ) setCgroupLimit(cg Cgroup, limit envexec.Limit) error {
if c.cpuset != "" {
if err := cg.SetCpuset(c.cpuset); isCgroupSetHasError(err) {
cpuSet := limit.CPUSet
if cpuSet == "" {
cpuSet = c.cpuset
}
if cpuSet != "" {
if err := cg.SetCpuset(cpuSet); isCgroupSetHasError(err) {
return fmt.Errorf("execve: cgroup failed to set cpu_set limit %v", err)
}
}
Expand Down
3 changes: 2 additions & 1 deletion envexec/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,9 @@ type Cmd struct {
ExtraMemoryLimit Size
OutputLimit Size
ProcLimit uint64
CPURateLimit float64
CPURateLimit uint64
StrictMemoryLimit bool
CPUSetLimit string

// Waiter is called after cmd starts and it should return
// once time limit exceeded.
Expand Down
3 changes: 2 additions & 1 deletion envexec/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ type Limit struct {
Proc uint64 // Process count limit
Stack Size // Stack limit
Output Size // Output limit
Rate float64 // CPU Rate limit
Rate uint64 // CPU Rate limit
CPUSet string // CPU set limit
StrictMemory bool // Use stricter memory limit (e.g. rlimit)
}

Expand Down
1 change: 1 addition & 0 deletions envexec/run_single.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ func runSingleExecve(ctx context.Context, m Environment, c *Cmd, fds []*os.File)
Proc: c.ProcLimit,
Stack: stackLimit,
Rate: c.CPURateLimit,
CPUSet: c.CPUSetLimit,
StrictMemory: c.StrictMemoryLimit,
},
}
Expand Down
12 changes: 6 additions & 6 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ module github.com/criyle/go-judge
go 1.17

require (
github.com/creack/pty v1.1.16
github.com/criyle/go-sandbox v0.8.6
github.com/creack/pty v1.1.17
github.com/criyle/go-sandbox v0.8.7
github.com/elastic/go-seccomp-bpf v1.2.0
github.com/elastic/go-ucfg v0.8.3
github.com/gin-contrib/pprof v1.3.0
Expand All @@ -19,9 +19,9 @@ require (
github.com/zsais/go-gin-prometheus v0.1.0
go.uber.org/zap v1.19.1
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519
golang.org/x/net v0.0.0-20210928044308-7d9f5e0b762b
golang.org/x/net v0.0.0-20211029224645-99673261e6eb
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6
golang.org/x/sys v0.0.0-20211030160813-b3129d9d1021
google.golang.org/grpc v1.41.0
google.golang.org/protobuf v1.27.1
gopkg.in/yaml.v2 v2.4.0
Expand All @@ -45,15 +45,15 @@ require (
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/prometheus/client_model v0.2.0 // indirect
github.com/prometheus/common v0.31.0 // indirect
github.com/prometheus/common v0.32.1 // indirect
github.com/prometheus/procfs v0.7.3 // indirect
github.com/sirupsen/logrus v1.8.1 // indirect
github.com/ugorji/go/codec v1.2.6 // indirect
go.uber.org/atomic v1.9.0 // indirect
go.uber.org/multierr v1.7.0 // indirect
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect
golang.org/x/text v0.3.7 // indirect
google.golang.org/genproto v0.0.0-20210927142257-433400c27d05 // indirect
google.golang.org/genproto v0.0.0-20211029142109-e255c875f7c7 // indirect
)

retract (
Expand Down
26 changes: 12 additions & 14 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,10 @@ github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnht
github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/creack/pty v1.1.16 h1:vfetlOf3A+9YKggibynnX9mnFjuSVvkRj+IWpcTSLEQ=
github.com/creack/pty v1.1.16/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
github.com/criyle/go-sandbox v0.8.6 h1:L6CJLfvmmyCKQByeaf9XoKss4onm1b2fmccs3uTxOtA=
github.com/criyle/go-sandbox v0.8.6/go.mod h1:NINfpuZ5Ywe5qt0tfoeHYxRJe5W7vcu32Jp9HKX4Jbw=
github.com/creack/pty v1.1.17 h1:QeVUsEDNrLBW4tMgZHvxy18sKtr6VI492kBhUfhDJNI=
github.com/creack/pty v1.1.17/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
github.com/criyle/go-sandbox v0.8.7 h1:mwRNoKz/DTvl8F37Ik0E8+BiJB//OMczeeOrMOEHPC8=
github.com/criyle/go-sandbox v0.8.7/go.mod h1:jPzRziXvdL3ZdK47bAUJP7F3s4udupx9M5lz/uPyeXg=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
Expand Down Expand Up @@ -256,8 +256,8 @@ github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6T
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=
github.com/prometheus/common v0.31.0 h1:FTJdLTjtrh4dXlCjpzdZJXMnejSTL5F/nVQm5sNwD34=
github.com/prometheus/common v0.31.0/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
github.com/prometheus/common v0.32.1 h1:hWIdL3N2HoUx3B8j3YN9mWor0qhY/NlEKZEaXxuIRh4=
github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
Expand Down Expand Up @@ -389,9 +389,8 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20210917221730-978cfadd31cf/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20210928044308-7d9f5e0b762b h1:eB48h3HiRycXNy8E0Gf5e0hv7YT6Kt14L/D73G1fuwo=
golang.org/x/net v0.0.0-20210928044308-7d9f5e0b762b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211029224645-99673261e6eb h1:pirldcYWx7rx7kE5r+9WsOXPXK0+WH5+uZ7uPmJ44uM=
golang.org/x/net v0.0.0-20211029224645-99673261e6eb/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
Expand Down Expand Up @@ -456,9 +455,8 @@ golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210917161153-d61c044b1678/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6 h1:foEbQz/B0Oz6YIqu/69kfXPYeFQAuuMYFkjaqXzl5Wo=
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211030160813-b3129d9d1021 h1:giLT+HuUP/gXYrG2Plg9WTjj4qhfgaW424ZIFog3rlk=
golang.org/x/sys v0.0.0-20211030160813-b3129d9d1021/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
Expand Down Expand Up @@ -576,8 +574,8 @@ google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7Fc
google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210927142257-433400c27d05 h1:6/1QShroBaS9sY9NbPquolxRETG6PZhfv8ohdbLieBg=
google.golang.org/genproto v0.0.0-20210927142257-433400c27d05/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
google.golang.org/genproto v0.0.0-20211029142109-e255c875f7c7 h1:aaSaYY/DIDJy3f/JLXWv6xJ1mBQSRnQ1s5JhAFTnzO4=
google.golang.org/genproto v0.0.0-20211029142109-e255c875f7c7/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
Expand Down
Loading

0 comments on commit d8581a0

Please sign in to comment.