From 0141c6db8107c5dadcb37f970b5351b5f4b2cd9b 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 --- 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 f2117daf55..202be78b9e 100644 --- a/daemon/container.go +++ b/daemon/container.go @@ -233,7 +233,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 f70677e359..fcc6f6b1d8 100644 --- a/daemon/start.go +++ b/daemon/start.go @@ -68,9 +68,9 @@ func (daemon *Daemon) ContainerStart(ctx context.Context, name string, hostConfi // 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() }