Skip to content

Commit

Permalink
fix: oci: enter cgroup before executing crun as non-root
Browse files Browse the repository at this point in the history
When executed from a root-owned cgroup, such as the session scope
resulting from a bare ssh login, crun will fail to create our
requested container cgroup.

If we are running as non-root, create and move into a user-owned
cgroup, so that there's a common user-owned ancestor. This avoids the
`crun` error.

Note that no workaround is needed for `runc` as it is able to create
the requested container cgroup without any issue.

Fixes sylabs/singularity#1538

Signed-off-by: Edita Kizinevic <edita.kizinevic@cern.ch>
  • Loading branch information
dtrudg authored and edytuk committed Jul 24, 2023
1 parent c4a40bd commit 1bb1254
Showing 1 changed file with 37 additions and 0 deletions.
37 changes: 37 additions & 0 deletions internal/pkg/runtime/launcher/oci/launcher_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,11 @@ func (l *Launcher) Exec(ctx context.Context, image string, process string, args
return fmt.Errorf("launcher SysContext must be set for OCI image handling")
}

// If we need to, enter a new cgroup to workaround an issue with crun container cgroup creation (#1538).
if err := l.crunNestCgroup(); err != nil {
return fmt.Errorf("while applying crun cgroup workaround: %w", err)
}

bundleDir, err := os.MkdirTemp("", "oci-bundle")
if err != nil {
return nil
Expand Down Expand Up @@ -440,6 +445,38 @@ func (l *Launcher) getCgroup() (path string, resources *specs.LinuxResources, er
return path, resources, nil
}

// crunNestCgroup will check whether we are using crun, and enter a cgroup if running as a non-root user.
// This is required to satisfy a common user-owned ancestor cgroup requirement on e.g. bare ssh logins.
// See: https://github.com/sylabs/singularity/issues/1538
func (l *Launcher) crunNestCgroup() error {
r, err := runtime()
if err != nil {
return err
}

// No workaround required for runc.
if filepath.Base(r) == "runc" {
return nil
}

// No workaround required if we are run as root.
if os.Getuid() == 0 {
return nil
}

// We are running crun as a user. Enter a cgroup now.
pid := os.Getpid()
sylog.Debugf("crun workaround - adding process %d to sibling cgroup", pid)
manager, err := cgroups.NewManagerWithSpec(&specs.LinuxResources{}, pid, "", l.apptainerConf.SystemdCgroups)
if err != nil {
return fmt.Errorf("couldn't create cgroup manager: %w", err)
}
cgPath, _ := manager.GetCgroupRelPath()
sylog.Debugf("In sibling cgroup: %s", cgPath)

return nil
}

func mergeMap(a map[string]string, b map[string]string) map[string]string {
for k, v := range b {
a[k] = v
Expand Down

0 comments on commit 1bb1254

Please sign in to comment.