summaryrefslogtreecommitdiff
path: root/vendor
diff options
context:
space:
mode:
Diffstat (limited to 'vendor')
-rw-r--r--vendor/github.com/containers/storage/drivers/aufs/aufs.go18
-rw-r--r--vendor/github.com/containers/storage/drivers/driver.go8
-rw-r--r--vendor/github.com/containers/storage/drivers/fsdiff.go30
-rw-r--r--vendor/github.com/containers/storage/drivers/overlay/overlay.go148
-rw-r--r--vendor/github.com/containers/storage/drivers/windows/windows.go10
-rw-r--r--vendor/github.com/containers/storage/layers.go15
-rw-r--r--vendor/github.com/containers/storage/layers_ffjson.go2
-rw-r--r--vendor/github.com/containers/storage/lockfile.go116
-rw-r--r--vendor/github.com/containers/storage/lockfile_darwin.go19
-rw-r--r--vendor/github.com/containers/storage/lockfile_linux.go20
-rw-r--r--vendor/github.com/containers/storage/lockfile_unix.go115
-rw-r--r--vendor/github.com/containers/storage/lockfile_windows.go40
-rw-r--r--vendor/github.com/containers/storage/pkg/truncindex/truncindex.go12
-rw-r--r--vendor/github.com/containers/storage/stat_mtim.go11
-rw-r--r--vendor/github.com/containers/storage/stat_mtimespec.go11
15 files changed, 323 insertions, 252 deletions
diff --git a/vendor/github.com/containers/storage/drivers/aufs/aufs.go b/vendor/github.com/containers/storage/drivers/aufs/aufs.go
index aa0da7ad0..c1cfabee9 100644
--- a/vendor/github.com/containers/storage/drivers/aufs/aufs.go
+++ b/vendor/github.com/containers/storage/drivers/aufs/aufs.go
@@ -463,9 +463,9 @@ func (a *Driver) isParent(id, parent string) bool {
// Diff produces an archive of the changes between the specified
// layer and its parent layer which may be "".
-func (a *Driver) Diff(id, parent string) (io.ReadCloser, error) {
+func (a *Driver) Diff(id, parent, mountLabel string) (io.ReadCloser, error) {
if !a.isParent(id, parent) {
- return a.naiveDiff.Diff(id, parent)
+ return a.naiveDiff.Diff(id, parent, mountLabel)
}
// AUFS doesn't need the parent layer to produce a diff.
@@ -502,9 +502,9 @@ func (a *Driver) applyDiff(id string, diff io.Reader) error {
// DiffSize calculates the changes between the specified id
// and its parent and returns the size in bytes of the changes
// relative to its base filesystem directory.
-func (a *Driver) DiffSize(id, parent string) (size int64, err error) {
+func (a *Driver) DiffSize(id, parent, mountLabel string) (size int64, err error) {
if !a.isParent(id, parent) {
- return a.naiveDiff.DiffSize(id, parent)
+ return a.naiveDiff.DiffSize(id, parent, mountLabel)
}
// AUFS doesn't need the parent layer to calculate the diff size.
return directory.Size(path.Join(a.rootPath(), "diff", id))
@@ -513,9 +513,9 @@ func (a *Driver) DiffSize(id, parent string) (size int64, err error) {
// ApplyDiff extracts the changeset from the given diff into the
// layer with the specified id and parent, returning the size of the
// new layer in bytes.
-func (a *Driver) ApplyDiff(id, parent string, diff io.Reader) (size int64, err error) {
+func (a *Driver) ApplyDiff(id, parent, mountLabel string, diff io.Reader) (size int64, err error) {
if !a.isParent(id, parent) {
- return a.naiveDiff.ApplyDiff(id, parent, diff)
+ return a.naiveDiff.ApplyDiff(id, parent, mountLabel, diff)
}
// AUFS doesn't need the parent id to apply the diff if it is the direct parent.
@@ -523,14 +523,14 @@ func (a *Driver) ApplyDiff(id, parent string, diff io.Reader) (size int64, err e
return
}
- return a.DiffSize(id, parent)
+ return a.DiffSize(id, parent, mountLabel)
}
// 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 (a *Driver) Changes(id, parent string) ([]archive.Change, error) {
+func (a *Driver) Changes(id, parent, mountLabel string) ([]archive.Change, error) {
if !a.isParent(id, parent) {
- return a.naiveDiff.Changes(id, parent)
+ return a.naiveDiff.Changes(id, parent, mountLabel)
}
// AUFS doesn't have snapshots, so we need to get changes from all parent
diff --git a/vendor/github.com/containers/storage/drivers/driver.go b/vendor/github.com/containers/storage/drivers/driver.go
index 569964784..615d93be5 100644
--- a/vendor/github.com/containers/storage/drivers/driver.go
+++ b/vendor/github.com/containers/storage/drivers/driver.go
@@ -92,19 +92,19 @@ type ProtoDriver interface {
type DiffDriver interface {
// Diff produces an archive of the changes between the specified
// layer and its parent layer which may be "".
- Diff(id, parent string) (io.ReadCloser, error)
+ Diff(id, parent, mountLabel string) (io.ReadCloser, error)
// Changes produces a list of changes between the specified layer
// and its parent layer. If parent is "", then all changes will be ADD changes.
- Changes(id, parent string) ([]archive.Change, error)
+ Changes(id, parent, mountLabel string) ([]archive.Change, error)
// ApplyDiff extracts the changeset from the given diff into the
// layer with the specified id and parent, returning the size of the
// new layer in bytes.
// The io.Reader must be an uncompressed stream.
- ApplyDiff(id, parent string, diff io.Reader) (size int64, err error)
+ ApplyDiff(id, parent, mountLabel string, diff io.Reader) (size int64, err error)
// DiffSize calculates the changes between the specified id
// and its parent and returns the size in bytes of the changes
// relative to its base filesystem directory.
- DiffSize(id, parent string) (size int64, err error)
+ DiffSize(id, parent, mountLabel string) (size int64, err error)
}
// Driver is the interface for layered/snapshot file system drivers.
diff --git a/vendor/github.com/containers/storage/drivers/fsdiff.go b/vendor/github.com/containers/storage/drivers/fsdiff.go
index 48a1f078f..f74239cb9 100644
--- a/vendor/github.com/containers/storage/drivers/fsdiff.go
+++ b/vendor/github.com/containers/storage/drivers/fsdiff.go
@@ -31,10 +31,10 @@ type NaiveDiffDriver struct {
// NewNaiveDiffDriver returns a fully functional driver that wraps the
// given ProtoDriver and adds the capability of the following methods which
// it may or may not support on its own:
-// Diff(id, parent string) (io.ReadCloser, error)
-// Changes(id, parent string) ([]archive.Change, error)
-// ApplyDiff(id, parent string, diff io.Reader) (size int64, err error)
-// DiffSize(id, parent string) (size int64, err error)
+// Diff(id, parent, mountLabel string) (io.ReadCloser, error)
+// Changes(id, parent, mountLabel string) ([]archive.Change, error)
+// ApplyDiff(id, parent, mountLabel string, diff io.Reader) (size int64, err error)
+// DiffSize(id, parent, mountLabel string) (size int64, err error)
func NewNaiveDiffDriver(driver ProtoDriver, uidMaps, gidMaps []idtools.IDMap) Driver {
return &NaiveDiffDriver{ProtoDriver: driver,
uidMaps: uidMaps,
@@ -43,11 +43,11 @@ func NewNaiveDiffDriver(driver ProtoDriver, uidMaps, gidMaps []idtools.IDMap) Dr
// 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) {
+func (gdw *NaiveDiffDriver) Diff(id, parent, mountLabel string) (arch io.ReadCloser, err error) {
startTime := time.Now()
driver := gdw.ProtoDriver
- layerFs, err := driver.Get(id, "")
+ layerFs, err := driver.Get(id, mountLabel)
if err != nil {
return nil, err
}
@@ -70,7 +70,7 @@ func (gdw *NaiveDiffDriver) Diff(id, parent string) (arch io.ReadCloser, err err
}), nil
}
- parentFs, err := driver.Get(parent, "")
+ parentFs, err := driver.Get(parent, mountLabel)
if err != nil {
return nil, err
}
@@ -101,10 +101,10 @@ func (gdw *NaiveDiffDriver) Diff(id, parent string) (arch io.ReadCloser, err err
// 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) {
+func (gdw *NaiveDiffDriver) Changes(id, parent, mountLabel string) ([]archive.Change, error) {
driver := gdw.ProtoDriver
- layerFs, err := driver.Get(id, "")
+ layerFs, err := driver.Get(id, mountLabel)
if err != nil {
return nil, err
}
@@ -113,7 +113,7 @@ func (gdw *NaiveDiffDriver) Changes(id, parent string) ([]archive.Change, error)
parentFs := ""
if parent != "" {
- parentFs, err = driver.Get(parent, "")
+ parentFs, err = driver.Get(parent, mountLabel)
if err != nil {
return nil, err
}
@@ -126,11 +126,11 @@ func (gdw *NaiveDiffDriver) Changes(id, parent string) ([]archive.Change, error)
// ApplyDiff extracts the changeset from the given diff into the
// 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) {
+func (gdw *NaiveDiffDriver) ApplyDiff(id, parent, mountLabel string, diff io.Reader) (size int64, err error) {
driver := gdw.ProtoDriver
// Mount the root filesystem so we can apply the diff/layer.
- layerFs, err := driver.Get(id, "")
+ layerFs, err := driver.Get(id, mountLabel)
if err != nil {
return
}
@@ -151,15 +151,15 @@ func (gdw *NaiveDiffDriver) ApplyDiff(id, parent string, diff io.Reader) (size i
// DiffSize calculates the changes between the specified layer
// 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) {
+func (gdw *NaiveDiffDriver) DiffSize(id, parent, mountLabel string) (size int64, err error) {
driver := gdw.ProtoDriver
- changes, err := gdw.Changes(id, parent)
+ changes, err := gdw.Changes(id, parent, mountLabel)
if err != nil {
return
}
- layerFs, err := driver.Get(id, "")
+ layerFs, err := driver.Get(id, mountLabel)
if err != nil {
return
}
diff --git a/vendor/github.com/containers/storage/drivers/overlay/overlay.go b/vendor/github.com/containers/storage/drivers/overlay/overlay.go
index d224406e7..4458b679a 100644
--- a/vendor/github.com/containers/storage/drivers/overlay/overlay.go
+++ b/vendor/github.com/containers/storage/drivers/overlay/overlay.go
@@ -3,7 +3,6 @@
package overlay
import (
- "bufio"
"fmt"
"io"
"io/ioutil"
@@ -26,7 +25,6 @@ import (
"github.com/containers/storage/pkg/locker"
"github.com/containers/storage/pkg/mount"
"github.com/containers/storage/pkg/parsers"
- "github.com/containers/storage/pkg/parsers/kernel"
"github.com/containers/storage/pkg/system"
units "github.com/docker/go-units"
"github.com/opencontainers/selinux/go-selinux/label"
@@ -124,22 +122,6 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap
return nil, err
}
- if err := supportsOverlay(); err != nil {
- return nil, errors.Wrap(graphdriver.ErrNotSupported, "kernel does not support overlay fs")
- }
-
- // require kernel 4.0.0 to ensure multiple lower dirs are supported
- v, err := kernel.GetKernelVersion()
- if err != nil {
- return nil, err
- }
- if kernel.CompareKernelVersion(*v, kernel.VersionInfo{Kernel: 4, Major: 0, Minor: 0}) < 0 {
- if !opts.overrideKernelCheck {
- return nil, errors.Wrap(graphdriver.ErrNotSupported, "kernel too old to provide multiple lowers feature for overlay")
- }
- logrus.Warn("Using pre-4.0.0 kernel for overlay, mount failures may require kernel update")
- }
-
fsMagic, err := graphdriver.GetFSMagic(home)
if err != nil {
return nil, err
@@ -153,40 +135,28 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap
case graphdriver.FsMagicAufs, graphdriver.FsMagicZfs, graphdriver.FsMagicOverlay, graphdriver.FsMagicEcryptfs:
logrus.Errorf("'overlay' is not supported over %s", backingFs)
return nil, errors.Wrapf(graphdriver.ErrIncompatibleFS, "'overlay' is not supported over %s", backingFs)
- case graphdriver.FsMagicBtrfs:
- // Support for OverlayFS on BTRFS was added in kernel 4.7
- // See https://btrfs.wiki.kernel.org/index.php/Changelog
- if kernel.CompareKernelVersion(*v, kernel.VersionInfo{Kernel: 4, Major: 7, Minor: 0}) < 0 {
- if !opts.overrideKernelCheck {
- logrus.Errorf("'overlay' requires kernel 4.7 to use on %s", backingFs)
- return nil, errors.Wrapf(graphdriver.ErrIncompatibleFS, "'overlay' requires kernel 4.7 to use on %s", backingFs)
- }
- logrus.Warn("Using pre-4.7.0 kernel for overlay on btrfs, may require kernel update")
- }
}
rootUID, rootGID, err := idtools.GetRootUIDGID(uidMaps, gidMaps)
if err != nil {
return nil, err
}
+
// Create the driver home dir
if err := idtools.MkdirAllAs(path.Join(home, linkDir), 0700, rootUID, rootGID); err != nil && !os.IsExist(err) {
return nil, err
}
- if err := mount.MakePrivate(home); err != nil {
- return nil, err
+ supportsDType, err := supportsOverlay(home, fsMagic, rootUID, rootGID)
+ if err != nil {
+ os.Remove(filepath.Join(home, linkDir))
+ os.Remove(home)
+ return nil, errors.Wrap(graphdriver.ErrNotSupported, "kernel does not support overlay fs")
}
- supportsDType, err := fsutils.SupportsDType(home)
- if err != nil {
+ if err := mount.MakePrivate(home); err != nil {
return nil, err
}
- if !supportsDType {
- logrus.Warn(overlayutils.ErrDTypeNotSupported("overlay", backingFs))
- // TODO: Will make fatal when CRI-O Has AMI built on RHEL7.4
- // return nil, overlayutils.ErrDTypeNotSupported("overlay", backingFs)
- }
d := &Driver{
name: "overlay",
@@ -210,10 +180,10 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap
}
} else if opts.quota.Size > 0 {
// if xfs is not the backing fs then error out if the storage-opt overlay.size is used.
- return nil, fmt.Errorf("Storage Option overlay.size only supported for backingFS XFS. Found %v", backingFs)
+ return nil, fmt.Errorf("Storage option overlay.size only supported for backingFS XFS. Found %v", backingFs)
}
- logrus.Debugf("backingFs=%s, projectQuotaSupported=%v", backingFs, projectQuotaSupported)
+ logrus.Debugf("backingFs=%s, projectQuotaSupported=%v, useNativeDiff=%v", backingFs, projectQuotaSupported, !useNaiveDiff(home))
return d, nil
}
@@ -264,25 +234,57 @@ func parseOptions(options []string) (*overlayOptions, error) {
return o, nil
}
-func supportsOverlay() error {
- // We can try to modprobe overlay first before looking at
- // proc/filesystems for when overlay is supported
+func supportsOverlay(home string, homeMagic graphdriver.FsMagic, rootUID, rootGID int) (supportsDType bool, err error) {
+ // We can try to modprobe overlay first
exec.Command("modprobe", "overlay").Run()
- f, err := os.Open("/proc/filesystems")
- if err != nil {
- return err
- }
- defer f.Close()
+ layerDir, err := ioutil.TempDir(home, "compat")
+ if err == nil {
+ // Check if reading the directory's contents populates the d_type field, which is required
+ // for proper operation of the overlay filesystem.
+ supportsDType, err = fsutils.SupportsDType(layerDir)
+ if err != nil {
+ return false, err
+ }
+ if !supportsDType {
+ return false, overlayutils.ErrDTypeNotSupported("overlay", backingFs)
+ }
- s := bufio.NewScanner(f)
- for s.Scan() {
- if s.Text() == "nodev\toverlay" {
- return nil
+ // Try a test mount in the specific location we're looking at using.
+ mergedDir := filepath.Join(layerDir, "merged")
+ lower1Dir := filepath.Join(layerDir, "lower1")
+ lower2Dir := filepath.Join(layerDir, "lower2")
+ defer func() {
+ // Permitted to fail, since the various subdirectories
+ // can be empty or not even there, and the home might
+ // legitimately be not empty
+ _ = unix.Unmount(mergedDir, unix.MNT_DETACH)
+ _ = os.RemoveAll(layerDir)
+ _ = os.Remove(home)
+ }()
+ _ = idtools.MkdirAs(mergedDir, 0700, rootUID, rootGID)
+ _ = idtools.MkdirAs(lower1Dir, 0700, rootUID, rootGID)
+ _ = idtools.MkdirAs(lower2Dir, 0700, rootUID, rootGID)
+ flags := fmt.Sprintf("lowerdir=%s:%s", lower1Dir, lower2Dir)
+ if len(flags) < unix.Getpagesize() {
+ if mountFrom(filepath.Dir(home), "overlay", mergedDir, "overlay", 0, flags) == nil {
+ logrus.Debugf("overlay test mount with multiple lowers succeeded")
+ return supportsDType, nil
+ }
+ }
+ flags = fmt.Sprintf("lowerdir=%s", lower1Dir)
+ if len(flags) < unix.Getpagesize() {
+ if mountFrom(filepath.Dir(home), "overlay", mergedDir, "overlay", 0, flags) == nil {
+ logrus.Errorf("overlay test mount with multiple lowers failed, but succeeded with a single lower")
+ return supportsDType, errors.Wrap(graphdriver.ErrNotSupported, "kernel too old to provide multiple lowers feature for overlay")
+ }
}
+ logrus.Errorf("'overlay' is not supported over %s at %q", backingFs, home)
+ return supportsDType, errors.Wrapf(graphdriver.ErrIncompatibleFS, "'overlay' is not supported over %s at %q", backingFs, home)
}
+
logrus.Error("'overlay' not found as a supported filesystem on this host. Please ensure kernel is new enough and has overlay support loaded.")
- return errors.Wrap(graphdriver.ErrNotSupported, "'overlay' not found as a supported filesystem on this host. Please ensure kernel is new enough and has overlay support loaded.")
+ return supportsDType, errors.Wrap(graphdriver.ErrNotSupported, "'overlay' not found as a supported filesystem on this host. Please ensure kernel is new enough and has overlay support loaded.")
}
func useNaiveDiff(home string) bool {
@@ -424,11 +426,6 @@ func (d *Driver) create(id, parent string, opts *graphdriver.CreateOpts) (retErr
return err
}
- // if no parent directory, done
- if parent == "" {
- return nil
- }
-
if err := idtools.MkdirAs(path.Join(dir, "work"), 0700, rootUID, rootGID); err != nil {
return err
}
@@ -436,6 +433,11 @@ func (d *Driver) create(id, parent string, opts *graphdriver.CreateOpts) (retErr
return err
}
+ // if no parent directory, create a dummy lower directory and skip writing a "lowers" file
+ if parent == "" {
+ return idtools.MkdirAs(path.Join(dir, "empty"), 0700, rootUID, rootGID)
+ }
+
lower, err := d.getLower(parent)
if err != nil {
return err
@@ -556,11 +558,7 @@ func (d *Driver) Get(id, mountLabel string) (_ string, retErr error) {
diffDir := path.Join(dir, "diff")
lowers, err := ioutil.ReadFile(path.Join(dir, lowerFile))
- if err != nil {
- // If no lower, just return diff directory
- if os.IsNotExist(err) {
- return diffDir, nil
- }
+ if err != nil && !os.IsNotExist(err) {
return "", err
}
@@ -588,6 +586,10 @@ func (d *Driver) Get(id, mountLabel string) (_ string, retErr error) {
newlowers = newlowers + ":" + lower
}
}
+ if len(lowers) == 0 {
+ newlowers = path.Join(dir, "empty")
+ lowers = []byte(newlowers)
+ }
mergedDir := path.Join(dir, "merged")
if count := d.ctr.Increment(mergedDir); count > 1 {
@@ -658,11 +660,7 @@ func (d *Driver) Put(id string) error {
if count := d.ctr.Decrement(mountpoint); count > 0 {
return nil
}
- if _, err := ioutil.ReadFile(path.Join(dir, lowerFile)); err != nil {
- // If no lower, we used the diff directory, so no work to do
- if os.IsNotExist(err) {
- return nil
- }
+ if _, err := ioutil.ReadFile(path.Join(dir, lowerFile)); err != nil && !os.IsNotExist(err) {
return err
}
if err := unix.Unmount(mountpoint, unix.MNT_DETACH); err != nil {
@@ -699,9 +697,9 @@ func (d *Driver) isParent(id, parent string) bool {
}
// ApplyDiff applies the new layer into a root
-func (d *Driver) ApplyDiff(id string, parent string, diff io.Reader) (size int64, err error) {
+func (d *Driver) ApplyDiff(id, parent, mountLabel string, diff io.Reader) (size int64, err error) {
if !d.isParent(id, parent) {
- return d.naiveDiff.ApplyDiff(id, parent, diff)
+ return d.naiveDiff.ApplyDiff(id, parent, mountLabel, diff)
}
applyDir := d.getDiffPath(id)
@@ -728,18 +726,18 @@ func (d *Driver) getDiffPath(id string) string {
// DiffSize calculates the changes between the specified id
// and its parent and returns the size in bytes of the changes
// relative to its base filesystem directory.
-func (d *Driver) DiffSize(id, parent string) (size int64, err error) {
+func (d *Driver) DiffSize(id, parent, mountLabel string) (size int64, err error) {
if useNaiveDiff(d.home) || !d.isParent(id, parent) {
- return d.naiveDiff.DiffSize(id, parent)
+ return d.naiveDiff.DiffSize(id, parent, mountLabel)
}
return directory.Size(d.getDiffPath(id))
}
// Diff produces an archive of the changes between the specified
// layer and its parent layer which may be "".
-func (d *Driver) Diff(id, parent string) (io.ReadCloser, error) {
+func (d *Driver) Diff(id, parent, mountLabel string) (io.ReadCloser, error) {
if useNaiveDiff(d.home) || !d.isParent(id, parent) {
- return d.naiveDiff.Diff(id, parent)
+ return d.naiveDiff.Diff(id, parent, mountLabel)
}
diffPath := d.getDiffPath(id)
@@ -754,9 +752,9 @@ func (d *Driver) Diff(id, parent string) (io.ReadCloser, error) {
// 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 (d *Driver) Changes(id, parent string) ([]archive.Change, error) {
+func (d *Driver) Changes(id, parent, mountLabel string) ([]archive.Change, error) {
if useNaiveDiff(d.home) || !d.isParent(id, parent) {
- return d.naiveDiff.Changes(id, parent)
+ return d.naiveDiff.Changes(id, parent, mountLabel)
}
// Overlay doesn't have snapshots, so we need to get changes from all parent
// layers.
diff --git a/vendor/github.com/containers/storage/drivers/windows/windows.go b/vendor/github.com/containers/storage/drivers/windows/windows.go
index abe2ac432..e9e9f5c65 100644
--- a/vendor/github.com/containers/storage/drivers/windows/windows.go
+++ b/vendor/github.com/containers/storage/drivers/windows/windows.go
@@ -472,7 +472,7 @@ func (d *Driver) Cleanup() error {
// Diff produces an archive of the changes between the specified
// layer and its parent layer which may be "".
// The layer should be mounted when calling this function
-func (d *Driver) Diff(id, parent string) (_ io.ReadCloser, err error) {
+func (d *Driver) Diff(id, parent, mountLabel string) (_ io.ReadCloser, err error) {
panicIfUsedByLcow()
rID, err := d.resolveID(id)
if err != nil {
@@ -509,7 +509,7 @@ func (d *Driver) Diff(id, parent string) (_ io.ReadCloser, err error) {
// Changes produces a list of changes between the specified layer
// and its parent layer. If parent is "", then all changes will be ADD changes.
// The layer should not be mounted when calling this function.
-func (d *Driver) Changes(id, parent string) ([]archive.Change, error) {
+func (d *Driver) Changes(id, parent, mountLabel string) ([]archive.Change, error) {
panicIfUsedByLcow()
rID, err := d.resolveID(id)
if err != nil {
@@ -565,7 +565,7 @@ func (d *Driver) Changes(id, parent string) ([]archive.Change, error) {
// layer with the specified id and parent, returning the size of the
// new layer in bytes.
// The layer should not be mounted when calling this function
-func (d *Driver) ApplyDiff(id, parent string, diff io.Reader) (int64, error) {
+func (d *Driver) ApplyDiff(id, parent, mountLabel string, diff io.Reader) (int64, error) {
panicIfUsedByLcow()
var layerChain []string
if parent != "" {
@@ -600,14 +600,14 @@ func (d *Driver) ApplyDiff(id, parent string, diff io.Reader) (int64, error) {
// DiffSize calculates the changes between the specified layer
// and its parent and returns the size in bytes of the changes
// relative to its base filesystem directory.
-func (d *Driver) DiffSize(id, parent string) (size int64, err error) {
+func (d *Driver) DiffSize(id, parent, mountLabel string) (size int64, err error) {
panicIfUsedByLcow()
rPId, err := d.resolveID(parent)
if err != nil {
return
}
- changes, err := d.Changes(id, rPId)
+ changes, err := d.Changes(id, rPId, mountLabel)
if err != nil {
return
}
diff --git a/vendor/github.com/containers/storage/layers.go b/vendor/github.com/containers/storage/layers.go
index f51406a02..a1be6eee7 100644
--- a/vendor/github.com/containers/storage/layers.go
+++ b/vendor/github.com/containers/storage/layers.go
@@ -778,11 +778,11 @@ func (r *layerStore) findParentAndLayer(from, to string) (fromID string, toID st
}
func (r *layerStore) Changes(from, to string) ([]archive.Change, error) {
- from, to, _, err := r.findParentAndLayer(from, to)
+ from, to, toLayer, err := r.findParentAndLayer(from, to)
if err != nil {
return nil, ErrLayerUnknown
}
- return r.driver.Changes(to, from)
+ return r.driver.Changes(to, from, toLayer.MountLabel)
}
type simpleGetCloser struct {
@@ -855,7 +855,7 @@ func (r *layerStore) Diff(from, to string, options *DiffOptions) (io.ReadCloser,
}
if from != toLayer.Parent {
- diff, err := r.driver.Diff(to, from)
+ diff, err := r.driver.Diff(to, from, toLayer.MountLabel)
if err != nil {
return nil, err
}
@@ -867,7 +867,7 @@ func (r *layerStore) Diff(from, to string, options *DiffOptions) (io.ReadCloser,
if !os.IsNotExist(err) {
return nil, err
}
- diff, err := r.driver.Diff(to, from)
+ diff, err := r.driver.Diff(to, from, toLayer.MountLabel)
if err != nil {
return nil, err
}
@@ -906,11 +906,12 @@ func (r *layerStore) Diff(from, to string, options *DiffOptions) (io.ReadCloser,
}
func (r *layerStore) DiffSize(from, to string) (size int64, err error) {
- from, to, _, err = r.findParentAndLayer(from, to)
+ var toLayer *Layer
+ from, to, toLayer, err = r.findParentAndLayer(from, to)
if err != nil {
return -1, ErrLayerUnknown
}
- return r.driver.DiffSize(to, from)
+ return r.driver.DiffSize(to, from, toLayer.MountLabel)
}
func (r *layerStore) ApplyDiff(to string, diff io.Reader) (size int64, err error) {
@@ -950,7 +951,7 @@ func (r *layerStore) ApplyDiff(to string, diff io.Reader) (size int64, err error
if err != nil {
return -1, err
}
- size, err = r.driver.ApplyDiff(layer.ID, layer.Parent, payload)
+ size, err = r.driver.ApplyDiff(layer.ID, layer.Parent, layer.MountLabel, payload)
if err != nil {
return -1, err
}
diff --git a/vendor/github.com/containers/storage/layers_ffjson.go b/vendor/github.com/containers/storage/layers_ffjson.go
index 8bec40e17..1d494e9d4 100644
--- a/vendor/github.com/containers/storage/layers_ffjson.go
+++ b/vendor/github.com/containers/storage/layers_ffjson.go
@@ -1,5 +1,5 @@
// Code generated by ffjson <https://github.com/pquerna/ffjson>. DO NOT EDIT.
-// source: layers.go
+// source: layers.go. Hack to make this work on github.com
package storage
diff --git a/vendor/github.com/containers/storage/lockfile.go b/vendor/github.com/containers/storage/lockfile.go
index 41ee9017a..c1aa482f8 100644
--- a/vendor/github.com/containers/storage/lockfile.go
+++ b/vendor/github.com/containers/storage/lockfile.go
@@ -2,14 +2,11 @@ package storage
import (
"fmt"
- "os"
"path/filepath"
"sync"
"time"
- "github.com/containers/storage/pkg/stringid"
"github.com/pkg/errors"
- "golang.org/x/sys/unix"
)
// A Locker represents a file lock where the file is used to cache an
@@ -33,16 +30,8 @@ type Locker interface {
IsReadWrite() bool
}
-type lockfile struct {
- mu sync.Mutex
- file string
- fd uintptr
- lw string
- locktype int16
-}
-
var (
- lockfiles map[string]*lockfile
+ lockfiles map[string]Locker
lockfilesLock sync.Mutex
)
@@ -52,7 +41,7 @@ func GetLockfile(path string) (Locker, error) {
lockfilesLock.Lock()
defer lockfilesLock.Unlock()
if lockfiles == nil {
- lockfiles = make(map[string]*lockfile)
+ lockfiles = make(map[string]Locker)
}
cleanPath := filepath.Clean(path)
if locker, ok := lockfiles[cleanPath]; ok {
@@ -61,12 +50,10 @@ func GetLockfile(path string) (Locker, error) {
}
return locker, nil
}
- fd, err := unix.Open(cleanPath, os.O_RDWR|os.O_CREATE, unix.S_IRUSR|unix.S_IWUSR)
+ locker, err := getLockFile(path, false) // platform dependent locker
if err != nil {
- return nil, errors.Wrapf(err, "error opening %q", cleanPath)
+ return nil, err
}
- unix.CloseOnExec(fd)
- locker := &lockfile{file: path, fd: uintptr(fd), lw: stringid.GenerateRandomID(), locktype: unix.F_WRLCK}
lockfiles[filepath.Clean(path)] = locker
return locker, nil
}
@@ -77,7 +64,7 @@ func GetROLockfile(path string) (Locker, error) {
lockfilesLock.Lock()
defer lockfilesLock.Unlock()
if lockfiles == nil {
- lockfiles = make(map[string]*lockfile)
+ lockfiles = make(map[string]Locker)
}
cleanPath := filepath.Clean(path)
if locker, ok := lockfiles[cleanPath]; ok {
@@ -86,99 +73,10 @@ func GetROLockfile(path string) (Locker, error) {
}
return locker, nil
}
- fd, err := unix.Open(cleanPath, os.O_RDONLY, 0)
+ locker, err := getLockFile(path, true) // platform dependent locker
if err != nil {
- return nil, errors.Wrapf(err, "error opening %q", cleanPath)
+ return nil, err
}
- unix.CloseOnExec(fd)
- locker := &lockfile{file: path, fd: uintptr(fd), lw: stringid.GenerateRandomID(), locktype: unix.F_RDLCK}
lockfiles[filepath.Clean(path)] = locker
return locker, nil
}
-
-// Lock locks the lock file
-func (l *lockfile) Lock() {
- lk := unix.Flock_t{
- Type: l.locktype,
- Whence: int16(os.SEEK_SET),
- Start: 0,
- Len: 0,
- Pid: int32(os.Getpid()),
- }
- l.mu.Lock()
- for unix.FcntlFlock(l.fd, unix.F_SETLKW, &lk) != nil {
- time.Sleep(10 * time.Millisecond)
- }
-}
-
-// Unlock unlocks the lock file
-func (l *lockfile) Unlock() {
- lk := unix.Flock_t{
- Type: unix.F_UNLCK,
- Whence: int16(os.SEEK_SET),
- Start: 0,
- Len: 0,
- Pid: int32(os.Getpid()),
- }
- for unix.FcntlFlock(l.fd, unix.F_SETLKW, &lk) != nil {
- time.Sleep(10 * time.Millisecond)
- }
- l.mu.Unlock()
-}
-
-// Touch updates the lock file with the UID of the user
-func (l *lockfile) Touch() error {
- l.lw = stringid.GenerateRandomID()
- id := []byte(l.lw)
- _, err := unix.Seek(int(l.fd), 0, os.SEEK_SET)
- if err != nil {
- return err
- }
- n, err := unix.Write(int(l.fd), id)
- if err != nil {
- return err
- }
- if n != len(id) {
- return unix.ENOSPC
- }
- err = unix.Fsync(int(l.fd))
- if err != nil {
- return err
- }
- return nil
-}
-
-// Modified indicates if the lock file has been updated since the last time it was loaded
-func (l *lockfile) Modified() (bool, error) {
- id := []byte(l.lw)
- _, err := unix.Seek(int(l.fd), 0, os.SEEK_SET)
- if err != nil {
- return true, err
- }
- n, err := unix.Read(int(l.fd), id)
- if err != nil {
- return true, err
- }
- if n != len(id) {
- return true, unix.ENOSPC
- }
- lw := l.lw
- l.lw = string(id)
- return l.lw != lw, nil
-}
-
-// TouchedSince indicates if the lock file has been touched since the specified time
-func (l *lockfile) TouchedSince(when time.Time) bool {
- st := unix.Stat_t{}
- err := unix.Fstat(int(l.fd), &st)
- if err != nil {
- return true
- }
- touched := time.Unix(statTMtimeUnix(st))
- return when.Before(touched)
-}
-
-// IsRWLock indicates if the lock file is a read-write lock
-func (l *lockfile) IsReadWrite() bool {
- return (l.locktype == unix.F_WRLCK)
-}
diff --git a/vendor/github.com/containers/storage/lockfile_darwin.go b/vendor/github.com/containers/storage/lockfile_darwin.go
new file mode 100644
index 000000000..041d54c05
--- /dev/null
+++ b/vendor/github.com/containers/storage/lockfile_darwin.go
@@ -0,0 +1,19 @@
+// +build darwin freebsd
+
+package storage
+
+import (
+ "time"
+
+ "golang.org/x/sys/unix"
+)
+
+func (l *lockfile) TouchedSince(when time.Time) bool {
+ st := unix.Stat_t{}
+ err := unix.Fstat(int(l.fd), &st)
+ if err != nil {
+ return true
+ }
+ touched := time.Unix(st.Mtimespec.Unix())
+ return when.Before(touched)
+}
diff --git a/vendor/github.com/containers/storage/lockfile_linux.go b/vendor/github.com/containers/storage/lockfile_linux.go
new file mode 100644
index 000000000..903387c66
--- /dev/null
+++ b/vendor/github.com/containers/storage/lockfile_linux.go
@@ -0,0 +1,20 @@
+// +build linux solaris
+
+package storage
+
+import (
+ "time"
+
+ "golang.org/x/sys/unix"
+)
+
+// TouchedSince indicates if the lock file has been touched since the specified time
+func (l *lockfile) TouchedSince(when time.Time) bool {
+ st := unix.Stat_t{}
+ err := unix.Fstat(int(l.fd), &st)
+ if err != nil {
+ return true
+ }
+ touched := time.Unix(st.Mtim.Unix())
+ return when.Before(touched)
+}
diff --git a/vendor/github.com/containers/storage/lockfile_unix.go b/vendor/github.com/containers/storage/lockfile_unix.go
new file mode 100644
index 000000000..679259234
--- /dev/null
+++ b/vendor/github.com/containers/storage/lockfile_unix.go
@@ -0,0 +1,115 @@
+// +build linux solaris darwin freebsd
+
+package storage
+
+import (
+ "os"
+ "sync"
+ "time"
+
+ "github.com/containers/storage/pkg/stringid"
+ "github.com/pkg/errors"
+ "golang.org/x/sys/unix"
+)
+
+func getLockFile(path string, ro bool) (Locker, error) {
+ var fd int
+ var err error
+ if ro {
+ fd, err = unix.Open(path, os.O_RDONLY, 0)
+ } else {
+ fd, err = unix.Open(path, os.O_RDWR|os.O_CREATE, unix.S_IRUSR|unix.S_IWUSR)
+ }
+ if err != nil {
+ return nil, errors.Wrapf(err, "error opening %q", path)
+ }
+ unix.CloseOnExec(fd)
+ if ro {
+ return &lockfile{file: path, fd: uintptr(fd), lw: stringid.GenerateRandomID(), locktype: unix.F_RDLCK}, nil
+ }
+ return &lockfile{file: path, fd: uintptr(fd), lw: stringid.GenerateRandomID(), locktype: unix.F_WRLCK}, nil
+}
+
+type lockfile struct {
+ mu sync.Mutex
+ file string
+ fd uintptr
+ lw string
+ locktype int16
+}
+
+// Lock locks the lock file
+func (l *lockfile) Lock() {
+ lk := unix.Flock_t{
+ Type: l.locktype,
+ Whence: int16(os.SEEK_SET),
+ Start: 0,
+ Len: 0,
+ Pid: int32(os.Getpid()),
+ }
+ l.mu.Lock()
+ for unix.FcntlFlock(l.fd, unix.F_SETLKW, &lk) != nil {
+ time.Sleep(10 * time.Millisecond)
+ }
+}
+
+// Unlock unlocks the lock file
+func (l *lockfile) Unlock() {
+ lk := unix.Flock_t{
+ Type: unix.F_UNLCK,
+ Whence: int16(os.SEEK_SET),
+ Start: 0,
+ Len: 0,
+ Pid: int32(os.Getpid()),
+ }
+ for unix.FcntlFlock(l.fd, unix.F_SETLKW, &lk) != nil {
+ time.Sleep(10 * time.Millisecond)
+ }
+ l.mu.Unlock()
+}
+
+// Touch updates the lock file with the UID of the user
+func (l *lockfile) Touch() error {
+ l.lw = stringid.GenerateRandomID()
+ id := []byte(l.lw)
+ _, err := unix.Seek(int(l.fd), 0, os.SEEK_SET)
+ if err != nil {
+ return err
+ }
+ n, err := unix.Write(int(l.fd), id)
+ if err != nil {
+ return err
+ }
+ if n != len(id) {
+ return unix.ENOSPC
+ }
+ err = unix.Fsync(int(l.fd))
+ if err != nil {
+ return err
+ }
+ return nil
+}
+
+// Modified indicates if the lock file has been updated since the last time it was loaded
+func (l *lockfile) Modified() (bool, error) {
+ id := []byte(l.lw)
+ _, err := unix.Seek(int(l.fd), 0, os.SEEK_SET)
+ if err != nil {
+ return true, err
+ }
+ n, err := unix.Read(int(l.fd), id)
+ if err != nil {
+ return true, err
+ }
+ if n != len(id) {
+ return true, unix.ENOSPC
+ }
+ lw := l.lw
+ l.lw = string(id)
+ return l.lw != lw, nil
+}
+
+// IsRWLock indicates if the lock file is a read-write lock
+func (l *lockfile) IsReadWrite() bool {
+ return (l.locktype == unix.F_WRLCK)
+}
diff --git a/vendor/github.com/containers/storage/lockfile_windows.go b/vendor/github.com/containers/storage/lockfile_windows.go
new file mode 100644
index 000000000..ed6c5c4b2
--- /dev/null
+++ b/vendor/github.com/containers/storage/lockfile_windows.go
@@ -0,0 +1,40 @@
+// +build windows
+
+package storage
+
+import (
+ "os"
+ "sync"
+ "time"
+)
+
+func getLockFile(path string, ro bool) (Locker, error) {
+ return &lockfile{}, nil
+}
+
+type lockfile struct {
+ mu sync.Mutex
+ file string
+}
+
+func (l *lockfile) Lock() {
+}
+func (l *lockfile) Unlock() {
+}
+func (l *lockfile) Modified() (bool, error) {
+ return false, nil
+}
+func (l *lockfile) Touch() error {
+ return nil
+}
+func (l *lockfile) IsReadWrite() bool {
+ return false
+}
+
+func (l *lockfile) TouchedSince(when time.Time) bool {
+ stat, err := os.Stat(l.file)
+ if err != nil {
+ return true
+ }
+ return when.Before(stat.ModTime())
+}
diff --git a/vendor/github.com/containers/storage/pkg/truncindex/truncindex.go b/vendor/github.com/containers/storage/pkg/truncindex/truncindex.go
index 02610b8b7..74776e65e 100644
--- a/vendor/github.com/containers/storage/pkg/truncindex/truncindex.go
+++ b/vendor/github.com/containers/storage/pkg/truncindex/truncindex.go
@@ -77,10 +77,7 @@ func (idx *TruncIndex) addID(id string) error {
func (idx *TruncIndex) Add(id string) error {
idx.Lock()
defer idx.Unlock()
- if err := idx.addID(id); err != nil {
- return err
- }
- return nil
+ return idx.addID(id)
}
// Delete removes an ID from the TruncIndex. If there are multiple IDs
@@ -128,8 +125,13 @@ func (idx *TruncIndex) Get(s string) (string, error) {
return "", ErrNotExist
}
-// Iterate iterates over all stored IDs, and passes each of them to the given handler.
+// Iterate iterates over all stored IDs and passes each of them to the given
+// handler. Take care that the handler method does not call any public
+// method on truncindex as the internal locking is not reentrant/recursive
+// and will result in deadlock.
func (idx *TruncIndex) Iterate(handler func(id string)) {
+ idx.Lock()
+ defer idx.Unlock()
idx.trie.Visit(func(prefix patricia.Prefix, item patricia.Item) error {
handler(string(prefix))
return nil
diff --git a/vendor/github.com/containers/storage/stat_mtim.go b/vendor/github.com/containers/storage/stat_mtim.go
deleted file mode 100644
index 84d34dce3..000000000
--- a/vendor/github.com/containers/storage/stat_mtim.go
+++ /dev/null
@@ -1,11 +0,0 @@
-// +build linux solaris
-
-package storage
-
-import (
- "golang.org/x/sys/unix"
-)
-
-func statTMtimeUnix(st unix.Stat_t) (int64, int64) {
- return st.Mtim.Unix()
-}
diff --git a/vendor/github.com/containers/storage/stat_mtimespec.go b/vendor/github.com/containers/storage/stat_mtimespec.go
deleted file mode 100644
index f55ed434b..000000000
--- a/vendor/github.com/containers/storage/stat_mtimespec.go
+++ /dev/null
@@ -1,11 +0,0 @@
-// +build !linux,!solaris
-
-package storage
-
-import (
- "golang.org/x/sys/unix"
-)
-
-func statTMtimeUnix(st unix.Stat_t) (int64, int64) {
- return st.Mtimespec.Unix()
-}