Hash the container ID, mount source and destination together to form a
layer name.
This ensures the generated names are filesystem-friendly and don't
exceed path length limits while maintaining uniqueness across different
mount points and containers.
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
(cherry picked from commit cb88c6ba10)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Add cleanup for the init layer directory if any operation fails after
driver.CreateReadWrite() succeeds in initMount(). Previously, failures
in driver.Get(), initFunc(), or driver.Put() would leave an orphaned
overlay2 directory.
Related to moby/moby#45939
Signed-off-by: Jan Scheffler <jan.scheffler@qodev.ai>
(cherry picked from commit 3fdde529e7)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Add cleanup for the RW layer directory if saveMount() fails after
driver.CreateReadWrite() succeeds. Previously, this failure path would
leave an orphaned overlay2 directory with no corresponding metadata.
Related to moby/moby#45939
Signed-off-by: Jan Scheffler <jan.scheffler@qodev.ai>
(cherry picked from commit d7a6250b91)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Start the metadata transaction before creating the overlay2 directory.
This ensures that if driver.Create() fails, we can properly cancel the
transaction. Previously, if StartTransaction() failed after driver.Create()
succeeded, the defer cleanup would not run (not registered yet), leaving
an orphaned overlay2 directory.
The fix reorders operations so that:
1. Transaction is started first (no filesystem changes yet)
2. Overlay2 directory is created second (transaction ready for cleanup)
3. Defer is registered after both succeed (tx is guaranteed non-nil)
If driver.Create() fails, the transaction is explicitly cancelled before
returning. The nil check for tx in the defer is no longer needed since
tx is guaranteed to exist when the defer runs.
Related to moby/moby#45939
Signed-off-by: Jan Scheffler <jan.scheffler@qodev.ai>
(cherry picked from commit 70004549fb)
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
Stopping the Engine while a container with autoremove set is running may
leave behind dead containers on disk. These containers aren't reclaimed
on next start, appear as "dead" in `docker ps -a` and can't be
inspected or removed by the user.
This bug has existed since a long time but became user visible with
9f5f4f5a42. Prior to that commit,
containers with no rwlayer weren't added to the in-memory viewdb, so
they weren't visible in `docker ps -a`. However, some dangling files
would still live on disk (e.g. folder in /var/lib/docker/containers,
mount points, etc).
The underlying issue is that when the daemon stops, it tries to stop all
running containers and then closes the containerd client. This leaves a
small window of time where the Engine might receive 'task stop' events
from containerd, and trigger autoremove. If the containerd client is
closed in parallel, the Engine is unable to complete the removal,
leaving the container in 'dead' state. In such case, the Engine logs the
following error:
cannot remove container "bcbc98b4f5c2b072eb3c4ca673fa1c222d2a8af00bf58eae0f37085b9724ea46": Canceled: grpc: the client connection is closing: context canceled
Solving the underlying issue would require complex changes to the
shutdown sequence. Moreover, the same issue could also happen if the
daemon crashes while it deletes a container. Thus, add a cleanup step
on daemon startup to remove these dead containers.
Signed-off-by: Albin Kerouanton <albin.kerouanton@docker.com>
(cherry picked from commit ec9315cd4f)
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
This code was added in 85b260fba8, but didn't
account for maps.Clone returning a `nil` map if the map cloned was `nil`.
This could lead to a panic, similar to the panic that was fixed in
7517464283d29969c4d3615397b369abd99ce395;
panic: assignment to entry in nil map
goroutine 498 [running]:
github.com/moby/moby/v2/daemon.buildPortsRelatedCreateEndpointOptions(0x400042f348, 0xaaaabcc8f458?, 0x40006feb40)
/root/build-deb/engine/daemon/network.go:1047 +0x844
github.com/moby/moby/v2/daemon.buildCreateEndpointOptions(0x400042f348, 0x4001015040, 0x400027d320, 0x40006feb40, {0x0, 0x0, 0x4001506cb8?})
/root/build-deb/engine/daemon/network.go:988 +0x20c
github.com/moby/moby/v2/daemon.(*Daemon).connectToNetwork(0x4000898008, {0xaaaabe21d9f8, 0x4000f12b10}, 0x400089a008, 0x400042f348, {0x400077a9f0, 0x6}, 0x400027d320)
/root/build-deb/engine/daemon/container_operations.go:738 +0x66c
github.com/moby/moby/v2/daemon.(*Daemon).allocateNetwork(0x4000898008, {0xaaaabe21d9f8, 0x4000f12b10}, 0x400089a008, 0x400042f348)
/root/build-deb/engine/daemon/container_operations.go:421 +0x298
github.com/moby/moby/v2/daemon.(*Daemon).initializeCreatedTask(0x4000898008, {0xaaaabe21d9f8, 0x4000f12b10}, 0x400089a008, {0xaaaabe23dc60, 0x4000eb21c8}, 0x400042f348, 0xaaaabd4db3df?)
/root/build-deb/engine/daemon/start_linux.go:37 +0x260
github.com/moby/moby/v2/daemon.(*Daemon).containerStart(0x4000898008, {0xaaaabe21d9c0, 0xaaaabfa05300}, 0x400089a008, 0x400042f348, {0x0, 0x0}, {0x0, 0x0}, 0x1)
/root/build-deb/engine/daemon/start.go:242 +0xba8
github.com/moby/moby/v2/daemon.(*Daemon).restore.func4(0x400042f348, 0x400117f1f0)
/root/build-deb/engine/daemon/daemon.go:633 +0x308
created by github.com/moby/moby/v2/daemon.(*Daemon).restore in goroutine 1
/root/build-deb/engine/daemon/daemon.go:607 +0x5ec
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 695010ba2e)
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
When inspecting multi-platform images where some layer blobs were
missing from the content store, the image inspect operation would return
too early causing some data (like config details or unpacked size) to be
omitted even though are available.
This ensures that `docker image inspect` returns as much information as
possible.
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
The value was calculated, but due to 0af2962fdd
changing to a non-pointer, the value was not written back to the resulting
slice.
Before this patch:
docker pull nginx:alpine
docker pull alpine
docker system df -v
Images space usage:
REPOSITORY TAG IMAGE ID CREATED SIZE SHARED SIZE UNIQUE SIZE CONTAINERS
nginx alpine cbad6347cca2 4 weeks ago 53.4MB N/A N/A 0
alpine latest 171e65262c80 7 weeks ago 8.51MB N/A N/A 0
With this patch:
docker system df -v
Images space usage:
REPOSITORY TAG IMAGE ID CREATED SIZE SHARED SIZE UNIQUE SIZE CONTAINERS
nginx alpine cbad6347cca2 4 weeks ago 53.4MB 8.512MB 44.91MB 0
alpine latest 171e65262c80 7 weeks ago 8.51MB 8.512MB 0B 0
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
In rootless mode, the Engine needs to call the rootless port driver to
know which IP address it should bind to inside of its network namespace.
The slirp4netns port drivers doesn't support binding to IPv6 address, so
we need to detect that before listening on the port.
Before commit 201968cc0, this wasn't a problem because the Engine was
binding the port, then calling rootless port driver to learn whether the
proto/IP family was supported, and listen on the port if so.
Starting with that commit, the Engine does bind + listen in one go, and
then calls the port driver — this is too late. Fix the bug by checking
if the port driver supports the PortBindingReq, and only allocate the
port if so.
Signed-off-by: Albin Kerouanton <albin.kerouanton@docker.com>
During a network disconnect, log rather than returning an error
if it's not possible to set up a new gateway.
This restores the behaviour from before commit 53390f8 ("Put
clearNetworkResources() inline in its only caller"). It's not
ideal, but by the time new gateways are selected the old
endpoint has been disconnected - and nothing puts things back.
Until that's cleaned up, a broken state is inevitable, but
letting endpoint deletion complete means the container can
be restarted or re-connected to the network without a zombie
endpoint causing further issues.
Signed-off-by: Rob Murray <rob.murray@docker.com>
Throw an error if the containerd snapshotter is enabled on Windows but
containerd has not been configured. This fixes a panic in this case when
trying to use an uninitialized client.
Signed-off-by: Derek McGowan <derek@mcg.dev>
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
When the endpoint providing a container's default gateway
is removed, there's no need to select a new gateway if the
container is being removed.
Signed-off-by: Rob Murray <rob.murray@docker.com>
Call resolvconf.UserModified() in sandbox.setupDNS() to check if
resolv.conf was manually modified before regenerating it during
container restart for non-host network modes.
Signed-off-by: zhangguanzhang <zhangguanzhang@qq.com>
Signed-off-by: Albin Kerouanton <albin.kerouanton@docker.com>
When ep.needResolver() is true, sb.startResolver() calls sb.rebuildDNS()
which doesn't update the resolv.conf hash file.
Subsequent calls to sb.updateDNS() (which is only called by
populateNetworkResourcesOS) won't have any effect since it'll compare
the hash file and consider that the file was manually modified.
Make this explicit by gating the call to updateDNS() on !needResolver().
Signed-off-by: Albin Kerouanton <albin.kerouanton@docker.com>
Make the DiscoverNew switch only responsible for asserting the correct
data type, and push the conversion logic into the setKeys and updateKeys
methods.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Also:
- remove the hostConfig param from Daemon.createContainerVolumesOS.
- rename var container -> ctr
Signed-off-by: Rob Murray <rob.murray@docker.com>