Update continuity vendor
Pulls in copy and fstest changes Signed-off-by: Derek McGowan <derek@mcgstyle.net>
This commit is contained in:
		@@ -50,25 +50,25 @@ func testLookup(t *testing.T, fsType string) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	defer os.RemoveAll(mnt)
 | 
						defer os.RemoveAll(mnt)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	deviceName, cleanupDevice, err := loopback.New(100 << 20) // 100 MB
 | 
						loop, err := loopback.New(100 << 20) // 100 MB
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		t.Fatal(err)
 | 
							t.Fatal(err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if out, err := exec.Command("mkfs", "-t", fsType, deviceName).CombinedOutput(); err != nil {
 | 
						if out, err := exec.Command("mkfs", "-t", fsType, loop.Device).CombinedOutput(); err != nil {
 | 
				
			||||||
		// not fatal
 | 
							// not fatal
 | 
				
			||||||
		cleanupDevice()
 | 
							loop.Close()
 | 
				
			||||||
		t.Skipf("could not mkfs (%s) %s: %v (out: %q)", fsType, deviceName, err, string(out))
 | 
							t.Skipf("could not mkfs (%s) %s: %v (out: %q)", fsType, loop.Device, err, string(out))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if out, err := exec.Command("mount", deviceName, mnt).CombinedOutput(); err != nil {
 | 
						if out, err := exec.Command("mount", loop.Device, mnt).CombinedOutput(); err != nil {
 | 
				
			||||||
		// not fatal
 | 
							// not fatal
 | 
				
			||||||
		cleanupDevice()
 | 
							loop.Close()
 | 
				
			||||||
		t.Skipf("could not mount %s: %v (out: %q)", deviceName, err, string(out))
 | 
							t.Skipf("could not mount %s: %v (out: %q)", loop.Device, err, string(out))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	defer func() {
 | 
						defer func() {
 | 
				
			||||||
		testutil.Unmount(t, mnt)
 | 
							testutil.Unmount(t, mnt)
 | 
				
			||||||
		cleanupDevice()
 | 
							loop.Close()
 | 
				
			||||||
	}()
 | 
						}()
 | 
				
			||||||
	assert.Check(t, strings.HasPrefix(deviceName, "/dev/loop"))
 | 
						assert.Check(t, strings.HasPrefix(loop.Device, "/dev/loop"))
 | 
				
			||||||
	checkLookup(t, fsType, mnt, mnt)
 | 
						checkLookup(t, fsType, mnt, mnt)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	newMnt, err := ioutil.TempDir("", "containerd-mountinfo-test-newMnt")
 | 
						newMnt, err := ioutil.TempDir("", "containerd-mountinfo-test-newMnt")
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -52,24 +52,24 @@ func boltSnapshotter(t *testing.T) func(context.Context, string) (snapshots.Snap
 | 
				
			|||||||
		if os.Getpagesize() > 4096 {
 | 
							if os.Getpagesize() > 4096 {
 | 
				
			||||||
			loopbackSize = int64(650 << 20) // 650 MB
 | 
								loopbackSize = int64(650 << 20) // 650 MB
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		deviceName, cleanupDevice, err := loopback.New(loopbackSize)
 | 
							loop, err := loopback.New(loopbackSize)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			return nil, nil, err
 | 
								return nil, nil, err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if out, err := exec.Command(mkbtrfs, deviceName).CombinedOutput(); err != nil {
 | 
							if out, err := exec.Command(mkbtrfs, loop.Device).CombinedOutput(); err != nil {
 | 
				
			||||||
			cleanupDevice()
 | 
								loop.Close()
 | 
				
			||||||
			return nil, nil, errors.Wrapf(err, "failed to make btrfs filesystem (out: %q)", out)
 | 
								return nil, nil, errors.Wrapf(err, "failed to make btrfs filesystem (out: %q)", out)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if out, err := exec.Command("mount", deviceName, root).CombinedOutput(); err != nil {
 | 
							if out, err := exec.Command("mount", loop.Device, root).CombinedOutput(); err != nil {
 | 
				
			||||||
			cleanupDevice()
 | 
								loop.Close()
 | 
				
			||||||
			return nil, nil, errors.Wrapf(err, "failed to mount device %s (out: %q)", deviceName, out)
 | 
								return nil, nil, errors.Wrapf(err, "failed to mount device %s (out: %q)", loop.Device, out)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		snapshotter, err := NewSnapshotter(root)
 | 
							snapshotter, err := NewSnapshotter(root)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			cleanupDevice()
 | 
								loop.Close()
 | 
				
			||||||
			return nil, nil, errors.Wrap(err, "failed to create new snapshotter")
 | 
								return nil, nil, errors.Wrap(err, "failed to create new snapshotter")
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -78,7 +78,7 @@ func boltSnapshotter(t *testing.T) func(context.Context, string) (snapshots.Snap
 | 
				
			|||||||
				return err
 | 
									return err
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			err := mount.UnmountAll(root, unix.MNT_DETACH)
 | 
								err := mount.UnmountAll(root, unix.MNT_DETACH)
 | 
				
			||||||
			if cerr := cleanupDevice(); cerr != nil {
 | 
								if cerr := loop.Close(); cerr != nil {
 | 
				
			||||||
				err = errors.Wrap(cerr, "device cleanup failed")
 | 
									err = errors.Wrap(cerr, "device cleanup failed")
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			return err
 | 
								return err
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -36,23 +36,23 @@ func testOverlaySupported(t testing.TB, expected bool, mkfs ...string) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	defer os.RemoveAll(mnt)
 | 
						defer os.RemoveAll(mnt)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	deviceName, cleanupDevice, err := loopback.New(100 << 20) // 100 MB
 | 
						loop, err := loopback.New(100 << 20) // 100 MB
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		t.Fatal(err)
 | 
							t.Fatal(err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if out, err := exec.Command(mkfs[0], append(mkfs[1:], deviceName)...).CombinedOutput(); err != nil {
 | 
						if out, err := exec.Command(mkfs[0], append(mkfs[1:], loop.Device)...).CombinedOutput(); err != nil {
 | 
				
			||||||
		// not fatal
 | 
							// not fatal
 | 
				
			||||||
		cleanupDevice()
 | 
							loop.Close()
 | 
				
			||||||
		t.Skipf("could not mkfs (%v) %s: %v (out: %q)", mkfs, deviceName, err, string(out))
 | 
							t.Skipf("could not mkfs (%v) %s: %v (out: %q)", mkfs, loop.Device, err, string(out))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if out, err := exec.Command("mount", deviceName, mnt).CombinedOutput(); err != nil {
 | 
						if out, err := exec.Command("mount", loop.Device, mnt).CombinedOutput(); err != nil {
 | 
				
			||||||
		// not fatal
 | 
							// not fatal
 | 
				
			||||||
		cleanupDevice()
 | 
							loop.Close()
 | 
				
			||||||
		t.Skipf("could not mount %s: %v (out: %q)", deviceName, err, string(out))
 | 
							t.Skipf("could not mount %s: %v (out: %q)", loop.Device, err, string(out))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	defer func() {
 | 
						defer func() {
 | 
				
			||||||
		testutil.Unmount(t, mnt)
 | 
							testutil.Unmount(t, mnt)
 | 
				
			||||||
		cleanupDevice()
 | 
							loop.Close()
 | 
				
			||||||
	}()
 | 
						}()
 | 
				
			||||||
	workload := func() {
 | 
						workload := func() {
 | 
				
			||||||
		err = Supported(mnt)
 | 
							err = Supported(mnt)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,7 +4,7 @@ github.com/containerd/cgroups c4b9ac5c7601384c965b9646fc515884e091ebb9
 | 
				
			|||||||
github.com/containerd/typeurl a93fcdb778cd272c6e9b3028b2f42d813e785d40
 | 
					github.com/containerd/typeurl a93fcdb778cd272c6e9b3028b2f42d813e785d40
 | 
				
			||||||
github.com/containerd/fifo 3d5202aec260678c48179c56f40e6f38a095738c
 | 
					github.com/containerd/fifo 3d5202aec260678c48179c56f40e6f38a095738c
 | 
				
			||||||
github.com/containerd/btrfs af5082808c833de0e79c1e72eea9fea239364877
 | 
					github.com/containerd/btrfs af5082808c833de0e79c1e72eea9fea239364877
 | 
				
			||||||
github.com/containerd/continuity bd77b46c8352f74eb12c85bdc01f4b90f69d66b4
 | 
					github.com/containerd/continuity f2a389ac0a02ce21c09edd7344677a601970f41c
 | 
				
			||||||
github.com/coreos/go-systemd 48702e0da86bd25e76cfef347e2adeb434a0d0a6
 | 
					github.com/coreos/go-systemd 48702e0da86bd25e76cfef347e2adeb434a0d0a6
 | 
				
			||||||
github.com/docker/go-metrics 4ea375f7759c82740c893fc030bc37088d2ec098
 | 
					github.com/docker/go-metrics 4ea375f7759c82740c893fc030bc37088d2ec098
 | 
				
			||||||
github.com/docker/go-events 9461782956ad83b30282bf90e31fa6a70c255ba9
 | 
					github.com/docker/go-events 9461782956ad83b30282bf90e31fa6a70c255ba9
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										19
									
								
								vendor/github.com/containerd/continuity/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										19
									
								
								vendor/github.com/containerd/continuity/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,6 +1,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                                 Apache License
 | 
					                                 Apache License
 | 
				
			||||||
                           Version 2.0, January 2004
 | 
					                           Version 2.0, January 2004
 | 
				
			||||||
                        http://www.apache.org/licenses/
 | 
					                        https://www.apache.org/licenses/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
 | 
					   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -175,28 +176,16 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
   END OF TERMS AND CONDITIONS
 | 
					   END OF TERMS AND CONDITIONS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   APPENDIX: How to apply the Apache License to your work.
 | 
					   Copyright The containerd Authors
 | 
				
			||||||
 | 
					 | 
				
			||||||
      To apply the Apache License to your work, attach the following
 | 
					 | 
				
			||||||
      boilerplate notice, with the fields enclosed by brackets "{}"
 | 
					 | 
				
			||||||
      replaced with your own identifying information. (Don't include
 | 
					 | 
				
			||||||
      the brackets!)  The text should be enclosed in the appropriate
 | 
					 | 
				
			||||||
      comment syntax for the file format. We also recommend that a
 | 
					 | 
				
			||||||
      file or class name and description of purpose be included on the
 | 
					 | 
				
			||||||
      same "printed page" as the copyright notice for easier
 | 
					 | 
				
			||||||
      identification within third-party archives.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   Copyright {yyyy} {name of copyright owner}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
   Licensed under the Apache License, Version 2.0 (the "License");
 | 
					   Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
   you may not use this file except in compliance with the License.
 | 
					   you may not use this file except in compliance with the License.
 | 
				
			||||||
   You may obtain a copy of the License at
 | 
					   You may obtain a copy of the License at
 | 
				
			||||||
 | 
					
 | 
				
			||||||
       http://www.apache.org/licenses/LICENSE-2.0
 | 
					       https://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   Unless required by applicable law or agreed to in writing, software
 | 
					   Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
   distributed under the License is distributed on an "AS IS" BASIS,
 | 
					   distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
					   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
   See the License for the specific language governing permissions and
 | 
					   See the License for the specific language governing permissions and
 | 
				
			||||||
   limitations under the License.
 | 
					   limitations under the License.
 | 
				
			||||||
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										10
									
								
								vendor/github.com/containerd/continuity/README.md
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										10
									
								
								vendor/github.com/containerd/continuity/README.md
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -72,3 +72,13 @@ If you change the proto file you will need to rebuild the generated Go with `go
 | 
				
			|||||||
```console
 | 
					```console
 | 
				
			||||||
$ go generate ./proto
 | 
					$ go generate ./proto
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Project details
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					continuity is a containerd sub-project, licensed under the [Apache 2.0 license](./LICENSE).
 | 
				
			||||||
 | 
					As a containerd sub-project, you will find the:
 | 
				
			||||||
 | 
					 * [Project governance](https://github.com/containerd/project/blob/master/GOVERNANCE.md),
 | 
				
			||||||
 | 
					 * [Maintainers](https://github.com/containerd/project/blob/master/MAINTAINERS),
 | 
				
			||||||
 | 
					 * and [Contributing guidelines](https://github.com/containerd/project/blob/master/CONTRIBUTING.md)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					information in our [`containerd/project`](https://github.com/containerd/project) repository.
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										51
									
								
								vendor/github.com/containerd/continuity/fs/copy.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										51
									
								
								vendor/github.com/containerd/continuity/fs/copy.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -32,14 +32,49 @@ var bufferPool = &sync.Pool{
 | 
				
			|||||||
	},
 | 
						},
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// CopyDir copies the directory from src to dst.
 | 
					// XAttrErrorHandlers transform a non-nil xattr error.
 | 
				
			||||||
// Most efficient copy of files is attempted.
 | 
					// Return nil to ignore an error.
 | 
				
			||||||
func CopyDir(dst, src string) error {
 | 
					// xattrKey can be empty for listxattr operation.
 | 
				
			||||||
	inodes := map[uint64]string{}
 | 
					type XAttrErrorHandler func(dst, src, xattrKey string, err error) error
 | 
				
			||||||
	return copyDirectory(dst, src, inodes)
 | 
					
 | 
				
			||||||
 | 
					type copyDirOpts struct {
 | 
				
			||||||
 | 
						xeh XAttrErrorHandler
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func copyDirectory(dst, src string, inodes map[uint64]string) error {
 | 
					type CopyDirOpt func(*copyDirOpts) error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// WithXAttrErrorHandler allows specifying XAttrErrorHandler
 | 
				
			||||||
 | 
					// If nil XAttrErrorHandler is specified (default), CopyDir stops
 | 
				
			||||||
 | 
					// on a non-nil xattr error.
 | 
				
			||||||
 | 
					func WithXAttrErrorHandler(xeh XAttrErrorHandler) CopyDirOpt {
 | 
				
			||||||
 | 
						return func(o *copyDirOpts) error {
 | 
				
			||||||
 | 
							o.xeh = xeh
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// WithAllowXAttrErrors allows ignoring xattr errors.
 | 
				
			||||||
 | 
					func WithAllowXAttrErrors() CopyDirOpt {
 | 
				
			||||||
 | 
						xeh := func(dst, src, xattrKey string, err error) error {
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return WithXAttrErrorHandler(xeh)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// CopyDir copies the directory from src to dst.
 | 
				
			||||||
 | 
					// Most efficient copy of files is attempted.
 | 
				
			||||||
 | 
					func CopyDir(dst, src string, opts ...CopyDirOpt) error {
 | 
				
			||||||
 | 
						var o copyDirOpts
 | 
				
			||||||
 | 
						for _, opt := range opts {
 | 
				
			||||||
 | 
							if err := opt(&o); err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						inodes := map[uint64]string{}
 | 
				
			||||||
 | 
						return copyDirectory(dst, src, inodes, &o)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func copyDirectory(dst, src string, inodes map[uint64]string, o *copyDirOpts) error {
 | 
				
			||||||
	stat, err := os.Stat(src)
 | 
						stat, err := os.Stat(src)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return errors.Wrapf(err, "failed to stat %s", src)
 | 
							return errors.Wrapf(err, "failed to stat %s", src)
 | 
				
			||||||
@@ -75,7 +110,7 @@ func copyDirectory(dst, src string, inodes map[uint64]string) error {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		switch {
 | 
							switch {
 | 
				
			||||||
		case fi.IsDir():
 | 
							case fi.IsDir():
 | 
				
			||||||
			if err := copyDirectory(target, source, inodes); err != nil {
 | 
								if err := copyDirectory(target, source, inodes, o); err != nil {
 | 
				
			||||||
				return err
 | 
									return err
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			continue
 | 
								continue
 | 
				
			||||||
@@ -111,7 +146,7 @@ func copyDirectory(dst, src string, inodes map[uint64]string) error {
 | 
				
			|||||||
			return errors.Wrap(err, "failed to copy file info")
 | 
								return errors.Wrap(err, "failed to copy file info")
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if err := copyXAttrs(target, source); err != nil {
 | 
							if err := copyXAttrs(target, source, o.xeh); err != nil {
 | 
				
			||||||
			return errors.Wrap(err, "failed to copy xattrs")
 | 
								return errors.Wrap(err, "failed to copy xattrs")
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										37
									
								
								vendor/github.com/containerd/continuity/fs/copy_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										37
									
								
								vendor/github.com/containerd/continuity/fs/copy_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -59,6 +59,8 @@ func copyFileInfo(fi os.FileInfo, name string) error {
 | 
				
			|||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const maxSSizeT = int64(^uint(0) >> 1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func copyFileContent(dst, src *os.File) error {
 | 
					func copyFileContent(dst, src *os.File) error {
 | 
				
			||||||
	st, err := src.Stat()
 | 
						st, err := src.Stat()
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
@@ -71,7 +73,16 @@ func copyFileContent(dst, src *os.File) error {
 | 
				
			|||||||
	dstFd := int(dst.Fd())
 | 
						dstFd := int(dst.Fd())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for size > 0 {
 | 
						for size > 0 {
 | 
				
			||||||
		n, err := unix.CopyFileRange(srcFd, nil, dstFd, nil, int(size), 0)
 | 
							// Ensure that we are never trying to copy more than SSIZE_MAX at a
 | 
				
			||||||
 | 
							// time and at the same time avoids overflows when the file is larger
 | 
				
			||||||
 | 
							// than 4GB on 32-bit systems.
 | 
				
			||||||
 | 
							var copySize int
 | 
				
			||||||
 | 
							if size > maxSSizeT {
 | 
				
			||||||
 | 
								copySize = int(maxSSizeT)
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								copySize = int(size)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							n, err := unix.CopyFileRange(srcFd, nil, dstFd, nil, copySize, 0)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			if (err != unix.ENOSYS && err != unix.EXDEV) || !first {
 | 
								if (err != unix.ENOSYS && err != unix.EXDEV) || !first {
 | 
				
			||||||
				return errors.Wrap(err, "copy file range failed")
 | 
									return errors.Wrap(err, "copy file range failed")
 | 
				
			||||||
@@ -90,18 +101,34 @@ func copyFileContent(dst, src *os.File) error {
 | 
				
			|||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func copyXAttrs(dst, src string) error {
 | 
					func copyXAttrs(dst, src string, xeh XAttrErrorHandler) error {
 | 
				
			||||||
	xattrKeys, err := sysx.LListxattr(src)
 | 
						xattrKeys, err := sysx.LListxattr(src)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return errors.Wrapf(err, "failed to list xattrs on %s", src)
 | 
							e := errors.Wrapf(err, "failed to list xattrs on %s", src)
 | 
				
			||||||
 | 
							if xeh != nil {
 | 
				
			||||||
 | 
								e = xeh(dst, src, "", e)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return e
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	for _, xattr := range xattrKeys {
 | 
						for _, xattr := range xattrKeys {
 | 
				
			||||||
		data, err := sysx.LGetxattr(src, xattr)
 | 
							data, err := sysx.LGetxattr(src, xattr)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			return errors.Wrapf(err, "failed to get xattr %q on %s", xattr, src)
 | 
								e := errors.Wrapf(err, "failed to get xattr %q on %s", xattr, src)
 | 
				
			||||||
 | 
								if xeh != nil {
 | 
				
			||||||
 | 
									if e = xeh(dst, src, xattr, e); e == nil {
 | 
				
			||||||
 | 
										continue
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								return e
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if err := sysx.LSetxattr(dst, xattr, data, 0); err != nil {
 | 
							if err := sysx.LSetxattr(dst, xattr, data, 0); err != nil {
 | 
				
			||||||
			return errors.Wrapf(err, "failed to set xattr %q on %s", xattr, dst)
 | 
								e := errors.Wrapf(err, "failed to set xattr %q on %s", xattr, dst)
 | 
				
			||||||
 | 
								if xeh != nil {
 | 
				
			||||||
 | 
									if e = xeh(dst, src, xattr, e); e == nil {
 | 
				
			||||||
 | 
										continue
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								return e
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										24
									
								
								vendor/github.com/containerd/continuity/fs/copy_unix.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										24
									
								
								vendor/github.com/containerd/continuity/fs/copy_unix.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -69,18 +69,34 @@ func copyFileContent(dst, src *os.File) error {
 | 
				
			|||||||
	return err
 | 
						return err
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func copyXAttrs(dst, src string) error {
 | 
					func copyXAttrs(dst, src string, xeh XAttrErrorHandler) error {
 | 
				
			||||||
	xattrKeys, err := sysx.LListxattr(src)
 | 
						xattrKeys, err := sysx.LListxattr(src)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return errors.Wrapf(err, "failed to list xattrs on %s", src)
 | 
							e := errors.Wrapf(err, "failed to list xattrs on %s", src)
 | 
				
			||||||
 | 
							if xeh != nil {
 | 
				
			||||||
 | 
								e = xeh(dst, src, "", e)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return e
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	for _, xattr := range xattrKeys {
 | 
						for _, xattr := range xattrKeys {
 | 
				
			||||||
		data, err := sysx.LGetxattr(src, xattr)
 | 
							data, err := sysx.LGetxattr(src, xattr)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			return errors.Wrapf(err, "failed to get xattr %q on %s", xattr, src)
 | 
								e := errors.Wrapf(err, "failed to get xattr %q on %s", xattr, src)
 | 
				
			||||||
 | 
								if xeh != nil {
 | 
				
			||||||
 | 
									if e = xeh(dst, src, xattr, e); e == nil {
 | 
				
			||||||
 | 
										continue
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								return e
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if err := sysx.LSetxattr(dst, xattr, data, 0); err != nil {
 | 
							if err := sysx.LSetxattr(dst, xattr, data, 0); err != nil {
 | 
				
			||||||
			return errors.Wrapf(err, "failed to set xattr %q on %s", xattr, dst)
 | 
								e := errors.Wrapf(err, "failed to set xattr %q on %s", xattr, dst)
 | 
				
			||||||
 | 
								if xeh != nil {
 | 
				
			||||||
 | 
									if e = xeh(dst, src, xattr, e); e == nil {
 | 
				
			||||||
 | 
										continue
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								return e
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								vendor/github.com/containerd/continuity/fs/copy_windows.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/containerd/continuity/fs/copy_windows.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -40,7 +40,7 @@ func copyFileContent(dst, src *os.File) error {
 | 
				
			|||||||
	return err
 | 
						return err
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func copyXAttrs(dst, src string) error {
 | 
					func copyXAttrs(dst, src string, xeh XAttrErrorHandler) error {
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										8
									
								
								vendor/github.com/containerd/continuity/fs/fstest/compare.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										8
									
								
								vendor/github.com/containerd/continuity/fs/fstest/compare.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -49,16 +49,8 @@ func CheckDirectoryEqual(d1, d2 string) error {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	diff := diffResourceList(m1.Resources, m2.Resources)
 | 
						diff := diffResourceList(m1.Resources, m2.Resources)
 | 
				
			||||||
	if diff.HasDiff() {
 | 
						if diff.HasDiff() {
 | 
				
			||||||
		if len(diff.Deletions) != 0 {
 | 
					 | 
				
			||||||
		return errors.Errorf("directory diff between %s and %s\n%s", d1, d2, diff.String())
 | 
							return errors.Errorf("directory diff between %s and %s\n%s", d1, d2, diff.String())
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
		// TODO: Also skip Recycle Bin contents in Windows layers which is used to store deleted files in some cases
 | 
					 | 
				
			||||||
		for _, add := range diff.Additions {
 | 
					 | 
				
			||||||
			if ok, _ := metadataFiles[add.Path()]; !ok {
 | 
					 | 
				
			||||||
				return errors.Errorf("directory diff between %s and %s\n%s", d1, d2, diff.String())
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										1
									
								
								vendor/github.com/containerd/continuity/fs/fstest/compare_windows.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								vendor/github.com/containerd/continuity/fs/fstest/compare_windows.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -17,6 +17,7 @@
 | 
				
			|||||||
package fstest
 | 
					package fstest
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// TODO: Any more metadata files generated by Windows layers?
 | 
					// TODO: Any more metadata files generated by Windows layers?
 | 
				
			||||||
 | 
					// TODO: Also skip Recycle Bin contents in Windows layers which is used to store deleted files in some cases
 | 
				
			||||||
var metadataFiles = map[string]bool{
 | 
					var metadataFiles = map[string]bool{
 | 
				
			||||||
	"\\System Volume Information": true,
 | 
						"\\System Volume Information": true,
 | 
				
			||||||
	"\\WcSandboxState":            true,
 | 
						"\\WcSandboxState":            true,
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										12
									
								
								vendor/github.com/containerd/continuity/fs/fstest/continuity_util.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										12
									
								
								vendor/github.com/containerd/continuity/fs/fstest/continuity_util.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -42,7 +42,17 @@ type resourceListDifference struct {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (l resourceListDifference) HasDiff() bool {
 | 
					func (l resourceListDifference) HasDiff() bool {
 | 
				
			||||||
	return len(l.Additions) > 0 || len(l.Deletions) > 0 || len(l.Updates) > 0
 | 
						if len(l.Deletions) > 0 || len(l.Updates) > 0 || (len(metadataFiles) == 0 && len(l.Additions) > 0) {
 | 
				
			||||||
 | 
							return true
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for _, add := range l.Additions {
 | 
				
			||||||
 | 
							if ok, _ := metadataFiles[add.Path()]; !ok {
 | 
				
			||||||
 | 
								return true
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return false
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (l resourceListDifference) String() string {
 | 
					func (l resourceListDifference) String() string {
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										33
									
								
								vendor/github.com/containerd/continuity/fs/path.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										33
									
								
								vendor/github.com/containerd/continuity/fs/path.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -22,7 +22,6 @@ import (
 | 
				
			|||||||
	"io"
 | 
						"io"
 | 
				
			||||||
	"os"
 | 
						"os"
 | 
				
			||||||
	"path/filepath"
 | 
						"path/filepath"
 | 
				
			||||||
	"strings"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/pkg/errors"
 | 
						"github.com/pkg/errors"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
@@ -47,9 +46,8 @@ func pathChange(lower, upper *currentPath) (ChangeKind, string) {
 | 
				
			|||||||
	if upper == nil {
 | 
						if upper == nil {
 | 
				
			||||||
		return ChangeKindDelete, lower.path
 | 
							return ChangeKindDelete, lower.path
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	// TODO: compare by directory
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch i := strings.Compare(lower.path, upper.path); {
 | 
						switch i := directoryCompare(lower.path, upper.path); {
 | 
				
			||||||
	case i < 0:
 | 
						case i < 0:
 | 
				
			||||||
		// File in lower that is not in upper
 | 
							// File in lower that is not in upper
 | 
				
			||||||
		return ChangeKindDelete, lower.path
 | 
							return ChangeKindDelete, lower.path
 | 
				
			||||||
@@ -61,6 +59,35 @@ func pathChange(lower, upper *currentPath) (ChangeKind, string) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func directoryCompare(a, b string) int {
 | 
				
			||||||
 | 
						l := len(a)
 | 
				
			||||||
 | 
						if len(b) < l {
 | 
				
			||||||
 | 
							l = len(b)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for i := 0; i < l; i++ {
 | 
				
			||||||
 | 
							c1, c2 := a[i], b[i]
 | 
				
			||||||
 | 
							if c1 == filepath.Separator {
 | 
				
			||||||
 | 
								c1 = byte(0)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if c2 == filepath.Separator {
 | 
				
			||||||
 | 
								c2 = byte(0)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if c1 < c2 {
 | 
				
			||||||
 | 
								return -1
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if c1 > c2 {
 | 
				
			||||||
 | 
								return +1
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if len(a) < len(b) {
 | 
				
			||||||
 | 
							return -1
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if len(a) > len(b) {
 | 
				
			||||||
 | 
							return +1
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return 0
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func sameFile(f1, f2 *currentPath) (bool, error) {
 | 
					func sameFile(f1, f2 *currentPath) (bool, error) {
 | 
				
			||||||
	if os.SameFile(f1.f, f2.f) {
 | 
						if os.SameFile(f1.f, f2.f) {
 | 
				
			||||||
		return true, nil
 | 
							return true, nil
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										55
									
								
								vendor/github.com/containerd/continuity/testutil/loopback/loopback_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										55
									
								
								vendor/github.com/containerd/continuity/testutil/loopback/loopback_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -22,24 +22,25 @@ import (
 | 
				
			|||||||
	"io/ioutil"
 | 
						"io/ioutil"
 | 
				
			||||||
	"os"
 | 
						"os"
 | 
				
			||||||
	"os/exec"
 | 
						"os/exec"
 | 
				
			||||||
 | 
						"syscall"
 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/pkg/errors"
 | 
						"github.com/pkg/errors"
 | 
				
			||||||
	"github.com/sirupsen/logrus"
 | 
						"github.com/sirupsen/logrus"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// New creates a loopback device, and returns its device name (/dev/loopX), and its clean-up function.
 | 
					// New creates a loopback device
 | 
				
			||||||
func New(size int64) (string, func() error, error) {
 | 
					func New(size int64) (*Loopback, error) {
 | 
				
			||||||
	// create temporary file for the disk image
 | 
						// create temporary file for the disk image
 | 
				
			||||||
	file, err := ioutil.TempFile("", "containerd-test-loopback")
 | 
						file, err := ioutil.TempFile("", "containerd-test-loopback")
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return "", nil, errors.Wrap(err, "could not create temporary file for loopback")
 | 
							return nil, errors.Wrap(err, "could not create temporary file for loopback")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err := file.Truncate(size); err != nil {
 | 
						if err := file.Truncate(size); err != nil {
 | 
				
			||||||
		file.Close()
 | 
							file.Close()
 | 
				
			||||||
		os.Remove(file.Name())
 | 
							os.Remove(file.Name())
 | 
				
			||||||
		return "", nil, errors.Wrap(err, "failed to resize temp file")
 | 
							return nil, errors.Wrap(err, "failed to resize temp file")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	file.Close()
 | 
						file.Close()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -48,7 +49,7 @@ func New(size int64) (string, func() error, error) {
 | 
				
			|||||||
	p, err := losetup.Output()
 | 
						p, err := losetup.Output()
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		os.Remove(file.Name())
 | 
							os.Remove(file.Name())
 | 
				
			||||||
		return "", nil, errors.Wrap(err, "loopback setup failed")
 | 
							return nil, errors.Wrap(err, "loopback setup failed")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	deviceName := strings.TrimSpace(string(p))
 | 
						deviceName := strings.TrimSpace(string(p))
 | 
				
			||||||
@@ -68,5 +69,47 @@ func New(size int64) (string, func() error, error) {
 | 
				
			|||||||
		return os.Remove(file.Name())
 | 
							return os.Remove(file.Name())
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return deviceName, cleanup, nil
 | 
						l := Loopback{
 | 
				
			||||||
 | 
							File: file.Name(),
 | 
				
			||||||
 | 
							Device: deviceName,
 | 
				
			||||||
 | 
							close: cleanup,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return &l, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Loopback device
 | 
				
			||||||
 | 
					type Loopback struct {
 | 
				
			||||||
 | 
						// File is the underlying sparse file
 | 
				
			||||||
 | 
						File string
 | 
				
			||||||
 | 
						// Device is /dev/loopX
 | 
				
			||||||
 | 
						Device string
 | 
				
			||||||
 | 
						close func() error
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// SoftSize returns st_size
 | 
				
			||||||
 | 
					func (l *Loopback) SoftSize() (int64, error) {
 | 
				
			||||||
 | 
						st, err := os.Stat(l.File)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return 0, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return st.Size(), nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// HardSize returns st_blocks * 512; see stat(2)
 | 
				
			||||||
 | 
					func (l *Loopback) HardSize() (int64, error) {
 | 
				
			||||||
 | 
						st, err := os.Stat(l.File)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return 0, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						st2, ok := st.Sys().(*syscall.Stat_t)
 | 
				
			||||||
 | 
						if !ok {
 | 
				
			||||||
 | 
							return 0, errors.New("st.Sys() is not a *syscall.Stat_t")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						// NOTE: st_blocks has nothing to do with st_blksize; see stat(2)
 | 
				
			||||||
 | 
						return st2.Blocks * 512, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Close detaches the device and removes the underlying file
 | 
				
			||||||
 | 
					func (l *Loopback) Close() error {
 | 
				
			||||||
 | 
						return l.close()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user