Skip to content

Commit

Permalink
FIXUP general drivers
Browse files Browse the repository at this point in the history
Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
  • Loading branch information
rhatdan committed Sep 26, 2017
1 parent 0852c71 commit 98cedd0
Show file tree
Hide file tree
Showing 7 changed files with 99 additions and 286 deletions.
34 changes: 13 additions & 21 deletions drivers/counter.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,30 +22,21 @@ func NewRefCounter(c Checker) *RefCounter {
}
}

// Increment increaes the ref count for the given id and returns the current count
// Increment increases the ref count for the given id and returns the current count
func (c *RefCounter) Increment(path string) int {
c.mu.Lock()
m := c.counts[path]
if m == nil {
m = &minfo{}
c.counts[path] = m
}
// if we are checking this path for the first time check to make sure
// if it was already mounted on the system and make sure we have a correct ref
// count if it is mounted as it is in use.
if !m.check {
m.check = true
if c.checker.IsMounted(path) {
m.count++
}
}
m.count++
c.mu.Unlock()
return m.count
return c.incdec(path, func(minfo *minfo) {
minfo.count++
})
}

// Decrement decreases the ref count for the given id and returns the current count
func (c *RefCounter) Decrement(path string) int {
return c.incdec(path, func(minfo *minfo) {
minfo.count--
})
}

func (c *RefCounter) incdec(path string, infoOp func(minfo *minfo)) int {
c.mu.Lock()
m := c.counts[path]
if m == nil {
Expand All @@ -61,7 +52,8 @@ func (c *RefCounter) Decrement(path string) int {
m.count++
}
}
m.count--
infoOp(m)
count := m.count
c.mu.Unlock()
return m.count
return count
}
6 changes: 3 additions & 3 deletions drivers/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ func New(name string, config Options) (Driver, error) {
// state, and now it is no longer supported/prereq/compatible, so
// something changed and needs attention. Otherwise the daemon's
// images would just "disappear".
logrus.Errorf("[graphdriver] prior storage driver %q failed: %s", name, err)
logrus.Errorf("[graphdriver] prior storage driver %s failed: %s", name, err)
return nil, err
}

Expand All @@ -230,10 +230,10 @@ func New(name string, config Options) (Driver, error) {
driversSlice = append(driversSlice, name)
}

return nil, fmt.Errorf("%q contains several valid graphdrivers: %s; Please cleanup or explicitly choose storage driver (-s <DRIVER>)", config.Root, strings.Join(driversSlice, ", "))
return nil, fmt.Errorf("%s contains several valid graphdrivers: %s; Please cleanup or explicitly choose storage driver (-s <DRIVER>)", config.Root, strings.Join(driversSlice, ", "))
}

logrus.Infof("[graphdriver] using prior storage driver: %q", name)
logrus.Infof("[graphdriver] using prior storage driver: %s", name)
return driver, nil
}
}
Expand Down
8 changes: 6 additions & 2 deletions drivers/driver_freebsd.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
package graphdriver

import "syscall"
import (
"syscall"

"golang.org/x/sys/unix"
)

