containerd / continuity

A transport-agnostic, filesystem metadata manifest system
https://containerd.io
Apache License 2.0
139 stars 67 forks source link

s390x: copy_file_range error in container #135

Open tonistiigi opened 5 years ago

tonistiigi commented 5 years ago

On s390x the copy package fails if run inside a container because it fails to detect the existence of copy_file_range properly.

If ran on host https://github.com/containerd/continuity/blob/7f53d412b9eb1cbf744c2063185d703a0ee34700/fs/copy_linux.go#L74 fails with ENOSYS and fallback method will be used.

But if the same code is run under limited capabilities it produces EPERM instead(even though it doesn't seem to be allowed error for this syscall) and the copy fails.

--- FAIL: TestCopyDirectory (0.00s)
    copy_test.go:47: Copy test failed: operation not permitted
        copy file range failed
        github.com/containerd/continuity/fs.copyFileContent
            /root/go/src/github.com/containerd/continuity/fs/copy_linux.go:79
        github.com/containerd/continuity/fs.CopyFile
            /root/go/src/github.com/containerd/continuity/fs/copy.go:137
        github.com/containerd/continuity/fs.copyDirectory
            /root/go/src/github.com/containerd/continuity/fs/copy.go:92
        github.com/containerd/continuity/fs.copyDirectory
            /root/go/src/github.com/containerd/continuity/fs/copy.go:79
        github.com/containerd/continuity/fs.CopyDir
            /root/go/src/github.com/containerd/continuity/fs/copy.go:40
        github.com/containerd/continuity/fs.testCopy
            /root/go/src/github.com/containerd/continuity/fs/copy_test.go:97
        github.com/containerd/continuity/fs.TestCopyDirectory
            /root/go/src/github.com/containerd/continuity/fs/copy_test.go:46
        testing.tRunner
            /usr/local/go/src/testing/testing.go:827
        runtime.goexit
            /usr/local/go/src/runtime/asm_s390x.s:782
        failed to copy files
        github.com/containerd/continuity/fs.copyDirectory
            /root/go/src/github.com/containerd/continuity/fs/copy.go:93
        github.com/containerd/continuity/fs.copyDirectory
            /root/go/src/github.com/containerd/continuity/fs/copy.go:79
        github.com/containerd/continuity/fs.CopyDir
            /root/go/src/github.com/containerd/continuity/fs/copy.go:40
        github.com/containerd/continuity/fs.testCopy
            /root/go/src/github.com/containerd/continuity/fs/copy_test.go:97
        github.com/containerd/continuity/fs.TestCopyDirectory
            /root/go/src/github.com/containerd/continuity/fs/copy_test.go:46
        testing.tRunner
            /usr/local/go/src/testing/testing.go:827
        runtime.goexit
            /usr/local/go/src/runtime/asm_s390x.s:782
        failed to copy
        github.com/containerd/continuity/fs.testCopy
            /root/go/src/github.com/containerd/continuity/fs/copy_test.go:98
        github.com/containerd/continuity/fs.TestCopyDirectory
            /root/go/src/github.com/containerd/continuity/fs/copy_test.go:46
        testing.tRunner
            /usr/local/go/src/testing/testing.go:827
        runtime.goexit
            /usr/local/go/src/runtime/asm_s390x.s:782
FAIL
root@s390x-ubuntu-17:/home/ubuntu# uname -a
Linux s390x-ubuntu-17 4.4.0-130-generic #156-Ubuntu SMP Thu Jun 14 09:18:59 UTC 2018 s390x s390x s390x GNU/Linux

@estesp

estesp commented 5 years ago

@cwsolee any ideas?

cwsolee commented 5 years ago

Looks like u're(@tonistiigi) using Ubuntu 17, we tried on Ubuntu 16.04 with 1.10.1 go from https://storage.googleapis.com/golang/go1.10.1.linux-s390x.tar.gz and seems ok. All we're tried is git clone https://github.com/containerd/continuity.git then make.

tonistiigi commented 5 years ago

@cwsolee You can test it with:

> docker run --rm tonistiigi/s390x-fs-test fs.test --test.run TestCopyDirectory
Unable to find image 'tonistiigi/s390x-fs-test:latest' locally
latest: Pulling from tonistiigi/s390x-fs-test
e5d7a290acc2: Already exists
ad01149bcd3b: Already exists
693f28fb14ad: Pull complete
Digest: sha256:a5d070c9e0549c1c2e5b3a7be618c526d59ff70f644e2efeba673c8d7edd4d42
Status: Downloaded newer image for tonistiigi/s390x-fs-test:latest
--- FAIL: TestCopyDirectory (0.00s)
    copy_test.go:47: Copy test failed: operation not permitted
        copy file range failed

I built the image with:

> go test -c ./fs
> docker build -t tonistiigi/s390x-fs-test -f - . <<EOF
from alpine
copy fs.test /bin/
EOF

Sending build context to Docker daemon  13.64MB
Step 1/2 : from alpine
 ---> 0be87466cf96
Step 2/2 : copy fs.test /bin/
 ---> 61e630d98e7d
Successfully built 61e630d98e7d
Successfully tagged tonistiigi/s390x-fs-test:latest
tonistiigi commented 5 years ago

go version if that can matter:

> go version
go version go1.11 linux/s390x
cwsolee commented 5 years ago

Ok, your combination is a bit different from what we've tried, will re-try with yours.

cwsolee commented 5 years ago

Which distro are u using as host? I thought u're using Ubuntu 17 but your kernel level is what Ubuntu 16.04 has. It might not be relevant in this case, just curious. What about docker version? Another findings, your image is using alpine as base, we see the same problem but changing it to ubuntu 16.04 will be ok. My team don't work with alpine much, not sure why alpine failed but I think alpine could be the root cause here. U can raise issue with alpine community, I did the same when I found problem on alpine too.