Skip to content

Commit 8eb801d

Browse files
authored
Merge pull request #3512 from kolyshkin/fix-mntns-userns-II
Refactor mountFd code
2 parents 712a781 + a60933b commit 8eb801d

File tree

4 files changed

+116
-99
lines changed

4 files changed

+116
-99
lines changed

libcontainer/console_linux.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ func mountConsole(slavePath string) error {
1818
if f != nil {
1919
f.Close()
2020
}
21-
return mount(slavePath, "/dev/console", "", "bind", unix.MS_BIND, "")
21+
return mount(slavePath, "/dev/console", "bind", unix.MS_BIND, "")
2222
}
2323

2424
// dupStdio opens the slavePath for the console and dups the fds to the current

libcontainer/container_linux.go

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1277,9 +1277,8 @@ func (c *Container) makeCriuRestoreMountpoints(m *configs.Mount) error {
12771277
case "bind":
12781278
// The prepareBindMount() function checks if source
12791279
// exists. So it cannot be used for other filesystem types.
1280-
// TODO: pass something else than nil? Not sure if criu is
1281-
// impacted by issue #2484
1282-
if err := prepareBindMount(m, c.config.Rootfs, nil); err != nil {
1280+
// TODO: pass srcFD? Not sure if criu is impacted by issue #2484.
1281+
if err := prepareBindMount(mountEntry{Mount: m}, c.config.Rootfs); err != nil {
12831282
return err
12841283
}
12851284
default:
@@ -1357,8 +1356,8 @@ func (c *Container) prepareCriuRestoreMounts(mounts []*configs.Mount) error {
13571356
// because during initial container creation mounts are
13581357
// set up in the order they are configured.
13591358
if m.Device == "bind" {
1360-
if err := utils.WithProcfd(c.config.Rootfs, m.Destination, func(procfd string) error {
1361-
if err := mount(m.Source, m.Destination, procfd, "", unix.MS_BIND|unix.MS_REC, ""); err != nil {
1359+
if err := utils.WithProcfd(c.config.Rootfs, m.Destination, func(dstFD string) error {
1360+
if err := mountViaFDs(m.Source, "", m.Destination, dstFD, "", unix.MS_BIND|unix.MS_REC, ""); err != nil {
13621361
return err
13631362
}
13641363
return nil
@@ -1411,7 +1410,7 @@ func (c *Container) Restore(process *Process, criuOpts *CriuOpts) error {
14111410
if err != nil {
14121411
return err
14131412
}
1414-
err = mount(c.config.Rootfs, root, "", "", unix.MS_BIND|unix.MS_REC, "")
1413+
err = mount(c.config.Rootfs, root, "", unix.MS_BIND|unix.MS_REC, "")
14151414
if err != nil {
14161415
return err
14171416
}

libcontainer/mount_linux.go

Lines changed: 35 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,9 @@ import (
1010
type mountError struct {
1111
op string
1212
source string
13+
srcFD string
1314
target string
14-
procfd string
15+
dstFD string
1516
flags uintptr
1617
data string
1718
err error
@@ -22,19 +23,21 @@ func (e *mountError) Error() string {
2223
out := e.op + " "
2324

2425
if e.source != "" {
25-
out += e.source + ":" + e.target
26-
} else {
27-
out += e.target
26+
out += "src=" + e.source + ", "
27+
if e.srcFD != "" {
28+
out += "srcFD=" + e.srcFD + ", "
29+
}
2830
}
29-
if e.procfd != "" {
30-
out += " (via " + e.procfd + ")"
31+
out += "dst=" + e.target
32+
if e.dstFD != "" {
33+
out += ", dstFD=" + e.dstFD
3134
}
3235

3336
if e.flags != uintptr(0) {
34-
out += ", flags: 0x" + strconv.FormatUint(uint64(e.flags), 16)
37+
out += ", flags=0x" + strconv.FormatUint(uint64(e.flags), 16)
3538
}
3639
if e.data != "" {
37-
out += ", data: " + e.data
40+
out += ", data=" + e.data
3841
}
3942

4043
out += ": " + e.err.Error()
@@ -47,19 +50,36 @@ func (e *mountError) Unwrap() error {
4750
return e.err
4851
}
4952

50-
// mount is a simple unix.Mount wrapper. If procfd is not empty, it is used
51-
// instead of target (and the target is only used to add context to an error).
52-
func mount(source, target, procfd, fstype string, flags uintptr, data string) error {
53+
// mount is a simple unix.Mount wrapper, returning an error with more context
54+
// in case it failed.
55+
func mount(source, target, fstype string, flags uintptr, data string) error {
56+
return mountViaFDs(source, "", target, "", fstype, flags, data)
57+
}
58+
59+
// mountViaFDs is a unix.Mount wrapper which uses srcFD instead of source,
60+
// and dstFD instead of target, unless those are empty. The *FD arguments,
61+
// if non-empty, are expected to be in the form of a path to an opened file
62+
// descriptor on procfs (i.e. "/proc/self/fd/NN").
63+
//
64+
// If case an FD is used instead of a source or a target path, the
65+
// corresponding path is only used to add context to an error in case
66+
// the mount operation has failed.
67+
func mountViaFDs(source, srcFD, target, dstFD, fstype string, flags uintptr, data string) error {
68+
src := source
69+
if srcFD != "" {
70+
src = srcFD
71+
}
5372
dst := target
54-
if procfd != "" {
55-
dst = procfd
73+
if dstFD != "" {
74+
dst = dstFD
5675
}
57-
if err := unix.Mount(source, dst, fstype, flags, data); err != nil {
76+
if err := unix.Mount(src, dst, fstype, flags, data); err != nil {
5877
return &mountError{
5978
op: "mount",
6079
source: source,
80+
srcFD: srcFD,
6181
target: target,
62-
procfd: procfd,
82+
dstFD: dstFD,
6383
flags: flags,
6484
data: data,
6585
err: err,

0 commit comments

Comments
 (0)