Use storage that better supports rootless overlayfs

overlayfs -- the kernel's version, not fuse-overlayfs -- recently learned
(as of linux 5.16.0, I believe) how to support rootless users. Previously,
rootless users had to use these storage.conf(5) settings:

* storage.driver=vfs          (aka STORAGE_DRIVER=vfs), or
* storage.driver=overlay      (aka STORAGE_DRIVER=overlay),
  storage.options.overlay.mount_program=/usr/bin/fuse-overlayfs
                              (aka STORAGE_OPTS=/usr/bin/fuse-overlayfs)

Now that a third backend is available, setting only:

* storage.driver=overlay      (aka STORAGE_DRIVER=overlay)

https://github.com/containers/podman/issues/13123 reported EXDEV errors
during the normal operation of their container. Tracing it out, the
problem turned out to be that their container was being mounted without
'userxattr'; I don't fully understand why, but mount(8) mentions this is
needed for rootless users:

> userxattr
>
>   Use the "user.overlay." xattr namespace instead of "trusted.overlay.".
>   This is useful for unprivileged mounting of overlayfs.

https://github.com/containers/storage/pull/1156 found and fixed the issue
in podman, and this just pulls in that via

    go get github.com/containers/storage@ebc90ab
    go mod vendor
    make vendor

Closes https://github.com/containers/podman/issues/13123

Signed-off-by: Nick Guenther <nick.guenther@polymtl.ca>
This commit is contained in:
Nick Guenther
2022-02-28 12:54:09 -05:00
parent 8bdda91ab7
commit 572e6464f6
31 changed files with 383 additions and 217 deletions

View File

@@ -1,3 +1,4 @@
//go:build !windows
// +build !windows
package graphdriver
@@ -6,17 +7,50 @@ import (
"errors"
"fmt"
"os"
"sync"
"syscall"
"github.com/containers/storage/pkg/idtools"
"github.com/containers/storage/pkg/system"
)
func platformLChown(path string, info os.FileInfo, toHost, toContainer *idtools.IDMappings) error {
type inode struct {
Dev uint64
Ino uint64
}
type platformChowner struct {
mutex sync.Mutex
inodes map[inode]bool
}
func newLChowner() *platformChowner {
return &platformChowner{
inodes: make(map[inode]bool),
}
}
func (c *platformChowner) LChown(path string, info os.FileInfo, toHost, toContainer *idtools.IDMappings) error {
st, ok := info.Sys().(*syscall.Stat_t)
if !ok {
return nil
}
i := inode{
Dev: uint64(st.Dev),
Ino: uint64(st.Ino),
}
c.mutex.Lock()
_, found := c.inodes[i]
if !found {
c.inodes[i] = true
}
c.mutex.Unlock()
if found {
return nil
}
// Map an on-disk UID/GID pair from host to container
// using the first map, then back to the host using the
// second map. Skip that first step if they're 0, to