@@ -14,6 +14,7 @@ import (
14
14
"time"
15
15
16
16
units "github.com/docker/go-units"
17
+ "golang.org/x/sys/unix"
17
18
)
18
19
19
20
const (
@@ -463,11 +464,40 @@ func WriteCgroupProc(dir string, pid int) error {
463
464
return fmt .Errorf ("no such directory for %s" , CgroupProcesses )
464
465
}
465
466
466
- // Don't attach any pid to the cgroup if -1 is specified as a pid
467
- if pid != - 1 {
468
- if err := ioutil .WriteFile (filepath .Join (dir , CgroupProcesses ), []byte (strconv .Itoa (pid )), 0700 ); err != nil {
469
- return fmt .Errorf ("failed to write %v to %v: %v" , pid , CgroupProcesses , err )
467
+ // Dont attach any pid to the cgroup if -1 is specified as a pid
468
+ if pid == - 1 {
469
+ return nil
470
+ }
471
+
472
+ cgroupProcessesFile , err := os .OpenFile (filepath .Join (dir , CgroupProcesses ), os .O_WRONLY | os .O_CREATE | os .O_TRUNC , 0700 )
473
+ if err != nil {
474
+ return fmt .Errorf ("failed to write %v to %v: %v" , pid , CgroupProcesses , err )
475
+ }
476
+ defer cgroupProcessesFile .Close ()
477
+
478
+ for i := 0 ; i < 5 ; i ++ {
479
+ _ , err = cgroupProcessesFile .WriteString (strconv .Itoa (pid ))
480
+ if err == nil {
481
+ return nil
470
482
}
483
+
484
+ // EINVAL might mean that the task being added to cgroup.procs is in state
485
+ // TASK_NEW. We should attempt to do so again.
486
+ if isEINVAL (err ) {
487
+ time .Sleep (30 * time .Millisecond )
488
+ continue
489
+ }
490
+
491
+ return fmt .Errorf ("failed to write %v to %v: %v" , pid , CgroupProcesses , err )
492
+ }
493
+ return err
494
+ }
495
+
496
+ func isEINVAL (err error ) bool {
497
+ switch err := err .(type ) {
498
+ case * os.PathError :
499
+ return err .Err == unix .EINVAL
500
+ default :
501
+ return false
471
502
}
472
- return nil
473
503
}
0 commit comments