diff --git a/Makefile b/Makefile index c1bbafaa..06b116d9 100644 --- a/Makefile +++ b/Makefile @@ -55,7 +55,7 @@ unittest: runctestimage docker run -e TESTFLAGS -ti --privileged --rm -v $(CURDIR):/go/src/$(PROJECT) $(RUNC_TEST_IMAGE) make localunittest localunittest: all - go test -tags "$(BUILDTAGS)" ${TESTFLAGS} -v ./... + go test -timeout 3m -tags "$(BUILDTAGS)" ${TESTFLAGS} -v ./... integration: runctestimage docker run -e TESTFLAGS -t --privileged --rm -v $(CURDIR):/go/src/$(PROJECT) $(RUNC_TEST_IMAGE) make localintegration diff --git a/libcontainer/container.go b/libcontainer/container.go index 5e081da5..7e89422a 100644 --- a/libcontainer/container.go +++ b/libcontainer/container.go @@ -17,16 +17,12 @@ type Status int const ( // Created is the status that denotes the container exists but has not been run yet. Created Status = iota - // Running is the status that denotes the container exists and is running. Running - // Pausing is the status that denotes the container exists, it is in the process of being paused. Pausing - // Paused is the status that denotes the container exists, but all its processes are paused. Paused - // Stopped is the status that denotes the container does not have a created or running process. Stopped ) @@ -127,6 +123,17 @@ type BaseContainer interface { // Systemerror - System error. Start(process *Process) (err error) + // StartI immediatly starts the process inside the conatiner. Returns error if process + // fails to start. It does not block waiting for a SIGCONT after start returns but + // sends the signal when the process has completed. + // + // errors: + // ContainerDestroyed - Container no longer exists, + // ConfigInvalid - config is invalid, + // ContainerPaused - Container is paused, + // Systemerror - System error. + StartI(process *Process) (err error) + // Destroys the container after killing all running processes. // // Any event registrations are removed before the container is destroyed. diff --git a/libcontainer/container_linux.go b/libcontainer/container_linux.go index 81139c1a..a0413069 100644 --- a/libcontainer/container_linux.go +++ b/libcontainer/container_linux.go @@ -29,6 +29,10 @@ import ( const stdioFdCount = 3 +// InitContinueSignal is used to signal the container init process to +// start the users specified process after the container create has finished. +const InitContinueSignal = syscall.SIGCONT + type linuxContainer struct { id string root string @@ -181,8 +185,28 @@ func (c *linuxContainer) Start(process *Process) error { if err != nil { return err } - doInit := status == Stopped - parent, err := c.newParentProcess(process, doInit) + return c.start(process, status == Stopped) +} + +func (c *linuxContainer) StartI(process *Process) error { + c.m.Lock() + defer c.m.Unlock() + status, err := c.currentStatus() + if err != nil { + return err + } + isInit := status == Stopped + if err := c.start(process, isInit); err != nil { + return err + } + if isInit { + return process.ops.signal(InitContinueSignal) + } + return nil +} + +func (c *linuxContainer) start(process *Process, isInit bool) error { + parent, err := c.newParentProcess(process, isInit) if err != nil { return newSystemErrorWithCause(err, "creating new parent process") } @@ -198,7 +222,10 @@ func (c *linuxContainer) Start(process *Process) error { c.state = &runningState{ c: c, } - if doInit { + if isInit { + c.state = &createdState{ + c: c, + } if err := c.updateState(parent); err != nil { return err } @@ -370,15 +397,16 @@ func (c *linuxContainer) Pause() error { if err != nil { return err } - if status != Running { - return newGenericError(fmt.Errorf("container not running"), ContainerNotRunning) + switch status { + case Running, Created: + if err := c.cgroupManager.Freeze(configs.Frozen); err != nil { + return err + } + return c.state.transition(&pausedState{ + c: c, + }) } - if err := c.cgroupManager.Freeze(configs.Frozen); err != nil { - return err - } - return c.state.transition(&pausedState{ - c: c, - }) + return newGenericError(fmt.Errorf("container not running: %s", status), ContainerNotRunning) } func (c *linuxContainer) Resume() error { diff --git a/libcontainer/factory_linux.go b/libcontainer/factory_linux.go index cf779509..1ac06fb0 100644 --- a/libcontainer/factory_linux.go +++ b/libcontainer/factory_linux.go @@ -222,7 +222,7 @@ func (l *LinuxFactory) Type() string { func (l *LinuxFactory) StartInitialization() (err error) { // start the signal handler as soon as we can s := make(chan os.Signal, 1) - signal.Notify(s, syscall.SIGCONT) + signal.Notify(s, InitContinueSignal) fdStr := os.Getenv("_LIBCONTAINER_INITPIPE") pipefd, err := strconv.Atoi(fdStr) if err != nil { diff --git a/libcontainer/integration/checkpoint_test.go b/libcontainer/integration/checkpoint_test.go index a71c172a..66867b0d 100644 --- a/libcontainer/integration/checkpoint_test.go +++ b/libcontainer/integration/checkpoint_test.go @@ -89,7 +89,7 @@ func TestCheckpoint(t *testing.T) { Stdout: &stdout, } - err = container.Start(&pconfig) + err = container.StartI(&pconfig) stdinR.Close() defer stdinW.Close() if err != nil { diff --git a/libcontainer/integration/exec_test.go b/libcontainer/integration/exec_test.go index 45c64128..4945048d 100644 --- a/libcontainer/integration/exec_test.go +++ b/libcontainer/integration/exec_test.go @@ -241,7 +241,7 @@ func TestEnter(t *testing.T) { Stdin: stdinR, Stdout: &stdout, } - err = container.Start(&pconfig) + err = container.StartI(&pconfig) stdinR.Close() defer stdinW.Close() ok(t, err) @@ -259,7 +259,7 @@ func TestEnter(t *testing.T) { pconfig2.Stdin = stdinR2 pconfig2.Stdout = &stdout2 - err = container.Start(&pconfig2) + err = container.StartI(&pconfig2) stdinR2.Close() defer stdinW2.Close() ok(t, err) @@ -330,7 +330,7 @@ func TestProcessEnv(t *testing.T) { Stdin: nil, Stdout: &stdout, } - err = container.Start(&pconfig) + err = container.StartI(&pconfig) ok(t, err) // Wait for process @@ -378,7 +378,7 @@ func TestProcessCaps(t *testing.T) { Stdin: nil, Stdout: &stdout, } - err = container.Start(&pconfig) + err = container.StartI(&pconfig) ok(t, err) // Wait for process @@ -448,7 +448,7 @@ func TestAdditionalGroups(t *testing.T) { Stdin: nil, Stdout: &stdout, } - err = container.Start(&pconfig) + err = container.StartI(&pconfig) ok(t, err) // Wait for process @@ -508,7 +508,7 @@ func testFreeze(t *testing.T, systemd bool) { Env: standardEnvironment, Stdin: stdinR, } - err = container.Start(pconfig) + err = container.StartI(pconfig) stdinR.Close() defer stdinW.Close() ok(t, err) @@ -719,7 +719,7 @@ func TestContainerState(t *testing.T) { Env: standardEnvironment, Stdin: stdinR, } - err = container.Start(p) + err = container.StartI(p) if err != nil { t.Fatal(err) } @@ -772,7 +772,7 @@ func TestPassExtraFiles(t *testing.T) { Stdin: nil, Stdout: &stdout, } - err = container.Start(&process) + err = container.StartI(&process) if err != nil { t.Fatal(err) } @@ -853,7 +853,7 @@ func TestMountCmds(t *testing.T) { Args: []string{"sh", "-c", "env"}, Env: standardEnvironment, } - err = container.Start(&pconfig) + err = container.StartI(&pconfig) if err != nil { t.Fatal(err) } @@ -902,7 +902,7 @@ func TestSysctl(t *testing.T) { Stdin: nil, Stdout: &stdout, } - err = container.Start(&pconfig) + err = container.StartI(&pconfig) ok(t, err) // Wait for process @@ -1042,7 +1042,7 @@ func TestOomScoreAdj(t *testing.T) { Stdin: nil, Stdout: &stdout, } - err = container.Start(&pconfig) + err = container.StartI(&pconfig) ok(t, err) // Wait for process @@ -1114,7 +1114,7 @@ func TestHook(t *testing.T) { Stdin: nil, Stdout: &stdout, } - err = container.Start(&pconfig) + err = container.StartI(&pconfig) ok(t, err) // Wait for process @@ -1231,7 +1231,7 @@ func TestRootfsPropagationSlaveMount(t *testing.T) { Stdin: stdinR, } - err = container.Start(pconfig) + err = container.StartI(pconfig) stdinR.Close() defer stdinW.Close() ok(t, err) @@ -1260,7 +1260,7 @@ func TestRootfsPropagationSlaveMount(t *testing.T) { Stdout: &stdout2, } - err = container.Start(pconfig2) + err = container.StartI(pconfig2) stdinR2.Close() defer stdinW2.Close() ok(t, err) @@ -1348,7 +1348,7 @@ func TestRootfsPropagationSharedMount(t *testing.T) { Stdin: stdinR, } - err = container.Start(pconfig) + err = container.StartI(pconfig) stdinR.Close() defer stdinW.Close() ok(t, err) @@ -1380,7 +1380,7 @@ func TestRootfsPropagationSharedMount(t *testing.T) { Capabilities: processCaps, } - err = container.Start(pconfig2) + err = container.StartI(pconfig2) stdinR2.Close() defer stdinW2.Close() ok(t, err) @@ -1452,7 +1452,7 @@ func TestInitJoinPID(t *testing.T) { Env: standardEnvironment, Stdin: stdinR1, } - err = container1.Start(init1) + err = container1.StartI(init1) stdinR1.Close() defer stdinW1.Close() ok(t, err) @@ -1462,7 +1462,7 @@ func TestInitJoinPID(t *testing.T) { ok(t, err) pidns1 := state1.NamespacePaths[configs.NEWPID] - // Start a container inside the existing pidns but with different cgroups + // StartI a container inside the existing pidns but with different cgroups config2 := newTemplateConfig(rootfs) config2.Namespaces.Add(configs.NEWPID, pidns1) config2.Cgroups.Path = "integration/test2" @@ -1478,7 +1478,7 @@ func TestInitJoinPID(t *testing.T) { Env: standardEnvironment, Stdin: stdinR2, } - err = container2.Start(init2) + err = container2.StartI(init2) stdinR2.Close() defer stdinW2.Close() ok(t, err) @@ -1508,7 +1508,7 @@ func TestInitJoinPID(t *testing.T) { Env: standardEnvironment, Stdout: buffers.Stdout, } - err = container1.Start(ps) + err = container1.StartI(ps) ok(t, err) waitProcess(ps, t) @@ -1557,7 +1557,7 @@ func TestInitJoinNetworkAndUser(t *testing.T) { Env: standardEnvironment, Stdin: stdinR1, } - err = container1.Start(init1) + err = container1.StartI(init1) stdinR1.Close() defer stdinW1.Close() ok(t, err) @@ -1568,7 +1568,7 @@ func TestInitJoinNetworkAndUser(t *testing.T) { netns1 := state1.NamespacePaths[configs.NEWNET] userns1 := state1.NamespacePaths[configs.NEWUSER] - // Start a container inside the existing pidns but with different cgroups + // StartI a container inside the existing pidns but with different cgroups rootfs2, err := newRootfs() ok(t, err) defer remove(rootfs2) @@ -1591,7 +1591,7 @@ func TestInitJoinNetworkAndUser(t *testing.T) { Env: standardEnvironment, Stdin: stdinR2, } - err = container2.Start(init2) + err = container2.StartI(init2) stdinR2.Close() defer stdinW2.Close() ok(t, err) diff --git a/libcontainer/integration/execin_test.go b/libcontainer/integration/execin_test.go index cd101cc2..b3211baa 100644 --- a/libcontainer/integration/execin_test.go +++ b/libcontainer/integration/execin_test.go @@ -36,7 +36,7 @@ func TestExecIn(t *testing.T) { Env: standardEnvironment, Stdin: stdinR, } - err = container.Start(process) + err = container.StartI(process) stdinR.Close() defer stdinW.Close() ok(t, err) @@ -51,7 +51,7 @@ func TestExecIn(t *testing.T) { Stderr: buffers.Stderr, } - err = container.Start(ps) + err = container.StartI(ps) ok(t, err) waitProcess(ps, t) stdinW.Close() @@ -103,7 +103,7 @@ func testExecInRlimit(t *testing.T, userns bool) { Env: standardEnvironment, Stdin: stdinR, } - err = container.Start(process) + err = container.StartI(process) stdinR.Close() defer stdinW.Close() ok(t, err) @@ -121,7 +121,7 @@ func testExecInRlimit(t *testing.T, userns bool) { {Type: syscall.RLIMIT_NOFILE, Hard: 1026, Soft: 1026}, }, } - err = container.Start(ps) + err = container.StartI(ps) ok(t, err) waitProcess(ps, t) @@ -155,7 +155,7 @@ func TestExecInError(t *testing.T) { Env: standardEnvironment, Stdin: stdinR, } - err = container.Start(process) + err = container.StartI(process) stdinR.Close() defer func() { stdinW.Close() @@ -173,7 +173,7 @@ func TestExecInError(t *testing.T) { Env: standardEnvironment, Stdout: &out, } - err = container.Start(unexistent) + err = container.StartI(unexistent) if err == nil { t.Fatal("Should be an error") } @@ -207,7 +207,7 @@ func TestExecInTTY(t *testing.T) { Env: standardEnvironment, Stdin: stdinR, } - err = container.Start(process) + err = container.StartI(process) stdinR.Close() defer stdinW.Close() ok(t, err) @@ -225,7 +225,7 @@ func TestExecInTTY(t *testing.T) { close(copy) }() ok(t, err) - err = container.Start(ps) + err = container.StartI(ps) ok(t, err) select { case <-time.After(5 * time.Second): @@ -264,7 +264,7 @@ func TestExecInEnvironment(t *testing.T) { Env: standardEnvironment, Stdin: stdinR, } - err = container.Start(process) + err = container.StartI(process) stdinR.Close() defer stdinW.Close() ok(t, err) @@ -283,7 +283,7 @@ func TestExecInEnvironment(t *testing.T) { Stdout: buffers.Stdout, Stderr: buffers.Stderr, } - err = container.Start(process2) + err = container.StartI(process2) ok(t, err) waitProcess(process2, t) @@ -328,7 +328,7 @@ func TestExecinPassExtraFiles(t *testing.T) { Env: standardEnvironment, Stdin: stdinR, } - err = container.Start(process) + err = container.StartI(process) stdinR.Close() defer stdinW.Close() if err != nil { @@ -346,7 +346,7 @@ func TestExecinPassExtraFiles(t *testing.T) { Stdin: nil, Stdout: &stdout, } - err = container.Start(inprocess) + err = container.StartI(inprocess) if err != nil { t.Fatal(err) } @@ -401,7 +401,7 @@ func TestExecInOomScoreAdj(t *testing.T) { Env: standardEnvironment, Stdin: stdinR, } - err = container.Start(process) + err = container.StartI(process) stdinR.Close() defer stdinW.Close() ok(t, err) @@ -415,7 +415,7 @@ func TestExecInOomScoreAdj(t *testing.T) { Stdout: buffers.Stdout, Stderr: buffers.Stderr, } - err = container.Start(ps) + err = container.StartI(ps) ok(t, err) waitProcess(ps, t) @@ -456,7 +456,7 @@ func TestExecInUserns(t *testing.T) { Env: standardEnvironment, Stdin: stdinR, } - err = container.Start(process) + err = container.StartI(process) stdinR.Close() defer stdinW.Close() ok(t, err) @@ -476,7 +476,7 @@ func TestExecInUserns(t *testing.T) { Stdout: buffers.Stdout, Stderr: os.Stderr, } - err = container.Start(process2) + err = container.StartI(process2) ok(t, err) waitProcess(process2, t) stdinW.Close() diff --git a/libcontainer/integration/seccomp_test.go b/libcontainer/integration/seccomp_test.go index 820773e6..4049033a 100644 --- a/libcontainer/integration/seccomp_test.go +++ b/libcontainer/integration/seccomp_test.go @@ -50,7 +50,7 @@ func TestSeccompDenyGetcwd(t *testing.T) { Stderr: buffers.Stderr, } - err = container.Start(pwd) + err = container.StartI(pwd) if err != nil { t.Fatal(err) } @@ -125,7 +125,7 @@ func TestSeccompPermitWriteConditional(t *testing.T) { Stderr: buffers.Stderr, } - err = container.Start(dmesg) + err = container.StartI(dmesg) if err != nil { t.Fatal(err) } @@ -186,7 +186,7 @@ func TestSeccompDenyWriteConditional(t *testing.T) { Stderr: buffers.Stderr, } - err = container.Start(dmesg) + err = container.StartI(dmesg) if err != nil { t.Fatal(err) } diff --git a/libcontainer/integration/template_test.go b/libcontainer/integration/template_test.go index f54a849a..2345dd35 100644 --- a/libcontainer/integration/template_test.go +++ b/libcontainer/integration/template_test.go @@ -89,12 +89,14 @@ func newTemplateConfig(rootfs string) *configs.Config { Data: "mode=1777,size=65536k", Flags: defaultMountFlags, }, - { - Source: "mqueue", - Destination: "/dev/mqueue", - Device: "mqueue", - Flags: defaultMountFlags, - }, + /* + { + Source: "mqueue", + Destination: "/dev/mqueue", + Device: "mqueue", + Flags: defaultMountFlags, + }, + */ { Source: "sysfs", Destination: "/sys", diff --git a/libcontainer/integration/utils_test.go b/libcontainer/integration/utils_test.go index e77587f6..b2f884c6 100644 --- a/libcontainer/integration/utils_test.go +++ b/libcontainer/integration/utils_test.go @@ -123,13 +123,10 @@ func runContainer(config *configs.Config, console string, args ...string) (buffe Stderr: buffers.Stderr, } - err = container.Start(process) + err = container.StartI(process) if err != nil { return buffers, -1, err } - if err := container.Signal(syscall.SIGCONT); err != nil { - return buffers, -1, err - } ps, err := process.Wait() if err != nil { return buffers, -1, err diff --git a/libcontainer/process_linux.go b/libcontainer/process_linux.go index 3a34b130..fc0c4fd2 100644 --- a/libcontainer/process_linux.go +++ b/libcontainer/process_linux.go @@ -221,6 +221,7 @@ func (p *initProcess) execSetns() error { return err } p.cmd.Process = process + p.process.ops = p return nil } diff --git a/libcontainer/state_linux.go b/libcontainer/state_linux.go index 790af081..b9860074 100644 --- a/libcontainer/state_linux.go +++ b/libcontainer/state_linux.go @@ -6,6 +6,7 @@ import ( "fmt" "os" "path/filepath" + "syscall" "github.com/Sirupsen/logrus" "github.com/opencontainers/runc/libcontainer/configs" @@ -149,8 +150,9 @@ func (i *createdState) status() Status { func (i *createdState) transition(s containerState) error { switch s.(type) { - case *runningState: + case *runningState, *pausedState, *stoppedState: i.c.state = s + return nil case *createdState: return nil } @@ -158,6 +160,7 @@ func (i *createdState) transition(s containerState) error { } func (i *createdState) destroy() error { + i.c.initProcess.signal(syscall.SIGKILL) return destroy(i.c) } diff --git a/libcontainer/state_linux_test.go b/libcontainer/state_linux_test.go index 417d9c22..cadacbe0 100644 --- a/libcontainer/state_linux_test.go +++ b/libcontainer/state_linux_test.go @@ -6,10 +6,11 @@ import "testing" func TestStateStatus(t *testing.T) { states := map[containerState]Status{ - &stoppedState{}: Destroyed, + &stoppedState{}: Stopped, &runningState{}: Running, &restoredState{}: Running, &pausedState{}: Paused, + &createdState{}: Created, } for s, status := range states { if s.status() != status { diff --git a/run.go b/run.go index 81832b2d..7b892035 100644 --- a/run.go +++ b/run.go @@ -40,7 +40,7 @@ command(s) that get executed on start, edit the args parameter of the spec. See Usage: "specify the pty slave path for use with the container", }, cli.BoolFlag{ - Name: "detach,d", + Name: "detach, d", Usage: "detach from the container's process", }, cli.StringFlag{ diff --git a/start.go b/start.go index 1ee571f3..c440e292 100644 --- a/start.go +++ b/start.go @@ -1,8 +1,6 @@ package main import ( - "syscall" - "github.com/codegangsta/cli" "github.com/opencontainers/runc/libcontainer" ) @@ -26,7 +24,7 @@ your host.`, fatal(err) } if status == libcontainer.Created { - if err := container.Signal(syscall.SIGCONT); err != nil { + if err := container.Signal(libcontainer.InitContinueSignal); err != nil { fatal(err) } } diff --git a/tests/integration/delete.bats b/tests/integration/delete.bats index 8e0e2948..89a60ebc 100644 --- a/tests/integration/delete.bats +++ b/tests/integration/delete.bats @@ -23,7 +23,7 @@ function teardown() { runc kill test_busybox KILL # wait for busybox to be in the destroyed state - retry 10 1 eval "__runc state test_busybox | grep -q 'destroyed'" + retry 10 1 eval "__runc state test_busybox | grep -q 'stopped'" # delete test_busybox runc delete test_busybox diff --git a/tests/integration/exec.bats b/tests/integration/exec.bats index a7fa9c54..4754da27 100644 --- a/tests/integration/exec.bats +++ b/tests/integration/exec.bats @@ -12,8 +12,8 @@ function teardown() { } @test "runc exec" { - # start busybox detached - runc start -d --console /dev/pts/ptmx test_busybox + # run busybox detached + runc run -d --console /dev/pts/ptmx test_busybox [ "$status" -eq 0 ] wait_for_container 15 1 test_busybox @@ -25,8 +25,8 @@ function teardown() { } @test "runc exec --pid-file" { - # start busybox detached - runc start -d --console /dev/pts/ptmx test_busybox + # run busybox detached + runc run -d --console /dev/pts/ptmx test_busybox [ "$status" -eq 0 ] wait_for_container 15 1 test_busybox diff --git a/tests/integration/helpers.bash b/tests/integration/helpers.bash index c2678890..e61ad301 100644 --- a/tests/integration/helpers.bash +++ b/tests/integration/helpers.bash @@ -153,7 +153,7 @@ function teardown_running_container() { runc list if [[ "${output}" == *"$1"* ]]; then runc kill $1 KILL - retry 10 1 eval "__runc state '$1' | grep -q 'destroyed'" + retry 10 1 eval "__runc state '$1' | grep -q 'stopped'" runc delete $1 fi } @@ -162,7 +162,7 @@ function teardown_running_container_inroot() { ROOT=$2 runc list if [[ "${output}" == *"$1"* ]]; then ROOT=$2 runc kill $1 KILL - retry 10 1 eval "ROOT='$2' __runc state '$1' | grep -q 'destroyed'" + retry 10 1 eval "ROOT='$2' __runc state '$1' | grep -q 'stopped'" ROOT=$2 runc delete $1 fi } diff --git a/tests/integration/kill.bats b/tests/integration/kill.bats index e688db00..e0d89e94 100644 --- a/tests/integration/kill.bats +++ b/tests/integration/kill.bats @@ -26,7 +26,7 @@ function teardown() { runc kill test_busybox KILL [ "$status" -eq 0 ] - retry 10 1 eval "__runc state test_busybox | grep -q 'destroyed'" + retry 10 1 eval "__runc state test_busybox | grep -q 'stopped'" runc delete test_busybox [ "$status" -eq 0 ] diff --git a/tests/integration/root.bats b/tests/integration/root.bats index f4a7ff0d..a2cb377c 100644 --- a/tests/integration/root.bats +++ b/tests/integration/root.bats @@ -42,13 +42,13 @@ function teardown() { runc kill test_busybox KILL [ "$status" -eq 0 ] - retry 10 1 eval "__runc state test_busybox | grep -q 'destroyed'" + retry 10 1 eval "__runc state test_busybox | grep -q 'stopped'" runc delete test_busybox [ "$status" -eq 0 ] ROOT=$HELLO_BUNDLE runc kill test_dotbox KILL [ "$status" -eq 0 ] - retry 10 1 eval "ROOT='$HELLO_BUNDLE' __runc state test_dotbox | grep -q 'destroyed'" + retry 10 1 eval "ROOT='$HELLO_BUNDLE' __runc state test_dotbox | grep -q 'stopped'" ROOT=$HELLO_BUNDLE runc delete test_dotbox [ "$status" -eq 0 ] } diff --git a/tests/integration/state.bats b/tests/integration/state.bats index 582986d3..0073a2a3 100644 --- a/tests/integration/state.bats +++ b/tests/integration/state.bats @@ -40,7 +40,7 @@ function teardown() { runc kill test_busybox KILL # wait for busybox to be in the destroyed state - retry 10 1 eval "__runc state test_busybox | grep -q 'destroyed'" + retry 10 1 eval "__runc state test_busybox | grep -q 'stopped'" # delete test_busybox runc delete test_busybox diff --git a/utils_linux.go b/utils_linux.go index 810d5d26..09302049 100644 --- a/utils_linux.go +++ b/utils_linux.go @@ -247,7 +247,7 @@ func (r *runner) run(config *specs.Process) (int, error) { } } if !r.create { - if err := process.Signal(syscall.SIGCONT); err != nil { + if err := process.Signal(libcontainer.InitContinueSignal); err != nil { r.terminate(process) r.destroy() tty.Close()