Skip to content

Commit

Permalink
Merge pull request #2069 from giuseppe/composefs-do-not-make-mount-vi…
Browse files Browse the repository at this point in the history
…sible

composefs fixes
  • Loading branch information
openshift-merge-bot[bot] authored Aug 21, 2024
2 parents 8ec73ca + 05df80e commit 7908bb8
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 50 deletions.
30 changes: 19 additions & 11 deletions drivers/overlay/composefs.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down
69 changes: 30 additions & 39 deletions drivers/overlay/overlay.go
Original file line number Diff line number Diff line change
Expand Up @@ -1456,6 +1456,31 @@ 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 {
logrus.Errorf("Unmounting %v: %v", mergedDir, mntErr)
}
}
}
}()

readWrite := !inAdditionalStore

if !d.SupportsShifting() || options.DisableShifting {
Expand Down Expand Up @@ -1575,7 +1600,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
}
Expand Down Expand Up @@ -1683,12 +1708,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"))
}
Expand All @@ -1703,26 +1722,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() {
Expand Down Expand Up @@ -2128,24 +2127,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")
if err != nil {
return nil, err
}
if err := mountComposefsBlob(composefsBlob, dir); err != nil {
return nil, err
}
fd, err := os.Open(dir)
fd, err := openComposefsMount(composefsData)
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
}
Expand Down
4 changes: 4 additions & 0 deletions drivers/overlay/overlay_nocgo.go
Original file line number Diff line number Diff line change
Expand Up @@ -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")
}
Expand Down

0 comments on commit 7908bb8

Please sign in to comment.