Skip to content

Commit 2cf8d24

Browse files
authored
Merge pull request #2494 from kolyshkin/cgroupv1-optimize-path
cgroups/v1: optimize path usage
2 parents bbd4ffe + 940e154 commit 2cf8d24

File tree

2 files changed

+55
-73
lines changed

2 files changed

+55
-73
lines changed

libcontainer/cgroups/fs/fs.go

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -220,26 +220,26 @@ func (m *manager) Apply(pid int) (err error) {
220220

221221
var c = m.cgroups
222222

223-
d, err := getCgroupData(m.cgroups, pid)
224-
if err != nil {
225-
return err
226-
}
227-
228223
m.paths = make(map[string]string)
229224
if c.Paths != nil {
225+
cgMap, err := cgroups.ParseCgroupFile("/proc/self/cgroup")
226+
if err != nil {
227+
return err
228+
}
230229
for name, path := range c.Paths {
231-
_, err := d.path(name)
232-
if err != nil {
233-
if cgroups.IsNotFound(err) {
234-
continue
235-
}
236-
return err
230+
// XXX(kolyshkin@): why this check is needed?
231+
if _, ok := cgMap[name]; ok {
232+
m.paths[name] = path
237233
}
238-
m.paths[name] = path
239234
}
240235
return cgroups.EnterPid(m.paths, pid)
241236
}
242237

238+
d, err := getCgroupData(m.cgroups, pid)
239+
if err != nil {
240+
return err
241+
}
242+
243243
for _, sys := range subsystems {
244244
p, err := d.path(sys.Name())
245245
if err != nil {

libcontainer/cgroups/systemd/v1.go

Lines changed: 43 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -105,16 +105,15 @@ func (m *legacyManager) Apply(pid int) error {
105105
defer m.mu.Unlock()
106106
if c.Paths != nil {
107107
paths := make(map[string]string)
108+
cgMap, err := cgroups.ParseCgroupFile("/proc/self/cgroup")
109+
if err != nil {
110+
return err
111+
}
112+
// XXX(kolyshkin@): why this check is needed?
108113
for name, path := range c.Paths {
109-
_, err := getSubsystemPath(m.cgroups, name)
110-
if err != nil {
111-
// Don't fail if a cgroup hierarchy was not found, just skip this subsystem
112-
if cgroups.IsNotFound(err) {
113-
continue
114-
}
115-
return err
114+
if _, ok := cgMap[name]; ok {
115+
paths[name] = path
116116
}
117-
paths[name] = path
118117
}
119118
m.paths = paths
120119
return cgroups.EnterPid(m.paths, pid)
@@ -179,14 +178,16 @@ func (m *legacyManager) Apply(pid int) error {
179178
return err
180179
}
181180

182-
if err := joinCgroups(c, pid); err != nil {
183-
return err
184-
}
185-
186181
paths := make(map[string]string)
187182
for _, s := range legacySubsystems {
188183
subsystemPath, err := getSubsystemPath(m.cgroups, s.Name())
189184
if err != nil {
185+
// Even if it's `not found` error, we'll return err
186+
// because devices cgroup is hard requirement for
187+
// container security.
188+
if s.Name() == "devices" {
189+
return err
190+
}
190191
// Don't fail if a cgroup hierarchy was not found, just skip this subsystem
191192
if cgroups.IsNotFound(err) {
192193
continue
@@ -196,6 +197,11 @@ func (m *legacyManager) Apply(pid int) error {
196197
paths[s.Name()] = subsystemPath
197198
}
198199
m.paths = paths
200+
201+
if err := m.joinCgroups(pid); err != nil {
202+
return err
203+
}
204+
199205
return nil
200206
}
201207

@@ -228,48 +234,25 @@ func (m *legacyManager) Path(subsys string) string {
228234
return m.paths[subsys]
229235
}
230236

231-
func join(c *configs.Cgroup, subsystem string, pid int) (string, error) {
232-
path, err := getSubsystemPath(c, subsystem)
233-
if err != nil {
234-
return "", err
235-
}
236-
237-
if err := os.MkdirAll(path, 0755); err != nil {
238-
return "", err
239-
}
240-
if err := cgroups.WriteCgroupProc(path, pid); err != nil {
241-
return "", err
242-
}
243-
return path, nil
244-
}
245-
246-
func joinCgroups(c *configs.Cgroup, pid int) error {
237+
func (m *legacyManager) joinCgroups(pid int) error {
247238
for _, sys := range legacySubsystems {
248239
name := sys.Name()
249240
switch name {
250241
case "name=systemd":
251242
// let systemd handle this
252243
case "cpuset":
253-
path, err := getSubsystemPath(c, name)
254-
if err != nil && !cgroups.IsNotFound(err) {
255-
return err
256-
}
257-
s := &fs.CpusetGroup{}
258-
if err := s.ApplyDir(path, c, pid); err != nil {
259-
return err
244+
if path, ok := m.paths[name]; ok {
245+
s := &fs.CpusetGroup{}
246+
if err := s.ApplyDir(path, m.cgroups, pid); err != nil {
247+
return err
248+
}
260249
}
261250
default:
262-
_, err := join(c, name, pid)
263-
if err != nil {
264-
// Even if it's `not found` error, we'll return err
265-
// because devices cgroup is hard requirement for
266-
// container security.
267-
if name == "devices" {
251+
if path, ok := m.paths[name]; ok {
252+
if err := os.MkdirAll(path, 0755); err != nil {
268253
return err
269254
}
270-
// For other subsystems, omit the `not found` error
271-
// because they are optional.
272-
if !cgroups.IsNotFound(err) {
255+
if err := cgroups.WriteCgroupProc(path, pid); err != nil {
273256
return err
274257
}
275258
}
@@ -306,33 +289,32 @@ func getSubsystemPath(c *configs.Cgroup, subsystem string) (string, error) {
306289
}
307290

308291
func (m *legacyManager) Freeze(state configs.FreezerState) error {
309-
path, err := getSubsystemPath(m.cgroups, "freezer")
310-
if err != nil {
311-
return err
292+
path, ok := m.paths["freezer"]
293+
if !ok {
294+
return errSubsystemDoesNotExist
312295
}
313296
prevState := m.cgroups.Resources.Freezer
314297
m.cgroups.Resources.Freezer = state
315298
freezer := &fs.FreezerGroup{}
316-
err = freezer.Set(path, m.cgroups)
317-
if err != nil {
299+
if err := freezer.Set(path, m.cgroups); err != nil {
318300
m.cgroups.Resources.Freezer = prevState
319301
return err
320302
}
321303
return nil
322304
}
323305

324306
func (m *legacyManager) GetPids() ([]int, error) {
325-
path, err := getSubsystemPath(m.cgroups, "devices")
326-
if err != nil {
327-
return nil, err
307+
path, ok := m.paths["devices"]
308+
if !ok {
309+
return nil, errSubsystemDoesNotExist
328310
}
329311
return cgroups.GetPids(path)
330312
}
331313

332314
func (m *legacyManager) GetAllPids() ([]int, error) {
333-
path, err := getSubsystemPath(m.cgroups, "devices")
334-
if err != nil {
335-
return nil, err
315+
path, ok := m.paths["devices"]
316+
if !ok {
317+
return nil, errSubsystemDoesNotExist
336318
}
337319
return cgroups.GetAllPids(path)
338320
}
@@ -403,9 +385,9 @@ func (m *legacyManager) Set(container *configs.Config) error {
403385

404386
for _, sys := range legacySubsystems {
405387
// Get the subsystem path, but don't error out for not found cgroups.
406-
path, err := getSubsystemPath(container.Cgroups, sys.Name())
407-
if err != nil && !cgroups.IsNotFound(err) {
408-
return err
388+
path, ok := m.paths[sys.Name()]
389+
if !ok {
390+
continue
409391
}
410392
if err := sys.Set(path, container.Cgroups); err != nil {
411393
return err
@@ -447,9 +429,9 @@ func (m *legacyManager) GetCgroups() (*configs.Cgroup, error) {
447429
}
448430

449431
func (m *legacyManager) GetFreezerState() (configs.FreezerState, error) {
450-
path, err := getSubsystemPath(m.cgroups, "freezer")
451-
if err != nil && !cgroups.IsNotFound(err) {
452-
return configs.Undefined, err
432+
path, ok := m.paths["freezer"]
433+
if !ok {
434+
return configs.Undefined, nil
453435
}
454436
freezer := &fs.FreezerGroup{}
455437
return freezer.GetState(path)

0 commit comments

Comments
 (0)