mirror of
https://github.com/opencontainers/runc.git
synced 2026-07-11 06:03:57 +08:00
Merge pull request #5116 from lifubang/backport-1.4-5091
[1.4] Fix runc exec vs go1.26 + older kernel
This commit is contained in:
@@ -25,7 +25,7 @@ jobs:
|
|||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu-24.04, ubuntu-24.04-arm]
|
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.x]
|
||||||
rootless: ["rootless", ""]
|
rootless: ["rootless", ""]
|
||||||
race: ["-race", ""]
|
race: ["-race", ""]
|
||||||
criu: ["", "criu-dev"]
|
criu: ["", "criu-dev"]
|
||||||
@@ -34,11 +34,15 @@ jobs:
|
|||||||
# (need to compile criu) and don't add much value/coverage.
|
# (need to compile criu) and don't add much value/coverage.
|
||||||
- criu: criu-dev
|
- criu: criu-dev
|
||||||
go-version: 1.24.x
|
go-version: 1.24.x
|
||||||
|
- criu: criu-dev
|
||||||
|
go-version: 1.25.x
|
||||||
- criu: criu-dev
|
- criu: criu-dev
|
||||||
rootless: rootless
|
rootless: rootless
|
||||||
# Do race detection only on latest Go.
|
# Do race detection only with latest stable Go version.
|
||||||
- race: -race
|
- race: -race
|
||||||
go-version: 1.24.x
|
go-version: 1.24.x
|
||||||
|
- race: -race
|
||||||
|
go-version: 1.25.x
|
||||||
|
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
|
|
||||||
|
|||||||
@@ -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")
|
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.Args[0] = os.Args[0]
|
||||||
cmd.Stdin = p.Stdin
|
cmd.Stdin = p.Stdin
|
||||||
cmd.Stdout = p.Stdout
|
cmd.Stdout = p.Stdout
|
||||||
|
|||||||
@@ -425,11 +425,14 @@ func (p *setnsProcess) startWithCgroupFD() error {
|
|||||||
defer fd.Close()
|
defer fd.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cmdCopy := cloneCmd(p.cmd)
|
||||||
err = p.startWithCPUAffinity()
|
err = p.startWithCPUAffinity()
|
||||||
if err != nil && p.cmd.SysProcAttr.UseCgroupFD {
|
if err != nil && p.cmd.SysProcAttr.UseCgroupFD {
|
||||||
logrus.Debugf("exec with CLONE_INTO_CGROUP failed: %v; retrying without", err)
|
logrus.Debugf("exec with CLONE_INTO_CGROUP failed: %v; retrying without", err)
|
||||||
// SysProcAttr.CgroupFD is never used when UseCgroupFD is unset.
|
// 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()
|
err = p.startWithCPUAffinity()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user