diff options
author | Doug Rabson <dfr@rabson.org> | 2022-08-25 08:47:42 +0100 |
---|---|---|
committer | Doug Rabson <dfr@rabson.org> | 2022-09-20 08:36:23 +0100 |
commit | 88f82ceab2b14b0523a56cd8c6b3a9cec8a323e2 (patch) | |
tree | 7357697636b6b805a7e07ada9a8d5cf5bb0f39cc /libpod | |
parent | 75d6e7bae5abb73fb248a6c4766ab799a030cb93 (diff) | |
download | podman-88f82ceab2b14b0523a56cd8c6b3a9cec8a323e2.tar.gz podman-88f82ceab2b14b0523a56cd8c6b3a9cec8a323e2.tar.bz2 podman-88f82ceab2b14b0523a56cd8c6b3a9cec8a323e2.zip |
libpod: Move jointMountAndExec to container_copy_linux.go
This also moves the logic for resolving paths in running and stopped
containers tp container_copy_linux.go.
On FreeBSD, we can execute the function argument to joinMountAndExec
directly using host-relative paths since the host mount namespace
includes all the container mounts.
[NO NEW TESTS NEEDED]
Signed-off-by: Doug Rabson <dfr@rabson.org>
Diffstat (limited to 'libpod')
-rw-r--r-- | libpod/container_copy_common.go | 85 | ||||
-rw-r--r-- | libpod/container_copy_linux.go | 88 |
2 files changed, 92 insertions, 81 deletions
diff --git a/libpod/container_copy_common.go b/libpod/container_copy_common.go index 557fead1e..d09a8b17d 100644 --- a/libpod/container_copy_common.go +++ b/libpod/container_copy_common.go @@ -5,11 +5,8 @@ package libpod import ( "errors" - "fmt" "io" - "os" "path/filepath" - "runtime" "strings" buildahCopiah "github.com/containers/buildah/copier" @@ -21,7 +18,6 @@ import ( "github.com/containers/storage/pkg/idtools" "github.com/opencontainers/runtime-spec/specs-go" "github.com/sirupsen/logrus" - "golang.org/x/sys/unix" ) func (c *Container) copyFromArchive(path string, chown, noOverwriteDirNonDir bool, rename map[string]string, reader io.Reader) (func() error, error) { @@ -56,15 +52,10 @@ func (c *Container) copyFromArchive(path string, chown, noOverwriteDirNonDir boo } } - if c.state.State == define.ContainerStateRunning { - resolvedRoot = "/" - resolvedPath = c.pathAbs(path) - } else { - resolvedRoot, resolvedPath, err = c.resolvePath(mountPoint, path) - if err != nil { - unmount() - return nil, err - } + resolvedRoot, resolvedPath, err = c.resolveCopyTarget(mountPoint, path) + if err != nil { + unmount() + return nil, err } var idPair *idtools.IDPair @@ -220,71 +211,3 @@ func idtoolsToRuntimeSpec(idMaps []idtools.IDMap) (convertedIDMap []specs.LinuxI } return convertedIDMap } - -// joinMountAndExec executes the specified function `f` inside the container's -// mount and PID namespace. That allows for having the exact view on the -// container's file system. -// -// Note, if the container is not running `f()` will be executed as is. -func (c *Container) joinMountAndExec(f func() error) error { - if c.state.State != define.ContainerStateRunning { - return f() - } - - // Container's running, so we need to execute `f()` inside its mount NS. - errChan := make(chan error) - go func() { - runtime.LockOSThread() - - // Join the mount and PID NS of the container. - getFD := func(ns LinuxNS) (*os.File, error) { - nsPath, err := c.namespacePath(ns) - if err != nil { - return nil, err - } - return os.Open(nsPath) - } - - mountFD, err := getFD(MountNS) - if err != nil { - errChan <- err - return - } - defer mountFD.Close() - - inHostPidNS, err := c.inHostPidNS() - if err != nil { - errChan <- fmt.Errorf("checking inHostPidNS: %w", err) - return - } - var pidFD *os.File - if !inHostPidNS { - pidFD, err = getFD(PIDNS) - if err != nil { - errChan <- err - return - } - defer pidFD.Close() - } - - if err := unix.Unshare(unix.CLONE_NEWNS); err != nil { - errChan <- err - return - } - - if pidFD != nil { - if err := unix.Setns(int(pidFD.Fd()), unix.CLONE_NEWPID); err != nil { - errChan <- err - return - } - } - if err := unix.Setns(int(mountFD.Fd()), unix.CLONE_NEWNS); err != nil { - errChan <- err - return - } - - // Last but not least, execute the workload. - errChan <- f() - }() - return <-errChan -} diff --git a/libpod/container_copy_linux.go b/libpod/container_copy_linux.go new file mode 100644 index 000000000..3b029f08f --- /dev/null +++ b/libpod/container_copy_linux.go @@ -0,0 +1,88 @@ +package libpod + +import ( + "fmt" + "os" + "runtime" + + "github.com/containers/podman/v4/libpod/define" + "golang.org/x/sys/unix" +) + +// joinMountAndExec executes the specified function `f` inside the container's +// mount and PID namespace. That allows for having the exact view on the +// container's file system. +// +// Note, if the container is not running `f()` will be executed as is. +func (c *Container) joinMountAndExec(f func() error) error { + if c.state.State != define.ContainerStateRunning { + return f() + } + + // Container's running, so we need to execute `f()` inside its mount NS. + errChan := make(chan error) + go func() { + runtime.LockOSThread() + + // Join the mount and PID NS of the container. + getFD := func(ns LinuxNS) (*os.File, error) { + nsPath, err := c.namespacePath(ns) + if err != nil { + return nil, err + } + return os.Open(nsPath) + } + + mountFD, err := getFD(MountNS) + if err != nil { + errChan <- err + return + } + defer mountFD.Close() + + inHostPidNS, err := c.inHostPidNS() + if err != nil { + errChan <- fmt.Errorf("checking inHostPidNS: %w", err) + return + } + var pidFD *os.File + if !inHostPidNS { + pidFD, err = getFD(PIDNS) + if err != nil { + errChan <- err + return + } + defer pidFD.Close() + } + + if err := unix.Unshare(unix.CLONE_NEWNS); err != nil { + errChan <- err + return + } + + if pidFD != nil { + if err := unix.Setns(int(pidFD.Fd()), unix.CLONE_NEWPID); err != nil { + errChan <- err + return + } + } + if err := unix.Setns(int(mountFD.Fd()), unix.CLONE_NEWNS); err != nil { + errChan <- err + return + } + + // Last but not least, execute the workload. + errChan <- f() + }() + return <-errChan +} + +func (c *Container) resolveCopyTarget(mountPoint string, containerPath string) (string, string, error) { + // If the container is running, we will execute the copy + // inside the container's mount namespace so we return a path + // relative to the container's root. + if c.state.State == define.ContainerStateRunning { + return "/", c.pathAbs(containerPath), nil + } + return c.resolvePath(mountPoint, containerPath) +} |