mirror of
https://github.com/containers/podman.git
synced 2025-12-08 23:00:23 +08:00
vendor: update c/storage
Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
This commit is contained in:
30
vendor/github.com/containers/storage/drivers/overlay/composefs.go
generated
vendored
30
vendor/github.com/containers/storage/drivers/overlay/composefs.go
generated
vendored
@@ -137,54 +137,62 @@ func hasACL(path string) (bool, error) {
|
||||
return binary.LittleEndian.Uint32(flags)&LCFS_EROFS_FLAGS_HAS_ACL != 0, nil
|
||||
}
|
||||
|
||||
func mountComposefsBlob(dataDir, mountPoint string) error {
|
||||
func openComposefsMount(dataDir string) (int, error) {
|
||||
blobFile := getComposefsBlob(dataDir)
|
||||
loop, err := loopback.AttachLoopDeviceRO(blobFile)
|
||||
if err != nil {
|
||||
return err
|
||||
return -1, err
|
||||
}
|
||||
defer loop.Close()
|
||||
|
||||
hasACL, err := hasACL(blobFile)
|
||||
if err != nil {
|
||||
return err
|
||||
return -1, err
|
||||
}
|
||||
|
||||
fsfd, err := unix.Fsopen("erofs", 0)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to open erofs filesystem: %w", err)
|
||||
return -1, fmt.Errorf("failed to open erofs filesystem: %w", err)
|
||||
}
|
||||
defer unix.Close(fsfd)
|
||||
|
||||
if err := unix.FsconfigSetString(fsfd, "source", loop.Name()); err != nil {
|
||||
return fmt.Errorf("failed to set source for erofs filesystem: %w", err)
|
||||
return -1, fmt.Errorf("failed to set source for erofs filesystem: %w", err)
|
||||
}
|
||||
|
||||
if err := unix.FsconfigSetFlag(fsfd, "ro"); err != nil {
|
||||
return fmt.Errorf("failed to set erofs filesystem read-only: %w", err)
|
||||
return -1, fmt.Errorf("failed to set erofs filesystem read-only: %w", err)
|
||||
}
|
||||
|
||||
if !hasACL {
|
||||
if err := unix.FsconfigSetFlag(fsfd, "noacl"); err != nil {
|
||||
return fmt.Errorf("failed to set noacl for erofs filesystem: %w", err)
|
||||
return -1, fmt.Errorf("failed to set noacl for erofs filesystem: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
if err := unix.FsconfigCreate(fsfd); err != nil {
|
||||
buffer := make([]byte, 4096)
|
||||
if n, _ := unix.Read(fsfd, buffer); n > 0 {
|
||||
return fmt.Errorf("failed to create erofs filesystem: %s: %w", string(buffer[:n]), err)
|
||||
return -1, fmt.Errorf("failed to create erofs filesystem: %s: %w", string(buffer[:n]), err)
|
||||
}
|
||||
return fmt.Errorf("failed to create erofs filesystem: %w", err)
|
||||
return -1, fmt.Errorf("failed to create erofs filesystem: %w", err)
|
||||
}
|
||||
|
||||
mfd, err := unix.Fsmount(fsfd, 0, unix.MOUNT_ATTR_RDONLY)
|
||||
if err != nil {
|
||||
buffer := make([]byte, 4096)
|
||||
if n, _ := unix.Read(fsfd, buffer); n > 0 {
|
||||
return fmt.Errorf("failed to mount erofs filesystem: %s: %w", string(buffer[:n]), err)
|
||||
return -1, fmt.Errorf("failed to mount erofs filesystem: %s: %w", string(buffer[:n]), err)
|
||||
}
|
||||
return fmt.Errorf("failed to mount erofs filesystem: %w", err)
|
||||
return -1, fmt.Errorf("failed to mount erofs filesystem: %w", err)
|
||||
}
|
||||
return mfd, nil
|
||||
}
|
||||
|
||||
func mountComposefsBlob(dataDir, mountPoint string) error {
|
||||
mfd, err := openComposefsMount(dataDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer unix.Close(mfd)
|
||||
|
||||
|
||||
92
vendor/github.com/containers/storage/drivers/overlay/overlay.go
generated
vendored
92
vendor/github.com/containers/storage/drivers/overlay/overlay.go
generated
vendored
@@ -1456,6 +1456,35 @@ func (d *Driver) get(id string, disableShifting bool, options graphdriver.MountO
|
||||
return "", err
|
||||
}
|
||||
|
||||
// user namespace requires this to move a directory from lower to upper.
|
||||
rootUID, rootGID, err := idtools.GetRootUIDGID(options.UidMaps, options.GidMaps)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
mergedDir := d.getMergedDir(id, dir, inAdditionalStore)
|
||||
// Attempt to create the merged dir if it doesn't exist, but don't chown an already existing directory (it might be in an additional store)
|
||||
if err := idtools.MkdirAllAndChownNew(mergedDir, 0o700, idtools.IDPair{UID: rootUID, GID: rootGID}); err != nil && !os.IsExist(err) {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if count := d.ctr.Increment(mergedDir); count > 1 {
|
||||
return mergedDir, nil
|
||||
}
|
||||
defer func() {
|
||||
if retErr != nil {
|
||||
if c := d.ctr.Decrement(mergedDir); c <= 0 {
|
||||
if mntErr := unix.Unmount(mergedDir, 0); mntErr != nil {
|
||||
// Ignore EINVAL, it means the directory is not a mount point and it can happen
|
||||
// if the current function fails before the mount point is created.
|
||||
if !errors.Is(mntErr, unix.EINVAL) {
|
||||
logrus.Errorf("Unmounting %v: %v", mergedDir, mntErr)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
readWrite := !inAdditionalStore
|
||||
|
||||
if !d.SupportsShifting() || options.DisableShifting {
|
||||
@@ -1575,7 +1604,7 @@ func (d *Driver) get(id string, disableShifting bool, options graphdriver.MountO
|
||||
return "", fmt.Errorf("cannot mount a composefs layer as writeable")
|
||||
}
|
||||
|
||||
dest := filepath.Join(composeFsLayersDir, fmt.Sprintf("%d", i))
|
||||
dest := filepath.Join(composeFsLayersDir, strconv.Itoa(i))
|
||||
if err := os.MkdirAll(dest, 0o700); err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -1683,12 +1712,6 @@ func (d *Driver) get(id string, disableShifting bool, options graphdriver.MountO
|
||||
optsList = append(optsList, "metacopy=on", "redirect_dir=on")
|
||||
}
|
||||
|
||||
// user namespace requires this to move a directory from lower to upper.
|
||||
rootUID, rootGID, err := idtools.GetRootUIDGID(options.UidMaps, options.GidMaps)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if len(absLowers) == 0 {
|
||||
absLowers = append(absLowers, path.Join(dir, "empty"))
|
||||
}
|
||||
@@ -1703,26 +1726,6 @@ func (d *Driver) get(id string, disableShifting bool, options graphdriver.MountO
|
||||
}
|
||||
}
|
||||
|
||||
mergedDir := d.getMergedDir(id, dir, inAdditionalStore)
|
||||
// Attempt to create the merged dir only if it doesn't exist.
|
||||
if err := fileutils.Exists(mergedDir); err != nil && os.IsNotExist(err) {
|
||||
if err := idtools.MkdirAllAs(mergedDir, 0o700, rootUID, rootGID); err != nil && !os.IsExist(err) {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
if count := d.ctr.Increment(mergedDir); count > 1 {
|
||||
return mergedDir, nil
|
||||
}
|
||||
defer func() {
|
||||
if retErr != nil {
|
||||
if c := d.ctr.Decrement(mergedDir); c <= 0 {
|
||||
if mntErr := unix.Unmount(mergedDir, 0); mntErr != nil {
|
||||
logrus.Errorf("Unmounting %v: %v", mergedDir, mntErr)
|
||||
}
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
workdir := path.Join(dir, "work")
|
||||
|
||||
if d.options.mountProgram == "" && unshare.IsRootless() {
|
||||
@@ -1879,10 +1882,21 @@ func (d *Driver) get(id string, disableShifting bool, options graphdriver.MountO
|
||||
|
||||
// getMergedDir returns the directory path that should be used as the mount point for the overlayfs.
|
||||
func (d *Driver) getMergedDir(id, dir string, inAdditionalStore bool) string {
|
||||
// If the layer is in an additional store, the lock we might hold only a reading lock. To prevent
|
||||
// races with other processes, use a private directory under the main store rundir. At this point, the
|
||||
// current process is holding an exclusive lock on the store, and since the rundir cannot be shared for
|
||||
// different stores, it is safe to assume the current process has exclusive access to it.
|
||||
// Ordinarily, .Get() (layer mounting) callers are supposed to guarantee exclusion.
|
||||
//
|
||||
// But additional stores are initialized with RO locks and don’t support a write
|
||||
// lock operation at all; and naiveDiff operations cause mounts/unmounts, so they might
|
||||
// happen on code paths where we might only holding a RO lock for the additional store.
|
||||
// To prevent races with other processes mounting or unmounting the layer,
|
||||
// use a private directory under the main store rundir, not the "merged" directory inside the
|
||||
// original layer store holding the layer data.
|
||||
//
|
||||
// To support this, contrary to the _general_ locking rules for .Diff / .Changes (which allow a RO lock),
|
||||
// the top-level Store implementation uses an exclusive lock for the primary layer store;
|
||||
// and since the rundir cannot be shared for different stores, it is safe to assume the
|
||||
// current process has exclusive access to it.
|
||||
//
|
||||
// LOCKING BUG? the .DiffSize operation does not currently hold an exclusive lock on the primary store.
|
||||
if inAdditionalStore {
|
||||
return path.Join(d.runhome, id, "merged")
|
||||
}
|
||||
@@ -2128,24 +2142,16 @@ func (d *Driver) DiffGetter(id string) (_ graphdriver.FileGetCloser, Err error)
|
||||
for _, diffDir := range diffDirs {
|
||||
// diffDir has the form $GRAPH_ROOT/overlay/$ID/diff, so grab the $ID from the parent directory
|
||||
id := path.Base(path.Dir(diffDir))
|
||||
composefsBlob := d.getComposefsData(id)
|
||||
if fileutils.Exists(composefsBlob) != nil {
|
||||
composefsData := d.getComposefsData(id)
|
||||
if fileutils.Exists(composefsData) != nil {
|
||||
// not a composefs layer, ignore it
|
||||
continue
|
||||
}
|
||||
dir, err := os.MkdirTemp(d.runhome, "composefs-mnt")
|
||||
fd, err := openComposefsMount(composefsData)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := mountComposefsBlob(composefsBlob, dir); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
fd, err := os.Open(dir)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
composefsMounts[diffDir] = fd
|
||||
_ = unix.Unmount(dir, unix.MNT_DETACH)
|
||||
composefsMounts[diffDir] = os.NewFile(uintptr(fd), composefsData)
|
||||
}
|
||||
return &overlayFileGetter{diffDirs: diffDirs, composefsMounts: composefsMounts}, nil
|
||||
}
|
||||
|
||||
4
vendor/github.com/containers/storage/drivers/overlay/overlay_nocgo.go
generated
vendored
4
vendor/github.com/containers/storage/drivers/overlay/overlay_nocgo.go
generated
vendored
@@ -7,6 +7,10 @@ import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
func openComposefsMount(dataDir string) (int, error) {
|
||||
return 0, fmt.Errorf("composefs not supported on this build")
|
||||
}
|
||||
|
||||
func getComposeFsHelper() (string, error) {
|
||||
return "", fmt.Errorf("composefs not supported on this build")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user