Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
gitpod-io
GitHub Repository: gitpod-io/gitpod
Path: blob/main/components/ws-daemon/pkg/cgroup/plugin_proc_limit_v2.go
2499 views
1
// Copyright (c) 2022 Gitpod GmbH. All rights reserved.
2
// Licensed under the GNU Affero General Public License (AGPL).
3
// See License.AGPL.txt in the project root for license information.
4
5
package cgroup
6
7
import (
8
"context"
9
"path/filepath"
10
"sync"
11
12
v2 "github.com/containerd/cgroups/v2"
13
"github.com/gitpod-io/gitpod/common-go/log"
14
)
15
16
type ProcLimiterV2 struct {
17
limits *v2.Resources
18
19
cond *sync.Cond
20
}
21
22
func NewProcLimiterV2(processes int64) (*ProcLimiterV2, error) {
23
return &ProcLimiterV2{
24
limits: &v2.Resources{
25
Pids: &v2.Pids{
26
Max: processes,
27
},
28
},
29
30
cond: sync.NewCond(&sync.Mutex{}),
31
}, nil
32
}
33
34
func (c *ProcLimiterV2) Name() string { return "proc-limiter-v2" }
35
func (c *ProcLimiterV2) Type() Version { return Version2 }
36
37
func (c *ProcLimiterV2) Apply(ctx context.Context, opts *PluginOptions) error {
38
update := make(chan struct{}, 1)
39
go func() {
40
defer close(update)
41
42
for {
43
c.cond.L.Lock()
44
c.cond.Wait()
45
c.cond.L.Unlock()
46
47
if ctx.Err() != nil {
48
return
49
}
50
51
update <- struct{}{}
52
}
53
}()
54
55
go func() {
56
log.WithField("cgroupPath", opts.CgroupPath).Debug("starting proc limiting")
57
58
_, err := v2.NewManager(opts.BasePath, filepath.Join("/", opts.CgroupPath), c.limits)
59
if err != nil {
60
log.WithError(err).WithFields(log.OWI("", "", opts.InstanceId)).WithField("basePath", opts.BasePath).WithField("cgroupPath", opts.CgroupPath).WithField("limits", c.limits).Error("cannot write proc limits")
61
}
62
63
for {
64
select {
65
case <-update:
66
_, err := v2.NewManager(opts.BasePath, filepath.Join("/", opts.CgroupPath), c.limits)
67
if err != nil {
68
log.WithError(err).WithFields(log.OWI("", "", opts.InstanceId)).WithField("basePath", opts.BasePath).WithField("cgroupPath", opts.CgroupPath).WithField("limits", c.limits).Error("cannot write proc limits")
69
}
70
case <-ctx.Done():
71
return
72
}
73
}
74
}()
75
76
return nil
77
}
78
79
func (c *ProcLimiterV2) Update(processes int64) {
80
c.cond.L.Lock()
81
defer c.cond.L.Unlock()
82
83
c.limits = &v2.Resources{
84
Pids: &v2.Pids{
85
Max: processes,
86
},
87
}
88
89
log.WithField("limits", c.limits.Pids).Info("updating proc cgroups v2 limits")
90
c.cond.Broadcast()
91
}
92
93