var (
// Slice of drivers that should be used in an order
Expand All @@ -11,7 +15,7 @@ var (

// Mounted checks if the given path is mounted as the fs type
func Mounted(fsType FsMagic, mountPath string) (bool, error) {
var buf syscall.Statfs_t
var buf unix.Statfs_t
if err := syscall.Statfs(mountPath, &buf); err != nil {
return false, err
}
Expand Down
15 changes: 8 additions & 7 deletions drivers/driver_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ package graphdriver

import (
"path/filepath"
"syscall"

"github.com/containers/storage/pkg/mount"
"golang.org/x/sys/unix"
)

const (
Expand Down Expand Up @@ -66,13 +66,14 @@ var (
FsMagicAufs: "aufs",
FsMagicBtrfs: "btrfs",
FsMagicCramfs: "cramfs",
FsMagicEcryptfs: "ecryptfs",
FsMagicExtfs: "extfs",
FsMagicF2fs: "f2fs",
FsMagicGPFS: "gpfs",
FsMagicJffs2Fs: "jffs2",
FsMagicJfs: "jfs",
FsMagicNfsFs: "nfs",
FsMagicOverlay: "overlay",
FsMagicOverlay: "overlayfs",
FsMagicRAMFs: "ramfs",
FsMagicReiserFs: "reiserfs",
FsMagicSmbFs: "smb",
Expand All @@ -87,14 +88,14 @@ var (

// GetFSMagic returns the filesystem id given the path.
func GetFSMagic(rootpath string) (FsMagic, error) {
var buf syscall.Statfs_t
if err := syscall.Statfs(filepath.Dir(rootpath), &buf); err != nil {
var buf unix.Statfs_t
if err := unix.Statfs(filepath.Dir(rootpath), &buf); err != nil {
return 0, err
}
return FsMagic(buf.Type), nil
}

// NewFsChecker returns a checker configured for the provied FsMagic
// NewFsChecker returns a checker configured for the provided FsMagic
func NewFsChecker(t FsMagic) Checker {
return &fsChecker{
t: t,
Expand Down Expand Up @@ -126,8 +127,8 @@ func (c *defaultChecker) IsMounted(path string) bool {

// Mounted checks if the given path is mounted as the fs type
func Mounted(fsType FsMagic, mountPath string) (bool, error) {
var buf syscall.Statfs_t
if err := syscall.Statfs(mountPath, &buf); err != nil {
var buf unix.Statfs_t
if err := unix.Statfs(mountPath, &buf); err != nil {
return false, err
}
return FsMagic(buf.Type) == fsType, nil
Expand Down
44 changes: 37 additions & 7 deletions drivers/driver_solaris.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ import (
"path/filepath"
"unsafe"

"github.com/pkg/errors"
log "github.com/sirupsen/logrus"
"github.com/docker/docker/pkg/mount"
"github.com/sirupsen/logrus"
)

const (
Expand All @@ -45,22 +45,52 @@ func GetFSMagic(rootpath string) (FsMagic, error) {
return 0, nil
}

type fsChecker struct {
t FsMagic
}

func (c *fsChecker) IsMounted(path string) bool {
m, _ := Mounted(c.t, path)
return m
}

// NewFsChecker returns a checker configured for the provided FsMagic
func NewFsChecker(t FsMagic) Checker {
return &fsChecker{
t: t,
}
}

// NewDefaultChecker returns a check that parses /proc/mountinfo to check
// if the specified path is mounted.
// No-op on Solaris.
func NewDefaultChecker() Checker {
return &defaultChecker{}
}

type defaultChecker struct {
}

func (c *defaultChecker) IsMounted(path string) bool {
m, _ := mount.Mounted(path)
return m
}

// Mounted checks if the given path is mounted as the fs type
//Solaris supports only ZFS for now
func Mounted(fsType FsMagic, mountPath string) (bool, error) {

cs := C.CString(filepath.Dir(mountPath))
defer C.free(unsafe.Pointer(cs))
buf := C.getstatfs(cs)
defer C.free(unsafe.Pointer(buf))

// on Solaris buf.f_basetype contains ['z', 'f', 's', 0 ... ]
if (buf.f_basetype[0] != 122) || (buf.f_basetype[1] != 102) || (buf.f_basetype[2] != 115) ||
(buf.f_basetype[3] != 0) {
log.Debugf("[zfs] no zfs dataset found for rootdir '%s'", mountPath)
C.free(unsafe.Pointer(buf))
return false, errors.Wrapf(graphdriver.ErrPrerequisites, "no zfs dataset found for rootdir '%s'", mountPath)
logrus.Debugf("[zfs] no zfs dataset found for rootdir '%s'", mountPath)
return false, ErrPrerequisites
}

C.free(unsafe.Pointer(buf))
C.free(unsafe.Pointer(cs))
return true, nil
}
52 changes: 32 additions & 20 deletions drivers/fsdiff.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,25 +36,25 @@ type NaiveDiffDriver struct {
// ApplyDiff(id, parent string, diff io.Reader) (size int64, err error)
// DiffSize(id, parent string) (size int64, err error)
func NewNaiveDiffDriver(driver ProtoDriver, uidMaps, gidMaps []idtools.IDMap) Driver {
gdw := &NaiveDiffDriver{
ProtoDriver: driver,
uidMaps: uidMaps,
gidMaps: gidMaps,
}
return gdw
return &NaiveDiffDriver{ProtoDriver: driver,
uidMaps: uidMaps,
gidMaps: gidMaps}
}

// Diff produces an archive of the changes between the specified
// layer and its parent layer which may be "".
func (gdw *NaiveDiffDriver) Diff(id, parent string) (arch io.ReadCloser, err error) {
layerFs, err := gdw.Get(id, "")
startTime := time.Now()
driver := gdw.ProtoDriver

layerFs, err := driver.Get(id, "")
if err != nil {
return nil, err
}

defer func() {
if err != nil {
gdw.Put(id)
driver.Put(id)
}
}()

Expand All @@ -65,16 +65,16 @@ func (gdw *NaiveDiffDriver) Diff(id, parent string) (arch io.ReadCloser, err err
}
return ioutils.NewReadCloserWrapper(archive, func() error {
err := archive.Close()
gdw.Put(id)
driver.Put(id)
return err
}), nil
}

parentFs, err := gdw.Get(parent, "")
parentFs, err := driver.Get(parent, "")
if err != nil {
return nil, err
}
defer gdw.Put(parent)
defer driver.Put(parent)

changes, err := archive.ChangesDirs(layerFs, parentFs)
if err != nil {
Expand All @@ -88,28 +88,36 @@ func (gdw *NaiveDiffDriver) Diff(id, parent string) (arch io.ReadCloser, err err

return ioutils.NewReadCloserWrapper(archive, func() error {
err := archive.Close()
gdw.Put(id)
driver.Put(id)

// NaiveDiffDriver compares file metadata with parent layers. Parent layers
// are extracted from tar's with full second precision on modified time.
// We need this hack here to make sure calls within same second receive
// correct result.
time.Sleep(time.Until(startTime.Truncate(time.Second).Add(time.Second)))
return err
}), nil
}

// Changes produces a list of changes between the specified layer
// and its parent layer. If parent is "", then all changes will be ADD changes.
func (gdw *NaiveDiffDriver) Changes(id, parent string) ([]archive.Change, error) {
layerFs, err := gdw.Get(id, "")
driver := gdw.ProtoDriver

layerFs, err := driver.Get(id, "")
if err != nil {
return nil, err
}
defer gdw.Put(id)
defer driver.Put(id)

parentFs := ""

if parent != "" {
parentFs, err = gdw.Get(parent, "")
parentFs, err = driver.Get(parent, "")
if err != nil {
return nil, err
}
defer gdw.Put(parent)
defer driver.Put(parent)
}

return archive.ChangesDirs(layerFs, parentFs)
Expand All @@ -119,12 +127,14 @@ func (gdw *NaiveDiffDriver) Changes(id, parent string) ([]archive.Change, error)
// layer with the specified id and parent, returning the size of the
// new layer in bytes.
func (gdw *NaiveDiffDriver) ApplyDiff(id, parent string, diff io.Reader) (size int64, err error) {
driver := gdw.ProtoDriver

// Mount the root filesystem so we can apply the diff/layer.
layerFs, err := gdw.Get(id, "")
layerFs, err := driver.Get(id, "")
if err != nil {
return
}
defer gdw.Put(id)
defer driver.Put(id)

options := &archive.TarOptions{UIDMaps: gdw.uidMaps,
GIDMaps: gdw.gidMaps}
Expand All @@ -142,16 +152,18 @@ func (gdw *NaiveDiffDriver) ApplyDiff(id, parent string, diff io.Reader) (size i
// and its parent and returns the size in bytes of the changes
// relative to its base filesystem directory.
func (gdw *NaiveDiffDriver) DiffSize(id, parent string) (size int64, err error) {
driver := gdw.ProtoDriver

changes, err := gdw.Changes(id, parent)
if err != nil {
return
}

layerFs, err := gdw.Get(id, "")
layerFs, err := driver.Get(id, "")
if err != nil {
return
}
defer gdw.Put(id)
defer driver.Put(id)

return archive.ChangesSize(layerFs, changes), nil
}
Loading

0 comments on commit 98cedd0

Please sign in to comment.