-
Notifications
You must be signed in to change notification settings - Fork 18.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix duplicate mount points for multiple --volumes-from
in docker run
#29563
Fix duplicate mount points for multiple --volumes-from
in docker run
#29563
Conversation
daemon/volumes.go
Outdated
@@ -103,6 +103,9 @@ func (daemon *Daemon) registerMountPoints(container *container.Container, hostCo | |||
} | |||
|
|||
for _, m := range c.MountPoints { | |||
if _, ok := mountPoints[m.Destination]; ok { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder similar checking about mountPoints
is needed for this loop (for _, cfg := range hostConfig.Mounts {}
) as well: https://github.com/yongtang/docker/blob/d231e33926a58a11974bbdd9a038e79fac2217df/daemon/volumes.go#L164-L206
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @AkihiroSuda for the reminder. I will double check for this case.
CI looks to be failing
|
Interesting, these work:
These don't
Not sure if it's all expected (i.e., can it be a problem as well for anonymous volumes?), |
daemon/volumes.go
Outdated
@@ -103,6 +103,9 @@ func (daemon *Daemon) registerMountPoints(container *container.Container, hostCo | |||
} | |||
|
|||
for _, m := range c.MountPoints { | |||
if _, ok := mountPoints[m.Destination]; ok { | |||
return fmt.Errorf("Duplicate mount point '%s'", m.Destination) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is really a behavior change.
I think this will end up breaking people who have already brought in a volume and then also do --volumes-from
on a container with the same volume.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we'll need to pick which one wins and log an error for the other one.
And the one we pick is whatever happens to win right now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@cpuguy83 @thaJeztah Got that, thanks. Was wondering how to best handle this situation. Will take a look and make sure the previous behavior is preserved.
0b89a8c
to
679ff0f
Compare
Update on this PR: In addition to the issue described above, the following will also prevent volumes from removed:
The bind Both the original issue and the bind override issue have been fixed. Will continue to investigate other scenarios. |
679ff0f
to
496ab3d
Compare
Update of the PR (case 3):
This case will also trigger |
@cpuguy83 @AkihiroSuda @thaJeztah. The PR has been updated with different possible combinations of scenarios covered. Please take a look and let me know if there are any issues. |
282e61b
to
6d8ee89
Compare
ping @thaJeztah @cpuguy83 |
Is this actually fixed now that references are stored as a map instead of a slice? |
daemon/volumes.go
Outdated
@@ -121,7 +121,12 @@ func (daemon *Daemon) registerMountPoints(container *container.Container, hostCo | |||
} | |||
cp.Volume = v | |||
} | |||
|
|||
if v, ok := mountPoints[m.Destination]; ok { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These seven lines are the same three times; maybe we should have a helper for it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @LK4D4. The PR has been updated with helper func. Please take a look.
6d8ee89
to
4b699af
Compare
Thanks @cpuguy83 for the review. To preserve the behavior we need to deference the old volume that points to the same mount point (when old and new volume point to the same mount point). So the change is needed for the fix. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Not sure if it's the same part that's causing this error, but;
As mentioned here; #6758 (comment) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
This looks like it's fixing a real problem with refcounting.
However our code looks really awful here because we're essentially leaking volumes.
Not sure what to do here at the moment, but we should figure out how to do this better.
daemon/volumes.go
Outdated
@@ -85,6 +85,15 @@ func (daemon *Daemon) registerMountPoints(container *container.Container, hostCo | |||
} | |||
}() | |||
|
|||
dereferenceIfExists := func(destination string) { | |||
if v, ok := mountPoints[destination]; ok { | |||
logrus.Errorf("Duplicate mount point '%s'", destination) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, sorry this looks like it should be Debug
, not Error
This fix tries to fix the issue raised in 21845. The issue with 21845 is that if multiple `--volumes-from` with the same destination has been specified, then one volume will be overridden by the other. This will mess up with volumes reference and prevent the overridden volume from being removed at the end. Issue 21845 was observed with `docker-compose` though it is possible to emulate the same behavior with `docker` alone: ``` $ cat Dockerfile FROM busybox VOLUME ["/tmp/data"] $ docker build -t vimage . $ docker run --name=data1 vimage true $ docker run --name=data2 vimage true $ docker run --name=app --volumes-from=data1 --volumes-from=data2 -d busybox top $ docker rm -f -v $(docker ps -aq) $ docker volume ls $ docker volume rm ... ``` NOTE: Second case: ``` $ cat Dockerfile FROM busybox VOLUME ["/tmp/data"] $ docker build -t vimage . $ docker run --name=data1 vimage true $ docker run --name=data2 vimage true $ docker run --name=app --volumes-from=data1 --volumes-from=data2 -v /tmp/data:/tmp/data -d busybox top $ docker rm -f -v $(docker ps -aq) $ docker volume ls $ docker volume rm ... ``` NOTE: Third case: Combination of --volumes-from and `HostConfig.Mounts` (API only) This fix tries to address the issue by return an error if duplicate mount points was used with `--volumes-from`. An integration test has been added. This fix fixes 21845. Signed-off-by: Yong Tang <[email protected]>
4b699af
to
9526e5c
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Thanks @cpuguy83. I agree the current way of handling it is less than ideal. I will spend some time to investigate it and see if we could come up with something better. |
This fix tries to fix the issue raised in 21845. The issue with 21845 is that if multiple `--volumes-from` with the same destination has been specified, then one volume will be overridden by the other. This will mess up with volumes reference and prevent the overridden volume from being removed at the end. Issue 21845 was observed with `docker-compose` though it is possible to emulate the same behavior with `docker` alone: ``` $ cat Dockerfile FROM busybox VOLUME ["/tmp/data"] $ docker build -t vimage . $ docker run --name=data1 vimage true $ docker run --name=data2 vimage true $ docker run --name=app --volumes-from=data1 --volumes-from=data2 -d busybox top $ docker rm -f -v $(docker ps -aq) $ docker volume ls $ docker volume rm ... ``` NOTE: Second case: ``` $ cat Dockerfile FROM busybox VOLUME ["/tmp/data"] $ docker build -t vimage . $ docker run --name=data1 vimage true $ docker run --name=data2 vimage true $ docker run --name=app --volumes-from=data1 --volumes-from=data2 -v /tmp/data:/tmp/data -d busybox top $ docker rm -f -v $(docker ps -aq) $ docker volume ls $ docker volume rm ... ``` NOTE: Third case: Combination of --volumes-from and `HostConfig.Mounts` (API only) This fix tries to address the issue by return an error if duplicate mount points was used with `--volumes-from`. An integration test has been added. This fix fixes 21845. cherry-picked from upstream moby#29563 Fix issue moby#338 Fix DTS2017070606746 note: Our code does not support API HostConfig.Mounts, so i delete the test case of third case. Signed-off-by: Yong Tang <[email protected]> Signed-off-by: Fengtu Wang <[email protected]> Conflicts: daemon/volumes.go integration-cli/docker_cli_volume_test.go
Fix duplicate mount point for `--volumes-from` in `docker run` This fix tries to fix the issue raised in 21845. The issue with 21845 is that if multiple `--volumes-from` with the same destination has been specified, then one volume will be overridden by the other. This will mess up with volumes reference and prevent the overridden volume from being removed at the end. Issue 21845 was observed with `docker-compose` though it is possible to emulate the same behavior with `docker` alone: ``` $ cat Dockerfile FROM busybox VOLUME ["/tmp/data"] $ docker build -t vimage . $ docker run --name=data1 vimage true $ docker run --name=data2 vimage true $ docker run --name=app --volumes-from=data1 --volumes-from=data2 -d busybox top $ docker rm -f -v $(docker ps -aq) $ docker volume ls $ docker volume rm ... ``` NOTE: Second case: ``` $ cat Dockerfile FROM busybox VOLUME ["/tmp/data"] $ docker build -t vimage . $ docker run --name=data1 vimage true $ docker run --name=data2 vimage true $ docker run --name=app --volumes-from=data1 --volumes-from=data2 -v /tmp/data:/tmp/data -d busybox top $ docker rm -f -v $(docker ps -aq) $ docker volume ls $ docker volume rm ... ``` NOTE: Third case: Combination of --volumes-from and `HostConfig.Mounts` (API only) This fix tries to address the issue by return an error if duplicate mount points was used with `--volumes-from`. An integration test has been added. This fix fixes 21845. cherry-picked from upstream moby#29563 Fix issue moby#338 Fix DTS2017070606746 note: Our code does not support API HostConfig.Mounts, so i delete the test case of third case. Signed-off-by: Yong Tang <[email protected]> Signed-off-by: Fengtu Wang <[email protected]> Conflicts: daemon/volumes.go integration-cli/docker_cli_volume_test.go See merge request docker/docker!661
- What I did
This fix tries to fix the issue raised in #21845.
The issue with #21845 is that if multiple
--volumes-from
with the same destination has been specified, then one volume will be overridden by the other. This will mess up reference and prevent the overridden volume from being removed at the end.Issue #21845 was observed with
docker-compose
though it is possible to emulate the same behavior withdocker
alone:- How I did it
This fix tries to address the issue by return an error if duplicate mount points was used with
--volumes-from
.- How to verify it
An integration test has been added.
- Description for the changelog
- A picture of a cute animal (not mandatory but encouraged)
This fix fixes #21845.
/cc @cpuguy83 @vdemeester @thaJeztah
Signed-off-by: Yong Tang [email protected]