Skip to content

Commit

Permalink
Enable masking stop signals within container creation
Browse files Browse the repository at this point in the history
Expand the use of the Shutdown package such that we now use it
to handle signals any time we run Libpod. From there, add code to
container creation to use the Inhibit function to prevent a
shutdown from occuring during the critical parts of container
creation.

We also need to turn off signal handling when --sig-proxy is
invoked - we don't want to catch the signals ourselves then, but
instead to forward them into the container via the existing
sig-proxy handler.

Fixes #7941

Signed-off-by: Matthew Heon <[email protected]>
  • Loading branch information
mheon committed Oct 12, 2020
1 parent 8381f3f commit 83e6e4c
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 6 deletions.
13 changes: 13 additions & 0 deletions libpod/runtime.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"github.com/containers/podman/v2/libpod/events"
"github.com/containers/podman/v2/libpod/image"
"github.com/containers/podman/v2/libpod/lock"
"github.com/containers/podman/v2/libpod/shutdown"
"github.com/containers/podman/v2/pkg/cgroups"
"github.com/containers/podman/v2/pkg/registries"
"github.com/containers/podman/v2/pkg/rootless"
Expand Down Expand Up @@ -174,9 +175,21 @@ func newRuntimeFromConfig(ctx context.Context, conf *config.Config, options ...R
}
}

if err := shutdown.Start(); err != nil {
return nil, errors.Wrapf(err, "error starting shutdown signal handler")
}

if err := makeRuntime(ctx, runtime); err != nil {
return nil, err
}

if err := shutdown.Register("libpod", func() error {
os.Exit(1)
return nil
}); err != nil {
logrus.Errorf("Error registering shutdown handler for libpod: %v", err)
}

return runtime, nil
}

Expand Down
5 changes: 5 additions & 0 deletions libpod/runtime_ctr.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/containers/common/pkg/config"
"github.com/containers/podman/v2/libpod/define"
"github.com/containers/podman/v2/libpod/events"
"github.com/containers/podman/v2/libpod/shutdown"
"github.com/containers/podman/v2/pkg/cgroups"
"github.com/containers/podman/v2/pkg/rootless"
"github.com/containers/storage"
Expand Down Expand Up @@ -149,6 +150,10 @@ func (r *Runtime) setupContainer(ctx context.Context, ctr *Container) (_ *Contai
return nil, err
}

// Inhibit shutdown until creation succeeds
shutdown.Inhibit()
defer shutdown.Uninhibit()

// Allocate a lock for the container
lock, err := r.lockManager.AllocateLock()
if err != nil {
Expand Down
8 changes: 8 additions & 0 deletions libpod/shutdown/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,10 @@ func Uninhibit() {
// Register registers a function that will be executed when Podman is terminated
// by a signal.
func Register(name string, handler func() error) error {
if handlers == nil {
handlers = make(map[string]func() error)
}

if _, ok := handlers[name]; ok {
return errors.Errorf("handler with name %s already exists", name)
}
Expand All @@ -95,6 +99,10 @@ func Register(name string, handler func() error) error {

// Unregister un-registers a given shutdown handler.
func Unregister(name string) error {
if handlers == nil {
handlers = make(map[string]func() error)
}

if _, ok := handlers[name]; !ok {
return errors.Errorf("no handler with name %s found", name)
}
Expand Down
10 changes: 4 additions & 6 deletions pkg/api/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,9 @@ func (s *APIServer) Serve() error {
}); err != nil {
return err
}
// Unregister the libpod handler, which just calls exit(1).
// Ignore errors if it doesn't exist.
_ = shutdown.Unregister("libpod")

errChan := make(chan error, 1)

Expand Down Expand Up @@ -226,12 +229,7 @@ func (s *APIServer) Serve() error {
errChan <- nil
}()

select {
case err := <-errChan:
return err
}

return nil
return <-errChan
}

// Shutdown is a clean shutdown waiting on existing clients
Expand Down
5 changes: 5 additions & 0 deletions pkg/domain/infra/abi/terminal/sigproxy_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,17 @@ import (
"syscall"

"github.com/containers/podman/v2/libpod"
"github.com/containers/podman/v2/libpod/shutdown"
"github.com/containers/podman/v2/pkg/signal"
"github.com/sirupsen/logrus"
)

// ProxySignals ...
func ProxySignals(ctr *libpod.Container) {
// Stop catching the shutdown signals (SIGINT, SIGTERM) - they're going
// to the container now.
shutdown.Stop()

sigBuffer := make(chan os.Signal, 128)
signal.CatchAll(sigBuffer)

Expand Down

0 comments on commit 83e6e4c

Please sign in to comment.