mirror of
https://github.com/clearlinux/docker.git
synced 2026-09-06 13:41:36 +00:00
Handle external mounts outside of lxc
This commit is contained in:
@@ -6,6 +6,8 @@ import (
|
||||
"github.com/dotcloud/docker/utils"
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
type InitFunc func(root string) (Driver, error)
|
||||
@@ -31,6 +33,13 @@ type Differ interface {
|
||||
DiffSize(id string) (bytes int64, err error)
|
||||
}
|
||||
|
||||
type Mount struct {
|
||||
Device string
|
||||
Target string
|
||||
Type string
|
||||
Options string
|
||||
}
|
||||
|
||||
var (
|
||||
DefaultDriver string
|
||||
// All registred drivers
|
||||
@@ -88,3 +97,91 @@ func New(root string) (driver Driver, err error) {
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
func (m *Mount) Mount(root string) error {
|
||||
var (
|
||||
flag int
|
||||
data []string
|
||||
target = path.Join(root, m.Target)
|
||||
)
|
||||
|
||||
if mounted, err := Mounted(target); err != nil || mounted {
|
||||
return err
|
||||
}
|
||||
|
||||
flags := map[string]struct {
|
||||
clear bool
|
||||
flag int
|
||||
}{
|
||||
"defaults": {false, 0},
|
||||
"ro": {false, syscall.MS_RDONLY},
|
||||
"rw": {true, syscall.MS_RDONLY},
|
||||
"suid": {true, syscall.MS_NOSUID},
|
||||
"nosuid": {false, syscall.MS_NOSUID},
|
||||
"dev": {true, syscall.MS_NODEV},
|
||||
"nodev": {false, syscall.MS_NODEV},
|
||||
"exec": {true, syscall.MS_NOEXEC},
|
||||
"noexec": {false, syscall.MS_NOEXEC},
|
||||
"sync": {false, syscall.MS_SYNCHRONOUS},
|
||||
"async": {true, syscall.MS_SYNCHRONOUS},
|
||||
"dirsync": {false, syscall.MS_DIRSYNC},
|
||||
"remount": {false, syscall.MS_REMOUNT},
|
||||
"mand": {false, syscall.MS_MANDLOCK},
|
||||
"nomand": {true, syscall.MS_MANDLOCK},
|
||||
"atime": {true, syscall.MS_NOATIME},
|
||||
"noatime": {false, syscall.MS_NOATIME},
|
||||
"diratime": {true, syscall.MS_NODIRATIME},
|
||||
"nodiratime": {false, syscall.MS_NODIRATIME},
|
||||
"bind": {false, syscall.MS_BIND},
|
||||
"rbind": {false, syscall.MS_BIND | syscall.MS_REC},
|
||||
"relatime": {false, syscall.MS_RELATIME},
|
||||
"norelatime": {true, syscall.MS_RELATIME},
|
||||
"strictatime": {false, syscall.MS_STRICTATIME},
|
||||
"nostrictatime": {true, syscall.MS_STRICTATIME},
|
||||
}
|
||||
|
||||
for _, o := range strings.Split(m.Options, ",") {
|
||||
// If the option does not exist in the flags table then it is a
|
||||
// data value for a specific fs type
|
||||
if f, exists := flags[o]; exists {
|
||||
if f.clear {
|
||||
flag &= ^f.flag
|
||||
} else {
|
||||
flag |= f.flag
|
||||
}
|
||||
} else {
|
||||
data = append(data, o)
|
||||
}
|
||||
}
|
||||
|
||||
if err := syscall.Mount(m.Device, target, m.Type, uintptr(flag), strings.Join(data, ",")); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Mount) Unmount(root string) error {
|
||||
target := path.Join(root, m.Target)
|
||||
if mounted, err := Mounted(target); err != nil || !mounted {
|
||||
return err
|
||||
}
|
||||
return syscall.Unmount(target, 0)
|
||||
}
|
||||
|
||||
func Mounted(mountpoint string) (bool, error) {
|
||||
mntpoint, err := os.Stat(mountpoint)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return false, nil
|
||||
}
|
||||
return false, err
|
||||
}
|
||||
parent, err := os.Stat(path.Join(mountpoint, ".."))
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
mntpointSt := mntpoint.Sys().(*syscall.Stat_t)
|
||||
parentSt := parent.Sys().(*syscall.Stat_t)
|
||||
|
||||
return mntpointSt.Dev != parentSt.Dev, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user