Skip to content

Commit a4fcbfb

Browse files
committed
Prepare startContainer() to have more action
Currently startContainer() is used to create and to run a container. In the next patch it will be used to restore a container. Signed-off-by: Andrei Vagin <[email protected]>
1 parent 1a8b0ac commit a4fcbfb

File tree

5 files changed

+37
-113
lines changed

5 files changed

+37
-113
lines changed

Diff for: create.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ command(s) that get executed on start, edit the args parameter of the spec. See
6262
if err != nil {
6363
return err
6464
}
65-
status, err := startContainer(context, spec, true)
65+
status, err := startContainer(context, spec, CT_ACT_CREATE, nil)
6666
if err != nil {
6767
return err
6868
}

Diff for: exec.go

+1
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ func execProcess(context *cli.Context) (int, error) {
135135
consoleSocket: context.String("console-socket"),
136136
detach: detach,
137137
pidFile: context.String("pid-file"),
138+
action: CT_ACT_RUN,
138139
}
139140
return r.run(p)
140141
}

Diff for: restore.go

+7-101
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,8 @@ package main
55
import (
66
"fmt"
77
"os"
8-
"syscall"
98

10-
"github.com/Sirupsen/logrus"
119
"github.com/opencontainers/runc/libcontainer"
12-
"github.com/opencontainers/runc/libcontainer/configs"
13-
"github.com/opencontainers/runc/libcontainer/specconv"
14-
"github.com/opencontainers/runtime-spec/specs-go"
1510
"github.com/urfave/cli"
1611
)
1712

