@@ -209,6 +209,74 @@ func prepareBindMount(m *configs.Mount, rootfs string) error {
209209 return nil
210210}
211211
212+ func mountCgroupV1 (m * configs.Mount , rootfs , mountLabel string , enableCgroupns bool ) error {
213+ binds , err := getCgroupMounts (m )
214+ if err != nil {
215+ return err
216+ }
217+ var merged []string
218+ for _ , b := range binds {
219+ ss := filepath .Base (b .Destination )
220+ if strings .Contains (ss , "," ) {
221+ merged = append (merged , ss )
222+ }
223+ }
224+ tmpfs := & configs.Mount {
225+ Source : "tmpfs" ,
226+ Device : "tmpfs" ,
227+ Destination : m .Destination ,
228+ Flags : defaultMountFlags ,
229+ Data : "mode=755" ,
230+ PropagationFlags : m .PropagationFlags ,
231+ }
232+ if err := mountToRootfs (tmpfs , rootfs , mountLabel , enableCgroupns ); err != nil {
233+ return err
234+ }
235+ for _ , b := range binds {
236+ if enableCgroupns {
237+ subsystemPath := filepath .Join (rootfs , b .Destination )
238+ if err := os .MkdirAll (subsystemPath , 0755 ); err != nil {
239+ return err
240+ }
241+ flags := defaultMountFlags
242+ if m .Flags & unix .MS_RDONLY != 0 {
243+ flags = flags | unix .MS_RDONLY
244+ }
245+ cgroupmount := & configs.Mount {
246+ Source : "cgroup" ,
247+ Device : "cgroup" ,
248+ Destination : subsystemPath ,
249+ Flags : flags ,
250+ Data : filepath .Base (subsystemPath ),
251+ }
252+ if err := mountNewCgroup (cgroupmount ); err != nil {
253+ return err
254+ }
255+ } else {
256+ if err := mountToRootfs (b , rootfs , mountLabel , enableCgroupns ); err != nil {
257+ return err
258+ }
259+ }
260+ }
261+ for _ , mc := range merged {
262+ for _ , ss := range strings .Split (mc , "," ) {
263+ // symlink(2) is very dumb, it will just shove the path into
264+ // the link and doesn't do any checks or relative path
265+ // conversion. Also, don't error out if the cgroup already exists.
266+ if err := os .Symlink (mc , filepath .Join (rootfs , m .Destination , ss )); err != nil && ! os .IsExist (err ) {
267+ return err
268+ }
269+ }
270+ }
271+ return nil
272+ }
273+
274+ func mountCgroupV2 (m * configs.Mount , rootfs , mountLabel string , enableCgroupns bool ) error {
275+ cgroupPath := filepath .Join (rootfs , m .Destination )
276+
277+ return unix .Mount (m .Source , cgroupPath , "cgroup2" , uintptr (m .Flags ), m .Data )
278+ }
279+
212280func mountToRootfs (m * configs.Mount , rootfs , mountLabel string , enableCgroupns bool ) error {
213281 var (
214282 dest = m .Destination
@@ -309,64 +377,16 @@ func mountToRootfs(m *configs.Mount, rootfs, mountLabel string, enableCgroupns b
309377 }
310378 }
311379 case "cgroup" :
312- binds , err := getCgroupMounts (m )
313- if err != nil {
314- return err
315- }
316- var merged []string
317- for _ , b := range binds {
318- ss := filepath .Base (b .Destination )
319- if strings .Contains (ss , "," ) {
320- merged = append (merged , ss )
321- }
322- }
323- tmpfs := & configs.Mount {
324- Source : "tmpfs" ,
325- Device : "tmpfs" ,
326- Destination : m .Destination ,
327- Flags : defaultMountFlags ,
328- Data : "mode=755" ,
329- PropagationFlags : m .PropagationFlags ,
330- }
331- if err := mountToRootfs (tmpfs , rootfs , mountLabel , enableCgroupns ); err != nil {
332- return err
333- }
334- for _ , b := range binds {
335- if enableCgroupns {
336- subsystemPath := filepath .Join (rootfs , b .Destination )
337- if err := os .MkdirAll (subsystemPath , 0755 ); err != nil {
338- return err
339- }
340- flags := defaultMountFlags
341- if m .Flags & unix .MS_RDONLY != 0 {
342- flags = flags | unix .MS_RDONLY
343- }
344- cgroupmount := & configs.Mount {
345- Source : "cgroup" ,
346- Device : "cgroup" ,
347- Destination : subsystemPath ,
348- Flags : flags ,
349- Data : filepath .Base (subsystemPath ),
350- }
351- if err := mountNewCgroup (cgroupmount ); err != nil {
352- return err
353- }
354- } else {
355- if err := mountToRootfs (b , rootfs , mountLabel , enableCgroupns ); err != nil {
356- return err
357- }
380+ if cgroups .IsCgroup2UnifiedMode () {
381+ if err := mountCgroupV2 (m , rootfs , mountLabel , enableCgroupns ); err != nil {
382+ return err
358383 }
359- }
360- for _ , mc := range merged {
361- for _ , ss := range strings .Split (mc , "," ) {
362- // symlink(2) is very dumb, it will just shove the path into
363- // the link and doesn't do any checks or relative path
364- // conversion. Also, don't error out if the cgroup already exists.
365- if err := os .Symlink (mc , filepath .Join (rootfs , m .Destination , ss )); err != nil && ! os .IsExist (err ) {
366- return err
367- }
384+ } else {
385+ if err := mountCgroupV1 (m , rootfs , mountLabel , enableCgroupns ); err != nil {
386+ return err
368387 }
369388 }
389+ return nil
370390 if m .Flags & unix .MS_RDONLY != 0 {
371391 // remount cgroup root as readonly
372392 mcgrouproot := & configs.Mount {
0 commit comments