Partial port to Darwin and FreeBSD
This mainly fixes Linux vs generic Unix differences, with some differences between Darwin and Freebsd (which are close bit not identical). Should make fixing for other Unix platforms easier. Note there are not yet `runc` equivalents for these platforms; my current use case is image manipulation for the `moby` tool. However there is interest in OCI runtime ports for both platforms. Current status is that MacOS can build and run `ctr`, `dist` and `containerd` and some operations are supported. FreeBSD 11 still needs some more fixes to continuity for extended attributes. Signed-off-by: Justin Cormack <justin.cormack@docker.com>
This commit is contained in:
parent
98be9f4b4e
commit
1d27259777
@ -1,3 +1,5 @@
|
|||||||
|
// +build !windows
|
||||||
|
|
||||||
package archive
|
package archive
|
||||||
|
|
||||||
import (
|
import (
|
14
archive/time_darwin.go
Normal file
14
archive/time_darwin.go
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
package archive
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
// as at MacOS 10.12 there is apparently no way to set timestamps
|
||||||
|
// with nanosecond precision. We could fall back to utimes/lutimes
|
||||||
|
// and lose the precision as a temporary workaround.
|
||||||
|
func chtimes(path string, atime, mtime time.Time) error {
|
||||||
|
return errors.New("OSX missing UtimesNanoAt")
|
||||||
|
}
|
@ -1,3 +1,5 @@
|
|||||||
|
// +build linux freebsd
|
||||||
|
|
||||||
package archive
|
package archive
|
||||||
|
|
||||||
import (
|
import (
|
7
cmd/containerd/builtins_unix.go
Normal file
7
cmd/containerd/builtins_unix.go
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
// +build darwin freebsd
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
_ "github.com/containerd/containerd/snapshot/naive"
|
||||||
|
)
|
16
cmd/containerd/config_linux.go
Normal file
16
cmd/containerd/config_linux.go
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
func defaultConfig() *config {
|
||||||
|
return &config{
|
||||||
|
Root: "/var/lib/containerd",
|
||||||
|
State: "/run/containerd",
|
||||||
|
GRPC: grpcConfig{
|
||||||
|
Address: "/run/containerd/containerd.sock",
|
||||||
|
},
|
||||||
|
Debug: debug{
|
||||||
|
Level: "info",
|
||||||
|
Address: "/run/containerd/debug.sock",
|
||||||
|
},
|
||||||
|
Snapshotter: "overlay",
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
// +build !windows
|
// +build darwin freebsd
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
@ -13,6 +13,6 @@ func defaultConfig() *config {
|
|||||||
Level: "info",
|
Level: "info",
|
||||||
Address: "/run/containerd/debug.sock",
|
Address: "/run/containerd/debug.sock",
|
||||||
},
|
},
|
||||||
Snapshotter: "overlay",
|
Snapshotter: "naive",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
59
cmd/containerd/main_linux.go
Normal file
59
cmd/containerd/main_linux.go
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"golang.org/x/sys/unix"
|
||||||
|
|
||||||
|
"github.com/containerd/containerd/log"
|
||||||
|
"github.com/containerd/containerd/reaper"
|
||||||
|
"github.com/containerd/containerd/sys"
|
||||||
|
"github.com/urfave/cli"
|
||||||
|
"google.golang.org/grpc"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
defaultConfigPath = "/etc/containerd/config.toml"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
handledSignals = []os.Signal{unix.SIGTERM, unix.SIGINT, unix.SIGUSR1, unix.SIGCHLD}
|
||||||
|
)
|
||||||
|
|
||||||
|
func platformInit(context *cli.Context) error {
|
||||||
|
if conf.Subreaper {
|
||||||
|
log.G(global).Info("setting subreaper...")
|
||||||
|
if err := sys.SetSubreaper(1); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if conf.OOMScore != 0 {
|
||||||
|
log.G(global).Infof("changing OOM score to %d", conf.OOMScore)
|
||||||
|
if err := sys.SetOOMScore(os.Getpid(), conf.OOMScore); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err := os.MkdirAll(conf.State, 0750); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := os.Chown(conf.State, conf.GRPC.Uid, conf.GRPC.Gid); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleSignals(signals chan os.Signal, server *grpc.Server) error {
|
||||||
|
for s := range signals {
|
||||||
|
log.G(global).WithField("signal", s).Debug("received signal")
|
||||||
|
switch s {
|
||||||
|
case unix.SIGCHLD:
|
||||||
|
if err := reaper.Reap(); err != nil {
|
||||||
|
log.G(global).WithError(err).Error("reap containerd processes")
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
server.Stop()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
// +build !windows
|
// +build darwin freebsd
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
@ -9,7 +9,6 @@ import (
|
|||||||
|
|
||||||
"github.com/containerd/containerd/log"
|
"github.com/containerd/containerd/log"
|
||||||
"github.com/containerd/containerd/reaper"
|
"github.com/containerd/containerd/reaper"
|
||||||
"github.com/containerd/containerd/sys"
|
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
)
|
)
|
||||||
@ -23,18 +22,6 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func platformInit(context *cli.Context) error {
|
func platformInit(context *cli.Context) error {
|
||||||
if conf.Subreaper {
|
|
||||||
log.G(global).Info("setting subreaper...")
|
|
||||||
if err := sys.SetSubreaper(1); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if conf.OOMScore != 0 {
|
|
||||||
log.G(global).Infof("changing OOM score to %d", conf.OOMScore)
|
|
||||||
if err := sys.SetOOMScore(os.Getpid(), conf.OOMScore); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if err := os.MkdirAll(conf.State, 0750); err != nil {
|
if err := os.MkdirAll(conf.State, 0750); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// +build linux
|
// +build !windows
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
|
45
cmd/ctr/signals_linux.go
Normal file
45
cmd/ctr/signals_linux.go
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"syscall"
|
||||||
|
|
||||||
|
"golang.org/x/sys/unix"
|
||||||
|
)
|
||||||
|
|
||||||
|
var signalMap = map[string]syscall.Signal{
|
||||||
|
"ABRT": unix.SIGABRT,
|
||||||
|
"ALRM": unix.SIGALRM,
|
||||||
|
"BUS": unix.SIGBUS,
|
||||||
|
"CHLD": unix.SIGCHLD,
|
||||||
|
"CLD": unix.SIGCLD,
|
||||||
|
"CONT": unix.SIGCONT,
|
||||||
|
"FPE": unix.SIGFPE,
|
||||||
|
"HUP": unix.SIGHUP,
|
||||||
|
"ILL": unix.SIGILL,
|
||||||
|
"INT": unix.SIGINT,
|
||||||
|
"IO": unix.SIGIO,
|
||||||
|
"IOT": unix.SIGIOT,
|
||||||
|
"KILL": unix.SIGKILL,
|
||||||
|
"PIPE": unix.SIGPIPE,
|
||||||
|
"POLL": unix.SIGPOLL,
|
||||||
|
"PROF": unix.SIGPROF,
|
||||||
|
"PWR": unix.SIGPWR,
|
||||||
|
"QUIT": unix.SIGQUIT,
|
||||||
|
"SEGV": unix.SIGSEGV,
|
||||||
|
"STKFLT": unix.SIGSTKFLT,
|
||||||
|
"STOP": unix.SIGSTOP,
|
||||||
|
"SYS": unix.SIGSYS,
|
||||||
|
"TERM": unix.SIGTERM,
|
||||||
|
"TRAP": unix.SIGTRAP,
|
||||||
|
"TSTP": unix.SIGTSTP,
|
||||||
|
"TTIN": unix.SIGTTIN,
|
||||||
|
"TTOU": unix.SIGTTOU,
|
||||||
|
"UNUSED": unix.SIGUNUSED,
|
||||||
|
"URG": unix.SIGURG,
|
||||||
|
"USR1": unix.SIGUSR1,
|
||||||
|
"USR2": unix.SIGUSR2,
|
||||||
|
"VTALRM": unix.SIGVTALRM,
|
||||||
|
"WINCH": unix.SIGWINCH,
|
||||||
|
"XCPU": unix.SIGXCPU,
|
||||||
|
"XFSZ": unix.SIGXFSZ,
|
||||||
|
}
|
42
cmd/ctr/signals_unix.go
Normal file
42
cmd/ctr/signals_unix.go
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
// +build darwin freebsd
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"syscall"
|
||||||
|
|
||||||
|
"golang.org/x/sys/unix"
|
||||||
|
)
|
||||||
|
|
||||||
|
var signalMap = map[string]syscall.Signal{
|
||||||
|
"ABRT": unix.SIGABRT,
|
||||||
|
"ALRM": unix.SIGALRM,
|
||||||
|
"BUS": unix.SIGBUS,
|
||||||
|
"CHLD": unix.SIGCHLD,
|
||||||
|
"CONT": unix.SIGCONT,
|
||||||
|
"FPE": unix.SIGFPE,
|
||||||
|
"HUP": unix.SIGHUP,
|
||||||
|
"ILL": unix.SIGILL,
|
||||||
|
"INT": unix.SIGINT,
|
||||||
|
"IO": unix.SIGIO,
|
||||||
|
"IOT": unix.SIGIOT,
|
||||||
|
"KILL": unix.SIGKILL,
|
||||||
|
"PIPE": unix.SIGPIPE,
|
||||||
|
"PROF": unix.SIGPROF,
|
||||||
|
"QUIT": unix.SIGQUIT,
|
||||||
|
"SEGV": unix.SIGSEGV,
|
||||||
|
"STOP": unix.SIGSTOP,
|
||||||
|
"SYS": unix.SIGSYS,
|
||||||
|
"TERM": unix.SIGTERM,
|
||||||
|
"TRAP": unix.SIGTRAP,
|
||||||
|
"TSTP": unix.SIGTSTP,
|
||||||
|
"TTIN": unix.SIGTTIN,
|
||||||
|
"TTOU": unix.SIGTTOU,
|
||||||
|
"URG": unix.SIGURG,
|
||||||
|
"USR1": unix.SIGUSR1,
|
||||||
|
"USR2": unix.SIGUSR2,
|
||||||
|
"VTALRM": unix.SIGVTALRM,
|
||||||
|
"WINCH": unix.SIGWINCH,
|
||||||
|
"XCPU": unix.SIGXCPU,
|
||||||
|
"XFSZ": unix.SIGXFSZ,
|
||||||
|
}
|
@ -17,7 +17,6 @@ import (
|
|||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/tonistiigi/fifo"
|
"github.com/tonistiigi/fifo"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
"golang.org/x/sys/unix"
|
|
||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
"google.golang.org/grpc/grpclog"
|
"google.golang.org/grpc/grpclog"
|
||||||
)
|
)
|
||||||
@ -100,41 +99,3 @@ func getGRPCConnection(context *cli.Context) (*grpc.ClientConn, error) {
|
|||||||
grpcConn = conn
|
grpcConn = conn
|
||||||
return grpcConn, nil
|
return grpcConn, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var signalMap = map[string]syscall.Signal{
|
|
||||||
"ABRT": unix.SIGABRT,
|
|
||||||
"ALRM": unix.SIGALRM,
|
|
||||||
"BUS": unix.SIGBUS,
|
|
||||||
"CHLD": unix.SIGCHLD,
|
|
||||||
"CLD": unix.SIGCLD,
|
|
||||||
"CONT": unix.SIGCONT,
|
|
||||||
"FPE": unix.SIGFPE,
|
|
||||||
"HUP": unix.SIGHUP,
|
|
||||||
"ILL": unix.SIGILL,
|
|
||||||
"INT": unix.SIGINT,
|
|
||||||
"IO": unix.SIGIO,
|
|
||||||
"IOT": unix.SIGIOT,
|
|
||||||
"KILL": unix.SIGKILL,
|
|
||||||
"PIPE": unix.SIGPIPE,
|
|
||||||
"POLL": unix.SIGPOLL,
|
|
||||||
"PROF": unix.SIGPROF,
|
|
||||||
"PWR": unix.SIGPWR,
|
|
||||||
"QUIT": unix.SIGQUIT,
|
|
||||||
"SEGV": unix.SIGSEGV,
|
|
||||||
"STKFLT": unix.SIGSTKFLT,
|
|
||||||
"STOP": unix.SIGSTOP,
|
|
||||||
"SYS": unix.SIGSYS,
|
|
||||||
"TERM": unix.SIGTERM,
|
|
||||||
"TRAP": unix.SIGTRAP,
|
|
||||||
"TSTP": unix.SIGTSTP,
|
|
||||||
"TTIN": unix.SIGTTIN,
|
|
||||||
"TTOU": unix.SIGTTOU,
|
|
||||||
"UNUSED": unix.SIGUNUSED,
|
|
||||||
"URG": unix.SIGURG,
|
|
||||||
"USR1": unix.SIGUSR1,
|
|
||||||
"USR2": unix.SIGUSR2,
|
|
||||||
"VTALRM": unix.SIGVTALRM,
|
|
||||||
"WINCH": unix.SIGWINCH,
|
|
||||||
"XCPU": unix.SIGXCPU,
|
|
||||||
"XFSZ": unix.SIGXFSZ,
|
|
||||||
}
|
|
||||||
|
15
content/store_linux.go
Normal file
15
content/store_linux.go
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
package content
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"syscall"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func getStartTime(fi os.FileInfo) time.Time {
|
||||||
|
if st, ok := fi.Sys().(*syscall.Stat_t); ok {
|
||||||
|
return time.Unix(int64(st.Ctim.Sec), int64(st.Ctim.Nsec))
|
||||||
|
}
|
||||||
|
|
||||||
|
return fi.ModTime()
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
// +build linux
|
// +build darwin freebsd
|
||||||
|
|
||||||
package content
|
package content
|
||||||
|
|
||||||
@ -10,7 +10,7 @@ import (
|
|||||||
|
|
||||||
func getStartTime(fi os.FileInfo) time.Time {
|
func getStartTime(fi os.FileInfo) time.Time {
|
||||||
if st, ok := fi.Sys().(*syscall.Stat_t); ok {
|
if st, ok := fi.Sys().(*syscall.Stat_t); ok {
|
||||||
return time.Unix(int64(st.Ctim.Sec), int64(st.Ctim.Nsec))
|
return time.Unix(int64(st.Ctimespec.Sec), int64(st.Ctimespec.Nsec))
|
||||||
}
|
}
|
||||||
|
|
||||||
return fi.ModTime()
|
return fi.ModTime()
|
||||||
|
65
fs/copy_unix.go
Normal file
65
fs/copy_unix.go
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
// +build darwin freebsd
|
||||||
|
|
||||||
|
package fs
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
"syscall"
|
||||||
|
|
||||||
|
"github.com/containerd/continuity/sysx"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
func copyFileInfo(fi os.FileInfo, name string) error {
|
||||||
|
st := fi.Sys().(*syscall.Stat_t)
|
||||||
|
if err := os.Lchown(name, int(st.Uid), int(st.Gid)); err != nil {
|
||||||
|
return errors.Wrapf(err, "failed to chown %s", name)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fi.Mode() & os.ModeSymlink) != os.ModeSymlink {
|
||||||
|
if err := os.Chmod(name, fi.Mode()); err != nil {
|
||||||
|
return errors.Wrapf(err, "failed to chmod %s", name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := syscall.UtimesNano(name, []syscall.Timespec{st.Atimespec, st.Mtimespec}); err != nil {
|
||||||
|
return errors.Wrapf(err, "failed to utime %s", name)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func copyFileContent(dst, src *os.File) error {
|
||||||
|
buf := bufferPool.Get().([]byte)
|
||||||
|
_, err := io.CopyBuffer(dst, src, buf)
|
||||||
|
bufferPool.Put(buf)
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func copyXAttrs(dst, src string) error {
|
||||||
|
xattrKeys, err := sysx.LListxattr(src)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrapf(err, "failed to list xattrs on %s", src)
|
||||||
|
}
|
||||||
|
for _, xattr := range xattrKeys {
|
||||||
|
data, err := sysx.LGetxattr(src, xattr)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrapf(err, "failed to get xattr %q on %s", xattr, src)
|
||||||
|
}
|
||||||
|
if err := sysx.LSetxattr(dst, xattr, data, 0); err != nil {
|
||||||
|
return errors.Wrapf(err, "failed to set xattr %q on %s", xattr, dst)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func copyDevice(dst string, fi os.FileInfo) error {
|
||||||
|
st, ok := fi.Sys().(*syscall.Stat_t)
|
||||||
|
if !ok {
|
||||||
|
return errors.New("unsupported stat type")
|
||||||
|
}
|
||||||
|
return syscall.Mknod(dst, uint32(fi.Mode()), int(st.Rdev))
|
||||||
|
}
|
@ -1,3 +1,5 @@
|
|||||||
|
// +build !windows
|
||||||
|
|
||||||
package fs
|
package fs
|
||||||
|
|
||||||
import (
|
import (
|
@ -27,7 +27,7 @@ func diskUsage(roots ...string) (Usage, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
stat := fi.Sys().(*syscall.Stat_t)
|
stat := fi.Sys().(*syscall.Stat_t)
|
||||||
inodes[inode{dev: stat.Dev, ino: stat.Ino}] = struct{}{}
|
inodes[inode{dev: uint64(stat.Dev), ino: stat.Ino}] = struct{}{}
|
||||||
size += fi.Size()
|
size += fi.Size()
|
||||||
return nil
|
return nil
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
|
70
mount_linux.go
Normal file
70
mount_linux.go
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
package containerd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"golang.org/x/sys/unix"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (m *Mount) Mount(target string) error {
|
||||||
|
flags, data := parseMountOptions(m.Options)
|
||||||
|
return unix.Mount(m.Source, target, m.Type, uintptr(flags), data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Unmount(mount string, flags int) error {
|
||||||
|
return unix.Unmount(mount, flags)
|
||||||
|
}
|
||||||
|
|
||||||
|
// parseMountOptions takes fstab style mount options and parses them for
|
||||||
|
// use with a standard mount() syscall
|
||||||
|
func parseMountOptions(options []string) (int, string) {
|
||||||
|
var (
|
||||||
|
flag int
|
||||||
|
data []string
|
||||||
|
)
|
||||||
|
flags := map[string]struct {
|
||||||
|
clear bool
|
||||||
|
flag int
|
||||||
|
}{
|
||||||
|
"async": {true, unix.MS_SYNCHRONOUS},
|
||||||
|
"atime": {true, unix.MS_NOATIME},
|
||||||
|
"bind": {false, unix.MS_BIND},
|
||||||
|
"defaults": {false, 0},
|
||||||
|
"dev": {true, unix.MS_NODEV},
|
||||||
|
"diratime": {true, unix.MS_NODIRATIME},
|
||||||
|
"dirsync": {false, unix.MS_DIRSYNC},
|
||||||
|
"exec": {true, unix.MS_NOEXEC},
|
||||||
|
"mand": {false, unix.MS_MANDLOCK},
|
||||||
|
"noatime": {false, unix.MS_NOATIME},
|
||||||
|
"nodev": {false, unix.MS_NODEV},
|
||||||
|
"nodiratime": {false, unix.MS_NODIRATIME},
|
||||||
|
"noexec": {false, unix.MS_NOEXEC},
|
||||||
|
"nomand": {true, unix.MS_MANDLOCK},
|
||||||
|
"norelatime": {true, unix.MS_RELATIME},
|
||||||
|
"nostrictatime": {true, unix.MS_STRICTATIME},
|
||||||
|
"nosuid": {false, unix.MS_NOSUID},
|
||||||
|
"rbind": {false, unix.MS_BIND | unix.MS_REC},
|
||||||
|
"relatime": {false, unix.MS_RELATIME},
|
||||||
|
"remount": {false, unix.MS_REMOUNT},
|
||||||
|
"ro": {false, unix.MS_RDONLY},
|
||||||
|
"rw": {true, unix.MS_RDONLY},
|
||||||
|
"strictatime": {false, unix.MS_STRICTATIME},
|
||||||
|
"suid": {true, unix.MS_NOSUID},
|
||||||
|
"sync": {false, unix.MS_SYNCHRONOUS},
|
||||||
|
}
|
||||||
|
for _, o := range 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,72 +1,17 @@
|
|||||||
// +build linux
|
// +build darwin freebsd
|
||||||
|
|
||||||
package containerd
|
package containerd
|
||||||
|
|
||||||
import (
|
import "github.com/pkg/errors"
|
||||||
"strings"
|
|
||||||
|
|
||||||
"golang.org/x/sys/unix"
|
var (
|
||||||
|
ErrNotImplementOnUnix = errors.New("not implemented under unix")
|
||||||
)
|
)
|
||||||
|
|
||||||
func (m *Mount) Mount(target string) error {
|
func (m *Mount) Mount(target string) error {
|
||||||
flags, data := parseMountOptions(m.Options)
|
return ErrNotImplementOnUnix
|
||||||
return unix.Mount(m.Source, target, m.Type, uintptr(flags), data)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func Unmount(mount string, flags int) error {
|
func Unmount(mount string, flags int) error {
|
||||||
return unix.Unmount(mount, flags)
|
return ErrNotImplementOnUnix
|
||||||
}
|
|
||||||
|
|
||||||
// parseMountOptions takes fstab style mount options and parses them for
|
|
||||||
// use with a standard mount() syscall
|
|
||||||
func parseMountOptions(options []string) (int, string) {
|
|
||||||
var (
|
|
||||||
flag int
|
|
||||||
data []string
|
|
||||||
)
|
|
||||||
flags := map[string]struct {
|
|
||||||
clear bool
|
|
||||||
flag int
|
|
||||||
}{
|
|
||||||
"async": {true, unix.MS_SYNCHRONOUS},
|
|
||||||
"atime": {true, unix.MS_NOATIME},
|
|
||||||
"bind": {false, unix.MS_BIND},
|
|
||||||
"defaults": {false, 0},
|
|
||||||
"dev": {true, unix.MS_NODEV},
|
|
||||||
"diratime": {true, unix.MS_NODIRATIME},
|
|
||||||
"dirsync": {false, unix.MS_DIRSYNC},
|
|
||||||
"exec": {true, unix.MS_NOEXEC},
|
|
||||||
"mand": {false, unix.MS_MANDLOCK},
|
|
||||||
"noatime": {false, unix.MS_NOATIME},
|
|
||||||
"nodev": {false, unix.MS_NODEV},
|
|
||||||
"nodiratime": {false, unix.MS_NODIRATIME},
|
|
||||||
"noexec": {false, unix.MS_NOEXEC},
|
|
||||||
"nomand": {true, unix.MS_MANDLOCK},
|
|
||||||
"norelatime": {true, unix.MS_RELATIME},
|
|
||||||
"nostrictatime": {true, unix.MS_STRICTATIME},
|
|
||||||
"nosuid": {false, unix.MS_NOSUID},
|
|
||||||
"rbind": {false, unix.MS_BIND | unix.MS_REC},
|
|
||||||
"relatime": {false, unix.MS_RELATIME},
|
|
||||||
"remount": {false, unix.MS_REMOUNT},
|
|
||||||
"ro": {false, unix.MS_RDONLY},
|
|
||||||
"rw": {true, unix.MS_RDONLY},
|
|
||||||
"strictatime": {false, unix.MS_STRICTATIME},
|
|
||||||
"suid": {true, unix.MS_NOSUID},
|
|
||||||
"sync": {false, unix.MS_SYNCHRONOUS},
|
|
||||||
}
|
|
||||||
for _, o := range 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, ",")
|
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@ github.com/containerd/btrfs e9c546f46bccffefe71a6bc137e4c21b5503cc18
|
|||||||
github.com/stretchr/testify v1.1.4
|
github.com/stretchr/testify v1.1.4
|
||||||
github.com/davecgh/go-spew v1.1.0
|
github.com/davecgh/go-spew v1.1.0
|
||||||
github.com/pmezard/go-difflib v1.0.0
|
github.com/pmezard/go-difflib v1.0.0
|
||||||
github.com/tonistiigi/fifo fe870ccf293940774c2b44e23f6c71fff8f7547d
|
github.com/tonistiigi/fifo f071cd4a2739654fec4e768a14efd9332b3e8af1
|
||||||
github.com/urfave/cli 8ba6f23b6e36d03666a14bd9421f5e3efcb59aca
|
github.com/urfave/cli 8ba6f23b6e36d03666a14bd9421f5e3efcb59aca
|
||||||
golang.org/x/net 8b4af36cd21a1f85a7484b49feb7c79363106d8e
|
golang.org/x/net 8b4af36cd21a1f85a7484b49feb7c79363106d8e
|
||||||
google.golang.org/grpc v1.0.5
|
google.golang.org/grpc v1.0.5
|
||||||
|
4
vendor/github.com/tonistiigi/fifo/handle_linux.go
generated
vendored
4
vendor/github.com/tonistiigi/fifo/handle_linux.go
generated
vendored
@ -36,7 +36,7 @@ func getHandle(fn string) (*handle, error) {
|
|||||||
h := &handle{
|
h := &handle{
|
||||||
f: f,
|
f: f,
|
||||||
name: fn,
|
name: fn,
|
||||||
dev: stat.Dev,
|
dev: uint64(stat.Dev),
|
||||||
ino: stat.Ino,
|
ino: stat.Ino,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,7 +62,7 @@ func (h *handle) Path() (string, error) {
|
|||||||
if err := syscall.Stat(h.procPath(), &stat); err != nil {
|
if err := syscall.Stat(h.procPath(), &stat); err != nil {
|
||||||
return "", errors.Wrapf(err, "path %v could not be statted", h.procPath())
|
return "", errors.Wrapf(err, "path %v could not be statted", h.procPath())
|
||||||
}
|
}
|
||||||
if stat.Dev != h.dev || stat.Ino != h.ino {
|
if uint64(stat.Dev) != h.dev || stat.Ino != h.ino {
|
||||||
return "", errors.Errorf("failed to verify handle %v/%v %v/%v", stat.Dev, h.dev, stat.Ino, h.ino)
|
return "", errors.Errorf("failed to verify handle %v/%v %v/%v", stat.Dev, h.dev, stat.Ino, h.ino)
|
||||||
}
|
}
|
||||||
return h.procPath(), nil
|
return h.procPath(), nil
|
||||||
|
4
vendor/github.com/tonistiigi/fifo/handle_nolinux.go
generated
vendored
4
vendor/github.com/tonistiigi/fifo/handle_nolinux.go
generated
vendored
@ -23,7 +23,7 @@ func getHandle(fn string) (*handle, error) {
|
|||||||
h := &handle{
|
h := &handle{
|
||||||
fn: fn,
|
fn: fn,
|
||||||
dev: uint64(stat.Dev),
|
dev: uint64(stat.Dev),
|
||||||
ino: stat.Ino,
|
ino: uint64(stat.Ino),
|
||||||
}
|
}
|
||||||
|
|
||||||
return h, nil
|
return h, nil
|
||||||
@ -34,7 +34,7 @@ func (h *handle) Path() (string, error) {
|
|||||||
if err := syscall.Stat(h.fn, &stat); err != nil {
|
if err := syscall.Stat(h.fn, &stat); err != nil {
|
||||||
return "", errors.Wrapf(err, "path %v could not be statted", h.fn)
|
return "", errors.Wrapf(err, "path %v could not be statted", h.fn)
|
||||||
}
|
}
|
||||||
if uint64(stat.Dev) != h.dev || stat.Ino != h.ino {
|
if uint64(stat.Dev) != h.dev || uint64(stat.Ino) != h.ino {
|
||||||
return "", errors.Errorf("failed to verify handle %v/%v %v/%v for %v", stat.Dev, h.dev, stat.Ino, h.ino, h.fn)
|
return "", errors.Errorf("failed to verify handle %v/%v %v/%v for %v", stat.Dev, h.dev, stat.Ino, h.ino, h.fn)
|
||||||
}
|
}
|
||||||
return h.fn, nil
|
return h.fn, nil
|
||||||
|
Loading…
Reference in New Issue
Block a user