@@ -92,111 +87,22 @@ using the runc checkpoint command.`,
9287
return fmt.Errorf("runc restore requires root")
9388
}
9489

95-
imagePath := context.String("image-path")
96-
id := context.Args().First()
97-
if id == "" {
98-
return errEmptyID
99-
}
100-
if imagePath == "" {
101-
imagePath = getDefaultImagePath(context)
102-
}
103-
bundle := context.String("bundle")
104-
if bundle != "" {
105-
if err := os.Chdir(bundle); err != nil {
106-
return err
107-
}
108-
}
109-
spec, err := loadSpec(specConfig)
90+
spec, err := setupSpec(context)
11091
if err != nil {
11192
return err
11293
}
113-
config, err := specconv.CreateLibcontainerConfig(&specconv.CreateOpts{
114-
CgroupName: id,
115-
UseSystemdCgroup: context.GlobalBool("systemd-cgroup"),
116-
NoPivotRoot: context.Bool("no-pivot"),
117-
Spec: spec,
118-
})
94+
options := criuOptions(context)
95+
status, err := startContainer(context, spec, CT_ACT_RESTORE, options)
11996
if err != nil {
12097
return err
12198
}
122-
status, err := restoreContainer(context, spec, config, imagePath)
123-
if err == nil {
124-
os.Exit(status)
125-
}
126-
return err
99+
// exit with the container's exit status so any external supervisor is
100+
// notified of the exit with the correct exit status.
101+
os.Exit(status)
102+
return nil
127103
},
128104
}
129105

130-
func restoreContainer(context *cli.Context, spec *specs.Spec, config *configs.Config, imagePath string) (int, error) {
131-
var (
132-
rootuid = 0
133-
rootgid = 0
134-
id = context.Args().First()
135-
)
136-
factory, err := loadFactory(context)
137-
if err != nil {
138-
return -1, err
139-
}
140-
container, err := factory.Load(id)
141-
if err != nil {
142-
container, err = factory.Create(id, config)
143-
if err != nil {
144-
return -1, err
145-
}
146-
}
147-
options := criuOptions(context)
148-
149-
status, err := container.Status()
150-
if err != nil {
151-
logrus.Error(err)
152-
}
153-
if status == libcontainer.Running {
154-
fatalf("Container with id %s already running", id)
155-
}
156-
157-
setManageCgroupsMode(context, options)
158-
159-
if err = setEmptyNsMask(context, options); err != nil {
160-
return -1, err
161-
}
162-
163-
// ensure that the container is always removed if we were the process
164-
// that created it.
165-
detach := context.Bool("detach")
166-
if !detach {
167-
defer destroy(container)
168-
}
169-
process := &libcontainer.Process{}
170-
tty, err := setupIO(process, rootuid, rootgid, false, detach, "")
171-
if err != nil {
172-
return -1, err
173-
}
174-
175-
notifySocket := newNotifySocket(context, os.Getenv("NOTIFY_SOCKET"), id)
176-
if notifySocket != nil {
177-
notifySocket.setupSpec(context, spec)
178-
notifySocket.setupSocket()
179-
}
180-
181-
handler := newSignalHandler(!context.Bool("no-subreaper"), notifySocket)
182-
if err := container.Restore(process, options); err != nil {
183-
return -1, err
184-
}
185-
// We don't need to do a tty.recvtty because config.Terminal is always false.
186-
defer tty.Close()
187-
if err := tty.ClosePostStart(); err != nil {
188-
return -1, err
189-
}
190-
if pidFile := context.String("pid-file"); pidFile != "" {
191-
if err := createPidFile(pidFile, process); err != nil {
192-
_ = process.Signal(syscall.SIGKILL)
193-
_, _ = process.Wait()
194-
return -1, err
195-
}
196-
}
197-
return handler.forward(process, tty, detach)
198-
}
199-
200106
func criuOptions(context *cli.Context) *libcontainer.CriuOpts {
201107
imagePath := getCheckpointImagePath(context)
202108
if err := os.MkdirAll(imagePath, 0655); err != nil {

Diff for: run.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ command(s) that get executed on start, edit the args parameter of the spec. See
7373
if err != nil {
7474
return err
7575
}
76-
status, err := startContainer(context, spec, false)
76+
status, err := startContainer(context, spec, CT_ACT_RUN, nil)
7777
if err == nil {
7878
// exit with the container's exit status so any external supervisor is
7979
// notified of the exit with the correct exit status.

Diff for: utils_linux.go

+27-10
Original file line numberDiff line numberDiff line change
@@ -220,8 +220,9 @@ type runner struct {
220220
pidFile string
221221
consoleSocket string
222222
container libcontainer.Container
223-
create bool
223+
action CtAct
224224
notifySocket *notifySocket
225+
criuOpts *libcontainer.CriuOpts
225226
}
226227

227228
func (r *runner) run(config *specs.Process) (int, error) {
@@ -253,12 +254,8 @@ func (r *runner) run(config *specs.Process) (int, error) {
253254
return -1, err
254255
}
255256
var (
256-
detach = r.detach || r.create
257-
startFn = r.container.Start
257+
detach = r.detach || (r.action == CT_ACT_CREATE)
258258
)
259-
if !r.create {
260-
startFn = r.container.Run
261-
}
262259
// Setting up IO is a two stage process. We need to modify process to deal
263260
// with detaching containers, and then we get a tty after the container has
264261
// started.
@@ -269,7 +266,18 @@ func (r *runner) run(config *specs.Process) (int, error) {
269266
return -1, err
270267
}
271268
defer tty.Close()
272-
if err = startFn(process); err != nil {
269+
270+
switch r.action {
271+
case CT_ACT_CREATE:
272+
err = r.container.Start(process)
273+
case CT_ACT_RESTORE:
274+
err = r.container.Restore(process, r.criuOpts)
275+
case CT_ACT_RUN:
276+
err = r.container.Run(process)
277+
default:
278+
panic("Unknown action")
279+
}
280+
if err != nil {
273281
r.destroy()
274282
return -1, err
275283
}
@@ -313,7 +321,7 @@ func (r *runner) terminate(p *libcontainer.Process) {
313321
}
314322

315323
func (r *runner) checkTerminal(config *specs.Process) error {
316-
detach := r.detach || r.create
324+
detach := r.detach || (r.action == CT_ACT_CREATE)
317325
// Check command-line for sanity.
318326
if detach && config.Terminal && r.consoleSocket == "" {
319327
return fmt.Errorf("cannot allocate tty if runc will detach without setting console socket")
@@ -337,7 +345,15 @@ func validateProcessSpec(spec *specs.Process) error {
337345
return nil
338346
}
339347

340-
func startContainer(context *cli.Context, spec *specs.Spec, create bool) (int, error) {
348+
type CtAct uint8
349+
350+
const (
351+
CT_ACT_CREATE CtAct = iota + 1
352+
CT_ACT_RUN
353+
CT_ACT_RESTORE
354+
)
355+
356+
func startContainer(context *cli.Context, spec *specs.Spec, action CtAct, criuOpts *libcontainer.CriuOpts) (int, error) {
341357
id := context.Args().First()
342358
if id == "" {
343359
return -1, errEmptyID
@@ -372,7 +388,8 @@ func startContainer(context *cli.Context, spec *specs.Spec, create bool) (int, e
372388
detach: context.Bool("detach"),
373389
pidFile: context.String("pid-file"),
374390
preserveFDs: context.Int("preserve-fds"),
375-
create: create,
391+
action: action,
392+
criuOpts: criuOpts,
376393
}
377394
return r.run(&spec.Process)
378395
}

0 commit comments

Comments
 (0)