mirror of
https://github.com/opencontainers/runc.git
synced 2026-02-05 09:46:08 +01:00
Merge pull request #5091 from kolyshkin/go126
Fix runc exec vs go1.26 + older kernel
This commit is contained in:
8
.github/workflows/test.yml
vendored
8
.github/workflows/test.yml
vendored
@@ -25,7 +25,7 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-24.04, ubuntu-24.04-arm]
|
||||
go-version: [1.24.x, 1.25.x]
|
||||
go-version: [1.24.x, 1.25.x, 1.26.0-rc.2]
|
||||
rootless: ["rootless", ""]
|
||||
race: ["-race", ""]
|
||||
criu: ["", "criu-dev"]
|
||||
@@ -34,11 +34,15 @@ jobs:
|
||||
# (need to compile criu) and don't add much value/coverage.
|
||||
- criu: criu-dev
|
||||
go-version: 1.24.x
|
||||
- criu: criu-dev
|
||||
go-version: 1.26.0-rc.2
|
||||
- criu: criu-dev
|
||||
rootless: rootless
|
||||
# Do race detection only on latest Go.
|
||||
# Do race detection only with latest stable Go version.
|
||||
- race: -race
|
||||
go-version: 1.24.x
|
||||
- race: -race
|
||||
go-version: 1.26.0-rc.2
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
|
||||
37
libcontainer/cmd_clone.go
Normal file
37
libcontainer/cmd_clone.go
Normal file
@@ -0,0 +1,37 @@
|
||||
package libcontainer
|
||||
|
||||
import "os/exec"
|
||||
|
||||
// cloneCmd creates a copy of exec.Cmd. It is needed because cmd.Start
|
||||
// must only be used once, and go1.26 actually enforces that (see
|
||||
// https://go-review.googlesource.com/c/go/+/728642). The implementation
|
||||
// is similar to
|
||||
//
|
||||
// cmd = *c
|
||||
// return &cmd
|
||||
//
|
||||
// except it does not copy private fields, or fields populated
|
||||
// after the call to cmd.Start.
|
||||
//
|
||||
// NOTE if Go will add exec.Cmd.Clone, we should switch to it.
|
||||
func cloneCmd(c *exec.Cmd) *exec.Cmd {
|
||||
cmd := &exec.Cmd{
|
||||
Path: c.Path,
|
||||
Args: c.Args,
|
||||
Env: c.Env,
|
||||
Dir: c.Dir,
|
||||
Stdin: c.Stdin,
|
||||
Stdout: c.Stdout,
|
||||
Stderr: c.Stderr,
|
||||
ExtraFiles: c.ExtraFiles,
|
||||
SysProcAttr: c.SysProcAttr,
|
||||
// Don't copy Process, ProcessState, Err since
|
||||
// these fields are populated after the start.
|
||||
|
||||
// Technically, we do not use Cancel or WaitDelay,
|
||||
// but they are here for the sake of completeness.
|
||||
Cancel: c.Cancel,
|
||||
WaitDelay: c.WaitDelay,
|
||||
}
|
||||
return cmd
|
||||
}
|
||||
@@ -528,6 +528,12 @@ func (c *Container) newParentProcess(p *Process) (parentProcess, error) {
|
||||
}
|
||||
|
||||
cmd := exec.Command(exePath, "init")
|
||||
// Theoretically, exec.Command can set cmd.Err. Practically, this
|
||||
// should never happen (Linux, Go <= 1.26, exePath is absolute),
|
||||
// but in the unlikely case it just did, let's fail early.
|
||||
if cmd.Err != nil {
|
||||
return nil, fmt.Errorf("exec.Command: %w", cmd.Err)
|
||||
}
|
||||
cmd.Args[0] = os.Args[0]
|
||||
cmd.Stdin = p.Stdin
|
||||
cmd.Stdout = p.Stdout
|
||||
|
||||
@@ -380,11 +380,14 @@ func (p *setnsProcess) startWithCgroupFD() error {
|
||||
defer fd.Close()
|
||||
}
|
||||
|
||||
cmdCopy := cloneCmd(p.cmd)
|
||||
err = p.startWithCPUAffinity()
|
||||
if err != nil && p.cmd.SysProcAttr.UseCgroupFD {
|
||||
logrus.Debugf("exec with CLONE_INTO_CGROUP failed: %v; retrying without", err)
|
||||
// SysProcAttr.CgroupFD is never used when UseCgroupFD is unset.
|
||||
p.cmd.SysProcAttr.UseCgroupFD = false
|
||||
cmdCopy.SysProcAttr.UseCgroupFD = false
|
||||
// Must not reuse exec.Cmd.
|
||||
p.cmd = cmdCopy
|
||||
err = p.startWithCPUAffinity()
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user