diff options
author | Matthew Heon <mheon@redhat.com> | 2022-09-14 09:36:46 -0400 |
---|---|---|
committer | Matthew Heon <mheon@redhat.com> | 2022-09-14 11:02:35 -0400 |
commit | 42937cd9a8f81550dd83b799fc6d0d4c7a1bba69 (patch) | |
tree | 823c37f6c363efc16411cf55dca28d1ae7b3a99a | |
parent | 017d81ddd0e8d228aadb949175c0aae1e4b9d925 (diff) | |
download | podman-42937cd9a8f81550dd83b799fc6d0d4c7a1bba69.tar.gz podman-42937cd9a8f81550dd83b799fc6d0d4c7a1bba69.tar.bz2 podman-42937cd9a8f81550dd83b799fc6d0d4c7a1bba69.zip |
Ensure that a broken OCI spec does not break inspect
The process of saving the OCI spec is not particularly
reboot-safe. Normally, this doesn't matter, because we recreate
the spec every time a container starts, but if one was to reboot
(or SIGKILL, or otherwise fatally interrupt) Podman in the middle
of writing the spec to disk, we can end up with a malformed spec
that sticks around until the container is next started. Some
Podman commands want to read the latest version of the spec off
disk (to get information only populated after a container is
started), and will break in the case that a partially populated
spec is present. Swap to just ignoring these errors (with a
logged warning, to let folks know something went wrong) so we
don't break important commands like `podman inspect` in these
cases.
[NO NEW TESTS NEEDED] Provided reproducer involves repeatedly
rebooting the system
Signed-off-by: Matthew Heon <mheon@redhat.com>
-rw-r--r-- | libpod/container.go | 4 |
1 files changed, 3 insertions, 1 deletions
diff --git a/libpod/container.go b/libpod/container.go index bdedafd22..cfffd8ea1 100644 --- a/libpod/container.go +++ b/libpod/container.go @@ -356,7 +356,9 @@ func (c *Container) specFromState() (*spec.Spec, error) { return nil, fmt.Errorf("reading container config: %w", err) } if err := json.Unmarshal(content, &returnSpec); err != nil { - return nil, fmt.Errorf("unmarshalling container config: %w", err) + // Malformed spec, just use c.config.Spec instead + logrus.Warnf("Error unmarshalling container %s config: %v", c.ID(), err) + return c.config.Spec, nil } } else if !os.IsNotExist(err) { // ignore when the file does not exist |