Skip to content

Commit 5a06eb6

Browse files
committed
Ensure we can always terminate the parent process on error
As we all know, we should terminate the parent process if there is an error when starting the container process, but these terminate function are called in many places, for example: `initProcess`, `setnsProcess`, and `Container`, if we forget this terminate call for some errors, it will let the container in unknown state, so we should change to call it in some final places. Signed-off-by: lifubang <[email protected]>
1 parent 1590491 commit 5a06eb6

File tree

3 files changed

+44
-22
lines changed

3 files changed

+44
-22
lines changed

libcontainer/container_linux.go

Lines changed: 43 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -201,18 +201,30 @@ func (c *Container) Set(config configs.Config) error {
201201

202202
// Start starts a process inside the container. Returns error if process fails
203203
// to start. You can track process lifecycle with passed Process structure.
204-
func (c *Container) Start(process *Process) error {
204+
func (c *Container) Start(process *Process) (retErr error) {
205205
c.m.Lock()
206206
defer c.m.Unlock()
207+
defer func() {
208+
if retErr != nil {
209+
c.terminate(process)
210+
}
211+
}()
207212
return c.start(process)
208213
}
209214

210215
// Run immediately starts the process inside the container. Returns an error if
211216
// the process fails to start. It does not block waiting for the exec fifo
212217
// after start returns but opens the fifo after start returns.
213-
func (c *Container) Run(process *Process) error {
218+
func (c *Container) Run(process *Process) (retErr error) {
214219
c.m.Lock()
215220
defer c.m.Unlock()
221+
222+
defer func() {
223+
if retErr != nil {
224+
c.terminate(process)
225+
}
226+
}()
227+
216228
if err := c.start(process); err != nil {
217229
return err
218230
}
@@ -229,6 +241,34 @@ func (c *Container) Exec() error {
229241
return c.exec()
230242
}
231243

244+
// terminate is to kill the container's init/exec process when got failure.
245+
func (c *Container) terminate(process *Process) {
246+
if process.ops == nil {
247+
return
248+
}
249+
if process.Init {
250+
if err := ignoreTerminateErrors(process.ops.terminate()); err != nil {
251+
logrus.WithError(err).Warn("unable to terminate initProcess")
252+
}
253+
// If we haven't saved container's state yet, we need to destroy the
254+
// cgroup & intelRdt manager manually.
255+
if _, err := os.Stat(filepath.Join(c.stateDir, stateFilename)); os.IsNotExist(err) {
256+
if err := c.cgroupManager.Destroy(); err != nil {
257+
logrus.WithError(err).Warn("unable to destroy cgroupManager")
258+
}
259+
if c.intelRdtManager != nil {
260+
if err := c.intelRdtManager.Destroy(); err != nil {
261+
logrus.WithError(err).Warn("unable to destroy intelRdtManager")
262+
}
263+
}
264+
}
265+
return
266+
}
267+
if err := ignoreTerminateErrors(process.ops.terminate()); err != nil {
268+
logrus.WithError(err).Warn("unable to terminate setnsProcess")
269+
}
270+
}
271+
232272
func (c *Container) exec() error {
233273
path := filepath.Join(c.stateDir, execFifoFilename)
234274
pid := c.initProcess.pid()
@@ -359,12 +399,7 @@ func (c *Container) start(process *Process) (retErr error) {
359399
return err
360400
}
361401

362-
if err := c.config.Hooks.Run(configs.Poststart, s); err != nil {
363-
if err := ignoreTerminateErrors(parent.terminate()); err != nil {
364-
logrus.Warn(fmt.Errorf("error running poststart hook: %w", err))
365-
}
366-
return err
367-
}
402+
return c.config.Hooks.Run(configs.Poststart, s)
368403
}
369404
}
370405
return nil

libcontainer/process.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
var errInvalidProcess = errors.New("invalid process")
1313

1414
type processOperations interface {
15+
terminate() error
1516
wait() (*os.ProcessState, error)
1617
signal(sig os.Signal) error
1718
pid() int

libcontainer/process_linux.go

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -151,10 +151,6 @@ func (p *setnsProcess) start() (retErr error) {
151151
if werr != nil {
152152
logrus.WithError(werr).Warn()
153153
}
154-
err := ignoreTerminateErrors(p.terminate())
155-
if err != nil {
156-
logrus.WithError(err).Warn("unable to terminate setnsProcess")
157-
}
158154
}
159155
}()
160156

@@ -563,16 +559,6 @@ func (p *initProcess) start() (retErr error) {
563559
if werr != nil {
564560
logrus.WithError(werr).Warn()
565561
}
566-
567-
// Terminate the process to ensure we can remove cgroups.
568-
if err := ignoreTerminateErrors(p.terminate()); err != nil {
569-
logrus.WithError(err).Warn("unable to terminate initProcess")
570-
}
571-
572-
_ = p.manager.Destroy()
573-
if p.intelRdtManager != nil {
574-
_ = p.intelRdtManager.Destroy()
575-
}
576562
}
577563
}()
578564

0 commit comments

Comments
 (0)