@@ -346,13 +346,64 @@ func (m *Manager) GetPaths() map[string]string {
346346 return paths
347347}
348348
349+ func createCgroupsv2Path (path string ) (Err error ) {
350+ content , err := ioutil .ReadFile ("/sys/fs/cgroup/cgroup.controllers" )
351+ if err != nil {
352+ return err
353+ }
354+ if ! filepath .HasPrefix (path , "/sys/fs/cgroup" ) {
355+ return fmt .Errorf ("invalid cgroup path %s" , path )
356+ }
357+
358+ res := ""
359+ for i , c := range strings .Split (strings .TrimSpace (string (content )), " " ) {
360+ if i == 0 {
361+ res = fmt .Sprintf ("+%s" , c )
362+ } else {
363+ res = res + fmt .Sprintf (" +%s" , c )
364+ }
365+ }
366+ resByte := []byte (res )
367+
368+ current := "/sys/fs"
369+ elements := strings .Split (path , "/" )
370+ for i , e := range elements [3 :] {
371+ current = filepath .Join (current , e )
372+ if i > 0 {
373+ if err := os .Mkdir (current , 0755 ); err != nil {
374+ if ! os .IsExist (err ) {
375+ return err
376+ }
377+ } else {
378+ // If the directory was created, be sure it is not left around on errors.
379+ defer func () {
380+ if Err != nil {
381+ os .Remove (current )
382+ }
383+ }()
384+ }
385+ }
386+ if err := ioutil .WriteFile (filepath .Join (current , "cgroup.subtree_control" ), resByte , 0755 ); err != nil {
387+ return err
388+ }
389+ }
390+ return nil
391+ }
392+
349393func join (c * configs.Cgroup , subsystem string , pid int ) (string , error ) {
350394 path , err := getSubsystemPath (c , subsystem )
351395 if err != nil {
352396 return "" , err
353397 }
354- if err := os .MkdirAll (path , 0755 ); err != nil {
355- return "" , err
398+
399+ if cgroups .IsCgroup2UnifiedMode () {
400+ if err := createCgroupsv2Path (path ); err != nil {
401+ return "" , err
402+ }
403+ } else {
404+ if err := os .MkdirAll (path , 0755 ); err != nil {
405+ return "" , err
406+ }
356407 }
357408 if err := cgroups .WriteCgroupProc (path , pid ); err != nil {
358409 return "" , err
@@ -361,6 +412,15 @@ func join(c *configs.Cgroup, subsystem string, pid int) (string, error) {
361412}
362413
363414func joinCgroups (c * configs.Cgroup , pid int ) error {
415+ if cgroups .IsCgroup2UnifiedMode () {
416+ path , err := getSubsystemPath (c , "memory" )
417+ if err != nil {
418+ return err
419+ }
420+ if err := createCgroupsv2Path (path ); err != nil {
421+ return err
422+ }
423+ }
364424 for _ , sys := range subsystems {
365425 name := sys .Name ()
366426 switch name {
0 commit comments