Skip to content

Commit

Permalink
Merge pull request #2145 from giuseppe/attempt-erofs-mount-via-file
Browse files Browse the repository at this point in the history
composefs: use mount from file where supported
  • Loading branch information
openshift-merge-bot[bot] authored Oct 23, 2024
2 parents a42802e + db1be74 commit 88909d1
Showing 1 changed file with 35 additions and 12 deletions.
47 changes: 35 additions & 12 deletions drivers/overlay/composefs.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"path/filepath"
"strings"
"sync"
"sync/atomic"

"github.com/containers/storage/pkg/chunked/dump"
"github.com/containers/storage/pkg/fsverity"
Expand All @@ -24,6 +25,10 @@ var (
composeFsHelperOnce sync.Once
composeFsHelperPath string
composeFsHelperErr error

// skipMountViaFile is used to avoid trying to mount EROFS directly via the file if we already know the current kernel
// does not support it. Mounting directly via a file will be supported in kernel 6.12.
skipMountViaFile atomic.Bool
)

func getComposeFsHelper() (string, error) {
Expand Down Expand Up @@ -136,17 +141,15 @@ func hasACL(path string) (bool, error) {
return binary.LittleEndian.Uint32(flags)&LCFS_EROFS_FLAGS_HAS_ACL != 0, nil
}

func openComposefsMount(dataDir string) (int, error) {
blobFile := getComposefsBlob(dataDir)
loop, err := loopback.AttachLoopDeviceRO(blobFile)
if err != nil {
return -1, err
}
defer loop.Close()
func openBlobFile(blobFile string, hasACL, useLoopDevice bool) (int, error) {
if useLoopDevice {
loop, err := loopback.AttachLoopDeviceRO(blobFile)
if err != nil {
return -1, err
}
defer loop.Close()

hasACL, err := hasACL(blobFile)
if err != nil {
return -1, err
blobFile = loop.Name()
}

fsfd, err := unix.Fsopen("erofs", 0)
Expand All @@ -155,7 +158,7 @@ func openComposefsMount(dataDir string) (int, error) {
}
defer unix.Close(fsfd)

if err := unix.FsconfigSetString(fsfd, "source", loop.Name()); err != nil {
if err := unix.FsconfigSetString(fsfd, "source", blobFile); err != nil {
return -1, fmt.Errorf("failed to set source for erofs filesystem: %w", err)
}

Expand All @@ -172,7 +175,7 @@ func openComposefsMount(dataDir string) (int, error) {
if err := unix.FsconfigCreate(fsfd); err != nil {
buffer := make([]byte, 4096)
if n, _ := unix.Read(fsfd, buffer); n > 0 {
return -1, fmt.Errorf("failed to create erofs filesystem: %s: %w", string(buffer[:n]), err)
return -1, fmt.Errorf("failed to create erofs filesystem: %s: %w", strings.TrimSuffix(string(buffer[:n]), "\n"), err)
}
return -1, fmt.Errorf("failed to create erofs filesystem: %w", err)
}
Expand All @@ -188,6 +191,26 @@ func openComposefsMount(dataDir string) (int, error) {
return mfd, nil
}

func openComposefsMount(dataDir string) (int, error) {
blobFile := getComposefsBlob(dataDir)

hasACL, err := hasACL(blobFile)
if err != nil {
return -1, err
}

if !skipMountViaFile.Load() {
fd, err := openBlobFile(blobFile, hasACL, false)
if err == nil || !errors.Is(err, unix.ENOTBLK) {
return fd, err
}
logrus.Debugf("The current kernel doesn't support mounting EROFS directly from a file, fallback to a loopback device")
skipMountViaFile.Store(true)
}

return openBlobFile(blobFile, hasACL, true)
}

func mountComposefsBlob(dataDir, mountPoint string) error {
mfd, err := openComposefsMount(dataDir)
if err != nil {
Expand Down

0 comments on commit 88909d1

Please sign in to comment.