mirror of
https://github.com/containers/podman.git
synced 2025-06-22 09:58:10 +08:00
Update containers/storage
New pinned commit is 477e551dd493e5c80999d3690d3a201fd26ba2f1 Signed-off-by: Matthew Heon <matthew.heon@gmail.com> Closes: #425 Approved by: rhatdan
This commit is contained in:
vendor.conf
vendor/github.com/containers/storage
@ -3,7 +3,7 @@ github.com/sirupsen/logrus v1.0.0
|
|||||||
github.com/containers/image f7ea1dcb32a06092905672e99faa75bf2f61632b
|
github.com/containers/image f7ea1dcb32a06092905672e99faa75bf2f61632b
|
||||||
github.com/docker/docker-credential-helpers d68f9aeca33f5fd3f08eeae5e9d175edf4e731d1
|
github.com/docker/docker-credential-helpers d68f9aeca33f5fd3f08eeae5e9d175edf4e731d1
|
||||||
github.com/ostreedev/ostree-go master
|
github.com/ostreedev/ostree-go master
|
||||||
github.com/containers/storage 1824cf917a6b42d8c41179e807bb20a5fd6c0f0a
|
github.com/containers/storage 477e551dd493e5c80999d3690d3a201fd26ba2f1
|
||||||
github.com/containernetworking/cni v0.4.0
|
github.com/containernetworking/cni v0.4.0
|
||||||
google.golang.org/grpc v1.0.4 https://github.com/grpc/grpc-go
|
google.golang.org/grpc v1.0.4 https://github.com/grpc/grpc-go
|
||||||
github.com/opencontainers/selinux b29023b86e4a69d1b46b7e7b4e2b6fda03f0b9cd
|
github.com/opencontainers/selinux b29023b86e4a69d1b46b7e7b4e2b6fda03f0b9cd
|
||||||
|
18
vendor/github.com/containers/storage/drivers/aufs/aufs.go
generated
vendored
18
vendor/github.com/containers/storage/drivers/aufs/aufs.go
generated
vendored
@ -463,9 +463,9 @@ func (a *Driver) isParent(id, parent string) bool {
|
|||||||
|
|
||||||
// Diff produces an archive of the changes between the specified
|
// Diff produces an archive of the changes between the specified
|
||||||
// layer and its parent layer which may be "".
|
// 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) {
|
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.
|
// 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
|
// DiffSize calculates the changes between the specified id
|
||||||
// and its parent and returns the size in bytes of the changes
|
// and its parent and returns the size in bytes of the changes
|
||||||
// relative to its base filesystem directory.
|
// 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) {
|
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.
|
// AUFS doesn't need the parent layer to calculate the diff size.
|
||||||
return directory.Size(path.Join(a.rootPath(), "diff", id))
|
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
|
// ApplyDiff extracts the changeset from the given diff into the
|
||||||
// layer with the specified id and parent, returning the size of the
|
// layer with the specified id and parent, returning the size of the
|
||||||
// new layer in bytes.
|
// 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) {
|
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.
|
// 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
|
||||||
}
|
}
|
||||||
|
|
||||||
return a.DiffSize(id, parent)
|
return a.DiffSize(id, parent, mountLabel)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Changes produces a list of changes between the specified layer
|
// Changes produces a list of changes between the specified layer
|
||||||
// and its parent layer. If parent is "", then all changes will be ADD changes.
|
// 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) {
|
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
|
// AUFS doesn't have snapshots, so we need to get changes from all parent
|
||||||
|
8
vendor/github.com/containers/storage/drivers/driver.go
generated
vendored
8
vendor/github.com/containers/storage/drivers/driver.go
generated
vendored
@ -92,19 +92,19 @@ type ProtoDriver interface {
|
|||||||
type DiffDriver interface {
|
type DiffDriver interface {
|
||||||
// Diff produces an archive of the changes between the specified
|
// Diff produces an archive of the changes between the specified
|
||||||
// layer and its parent layer which may be "".
|
// 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
|
// Changes produces a list of changes between the specified layer
|
||||||
// and its parent layer. If parent is "", then all changes will be ADD changes.
|
// 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
|
// ApplyDiff extracts the changeset from the given diff into the
|
||||||
// layer with the specified id and parent, returning the size of the
|
// layer with the specified id and parent, returning the size of the
|
||||||
// new layer in bytes.
|
// new layer in bytes.
|
||||||
// The io.Reader must be an uncompressed stream.
|
// 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
|
// DiffSize calculates the changes between the specified id
|
||||||
// and its parent and returns the size in bytes of the changes
|
// and its parent and returns the size in bytes of the changes
|
||||||
// relative to its base filesystem directory.
|
// 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.
|
// Driver is the interface for layered/snapshot file system drivers.
|
||||||
|
30
vendor/github.com/containers/storage/drivers/fsdiff.go
generated
vendored
30
vendor/github.com/containers/storage/drivers/fsdiff.go
generated
vendored
@ -31,10 +31,10 @@ type NaiveDiffDriver struct {
|
|||||||
// NewNaiveDiffDriver returns a fully functional driver that wraps the
|
// NewNaiveDiffDriver returns a fully functional driver that wraps the
|
||||||
// given ProtoDriver and adds the capability of the following methods which
|
// given ProtoDriver and adds the capability of the following methods which
|
||||||
// it may or may not support on its own:
|
// it may or may not support on its own:
|
||||||
// Diff(id, parent string) (io.ReadCloser, error)
|
// Diff(id, parent, mountLabel string) (io.ReadCloser, error)
|
||||||
// Changes(id, parent string) ([]archive.Change, error)
|
// Changes(id, parent, mountLabel string) ([]archive.Change, error)
|
||||||
// ApplyDiff(id, parent string, diff io.Reader) (size int64, err error)
|
// ApplyDiff(id, parent, mountLabel string, diff io.Reader) (size int64, err error)
|
||||||
// DiffSize(id, parent string) (size int64, err error)
|
// DiffSize(id, parent, mountLabel string) (size int64, err error)
|
||||||
func NewNaiveDiffDriver(driver ProtoDriver, uidMaps, gidMaps []idtools.IDMap) Driver {
|
func NewNaiveDiffDriver(driver ProtoDriver, uidMaps, gidMaps []idtools.IDMap) Driver {
|
||||||
return &NaiveDiffDriver{ProtoDriver: driver,
|
return &NaiveDiffDriver{ProtoDriver: driver,
|
||||||
uidMaps: uidMaps,
|
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
|
// Diff produces an archive of the changes between the specified
|
||||||
// layer and its parent layer which may be "".
|
// 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()
|
startTime := time.Now()
|
||||||
driver := gdw.ProtoDriver
|
driver := gdw.ProtoDriver
|
||||||
|
|
||||||
layerFs, err := driver.Get(id, "")
|
layerFs, err := driver.Get(id, mountLabel)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -70,7 +70,7 @@ func (gdw *NaiveDiffDriver) Diff(id, parent string) (arch io.ReadCloser, err err
|
|||||||
}), nil
|
}), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
parentFs, err := driver.Get(parent, "")
|
parentFs, err := driver.Get(parent, mountLabel)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
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
|
// Changes produces a list of changes between the specified layer
|
||||||
// and its parent layer. If parent is "", then all changes will be ADD changes.
|
// 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
|
driver := gdw.ProtoDriver
|
||||||
|
|
||||||
layerFs, err := driver.Get(id, "")
|
layerFs, err := driver.Get(id, mountLabel)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -113,7 +113,7 @@ func (gdw *NaiveDiffDriver) Changes(id, parent string) ([]archive.Change, error)
|
|||||||
parentFs := ""
|
parentFs := ""
|
||||||
|
|
||||||
if parent != "" {
|
if parent != "" {
|
||||||
parentFs, err = driver.Get(parent, "")
|
parentFs, err = driver.Get(parent, mountLabel)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
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
|
// ApplyDiff extracts the changeset from the given diff into the
|
||||||
// layer with the specified id and parent, returning the size of the
|
// layer with the specified id and parent, returning the size of the
|
||||||
// new layer in bytes.
|
// 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
|
driver := gdw.ProtoDriver
|
||||||
|
|
||||||
// Mount the root filesystem so we can apply the diff/layer.
|
// 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 {
|
if err != nil {
|
||||||
return
|
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
|
// DiffSize calculates the changes between the specified layer
|
||||||
// and its parent and returns the size in bytes of the changes
|
// and its parent and returns the size in bytes of the changes
|
||||||
// relative to its base filesystem directory.
|
// 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
|
driver := gdw.ProtoDriver
|
||||||
|
|
||||||
changes, err := gdw.Changes(id, parent)
|
changes, err := gdw.Changes(id, parent, mountLabel)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
layerFs, err := driver.Get(id, "")
|
layerFs, err := driver.Get(id, mountLabel)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
144
vendor/github.com/containers/storage/drivers/overlay/overlay.go
generated
vendored
144
vendor/github.com/containers/storage/drivers/overlay/overlay.go
generated
vendored
@ -3,7 +3,6 @@
|
|||||||
package overlay
|
package overlay
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
@ -26,7 +25,6 @@ import (
|
|||||||
"github.com/containers/storage/pkg/locker"
|
"github.com/containers/storage/pkg/locker"
|
||||||
"github.com/containers/storage/pkg/mount"
|
"github.com/containers/storage/pkg/mount"
|
||||||
"github.com/containers/storage/pkg/parsers"
|
"github.com/containers/storage/pkg/parsers"
|
||||||
"github.com/containers/storage/pkg/parsers/kernel"
|
|
||||||
"github.com/containers/storage/pkg/system"
|
"github.com/containers/storage/pkg/system"
|
||||||
units "github.com/docker/go-units"
|
units "github.com/docker/go-units"
|
||||||
"github.com/opencontainers/selinux/go-selinux/label"
|
"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
|
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)
|
fsMagic, err := graphdriver.GetFSMagic(home)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
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:
|
case graphdriver.FsMagicAufs, graphdriver.FsMagicZfs, graphdriver.FsMagicOverlay, graphdriver.FsMagicEcryptfs:
|
||||||
logrus.Errorf("'overlay' is not supported over %s", backingFs)
|
logrus.Errorf("'overlay' is not supported over %s", backingFs)
|
||||||
return nil, errors.Wrapf(graphdriver.ErrIncompatibleFS, "'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)
|
rootUID, rootGID, err := idtools.GetRootUIDGID(uidMaps, gidMaps)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the driver home dir
|
// Create the driver home dir
|
||||||
if err := idtools.MkdirAllAs(path.Join(home, linkDir), 0700, rootUID, rootGID); err != nil && !os.IsExist(err) {
|
if err := idtools.MkdirAllAs(path.Join(home, linkDir), 0700, rootUID, rootGID); err != nil && !os.IsExist(err) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := mount.MakePrivate(home); err != nil {
|
supportsDType, err := supportsOverlay(home, fsMagic, rootUID, rootGID)
|
||||||
return nil, err
|
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 := mount.MakePrivate(home); err != nil {
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
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{
|
d := &Driver{
|
||||||
name: "overlay",
|
name: "overlay",
|
||||||
@ -210,10 +180,10 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap
|
|||||||
}
|
}
|
||||||
} else if opts.quota.Size > 0 {
|
} else if opts.quota.Size > 0 {
|
||||||
// if xfs is not the backing fs then error out if the storage-opt overlay.size is used.
|
// 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
|
return d, nil
|
||||||
}
|
}
|
||||||
@ -264,25 +234,57 @@ func parseOptions(options []string) (*overlayOptions, error) {
|
|||||||
return o, nil
|
return o, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func supportsOverlay() error {
|
func supportsOverlay(home string, homeMagic graphdriver.FsMagic, rootUID, rootGID int) (supportsDType bool, err error) {
|
||||||
// We can try to modprobe overlay first before looking at
|
// We can try to modprobe overlay first
|
||||||
// proc/filesystems for when overlay is supported
|
|
||||||
exec.Command("modprobe", "overlay").Run()
|
exec.Command("modprobe", "overlay").Run()
|
||||||
|
|
||||||
f, err := os.Open("/proc/filesystems")
|
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 {
|
if err != nil {
|
||||||
return err
|
return false, err
|
||||||
|
}
|
||||||
|
if !supportsDType {
|
||||||
|
return false, overlayutils.ErrDTypeNotSupported("overlay", backingFs)
|
||||||
}
|
}
|
||||||
defer f.Close()
|
|
||||||
|
|
||||||
s := bufio.NewScanner(f)
|
// Try a test mount in the specific location we're looking at using.
|
||||||
for s.Scan() {
|
mergedDir := filepath.Join(layerDir, "merged")
|
||||||
if s.Text() == "nodev\toverlay" {
|
lower1Dir := filepath.Join(layerDir, "lower1")
|
||||||
return nil
|
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.")
|
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 {
|
func useNaiveDiff(home string) bool {
|
||||||
@ -424,11 +426,6 @@ func (d *Driver) create(id, parent string, opts *graphdriver.CreateOpts) (retErr
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// if no parent directory, done
|
|
||||||
if parent == "" {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := idtools.MkdirAs(path.Join(dir, "work"), 0700, rootUID, rootGID); err != nil {
|
if err := idtools.MkdirAs(path.Join(dir, "work"), 0700, rootUID, rootGID); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -436,6 +433,11 @@ func (d *Driver) create(id, parent string, opts *graphdriver.CreateOpts) (retErr
|
|||||||
return err
|
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)
|
lower, err := d.getLower(parent)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -556,11 +558,7 @@ func (d *Driver) Get(id, mountLabel string) (_ string, retErr error) {
|
|||||||
|
|
||||||
diffDir := path.Join(dir, "diff")
|
diffDir := path.Join(dir, "diff")
|
||||||
lowers, err := ioutil.ReadFile(path.Join(dir, lowerFile))
|
lowers, err := ioutil.ReadFile(path.Join(dir, lowerFile))
|
||||||
if err != nil {
|
if err != nil && !os.IsNotExist(err) {
|
||||||
// If no lower, just return diff directory
|
|
||||||
if os.IsNotExist(err) {
|
|
||||||
return diffDir, nil
|
|
||||||
}
|
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -588,6 +586,10 @@ func (d *Driver) Get(id, mountLabel string) (_ string, retErr error) {
|
|||||||
newlowers = newlowers + ":" + lower
|
newlowers = newlowers + ":" + lower
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if len(lowers) == 0 {
|
||||||
|
newlowers = path.Join(dir, "empty")
|
||||||
|
lowers = []byte(newlowers)
|
||||||
|
}
|
||||||
|
|
||||||
mergedDir := path.Join(dir, "merged")
|
mergedDir := path.Join(dir, "merged")
|
||||||
if count := d.ctr.Increment(mergedDir); count > 1 {
|
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 {
|
if count := d.ctr.Decrement(mountpoint); count > 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if _, err := ioutil.ReadFile(path.Join(dir, lowerFile)); err != nil {
|
if _, err := ioutil.ReadFile(path.Join(dir, lowerFile)); err != nil && !os.IsNotExist(err) {
|
||||||
// If no lower, we used the diff directory, so no work to do
|
|
||||||
if os.IsNotExist(err) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := unix.Unmount(mountpoint, unix.MNT_DETACH); err != nil {
|
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
|
// 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) {
|
if !d.isParent(id, parent) {
|
||||||
return d.naiveDiff.ApplyDiff(id, parent, diff)
|
return d.naiveDiff.ApplyDiff(id, parent, mountLabel, diff)
|
||||||
}
|
}
|
||||||
|
|
||||||
applyDir := d.getDiffPath(id)
|
applyDir := d.getDiffPath(id)
|
||||||
@ -728,18 +726,18 @@ func (d *Driver) getDiffPath(id string) string {
|
|||||||
// DiffSize calculates the changes between the specified id
|
// DiffSize calculates the changes between the specified id
|
||||||
// and its parent and returns the size in bytes of the changes
|
// and its parent and returns the size in bytes of the changes
|
||||||
// relative to its base filesystem directory.
|
// 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) {
|
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))
|
return directory.Size(d.getDiffPath(id))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Diff produces an archive of the changes between the specified
|
// Diff produces an archive of the changes between the specified
|
||||||
// layer and its parent layer which may be "".
|
// 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) {
|
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)
|
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
|
// Changes produces a list of changes between the specified layer
|
||||||
// and its parent layer. If parent is "", then all changes will be ADD changes.
|
// 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) {
|
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
|
// Overlay doesn't have snapshots, so we need to get changes from all parent
|
||||||
// layers.
|
// layers.
|
||||||
|
10
vendor/github.com/containers/storage/drivers/windows/windows.go
generated
vendored
10
vendor/github.com/containers/storage/drivers/windows/windows.go
generated
vendored
@ -472,7 +472,7 @@ func (d *Driver) Cleanup() error {
|
|||||||
// Diff produces an archive of the changes between the specified
|
// Diff produces an archive of the changes between the specified
|
||||||
// layer and its parent layer which may be "".
|
// layer and its parent layer which may be "".
|
||||||
// The layer should be mounted when calling this function
|
// 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()
|
panicIfUsedByLcow()
|
||||||
rID, err := d.resolveID(id)
|
rID, err := d.resolveID(id)
|
||||||
if err != nil {
|
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
|
// Changes produces a list of changes between the specified layer
|
||||||
// and its parent layer. If parent is "", then all changes will be ADD changes.
|
// and its parent layer. If parent is "", then all changes will be ADD changes.
|
||||||
// The layer should not be mounted when calling this function.
|
// 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()
|
panicIfUsedByLcow()
|
||||||
rID, err := d.resolveID(id)
|
rID, err := d.resolveID(id)
|
||||||
if err != nil {
|
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
|
// layer with the specified id and parent, returning the size of the
|
||||||
// new layer in bytes.
|
// new layer in bytes.
|
||||||
// The layer should not be mounted when calling this function
|
// 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()
|
panicIfUsedByLcow()
|
||||||
var layerChain []string
|
var layerChain []string
|
||||||
if parent != "" {
|
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
|
// DiffSize calculates the changes between the specified layer
|
||||||
// and its parent and returns the size in bytes of the changes
|
// and its parent and returns the size in bytes of the changes
|
||||||
// relative to its base filesystem directory.
|
// 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()
|
panicIfUsedByLcow()
|
||||||
rPId, err := d.resolveID(parent)
|
rPId, err := d.resolveID(parent)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
changes, err := d.Changes(id, rPId)
|
changes, err := d.Changes(id, rPId, mountLabel)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
15
vendor/github.com/containers/storage/layers.go
generated
vendored
15
vendor/github.com/containers/storage/layers.go
generated
vendored
@ -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) {
|
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 {
|
if err != nil {
|
||||||
return nil, ErrLayerUnknown
|
return nil, ErrLayerUnknown
|
||||||
}
|
}
|
||||||
return r.driver.Changes(to, from)
|
return r.driver.Changes(to, from, toLayer.MountLabel)
|
||||||
}
|
}
|
||||||
|
|
||||||
type simpleGetCloser struct {
|
type simpleGetCloser struct {
|
||||||
@ -855,7 +855,7 @@ func (r *layerStore) Diff(from, to string, options *DiffOptions) (io.ReadCloser,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if from != toLayer.Parent {
|
if from != toLayer.Parent {
|
||||||
diff, err := r.driver.Diff(to, from)
|
diff, err := r.driver.Diff(to, from, toLayer.MountLabel)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -867,7 +867,7 @@ func (r *layerStore) Diff(from, to string, options *DiffOptions) (io.ReadCloser,
|
|||||||
if !os.IsNotExist(err) {
|
if !os.IsNotExist(err) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
diff, err := r.driver.Diff(to, from)
|
diff, err := r.driver.Diff(to, from, toLayer.MountLabel)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
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) {
|
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 {
|
if err != nil {
|
||||||
return -1, ErrLayerUnknown
|
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) {
|
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 {
|
if err != nil {
|
||||||
return -1, err
|
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 {
|
if err != nil {
|
||||||
return -1, err
|
return -1, err
|
||||||
}
|
}
|
||||||
|
2
vendor/github.com/containers/storage/layers_ffjson.go
generated
vendored
2
vendor/github.com/containers/storage/layers_ffjson.go
generated
vendored
@ -1,5 +1,5 @@
|
|||||||
// Code generated by ffjson <https://github.com/pquerna/ffjson>. DO NOT EDIT.
|
// 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
|
package storage
|
||||||
|
|
||||||
|
116
vendor/github.com/containers/storage/lockfile.go
generated
vendored
116
vendor/github.com/containers/storage/lockfile.go
generated
vendored
@ -2,14 +2,11 @@ package storage
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/containers/storage/pkg/stringid"
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"golang.org/x/sys/unix"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// A Locker represents a file lock where the file is used to cache an
|
// A Locker represents a file lock where the file is used to cache an
|
||||||
@ -33,16 +30,8 @@ type Locker interface {
|
|||||||
IsReadWrite() bool
|
IsReadWrite() bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type lockfile struct {
|
|
||||||
mu sync.Mutex
|
|
||||||
file string
|
|
||||||
fd uintptr
|
|
||||||
lw string
|
|
||||||
locktype int16
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
var (
|
||||||
lockfiles map[string]*lockfile
|
lockfiles map[string]Locker
|
||||||
lockfilesLock sync.Mutex
|
lockfilesLock sync.Mutex
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -52,7 +41,7 @@ func GetLockfile(path string) (Locker, error) {
|
|||||||
lockfilesLock.Lock()
|
lockfilesLock.Lock()
|
||||||
defer lockfilesLock.Unlock()
|
defer lockfilesLock.Unlock()
|
||||||
if lockfiles == nil {
|
if lockfiles == nil {
|
||||||
lockfiles = make(map[string]*lockfile)
|
lockfiles = make(map[string]Locker)
|
||||||
}
|
}
|
||||||
cleanPath := filepath.Clean(path)
|
cleanPath := filepath.Clean(path)
|
||||||
if locker, ok := lockfiles[cleanPath]; ok {
|
if locker, ok := lockfiles[cleanPath]; ok {
|
||||||
@ -61,12 +50,10 @@ func GetLockfile(path string) (Locker, error) {
|
|||||||
}
|
}
|
||||||
return locker, nil
|
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 {
|
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
|
lockfiles[filepath.Clean(path)] = locker
|
||||||
return locker, nil
|
return locker, nil
|
||||||
}
|
}
|
||||||
@ -77,7 +64,7 @@ func GetROLockfile(path string) (Locker, error) {
|
|||||||
lockfilesLock.Lock()
|
lockfilesLock.Lock()
|
||||||
defer lockfilesLock.Unlock()
|
defer lockfilesLock.Unlock()
|
||||||
if lockfiles == nil {
|
if lockfiles == nil {
|
||||||
lockfiles = make(map[string]*lockfile)
|
lockfiles = make(map[string]Locker)
|
||||||
}
|
}
|
||||||
cleanPath := filepath.Clean(path)
|
cleanPath := filepath.Clean(path)
|
||||||
if locker, ok := lockfiles[cleanPath]; ok {
|
if locker, ok := lockfiles[cleanPath]; ok {
|
||||||
@ -86,99 +73,10 @@ func GetROLockfile(path string) (Locker, error) {
|
|||||||
}
|
}
|
||||||
return locker, nil
|
return locker, nil
|
||||||
}
|
}
|
||||||
fd, err := unix.Open(cleanPath, os.O_RDONLY, 0)
|
locker, err := getLockFile(path, true) // platform dependent locker
|
||||||
if err != nil {
|
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
|
lockfiles[filepath.Clean(path)] = locker
|
||||||
return locker, nil
|
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)
|
|
||||||
}
|
|
||||||
|
19
vendor/github.com/containers/storage/lockfile_darwin.go
generated
vendored
Normal file
19
vendor/github.com/containers/storage/lockfile_darwin.go
generated
vendored
Normal file
@ -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)
|
||||||
|
}
|
20
vendor/github.com/containers/storage/lockfile_linux.go
generated
vendored
Normal file
20
vendor/github.com/containers/storage/lockfile_linux.go
generated
vendored
Normal file
@ -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)
|
||||||
|
}
|
115
vendor/github.com/containers/storage/lockfile_unix.go
generated
vendored
Normal file
115
vendor/github.com/containers/storage/lockfile_unix.go
generated
vendored
Normal file
@ -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)
|
||||||
|
}
|
40
vendor/github.com/containers/storage/lockfile_windows.go
generated
vendored
Normal file
40
vendor/github.com/containers/storage/lockfile_windows.go
generated
vendored
Normal file
@ -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())
|
||||||
|
}
|
12
vendor/github.com/containers/storage/pkg/truncindex/truncindex.go
generated
vendored
12
vendor/github.com/containers/storage/pkg/truncindex/truncindex.go
generated
vendored
@ -77,10 +77,7 @@ func (idx *TruncIndex) addID(id string) error {
|
|||||||
func (idx *TruncIndex) Add(id string) error {
|
func (idx *TruncIndex) Add(id string) error {
|
||||||
idx.Lock()
|
idx.Lock()
|
||||||
defer idx.Unlock()
|
defer idx.Unlock()
|
||||||
if err := idx.addID(id); err != nil {
|
return idx.addID(id)
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete removes an ID from the TruncIndex. If there are multiple IDs
|
// 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
|
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)) {
|
func (idx *TruncIndex) Iterate(handler func(id string)) {
|
||||||
|
idx.Lock()
|
||||||
|
defer idx.Unlock()
|
||||||
idx.trie.Visit(func(prefix patricia.Prefix, item patricia.Item) error {
|
idx.trie.Visit(func(prefix patricia.Prefix, item patricia.Item) error {
|
||||||
handler(string(prefix))
|
handler(string(prefix))
|
||||||
return nil
|
return nil
|
||||||
|
11
vendor/github.com/containers/storage/stat_mtim.go
generated
vendored
11
vendor/github.com/containers/storage/stat_mtim.go
generated
vendored
@ -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()
|
|
||||||
}
|
|
11
vendor/github.com/containers/storage/stat_mtimespec.go
generated
vendored
11
vendor/github.com/containers/storage/stat_mtimespec.go
generated
vendored
@ -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()
|
|
||||||
}
|
|
Reference in New Issue
Block a user