From 6149c333ffb27579542ad36f973a109c82369715 Mon Sep 17 00:00:00 2001 From: Cory Snider Date: Mon, 12 Dec 2022 15:23:43 -0500 Subject: [PATCH] daemon: don't checkpoint container until registered (*Container).CheckpointTo() upserts a snapshot of the container to the daemon's in-memory ViewDB and also persists the snapshot to disk. It does not register the live container object with the daemon's container store, however. The ViewDB and container store are used as the source of truth for different operations, so having a container registered in one but not the other can result in inconsistencies. In particular, the List Containers API uses the ViewDB as its source of truth and the Container Inspect API uses the container store. The (*Daemon).setHostConfig() method is called fairly early in the process of creating a container, long before the container is registered in the daemon's container store. Due to a rogue CheckpointTo() call inside setHostConfig(), there is a window of time where a container can be included in a List Containers API response but "not exist" according to the Container Inspect API and similar endpoints which operate on a particular container. Remove the rogue call so that the caller has full control over when the container is checkpointed and update callers to checkpoint explicitly. No changes to (*Daemon).create() are needed as it checkpoints the fully-created container via (*Daemon).Register(). Fixes #44512. Signed-off-by: Cory Snider (cherry picked from commit 0141c6db8107c5dadcb37f970b5351b5f4b2cd9b) Signed-off-by: Cory Snider --- daemon/container.go | 2 +- daemon/start.go | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/daemon/container.go b/daemon/container.go index 52830f72894cd..24af5945906d5 100644 --- a/daemon/container.go +++ b/daemon/container.go @@ -235,7 +235,7 @@ func (daemon *Daemon) setHostConfig(container *container.Container, hostConfig * runconfig.SetDefaultNetModeIfBlank(hostConfig) container.HostConfig = hostConfig - return container.CheckpointTo(daemon.containersReplica) + return nil } // verifyContainerSettings performs validation of the hostconfig and config diff --git a/daemon/start.go b/daemon/start.go index ecc0f8b8afccc..9d6f7812b67c7 100644 --- a/daemon/start.go +++ b/daemon/start.go @@ -67,9 +67,9 @@ func (daemon *Daemon) ContainerStart(name string, hostConfig *containertypes.Hos // if user has change the network mode on starting, clean up the // old networks. It is a deprecated feature and has been removed in Docker 1.12 ctr.NetworkSettings.Networks = nil - if err := ctr.CheckpointTo(daemon.containersReplica); err != nil { - return errdefs.System(err) - } + } + if err := ctr.CheckpointTo(daemon.containersReplica); err != nil { + return errdefs.System(err) } ctr.InitDNSHostConfig() }