@@ -256,6 +256,11 @@ func (m *Manager) GetPaths() map[string]string {
256
256
}
257
257
258
258
func writeFile (dir , file , data string ) error {
259
+ // Normally dir should not be empty, one case is that cgroup subsystem
260
+ // is not mounted, we will get empty dir, and we want it fail here.
261
+ if dir == "" {
262
+ return fmt .Errorf ("no such directory for %s." , file )
263
+ }
259
264
return ioutil .WriteFile (filepath .Join (dir , file ), []byte (data ), 0700 )
260
265
}
261
266
@@ -276,24 +281,24 @@ func join(c *configs.Cgroup, subsystem string, pid int) (string, error) {
276
281
277
282
func joinCpu (c * configs.Cgroup , pid int ) error {
278
283
path , err := getSubsystemPath (c , "cpu" )
279
- if err != nil {
284
+ if err != nil && ! cgroups . IsNotFound ( err ) {
280
285
return err
281
286
}
282
287
if c .CpuQuota != 0 {
283
- if err = ioutil . WriteFile ( filepath . Join ( path , "cpu.cfs_quota_us" ), [] byte ( strconv .FormatInt (c .CpuQuota , 10 )), 0700 ); err != nil {
288
+ if err = writeFile ( path , "cpu.cfs_quota_us" , strconv .FormatInt (c .CpuQuota , 10 )); err != nil {
284
289
return err
285
290
}
286
291
}
287
292
if c .CpuPeriod != 0 {
288
- if err = ioutil . WriteFile ( filepath . Join ( path , "cpu.cfs_period_us" ), [] byte ( strconv .FormatInt (c .CpuPeriod , 10 )), 0700 ); err != nil {
293
+ if err = writeFile ( path , "cpu.cfs_period_us" , strconv .FormatInt (c .CpuPeriod , 10 )); err != nil {
289
294
return err
290
295
}
291
296
}
292
297
return nil
293
298
}
294
299
295
300
func joinFreezer (c * configs.Cgroup , pid int ) error {
296
- if _ , err := join (c , "freezer" , pid ); err != nil {
301
+ if _ , err := join (c , "freezer" , pid ); err != nil && ! cgroups . IsNotFound ( err ) {
297
302
return err
298
303
}
299
304
@@ -393,6 +398,8 @@ func getUnitName(c *configs.Cgroup) string {
393
398
// This happens at least for v208 when any sibling unit is started.
394
399
func joinDevices (c * configs.Cgroup , pid int ) error {
395
400
path , err := join (c , "devices" , pid )
401
+ // Even if it's `not found` error, we'll return err because devices cgroup
402
+ // is hard requirement for container security.
396
403
if err != nil {
397
404
return err
398
405
}
@@ -410,19 +417,19 @@ func joinMemory(c *configs.Cgroup, pid int) error {
410
417
}
411
418
412
419
path , err := getSubsystemPath (c , "memory" )
413
- if err != nil {
420
+ if err != nil && ! cgroups . IsNotFound ( err ) {
414
421
return err
415
422
}
416
423
417
- return ioutil . WriteFile ( filepath . Join ( path , "memory.memsw.limit_in_bytes" ), [] byte ( strconv .FormatInt (memorySwap , 10 )), 0700 )
424
+ return writeFile ( path , "memory.memsw.limit_in_bytes" , strconv .FormatInt (memorySwap , 10 ))
418
425
}
419
426
420
427
// systemd does not atm set up the cpuset controller, so we must manually
421
428
// join it. Additionally that is a very finicky controller where each
422
429
// level must have a full setup as the default for a new directory is "no cpus"
423
430
func joinCpuset (c * configs.Cgroup , pid int ) error {
424
431
path , err := getSubsystemPath (c , "cpuset" )
425
- if err != nil {
432
+ if err != nil && ! cgroups . IsNotFound ( err ) {
426
433
return err
427
434
}
428
435
0 commit comments