mirror of
https://github.com/opencontainers/runc.git
synced 2026-07-11 14:13:58 +08:00
976748e8d6
1. Simplify mount call by removing the procfd argument, and use the new mount() where procfd is not used. Now, the mount() arguments are the same as for unix.Mount. 2. Introduce a new mountViaFDs function, which is similar to the old mount(), except it can take procfd for both source and target. The new arguments are called srcFD and dstFD. 3. Modify the mount error to show both srcFD and dstFD so it's clear which one is used for which purpose. This fixes the issue of having a somewhat cryptic errors like this: > mount /proc/self/fd/11:/sys/fs/cgroup/systemd (via /proc/self/fd/12), flags: 0x20502f: operation not permitted (in which fd 11 is actually the source, and fd 12 is the target). After this change, it looks like > mount src=/proc/self/fd/11, dst=/sys/fs/cgroup/systemd, dstFD=/proc/self/fd/12, flags=0x20502f: operation not permitted so it's clear that 12 is a destination fd. 4. Fix the mountViaFDs callers to use dstFD (rather than procfd) for the variable name. 5. Use srcFD where mountFd is set. Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
104 lines
2.3 KiB
Go
104 lines
2.3 KiB
Go
package libcontainer
|
|
|
|
import (
|
|
"strconv"
|
|
|
|
"golang.org/x/sys/unix"
|
|
)
|
|
|
|
// mountError holds an error from a failed mount or unmount operation.
|
|
type mountError struct {
|
|
op string
|
|
source string
|
|
srcFD string
|
|
target string
|
|
dstFD string
|
|
flags uintptr
|
|
data string
|
|
err error
|
|
}
|
|
|
|
// Error provides a string error representation.
|
|
func (e *mountError) Error() string {
|
|
out := e.op + " "
|
|
|
|
if e.source != "" {
|
|
out += "src=" + e.source + ", "
|
|
if e.srcFD != "" {
|
|
out += "srcFD=" + e.srcFD + ", "
|
|
}
|
|
}
|
|
out += "dst=" + e.target
|
|
if e.dstFD != "" {
|
|
out += ", dstFD=" + e.dstFD
|
|
}
|
|
|
|
if e.flags != uintptr(0) {
|
|
out += ", flags=0x" + strconv.FormatUint(uint64(e.flags), 16)
|
|
}
|
|
if e.data != "" {
|
|
out += ", data=" + e.data
|
|
}
|
|
|
|
out += ": " + e.err.Error()
|
|
return out
|
|
}
|
|
|
|
// Unwrap returns the underlying error.
|
|
// This is a convention used by Go 1.13+ standard library.
|
|
func (e *mountError) Unwrap() error {
|
|
return e.err
|
|
}
|
|
|
|
// mount is a simple unix.Mount wrapper, returning an error with more context
|
|
// in case it failed.
|
|
func mount(source, target, fstype string, flags uintptr, data string) error {
|
|
return mountViaFDs(source, "", target, "", fstype, flags, data)
|
|
}
|
|
|
|
// mountViaFDs is a unix.Mount wrapper which uses srcFD instead of source,
|
|
// and dstFD instead of target, unless those are empty. The *FD arguments,
|
|
// if non-empty, are expected to be in the form of a path to an opened file
|
|
// descriptor on procfs (i.e. "/proc/self/fd/NN").
|
|
//
|
|
// If case an FD is used instead of a source or a target path, the
|
|
// corresponding path is only used to add context to an error in case
|
|
// the mount operation has failed.
|
|
func mountViaFDs(source, srcFD, target, dstFD, fstype string, flags uintptr, data string) error {
|
|
src := source
|
|
if srcFD != "" {
|
|
src = srcFD
|
|
}
|
|
dst := target
|
|
if dstFD != "" {
|
|
dst = dstFD
|
|
}
|
|
if err := unix.Mount(src, dst, fstype, flags, data); err != nil {
|
|
return &mountError{
|
|
op: "mount",
|
|
source: source,
|
|
srcFD: srcFD,
|
|
target: target,
|
|
dstFD: dstFD,
|
|
flags: flags,
|
|
data: data,
|
|
err: err,
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// unmount is a simple unix.Unmount wrapper.
|
|
func unmount(target string, flags int) error {
|
|
err := unix.Unmount(target, flags)
|
|
if err != nil {
|
|
return &mountError{
|
|
op: "unmount",
|
|
target: target,
|
|
flags: uintptr(flags),
|
|
err: err,
|
|
}
|
|
}
|
|
return nil
|
|
}
|