summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libpod/container_copy_common.go85
-rw-r--r--libpod/container_copy_linux.go88
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)
+}