Enable masking stop signals within container creation

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 <mheon@redhat.com>
This commit is contained in:
Matthew Heon 2020-10-12 15:10:52 -04:00
parent 8381f3feee
commit 83e6e4ccdd
5 changed files with 35 additions and 6 deletions

View File

@ -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"
@ -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
}

View File

@ -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"
@ -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 {

View File

@ -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)
}
@ -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)
}

View File

@ -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)
@ -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

View File

@ -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)