prepareCgroupFD sets up p.cmd to use clone3 with CLONE_INTO_CGROUP to join cgroup early, in p.cmd.Start. Returns an *os.File which must be closed by the caller after p.Cmd.Start return.
()
| 369 | // to join cgroup early, in p.cmd.Start. Returns an *os.File which |
| 370 | // must be closed by the caller after p.Cmd.Start return. |
| 371 | func (p *setnsProcess) prepareCgroupFD() (*os.File, error) { |
| 372 | const openFlags = unix.O_PATH | unix.O_DIRECTORY | unix.O_CLOEXEC |
| 373 | |
| 374 | if !cgroups.IsCgroup2UnifiedMode() { |
| 375 | return nil, nil |
| 376 | } |
| 377 | |
| 378 | base := p.manager.Path("") |
| 379 | if base == "" { // No cgroup to join. |
| 380 | return nil, nil |
| 381 | } |
| 382 | sub := "" |
| 383 | if p.process.SubCgroupPaths != nil { |
| 384 | sub = p.process.SubCgroupPaths[""] |
| 385 | } |
| 386 | cgroup := path.Join(base, sub) |
| 387 | if !strings.HasPrefix(cgroup, base) { |
| 388 | return nil, fmt.Errorf("bad sub cgroup path: %s", sub) |
| 389 | } |
| 390 | |
| 391 | fd, err := cgroups.OpenFile(base, sub, openFlags) |
| 392 | if err == nil { |
| 393 | goto success |
| 394 | } |
| 395 | // Failed to open the configured cgroup. Fall back to container init's cgroup |
| 396 | // unless sub-cgroup is explicitly requested. The fallback logic should be |
| 397 | // the same as in addIntoCgroupV2. |
| 398 | if sub != "" { |
| 399 | goto fail |
| 400 | } |
| 401 | cgroup = p.initProcessCgroupPath() |
| 402 | if cgroup == "" { |
| 403 | goto fail |
| 404 | } |
| 405 | logrus.Debugf("failed to open configured cgroup (%v), will open container init cgroup %q", err, cgroup) |
| 406 | // NOTE: path is not guaranteed to exist because we didn't pause the container. |
| 407 | fd, err = cgroups.OpenFile(cgroup, "", openFlags) |
| 408 | if err != nil { |
| 409 | goto fail |
| 410 | } |
| 411 | |
| 412 | success: |
| 413 | logrus.Debugf("using CLONE_INTO_CGROUP %q", cgroup) |
| 414 | if p.cmd.SysProcAttr == nil { |
| 415 | p.cmd.SysProcAttr = &syscall.SysProcAttr{} |
| 416 | } |
| 417 | p.cmd.SysProcAttr.UseCgroupFD = true |
| 418 | p.cmd.SysProcAttr.CgroupFD = int(fd.Fd()) |
| 419 | |
| 420 | return fd, nil |
| 421 | |
| 422 | fail: |
| 423 | // Ignore cgroup join error for rootless. |
| 424 | if p.rootlessCgroups { |
| 425 | return nil, nil |
| 426 | } |
| 427 | return nil, fmt.Errorf("can't open cgroup: %w", err) |
| 428 | } |
no test coverage detected