mirror of
				https://github.com/containers/podman.git
				synced 2025-11-04 08:56:05 +08:00 
			
		
		
		
	Moving from Go module v4 to v5 prepares us for public releases. Move done using gomove [1] as with the v3 and v4 moves. [1] https://github.com/KSubedi/gomove Signed-off-by: Matt Heon <mheon@redhat.com>
		
			
				
	
	
		
			91 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			91 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
//go:build !remote
 | 
						|
 | 
						|
package libpod
 | 
						|
 | 
						|
import (
 | 
						|
	"fmt"
 | 
						|
	"os"
 | 
						|
	"runtime"
 | 
						|
 | 
						|
	"github.com/containers/podman/v5/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)
 | 
						|
}
 |