mirror of
https://github.com/containers/podman.git
synced 2025-10-17 19:24:04 +08:00
podman cp: support copying on tmpfs mounts
Traditionally, the path resolution for containers has been resolved on the *host*; relative to the container's mount point or relative to specified bind mounts or volumes. While this works nicely for non-running containers, it poses a problem for running ones. In that case, certain kinds of mounts (e.g., tmpfs) will not resolve correctly. A tmpfs is held in memory and hence cannot be resolved relatively to the container's mount point. A copy operation will succeed but the data will not show up inside the container. To support these kinds of mounts, we need to join the *running* container's mount namespace (and PID namespace) when copying. Note that this change implies moving the copy and stat logic into `libpod` since we need to keep the container locked to avoid race conditions. The immediate benefit is that all logic is now inside `libpod`; the code isn't scattered anymore. Further note that Docker does not support copying to tmpfs mounts. Tests have been extended to cover *both* path resolutions for running and created containers. New tests have been added to exercise the tmpfs-mount case. For the record: Some tests could be improved by using `start -a` instead of a start-exec sequence. Unfortunately, `start -a` is flaky in the CI which forced me to use the more expensive start-exec option. Signed-off-by: Valentin Rothberg <rothberg@redhat.com>
This commit is contained in:
@ -1,3 +1,4 @@
|
||||
// +linux
|
||||
package libpod
|
||||
|
||||
import (
|
||||
@ -10,6 +11,19 @@ import (
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// pathAbs returns an absolute path. If the specified path is
|
||||
// relative, it will be resolved relative to the container's working dir.
|
||||
func (c *Container) pathAbs(path string) string {
|
||||
if !filepath.IsAbs(path) {
|
||||
// If the containerPath is not absolute, it's relative to the
|
||||
// container's working dir. To be extra careful, let's first
|
||||
// join the working dir with "/", and the add the containerPath
|
||||
// to it.
|
||||
path = filepath.Join(filepath.Join("/", c.WorkingDir()), path)
|
||||
}
|
||||
return path
|
||||
}
|
||||
|
||||
// resolveContainerPaths resolves the container's mount point and the container
|
||||
// path as specified by the user. Both may resolve to paths outside of the
|
||||
// container's mount point when the container path hits a volume or bind mount.
|
||||
@ -20,14 +34,7 @@ import (
|
||||
// the host).
|
||||
func (c *Container) resolvePath(mountPoint string, containerPath string) (string, string, error) {
|
||||
// Let's first make sure we have a path relative to the mount point.
|
||||
pathRelativeToContainerMountPoint := containerPath
|
||||
if !filepath.IsAbs(containerPath) {
|
||||
// If the containerPath is not absolute, it's relative to the
|
||||
// container's working dir. To be extra careful, let's first
|
||||
// join the working dir with "/", and the add the containerPath
|
||||
// to it.
|
||||
pathRelativeToContainerMountPoint = filepath.Join(filepath.Join("/", c.WorkingDir()), containerPath)
|
||||
}
|
||||
pathRelativeToContainerMountPoint := c.pathAbs(containerPath)
|
||||
resolvedPathOnTheContainerMountPoint := filepath.Join(mountPoint, pathRelativeToContainerMountPoint)
|
||||
pathRelativeToContainerMountPoint = strings.TrimPrefix(pathRelativeToContainerMountPoint, mountPoint)
|
||||
pathRelativeToContainerMountPoint = filepath.Join("/", pathRelativeToContainerMountPoint)
|
||||
|
Reference in New Issue
Block a user