(m mountEntry, c *mountConfig)
| 397 | } |
| 398 | |
| 399 | func mountCgroupV2(m mountEntry, c *mountConfig) error { |
| 400 | err := utils.WithProcfdFile(m.dstFile, func(dstFd string) error { |
| 401 | return mountViaFds(m.Source, nil, m.Destination, dstFd, "cgroup2", uintptr(m.Flags), m.Data) |
| 402 | }) |
| 403 | if err == nil || (!errors.Is(err, unix.EPERM) && !errors.Is(err, unix.EBUSY)) { |
| 404 | return err |
| 405 | } |
| 406 | |
| 407 | // When we are in UserNS but CgroupNS is not unshared, we cannot mount |
| 408 | // cgroup2 (#2158), so fall back to bind mount. |
| 409 | bindM := &configs.Mount{ |
| 410 | Device: "bind", |
| 411 | Source: fs2.UnifiedMountpoint, |
| 412 | Destination: m.Destination, |
| 413 | Flags: unix.MS_BIND | m.Flags, |
| 414 | PropagationFlags: m.PropagationFlags, |
| 415 | } |
| 416 | if c.cgroupns && c.cgroup2Path != "" { |
| 417 | // Emulate cgroupns by bind-mounting the container cgroup path |
| 418 | // rather than the whole /sys/fs/cgroup. |
| 419 | bindM.Source = c.cgroup2Path |
| 420 | } |
| 421 | // mountToRootfs() handles remounting for MS_RDONLY. |
| 422 | err = mountToRootfs(c, mountEntry{Mount: bindM}) |
| 423 | if c.rootlessCgroups && errors.Is(err, unix.ENOENT) { |
| 424 | // ENOENT (for `src = c.cgroup2Path`) happens when rootless runc is being executed |
| 425 | // outside the userns+mountns. |
| 426 | // |
| 427 | // Mask `/sys/fs/cgroup` to ensure it is read-only, even when `/sys` is mounted |
| 428 | // with `rbind,ro` (`runc spec --rootless` produces `rbind,ro` for `/sys`). |
| 429 | err = utils.WithProcfdFile(m.dstFile, func(procfd string) error { |
| 430 | return maskDir(procfd, c.label) |
| 431 | }) |
| 432 | } |
| 433 | return err |
| 434 | } |
| 435 | |
| 436 | func doTmpfsCopyUp(m mountEntry, mountLabel string) (Err error) { |
| 437 | // Set up a scratch dir for the tmpfs on the host. |
no test coverage detected
searching dependent graphs…