Import docker/docker/pkg/mount into runc
This will help get rid of docker/docker dependency in runc 👼
Signed-off-by: Vincent Demeester <vincent@sbr.pm>
This commit is contained in:
parent
ababa2d2ce
commit
3ca4c78b1a
|
@ -11,13 +11,13 @@ import (
|
||||||
"runtime/debug"
|
"runtime/debug"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/docker/docker/pkg/mount"
|
|
||||||
"github.com/opencontainers/runc/libcontainer/cgroups"
|
"github.com/opencontainers/runc/libcontainer/cgroups"
|
||||||
"github.com/opencontainers/runc/libcontainer/cgroups/fs"
|
"github.com/opencontainers/runc/libcontainer/cgroups/fs"
|
||||||
"github.com/opencontainers/runc/libcontainer/cgroups/systemd"
|
"github.com/opencontainers/runc/libcontainer/cgroups/systemd"
|
||||||
"github.com/opencontainers/runc/libcontainer/configs"
|
"github.com/opencontainers/runc/libcontainer/configs"
|
||||||
"github.com/opencontainers/runc/libcontainer/configs/validate"
|
"github.com/opencontainers/runc/libcontainer/configs/validate"
|
||||||
"github.com/opencontainers/runc/libcontainer/intelrdt"
|
"github.com/opencontainers/runc/libcontainer/intelrdt"
|
||||||
|
"github.com/opencontainers/runc/libcontainer/mount"
|
||||||
"github.com/opencontainers/runc/libcontainer/utils"
|
"github.com/opencontainers/runc/libcontainer/utils"
|
||||||
|
|
||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
|
|
|
@ -9,8 +9,8 @@ import (
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/docker/docker/pkg/mount"
|
|
||||||
"github.com/opencontainers/runc/libcontainer/configs"
|
"github.com/opencontainers/runc/libcontainer/configs"
|
||||||
|
"github.com/opencontainers/runc/libcontainer/mount"
|
||||||
"github.com/opencontainers/runc/libcontainer/utils"
|
"github.com/opencontainers/runc/libcontainer/utils"
|
||||||
|
|
||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
package mount
|
||||||
|
|
||||||
|
// GetMounts retrieves a list of mounts for the current running process.
|
||||||
|
func GetMounts() ([]*Info, error) {
|
||||||
|
return parseMountTable()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mounted looks at /proc/self/mountinfo to determine of the specified
|
||||||
|
// mountpoint has been mounted
|
||||||
|
func Mounted(mountpoint string) (bool, error) {
|
||||||
|
entries, err := parseMountTable()
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Search the table for the mountpoint
|
||||||
|
for _, e := range entries {
|
||||||
|
if e.Mountpoint == mountpoint {
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false, nil
|
||||||
|
}
|
|
@ -80,16 +80,3 @@ func parseInfoFile(r io.Reader) ([]*Info, error) {
|
||||||
}
|
}
|
||||||
return out, nil
|
return out, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// PidMountInfo collects the mounts for a specific process ID. If the process
|
|
||||||
// ID is unknown, it is better to use `GetMounts` which will inspect
|
|
||||||
// "/proc/self/mountinfo" instead.
|
|
||||||
func PidMountInfo(pid int) ([]*Info, error) {
|
|
||||||
f, err := os.Open(fmt.Sprintf("/proc/%d/mountinfo", pid))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
defer f.Close()
|
|
||||||
|
|
||||||
return parseInfoFile(f)
|
|
||||||
}
|
|
|
@ -14,10 +14,10 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/cyphar/filepath-securejoin"
|
"github.com/cyphar/filepath-securejoin"
|
||||||
"github.com/docker/docker/pkg/mount"
|
|
||||||
"github.com/mrunalp/fileutils"
|
"github.com/mrunalp/fileutils"
|
||||||
"github.com/opencontainers/runc/libcontainer/cgroups"
|
"github.com/opencontainers/runc/libcontainer/cgroups"
|
||||||
"github.com/opencontainers/runc/libcontainer/configs"
|
"github.com/opencontainers/runc/libcontainer/configs"
|
||||||
|
"github.com/opencontainers/runc/libcontainer/mount"
|
||||||
"github.com/opencontainers/runc/libcontainer/system"
|
"github.com/opencontainers/runc/libcontainer/system"
|
||||||
libcontainerUtils "github.com/opencontainers/runc/libcontainer/utils"
|
libcontainerUtils "github.com/opencontainers/runc/libcontainer/utils"
|
||||||
"github.com/opencontainers/selinux/go-selinux/label"
|
"github.com/opencontainers/selinux/go-selinux/label"
|
||||||
|
|
|
@ -1,69 +0,0 @@
|
||||||
package mount
|
|
||||||
|
|
||||||
import (
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Parse fstab type mount options into mount() flags
|
|
||||||
// and device specific data
|
|
||||||
func parseOptions(options string) (int, string) {
|
|
||||||
var (
|
|
||||||
flag int
|
|
||||||
data []string
|
|
||||||
)
|
|
||||||
|
|
||||||
flags := map[string]struct {
|
|
||||||
clear bool
|
|
||||||
flag int
|
|
||||||
}{
|
|
||||||
"defaults": {false, 0},
|
|
||||||
"ro": {false, RDONLY},
|
|
||||||
"rw": {true, RDONLY},
|
|
||||||
"suid": {true, NOSUID},
|
|
||||||
"nosuid": {false, NOSUID},
|
|
||||||
"dev": {true, NODEV},
|
|
||||||
"nodev": {false, NODEV},
|
|
||||||
"exec": {true, NOEXEC},
|
|
||||||
"noexec": {false, NOEXEC},
|
|
||||||
"sync": {false, SYNCHRONOUS},
|
|
||||||
"async": {true, SYNCHRONOUS},
|
|
||||||
"dirsync": {false, DIRSYNC},
|
|
||||||
"remount": {false, REMOUNT},
|
|
||||||
"mand": {false, MANDLOCK},
|
|
||||||
"nomand": {true, MANDLOCK},
|
|
||||||
"atime": {true, NOATIME},
|
|
||||||
"noatime": {false, NOATIME},
|
|
||||||
"diratime": {true, NODIRATIME},
|
|
||||||
"nodiratime": {false, NODIRATIME},
|
|
||||||
"bind": {false, BIND},
|
|
||||||
"rbind": {false, RBIND},
|
|
||||||
"unbindable": {false, UNBINDABLE},
|
|
||||||
"runbindable": {false, RUNBINDABLE},
|
|
||||||
"private": {false, PRIVATE},
|
|
||||||
"rprivate": {false, RPRIVATE},
|
|
||||||
"shared": {false, SHARED},
|
|
||||||
"rshared": {false, RSHARED},
|
|
||||||
"slave": {false, SLAVE},
|
|
||||||
"rslave": {false, RSLAVE},
|
|
||||||
"relatime": {false, RELATIME},
|
|
||||||
"norelatime": {true, RELATIME},
|
|
||||||
"strictatime": {false, STRICTATIME},
|
|
||||||
"nostrictatime": {true, STRICTATIME},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, o := range strings.Split(options, ",") {
|
|
||||||
// If the option does not exist in the flags table or the flag
|
|
||||||
// is not supported on the platform,
|
|
||||||
// then it is a data value for a specific fs type
|
|
||||||
if f, exists := flags[o]; exists && f.flag != 0 {
|
|
||||||
if f.clear {
|
|
||||||
flag &= ^f.flag
|
|
||||||
} else {
|
|
||||||
flag |= f.flag
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
data = append(data, o)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return flag, strings.Join(data, ",")
|
|
||||||
}
|
|
|
@ -1,48 +0,0 @@
|
||||||
// +build freebsd,cgo
|
|
||||||
|
|
||||||
package mount
|
|
||||||
|
|
||||||
/*
|
|
||||||
#include <sys/mount.h>
|
|
||||||
*/
|
|
||||||
import "C"
|
|
||||||
|
|
||||||
const (
|
|
||||||
// RDONLY will mount the filesystem as read-only.
|
|
||||||
RDONLY = C.MNT_RDONLY
|
|
||||||
|
|
||||||
// NOSUID will not allow set-user-identifier or set-group-identifier bits to
|
|
||||||
// take effect.
|
|
||||||
NOSUID = C.MNT_NOSUID
|
|
||||||
|
|
||||||
// NOEXEC will not allow execution of any binaries on the mounted file system.
|
|
||||||
NOEXEC = C.MNT_NOEXEC
|
|
||||||
|
|
||||||
// SYNCHRONOUS will allow any I/O to the file system to be done synchronously.
|
|
||||||
SYNCHRONOUS = C.MNT_SYNCHRONOUS
|
|
||||||
|
|
||||||
// NOATIME will not update the file access time when reading from a file.
|
|
||||||
NOATIME = C.MNT_NOATIME
|
|
||||||
)
|
|
||||||
|
|
||||||
// These flags are unsupported.
|
|
||||||
const (
|
|
||||||
BIND = 0
|
|
||||||
DIRSYNC = 0
|
|
||||||
MANDLOCK = 0
|
|
||||||
NODEV = 0
|
|
||||||
NODIRATIME = 0
|
|
||||||
UNBINDABLE = 0
|
|
||||||
RUNBINDABLE = 0
|
|
||||||
PRIVATE = 0
|
|
||||||
RPRIVATE = 0
|
|
||||||
SHARED = 0
|
|
||||||
RSHARED = 0
|
|
||||||
SLAVE = 0
|
|
||||||
RSLAVE = 0
|
|
||||||
RBIND = 0
|
|
||||||
RELATIVE = 0
|
|
||||||
RELATIME = 0
|
|
||||||
REMOUNT = 0
|
|
||||||
STRICTATIME = 0
|
|
||||||
)
|
|
|
@ -1,85 +0,0 @@
|
||||||
package mount
|
|
||||||
|
|
||||||
import (
|
|
||||||
"syscall"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
// RDONLY will mount the file system read-only.
|
|
||||||
RDONLY = syscall.MS_RDONLY
|
|
||||||
|
|
||||||
// NOSUID will not allow set-user-identifier or set-group-identifier bits to
|
|
||||||
// take effect.
|
|
||||||
NOSUID = syscall.MS_NOSUID
|
|
||||||
|
|
||||||
// NODEV will not interpret character or block special devices on the file
|
|
||||||
// system.
|
|
||||||
NODEV = syscall.MS_NODEV
|
|
||||||
|
|
||||||
// NOEXEC will not allow execution of any binaries on the mounted file system.
|
|
||||||
NOEXEC = syscall.MS_NOEXEC
|
|
||||||
|
|
||||||
// SYNCHRONOUS will allow I/O to the file system to be done synchronously.
|
|
||||||
SYNCHRONOUS = syscall.MS_SYNCHRONOUS
|
|
||||||
|
|
||||||
// DIRSYNC will force all directory updates within the file system to be done
|
|
||||||
// synchronously. This affects the following system calls: creat, link,
|
|
||||||
// unlink, symlink, mkdir, rmdir, mknod and rename.
|
|
||||||
DIRSYNC = syscall.MS_DIRSYNC
|
|
||||||
|
|
||||||
// REMOUNT will attempt to remount an already-mounted file system. This is
|
|
||||||
// commonly used to change the mount flags for a file system, especially to
|
|
||||||
// make a readonly file system writeable. It does not change device or mount
|
|
||||||
// point.
|
|
||||||
REMOUNT = syscall.MS_REMOUNT
|
|
||||||
|
|
||||||
// MANDLOCK will force mandatory locks on a filesystem.
|
|
||||||
MANDLOCK = syscall.MS_MANDLOCK
|
|
||||||
|
|
||||||
// NOATIME will not update the file access time when reading from a file.
|
|
||||||
NOATIME = syscall.MS_NOATIME
|
|
||||||
|
|
||||||
// NODIRATIME will not update the directory access time.
|
|
||||||
NODIRATIME = syscall.MS_NODIRATIME
|
|
||||||
|
|
||||||
// BIND remounts a subtree somewhere else.
|
|
||||||
BIND = syscall.MS_BIND
|
|
||||||
|
|
||||||
// RBIND remounts a subtree and all possible submounts somewhere else.
|
|
||||||
RBIND = syscall.MS_BIND | syscall.MS_REC
|
|
||||||
|
|
||||||
// UNBINDABLE creates a mount which cannot be cloned through a bind operation.
|
|
||||||
UNBINDABLE = syscall.MS_UNBINDABLE
|
|
||||||
|
|
||||||
// RUNBINDABLE marks the entire mount tree as UNBINDABLE.
|
|
||||||
RUNBINDABLE = syscall.MS_UNBINDABLE | syscall.MS_REC
|
|
||||||
|
|
||||||
// PRIVATE creates a mount which carries no propagation abilities.
|
|
||||||
PRIVATE = syscall.MS_PRIVATE
|
|
||||||
|
|
||||||
// RPRIVATE marks the entire mount tree as PRIVATE.
|
|
||||||
RPRIVATE = syscall.MS_PRIVATE | syscall.MS_REC
|
|
||||||
|
|
||||||
// SLAVE creates a mount which receives propagation from its master, but not
|
|
||||||
// vice versa.
|
|
||||||
SLAVE = syscall.MS_SLAVE
|
|
||||||
|
|
||||||
// RSLAVE marks the entire mount tree as SLAVE.
|
|
||||||
RSLAVE = syscall.MS_SLAVE | syscall.MS_REC
|
|
||||||
|
|
||||||
// SHARED creates a mount which provides the ability to create mirrors of
|
|
||||||
// that mount such that mounts and unmounts within any of the mirrors
|
|
||||||
// propagate to the other mirrors.
|
|
||||||
SHARED = syscall.MS_SHARED
|
|
||||||
|
|
||||||
// RSHARED marks the entire mount tree as SHARED.
|
|
||||||
RSHARED = syscall.MS_SHARED | syscall.MS_REC
|
|
||||||
|
|
||||||
// RELATIME updates inode access times relative to modify or change time.
|
|
||||||
RELATIME = syscall.MS_RELATIME
|
|
||||||
|
|
||||||
// STRICTATIME allows to explicitly request full atime updates. This makes
|
|
||||||
// it possible for the kernel to default to relatime or noatime but still
|
|
||||||
// allow userspace to override it.
|
|
||||||
STRICTATIME = syscall.MS_STRICTATIME
|
|
||||||
)
|
|
|
@ -1,30 +0,0 @@
|
||||||
// +build !linux,!freebsd freebsd,!cgo
|
|
||||||
|
|
||||||
package mount
|
|
||||||
|
|
||||||
// These flags are unsupported.
|
|
||||||
const (
|
|
||||||
BIND = 0
|
|
||||||
DIRSYNC = 0
|
|
||||||
MANDLOCK = 0
|
|
||||||
NOATIME = 0
|
|
||||||
NODEV = 0
|
|
||||||
NODIRATIME = 0
|
|
||||||
NOEXEC = 0
|
|
||||||
NOSUID = 0
|
|
||||||
UNBINDABLE = 0
|
|
||||||
RUNBINDABLE = 0
|
|
||||||
PRIVATE = 0
|
|
||||||
RPRIVATE = 0
|
|
||||||
SHARED = 0
|
|
||||||
RSHARED = 0
|
|
||||||
SLAVE = 0
|
|
||||||
RSLAVE = 0
|
|
||||||
RBIND = 0
|
|
||||||
RELATIME = 0
|
|
||||||
RELATIVE = 0
|
|
||||||
REMOUNT = 0
|
|
||||||
STRICTATIME = 0
|
|
||||||
SYNCHRONOUS = 0
|
|
||||||
RDONLY = 0
|
|
||||||
)
|
|
|
@ -1,74 +0,0 @@
|
||||||
package mount
|
|
||||||
|
|
||||||
import (
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
// GetMounts retrieves a list of mounts for the current running process.
|
|
||||||
func GetMounts() ([]*Info, error) {
|
|
||||||
return parseMountTable()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mounted looks at /proc/self/mountinfo to determine of the specified
|
|
||||||
// mountpoint has been mounted
|
|
||||||
func Mounted(mountpoint string) (bool, error) {
|
|
||||||
entries, err := parseMountTable()
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Search the table for the mountpoint
|
|
||||||
for _, e := range entries {
|
|
||||||
if e.Mountpoint == mountpoint {
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mount will mount filesystem according to the specified configuration, on the
|
|
||||||
// condition that the target path is *not* already mounted. Options must be
|
|
||||||
// specified like the mount or fstab unix commands: "opt1=val1,opt2=val2". See
|
|
||||||
// flags.go for supported option flags.
|
|
||||||
func Mount(device, target, mType, options string) error {
|
|
||||||
flag, _ := parseOptions(options)
|
|
||||||
if flag&REMOUNT != REMOUNT {
|
|
||||||
if mounted, err := Mounted(target); err != nil || mounted {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ForceMount(device, target, mType, options)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ForceMount will mount a filesystem according to the specified configuration,
|
|
||||||
// *regardless* if the target path is not already mounted. Options must be
|
|
||||||
// specified like the mount or fstab unix commands: "opt1=val1,opt2=val2". See
|
|
||||||
// flags.go for supported option flags.
|
|
||||||
func ForceMount(device, target, mType, options string) error {
|
|
||||||
flag, data := parseOptions(options)
|
|
||||||
if err := mount(device, target, mType, uintptr(flag), data); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unmount will unmount the target filesystem, so long as it is mounted.
|
|
||||||
func Unmount(target string) error {
|
|
||||||
if mounted, err := Mounted(target); err != nil || !mounted {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return ForceUnmount(target)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ForceUnmount will force an unmount of the target filesystem, regardless if
|
|
||||||
// it is mounted or not.
|
|
||||||
func ForceUnmount(target string) (err error) {
|
|
||||||
// Simple retry logic for unmount
|
|
||||||
for i := 0; i < 10; i++ {
|
|
||||||
if err = unmount(target, 0); err == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
time.Sleep(100 * time.Millisecond)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
|
@ -1,59 +0,0 @@
|
||||||
package mount
|
|
||||||
|
|
||||||
/*
|
|
||||||
#include <errno.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <sys/_iovec.h>
|
|
||||||
#include <sys/mount.h>
|
|
||||||
#include <sys/param.h>
|
|
||||||
*/
|
|
||||||
import "C"
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
"syscall"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
func allocateIOVecs(options []string) []C.struct_iovec {
|
|
||||||
out := make([]C.struct_iovec, len(options))
|
|
||||||
for i, option := range options {
|
|
||||||
out[i].iov_base = unsafe.Pointer(C.CString(option))
|
|
||||||
out[i].iov_len = C.size_t(len(option) + 1)
|
|
||||||
}
|
|
||||||
return out
|
|
||||||
}
|
|
||||||
|
|
||||||
func mount(device, target, mType string, flag uintptr, data string) error {
|
|
||||||
isNullFS := false
|
|
||||||
|
|
||||||
xs := strings.Split(data, ",")
|
|
||||||
for _, x := range xs {
|
|
||||||
if x == "bind" {
|
|
||||||
isNullFS = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
options := []string{"fspath", target}
|
|
||||||
if isNullFS {
|
|
||||||
options = append(options, "fstype", "nullfs", "target", device)
|
|
||||||
} else {
|
|
||||||
options = append(options, "fstype", mType, "from", device)
|
|
||||||
}
|
|
||||||
rawOptions := allocateIOVecs(options)
|
|
||||||
for _, rawOption := range rawOptions {
|
|
||||||
defer C.free(rawOption.iov_base)
|
|
||||||
}
|
|
||||||
|
|
||||||
if errno := C.nmount(&rawOptions[0], C.uint(len(options)), C.int(flag)); errno != 0 {
|
|
||||||
reason := C.GoString(C.strerror(*C.__error()))
|
|
||||||
return fmt.Errorf("Failed to call nmount: %s", reason)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func unmount(target string, flag int) error {
|
|
||||||
return syscall.Unmount(target, flag)
|
|
||||||
}
|
|
|
@ -1,21 +0,0 @@
|
||||||
package mount
|
|
||||||
|
|
||||||
import (
|
|
||||||
"syscall"
|
|
||||||
)
|
|
||||||
|
|
||||||
func mount(device, target, mType string, flag uintptr, data string) error {
|
|
||||||
if err := syscall.Mount(device, target, mType, flag, data); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we have a bind mount or remount, remount...
|
|
||||||
if flag&syscall.MS_BIND == syscall.MS_BIND && flag&syscall.MS_RDONLY == syscall.MS_RDONLY {
|
|
||||||
return syscall.Mount(device, target, mType, flag|syscall.MS_REMOUNT, data)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func unmount(target string, flag int) error {
|
|
||||||
return syscall.Unmount(target, flag)
|
|
||||||
}
|
|
|
@ -1,11 +0,0 @@
|
||||||
// +build !linux,!freebsd freebsd,!cgo
|
|
||||||
|
|
||||||
package mount
|
|
||||||
|
|
||||||
func mount(device, target, mType string, flag uintptr, data string) error {
|
|
||||||
panic("Not implemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
func unmount(target string, flag int) error {
|
|
||||||
panic("Not implemented")
|
|
||||||
}
|
|
|
@ -1,70 +0,0 @@
|
||||||
// +build linux
|
|
||||||
|
|
||||||
package mount
|
|
||||||
|
|
||||||
// MakeShared ensures a mounted filesystem has the SHARED mount option enabled.
|
|
||||||
// See the supported options in flags.go for further reference.
|
|
||||||
func MakeShared(mountPoint string) error {
|
|
||||||
return ensureMountedAs(mountPoint, "shared")
|
|
||||||
}
|
|
||||||
|
|
||||||
// MakeRShared ensures a mounted filesystem has the RSHARED mount option enabled.
|
|
||||||
// See the supported options in flags.go for further reference.
|
|
||||||
func MakeRShared(mountPoint string) error {
|
|
||||||
return ensureMountedAs(mountPoint, "rshared")
|
|
||||||
}
|
|
||||||
|
|
||||||
// MakePrivate ensures a mounted filesystem has the PRIVATE mount option enabled.
|
|
||||||
// See the supported options in flags.go for further reference.
|
|
||||||
func MakePrivate(mountPoint string) error {
|
|
||||||
return ensureMountedAs(mountPoint, "private")
|
|
||||||
}
|
|
||||||
|
|
||||||
// MakeRPrivate ensures a mounted filesystem has the RPRIVATE mount option
|
|
||||||
// enabled. See the supported options in flags.go for further reference.
|
|
||||||
func MakeRPrivate(mountPoint string) error {
|
|
||||||
return ensureMountedAs(mountPoint, "rprivate")
|
|
||||||
}
|
|
||||||
|
|
||||||
// MakeSlave ensures a mounted filesystem has the SLAVE mount option enabled.
|
|
||||||
// See the supported options in flags.go for further reference.
|
|
||||||
func MakeSlave(mountPoint string) error {
|
|
||||||
return ensureMountedAs(mountPoint, "slave")
|
|
||||||
}
|
|
||||||
|
|
||||||
// MakeRSlave ensures a mounted filesystem has the RSLAVE mount option enabled.
|
|
||||||
// See the supported options in flags.go for further reference.
|
|
||||||
func MakeRSlave(mountPoint string) error {
|
|
||||||
return ensureMountedAs(mountPoint, "rslave")
|
|
||||||
}
|
|
||||||
|
|
||||||
// MakeUnbindable ensures a mounted filesystem has the UNBINDABLE mount option
|
|
||||||
// enabled. See the supported options in flags.go for further reference.
|
|
||||||
func MakeUnbindable(mountPoint string) error {
|
|
||||||
return ensureMountedAs(mountPoint, "unbindable")
|
|
||||||
}
|
|
||||||
|
|
||||||
// MakeRUnbindable ensures a mounted filesystem has the RUNBINDABLE mount
|
|
||||||
// option enabled. See the supported options in flags.go for further reference.
|
|
||||||
func MakeRUnbindable(mountPoint string) error {
|
|
||||||
return ensureMountedAs(mountPoint, "runbindable")
|
|
||||||
}
|
|
||||||
|
|
||||||
func ensureMountedAs(mountPoint, options string) error {
|
|
||||||
mounted, err := Mounted(mountPoint)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if !mounted {
|
|
||||||
if err := Mount(mountPoint, mountPoint, "none", "bind,rw"); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mounted, err = Mounted(mountPoint)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return ForceMount("", mountPoint, "none", options)
|
|
||||||
}
|
|
Loading…
Reference in New Issue