podman

Форк
0
/
container_copy_linux.go 
90 строк · 2.1 Кб
1
//go:build !remote
2

3
package libpod
4

5
import (
6
	"fmt"
7
	"os"
8
	"runtime"
9

10
	"github.com/containers/podman/v5/libpod/define"
11
	"golang.org/x/sys/unix"
12
)
13

14
// joinMountAndExec executes the specified function `f` inside the container's
15
// mount and PID namespace.  That allows for having the exact view on the
16
// container's file system.
17
//
18
// Note, if the container is not running `f()` will be executed as is.
19
func (c *Container) joinMountAndExec(f func() error) error {
20
	if c.state.State != define.ContainerStateRunning {
21
		return f()
22
	}
23

24
	// Container's running, so we need to execute `f()` inside its mount NS.
25
	errChan := make(chan error)
26
	go func() {
27
		runtime.LockOSThread()
28

29
		// Join the mount and PID NS of the container.
30
		getFD := func(ns LinuxNS) (*os.File, error) {
31
			nsPath, err := c.namespacePath(ns)
32
			if err != nil {
33
				return nil, err
34
			}
35
			return os.Open(nsPath)
36
		}
37

38
		mountFD, err := getFD(MountNS)
39
		if err != nil {
40
			errChan <- err
41
			return
42
		}
43
		defer mountFD.Close()
44

45
		inHostPidNS, err := c.inHostPidNS()
46
		if err != nil {
47
			errChan <- fmt.Errorf("checking inHostPidNS: %w", err)
48
			return
49
		}
50
		var pidFD *os.File
51
		if !inHostPidNS {
52
			pidFD, err = getFD(PIDNS)
53
			if err != nil {
54
				errChan <- err
55
				return
56
			}
57
			defer pidFD.Close()
58
		}
59

60
		if err := unix.Unshare(unix.CLONE_NEWNS); err != nil {
61
			errChan <- err
62
			return
63
		}
64

65
		if pidFD != nil {
66
			if err := unix.Setns(int(pidFD.Fd()), unix.CLONE_NEWPID); err != nil {
67
				errChan <- err
68
				return
69
			}
70
		}
71
		if err := unix.Setns(int(mountFD.Fd()), unix.CLONE_NEWNS); err != nil {
72
			errChan <- err
73
			return
74
		}
75

76
		// Last but not least, execute the workload.
77
		errChan <- f()
78
	}()
79
	return <-errChan
80
}
81

82
func (c *Container) resolveCopyTarget(mountPoint string, containerPath string) (string, string, error) {
83
	// If the container is running, we will execute the copy
84
	// inside the container's mount namespace so we return a path
85
	// relative to the container's root.
86
	if c.state.State == define.ContainerStateRunning {
87
		return "/", c.pathAbs(containerPath), nil
88
	}
89
	return c.resolvePath(mountPoint, containerPath)
90
}
91

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.