diff options
Diffstat (limited to 'vendor')
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() -} |