Skip to content

Commit efcd73f

Browse files
committed
Fix signal handling for unit tests
Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
1 parent 60f5df6 commit efcd73f

22 files changed

+125
-88
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ unittest: runctestimage
5555
docker run -e TESTFLAGS -ti --privileged --rm -v $(CURDIR):/go/src/$(PROJECT) $(RUNC_TEST_IMAGE) make localunittest
5656

5757
localunittest: all
58-
go test -tags "$(BUILDTAGS)" ${TESTFLAGS} -v ./...
58+
go test -timeout 3m -tags "$(BUILDTAGS)" ${TESTFLAGS} -v ./...
5959

6060
integration: runctestimage
6161
docker run -e TESTFLAGS -t --privileged --rm -v $(CURDIR):/go/src/$(PROJECT) $(RUNC_TEST_IMAGE) make localintegration

libcontainer/container.go

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,12 @@ type Status int
1717
const (
1818
// Created is the status that denotes the container exists but has not been run yet.
1919
Created Status = iota
20-
2120
// Running is the status that denotes the container exists and is running.
2221
Running
23-
2422
// Pausing is the status that denotes the container exists, it is in the process of being paused.
2523
Pausing
26-
2724
// Paused is the status that denotes the container exists, but all its processes are paused.
2825
Paused
29-
3026
// Stopped is the status that denotes the container does not have a created or running process.
3127
Stopped
3228
)
@@ -127,6 +123,17 @@ type BaseContainer interface {
127123
// Systemerror - System error.
128124
Start(process *Process) (err error)
129125

126+
// StartI immediatly starts the process inside the conatiner. Returns error if process
127+
// fails to start. It does not block waiting for a SIGCONT after start returns but
128+
// sends the signal when the process has completed.
129+
//
130+
// errors:
131+
// ContainerDestroyed - Container no longer exists,
132+
// ConfigInvalid - config is invalid,
133+
// ContainerPaused - Container is paused,
134+
// Systemerror - System error.
135+
StartI(process *Process) (err error)
136+
130137
// Destroys the container after killing all running processes.
131138
//
132139
// Any event registrations are removed before the container is destroyed.

libcontainer/container_linux.go

Lines changed: 39 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ import (
2929

3030
const stdioFdCount = 3
3131

32+
// InitContinueSignal is used to signal the container init process to
33+
// start the users specified process after the container create has finished.
34+
const InitContinueSignal = syscall.SIGCONT
35+
3236
type linuxContainer struct {
3337
id string
3438
root string
@@ -181,8 +185,28 @@ func (c *linuxContainer) Start(process *Process) error {
181185
if err != nil {
182186
return err
183187
}
184-
doInit := status == Stopped
185-
parent, err := c.newParentProcess(process, doInit)
188+
return c.start(process, status == Stopped)
189+
}
190+
191+
func (c *linuxContainer) StartI(process *Process) error {
192+
c.m.Lock()
193+
defer c.m.Unlock()
194+
status, err := c.currentStatus()
195+
if err != nil {
196+
return err
197+
}
198+
isInit := status == Stopped
199+
if err := c.start(process, isInit); err != nil {
200+
return err
201+
}
202+
if isInit {
203+
return process.ops.signal(InitContinueSignal)
204+
}
205+
return nil
206+
}
207+
208+
func (c *linuxContainer) start(process *Process, isInit bool) error {
209+
parent, err := c.newParentProcess(process, isInit)
186210
if err != nil {
187211
return newSystemErrorWithCause(err, "creating new parent process")
188212
}
@@ -198,7 +222,10 @@ func (c *linuxContainer) Start(process *Process) error {
198222
c.state = &runningState{
199223
c: c,
200224
}
201-
if doInit {
225+
if isInit {
226+
c.state = &createdState{
227+
c: c,
228+
}
202229
if err := c.updateState(parent); err != nil {
203230
return err
204231
}
@@ -370,15 +397,16 @@ func (c *linuxContainer) Pause() error {
370397
if err != nil {
371398
return err
372399
}
373-
if status != Running {
374-
return newGenericError(fmt.Errorf("container not running"), ContainerNotRunning)
375-
}
376-
if err := c.cgroupManager.Freeze(configs.Frozen); err != nil {
377-
return err
400+
switch status {
401+
case Running, Created:
402+
if err := c.cgroupManager.Freeze(configs.Frozen); err != nil {
403+
return err
404+
}
405+
return c.state.transition(&pausedState{
406+
c: c,
407+
})
378408
}
379-
return c.state.transition(&pausedState{
380-
c: c,
381-
})
409+
return newGenericError(fmt.Errorf("container not running: %s", status), ContainerNotRunning)
382410
}
383411

384412
func (c *linuxContainer) Resume() error {

libcontainer/factory_linux.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ func (l *LinuxFactory) Type() string {
222222
func (l *LinuxFactory) StartInitialization() (err error) {
223223
// start the signal handler as soon as we can
224224
s := make(chan os.Signal, 1)
225-
signal.Notify(s, syscall.SIGCONT)
225+
signal.Notify(s, InitContinueSignal)
226226
fdStr := os.Getenv("_LIBCONTAINER_INITPIPE")
227227
pipefd, err := strconv.Atoi(fdStr)
228228
if err != nil {

libcontainer/integration/checkpoint_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ func TestCheckpoint(t *testing.T) {
8989
Stdout: &stdout,
9090
}
9191

92-
err = container.Start(&pconfig)
92+
err = container.StartI(&pconfig)
9393
stdinR.Close()
9494
defer stdinW.Close()
9595
if err != nil {

libcontainer/integration/exec_test.go

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ func TestEnter(t *testing.T) {
241241
Stdin: stdinR,
242242
Stdout: &stdout,
243243
}
244-
err = container.Start(&pconfig)
244+
err = container.StartI(&pconfig)
245245
stdinR.Close()
246246
defer stdinW.Close()
247247
ok(t, err)
@@ -259,7 +259,7 @@ func TestEnter(t *testing.T) {
259259
pconfig2.Stdin = stdinR2
260260
pconfig2.Stdout = &stdout2
261261

262-
err = container.Start(&pconfig2)
262+
err = container.StartI(&pconfig2)
263263
stdinR2.Close()
264264
defer stdinW2.Close()
265265
ok(t, err)
@@ -330,7 +330,7 @@ func TestProcessEnv(t *testing.T) {
330330
Stdin: nil,
331331
Stdout: &stdout,
332332
}
333-
err = container.Start(&pconfig)
333+
err = container.StartI(&pconfig)
334334
ok(t, err)
335335

336336
// Wait for process
@@ -378,7 +378,7 @@ func TestProcessCaps(t *testing.T) {
378378
Stdin: nil,
379379
Stdout: &stdout,
380380
}
381-
err = container.Start(&pconfig)
381+
err = container.StartI(&pconfig)
382382
ok(t, err)
383383

384384
// Wait for process
@@ -448,7 +448,7 @@ func TestAdditionalGroups(t *testing.T) {
448448
Stdin: nil,
449449
Stdout: &stdout,
450450
}
451-
err = container.Start(&pconfig)
451+
err = container.StartI(&pconfig)
452452
ok(t, err)
453453

454454
// Wait for process
@@ -508,7 +508,7 @@ func testFreeze(t *testing.T, systemd bool) {
508508
Env: standardEnvironment,
509509
Stdin: stdinR,
510510
}
511-
err = container.Start(pconfig)
511+
err = container.StartI(pconfig)
512512
stdinR.Close()
513513
defer stdinW.Close()
514514
ok(t, err)
@@ -719,7 +719,7 @@ func TestContainerState(t *testing.T) {
719719
Env: standardEnvironment,
720720
Stdin: stdinR,
721721
}
722-
err = container.Start(p)
722+
err = container.StartI(p)
723723
if err != nil {
724724
t.Fatal(err)
725725
}
@@ -772,7 +772,7 @@ func TestPassExtraFiles(t *testing.T) {
772772
Stdin: nil,
773773
Stdout: &stdout,
774774
}
775-
err = container.Start(&process)
775+
err = container.StartI(&process)
776776
if err != nil {
777777
t.Fatal(err)
778778
}
@@ -853,7 +853,7 @@ func TestMountCmds(t *testing.T) {
853853
Args: []string{"sh", "-c", "env"},
854854
Env: standardEnvironment,
855855
}
856-
err = container.Start(&pconfig)
856+
err = container.StartI(&pconfig)
857857
if err != nil {
858858
t.Fatal(err)
859859
}
@@ -902,7 +902,7 @@ func TestSysctl(t *testing.T) {
902902
Stdin: nil,
903903
Stdout: &stdout,
904904
}
905-
err = container.Start(&pconfig)
905+
err = container.StartI(&pconfig)
906906
ok(t, err)
907907

908908
// Wait for process
@@ -1042,7 +1042,7 @@ func TestOomScoreAdj(t *testing.T) {
10421042
Stdin: nil,
10431043
Stdout: &stdout,
10441044
}
1045-
err = container.Start(&pconfig)
1045+
err = container.StartI(&pconfig)
10461046
ok(t, err)
10471047

10481048
// Wait for process
@@ -1114,7 +1114,7 @@ func TestHook(t *testing.T) {
11141114
Stdin: nil,
11151115
Stdout: &stdout,
11161116
}
1117-
err = container.Start(&pconfig)
1117+
err = container.StartI(&pconfig)
11181118
ok(t, err)
11191119

11201120
// Wait for process
@@ -1231,7 +1231,7 @@ func TestRootfsPropagationSlaveMount(t *testing.T) {
12311231
Stdin: stdinR,
12321232
}
12331233

1234-
err = container.Start(pconfig)
1234+
err = container.StartI(pconfig)
12351235
stdinR.Close()
12361236
defer stdinW.Close()
12371237
ok(t, err)
@@ -1260,7 +1260,7 @@ func TestRootfsPropagationSlaveMount(t *testing.T) {
12601260
Stdout: &stdout2,
12611261
}
12621262

1263-
err = container.Start(pconfig2)
1263+
err = container.StartI(pconfig2)
12641264
stdinR2.Close()
12651265
defer stdinW2.Close()
12661266
ok(t, err)
@@ -1348,7 +1348,7 @@ func TestRootfsPropagationSharedMount(t *testing.T) {
13481348
Stdin: stdinR,
13491349
}
13501350

1351-
err = container.Start(pconfig)
1351+
err = container.StartI(pconfig)
13521352
stdinR.Close()
13531353
defer stdinW.Close()
13541354
ok(t, err)
@@ -1380,7 +1380,7 @@ func TestRootfsPropagationSharedMount(t *testing.T) {
13801380
Capabilities: processCaps,
13811381
}
13821382

1383-
err = container.Start(pconfig2)
1383+
err = container.StartI(pconfig2)
13841384
stdinR2.Close()
13851385
defer stdinW2.Close()
13861386
ok(t, err)
@@ -1452,7 +1452,7 @@ func TestInitJoinPID(t *testing.T) {
14521452
Env: standardEnvironment,
14531453
Stdin: stdinR1,
14541454
}
1455-
err = container1.Start(init1)
1455+
err = container1.StartI(init1)
14561456
stdinR1.Close()
14571457
defer stdinW1.Close()
14581458
ok(t, err)
@@ -1462,7 +1462,7 @@ func TestInitJoinPID(t *testing.T) {
14621462
ok(t, err)
14631463
pidns1 := state1.NamespacePaths[configs.NEWPID]
14641464

1465-
// Start a container inside the existing pidns but with different cgroups
1465+
// StartI a container inside the existing pidns but with different cgroups
14661466
config2 := newTemplateConfig(rootfs)
14671467
config2.Namespaces.Add(configs.NEWPID, pidns1)
14681468
config2.Cgroups.Path = "integration/test2"
@@ -1478,7 +1478,7 @@ func TestInitJoinPID(t *testing.T) {
14781478
Env: standardEnvironment,
14791479
Stdin: stdinR2,
14801480
}
1481-
err = container2.Start(init2)
1481+
err = container2.StartI(init2)
14821482
stdinR2.Close()
14831483
defer stdinW2.Close()
14841484
ok(t, err)
@@ -1508,7 +1508,7 @@ func TestInitJoinPID(t *testing.T) {
15081508
Env: standardEnvironment,
15091509
Stdout: buffers.Stdout,
15101510
}
1511-
err = container1.Start(ps)
1511+
err = container1.StartI(ps)
15121512
ok(t, err)
15131513
waitProcess(ps, t)
15141514

@@ -1557,7 +1557,7 @@ func TestInitJoinNetworkAndUser(t *testing.T) {
15571557
Env: standardEnvironment,
15581558
Stdin: stdinR1,
15591559
}
1560-
err = container1.Start(init1)
1560+
err = container1.StartI(init1)
15611561
stdinR1.Close()
15621562
defer stdinW1.Close()
15631563
ok(t, err)
@@ -1568,7 +1568,7 @@ func TestInitJoinNetworkAndUser(t *testing.T) {
15681568
netns1 := state1.NamespacePaths[configs.NEWNET]
15691569
userns1 := state1.NamespacePaths[configs.NEWUSER]
15701570

1571-
// Start a container inside the existing pidns but with different cgroups
1571+
// StartI a container inside the existing pidns but with different cgroups
15721572
rootfs2, err := newRootfs()
15731573
ok(t, err)
15741574
defer remove(rootfs2)
@@ -1591,7 +1591,7 @@ func TestInitJoinNetworkAndUser(t *testing.T) {
15911591
Env: standardEnvironment,
15921592
Stdin: stdinR2,
15931593
}
1594-
err = container2.Start(init2)
1594+
err = container2.StartI(init2)
15951595
stdinR2.Close()
15961596
defer stdinW2.Close()
15971597
ok(t, err)

0 commit comments

Comments
 (0)