From 3acfd0c98e5d83c4e5ac6895cb5db10890e30d6b Mon Sep 17 00:00:00 2001 From: Giuseppe Scrivano Date: Wed, 5 Jul 2023 14:58:11 +0200 Subject: [PATCH 1/2] overlay: store erofs blob under a sub-directory Signed-off-by: Giuseppe Scrivano --- drivers/overlay/composefs_notsupported.go | 4 +-- drivers/overlay/composefs_supported.go | 14 ++++++-- drivers/overlay/overlay.go | 44 +++++++++++------------ 3 files changed, 36 insertions(+), 26 deletions(-) diff --git a/drivers/overlay/composefs_notsupported.go b/drivers/overlay/composefs_notsupported.go index 75eae0affb..5cdbcff6c4 100644 --- a/drivers/overlay/composefs_notsupported.go +++ b/drivers/overlay/composefs_notsupported.go @@ -11,11 +11,11 @@ func composeFsSupported() bool { return false } -func generateComposeFsBlob(toc []byte, destFile string) error { +func generateComposeFsBlob(toc []byte, composefsDir string) error { return fmt.Errorf("composefs is not supported") } -func mountErofsBlob(blobFile, mountPoint string) error { +func mountComposefsBlob(dataDir, mountPoint string) error { return fmt.Errorf("composefs is not supported") } diff --git a/drivers/overlay/composefs_supported.go b/drivers/overlay/composefs_supported.go index b9efee8a3e..931be6d579 100644 --- a/drivers/overlay/composefs_supported.go +++ b/drivers/overlay/composefs_supported.go @@ -75,7 +75,16 @@ func enableVerityRecursive(path string) error { return filepath.WalkDir(path, walkFn) } -func generateComposeFsBlob(toc []byte, destFile string) error { +func getComposefsBlob(dataDir string) string { + return filepath.Join(dataDir, "composefs.blob") +} + +func generateComposeFsBlob(toc []byte, composefsDir string) error { + if err := os.MkdirAll(composefsDir, 0o700); err != nil { + return err + } + + destFile := getComposefsBlob(composefsDir) writerJson, err := getComposeFsHelper() if err != nil { return fmt.Errorf("failed to find composefs-from-json: %w", err) @@ -119,7 +128,8 @@ func generateComposeFsBlob(toc []byte, destFile string) error { return nil } -func mountErofsBlob(blobFile, mountPoint string) error { +func mountComposefsBlob(dataDir, mountPoint string) error { + blobFile := getComposefsBlob(dataDir) loop, err := loopback.AttachLoopDevice(blobFile) if err != nil { return err diff --git a/drivers/overlay/overlay.go b/drivers/overlay/overlay.go index 3170f09645..6b6f20637d 100644 --- a/drivers/overlay/overlay.go +++ b/drivers/overlay/overlay.go @@ -1518,8 +1518,8 @@ func (d *Driver) get(id string, disableShifting bool, options graphdriver.MountO defer cleanupFunc() } - erofsLayers := filepath.Join(workDirBase, "erofs-layers") - if err := os.MkdirAll(erofsLayers, 0o700); err != nil { + composefsLayers := filepath.Join(workDirBase, "composefs-layers") + if err := os.MkdirAll(composefsLayers, 0o700); err != nil { return "", err } @@ -1527,33 +1527,33 @@ func (d *Driver) get(id string, disableShifting bool, options graphdriver.MountO composeFsLayers := []string{} - erofsMounts := []string{} + composefsMounts := []string{} defer func() { - for _, m := range erofsMounts { + for _, m := range composefsMounts { defer unix.Unmount(m, unix.MNT_DETACH) } }() - maybeAddErofsMount := func(lowerID string, i int) (string, error) { - erofsBlob := d.getErofsBlob(lowerID) - _, err = os.Stat(erofsBlob) + maybeAddComposefsMount := func(lowerID string, i int) (string, error) { + composefsBlob := d.getComposefsData(lowerID) + _, err = os.Stat(composefsBlob) if err != nil { if os.IsNotExist(err) { return "", nil } return "", err } - logrus.Debugf("overlay: using erofs blob %s for lower %s", erofsBlob, lowerID) + logrus.Debugf("overlay: using composefs blob %s for lower %s", composefsBlob, lowerID) - dest := filepath.Join(erofsLayers, fmt.Sprintf("%d", i)) + dest := filepath.Join(composefsLayers, fmt.Sprintf("%d", i)) if err := os.MkdirAll(dest, 0o700); err != nil { return "", err } - if err := mountErofsBlob(erofsBlob, dest); err != nil { + if err := mountComposefsBlob(composefsBlob, dest); err != nil { return "", err } - erofsMounts = append(erofsMounts, dest) + composefsMounts = append(composefsMounts, dest) composeFsPath, err := d.getDiffPath(lowerID) if err != nil { return "", err @@ -1565,7 +1565,7 @@ func (d *Driver) get(id string, disableShifting bool, options graphdriver.MountO diffDir := path.Join(workDirBase, "diff") - if dest, err := maybeAddErofsMount(id, 0); err != nil { + if dest, err := maybeAddComposefsMount(id, 0); err != nil { return "", err } else if dest != "" { diffDir = dest @@ -1617,21 +1617,21 @@ func (d *Driver) get(id string, disableShifting bool, options graphdriver.MountO return "", err } lowerID := filepath.Base(filepath.Dir(linkContent)) - erofsMount, err := maybeAddErofsMount(lowerID, i+1) + composefsMount, err := maybeAddComposefsMount(lowerID, i+1) if err != nil { return "", err } - if erofsMount != "" { + if composefsMount != "" { if needsIDMapping { - if err := idmap.CreateIDMappedMount(erofsMount, erofsMount, idmappedMountProcessPid); err != nil { - return "", fmt.Errorf("create mapped mount for %q: %w", erofsMount, err) + if err := idmap.CreateIDMappedMount(composefsMount, composefsMount, idmappedMountProcessPid); err != nil { + return "", fmt.Errorf("create mapped mount for %q: %w", composefsMount, err) } - skipIDMappingLayers[erofsMount] = erofsMount + skipIDMappingLayers[composefsMount] = composefsMount // overlay takes a reference on the mount, so it is safe to unmount // the mapped idmounts as soon as the final overlay file system is mounted. - defer unix.Unmount(erofsMount, unix.MNT_DETACH) + defer unix.Unmount(composefsMount, unix.MNT_DETACH) } - absLowers = append(absLowers, erofsMount) + absLowers = append(absLowers, composefsMount) continue } @@ -2070,7 +2070,7 @@ func (d *Driver) ApplyDiffFromStagingDirectory(id, parent, stagingDirectory stri logrus.Warningf("%s", err) } toc := diffOutput.BigData[zstdChunkedManifest] - if err := generateComposeFsBlob(toc, d.getErofsBlob(id)); err != nil { + if err := generateComposeFsBlob(toc, d.getComposefsData(id)); err != nil { return err } } @@ -2130,9 +2130,9 @@ func (d *Driver) ApplyDiff(id, parent string, options graphdriver.ApplyDiffOpts) return directory.Size(applyDir) } -func (d *Driver) getErofsBlob(id string) string { +func (d *Driver) getComposefsData(id string) string { dir := d.dir(id) - return path.Join(dir, "erofs-blob") + return path.Join(dir, "composefs-data") } func (d *Driver) getDiffPath(id string) (string, error) { From 0d28d3eb8a4f601177d9b32e4c041872e766862d Mon Sep 17 00:00:00 2001 From: Giuseppe Scrivano Date: Wed, 5 Jul 2023 15:30:15 +0200 Subject: [PATCH 2/2] overlay: specify "noacl" if there are no ACLs if there are no ACLs, then we mount the EROFS layer with the "noacl" mount option. Signed-off-by: Giuseppe Scrivano --- drivers/overlay/composefs_supported.go | 47 +++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/drivers/overlay/composefs_supported.go b/drivers/overlay/composefs_supported.go index 931be6d579..aaf7691317 100644 --- a/drivers/overlay/composefs_supported.go +++ b/drivers/overlay/composefs_supported.go @@ -5,6 +5,7 @@ package overlay import ( "bytes" + "encoding/binary" "errors" "fmt" "io/fs" @@ -128,6 +129,41 @@ func generateComposeFsBlob(toc []byte, composefsDir string) error { return nil } +/* +typedef enum { + LCFS_EROFS_FLAGS_HAS_ACL = (1 << 0), +} lcfs_erofs_flag_t; + +struct lcfs_erofs_header_s { + uint32_t magic; + uint32_t version; + uint32_t flags; + uint32_t unused[5]; +} __attribute__((__packed__)); +*/ + +// hasACL returns true if the erofs blob has ACLs enabled +func hasACL(path string) (bool, error) { + const LCFS_EROFS_FLAGS_HAS_ACL = (1 << 0) + + fd, err := unix.Openat(unix.AT_FDCWD, path, unix.O_RDONLY|unix.O_CLOEXEC, 0) + if err != nil { + return false, err + } + defer unix.Close(fd) + // do not worry about checking the magic number, if the file is invalid + // we will fail to mount it anyway + flags := make([]byte, 4) + nread, err := unix.Pread(fd, flags, 8) + if err != nil { + return false, err + } + if nread != 4 { + return false, fmt.Errorf("failed to read flags from %q", path) + } + return binary.LittleEndian.Uint32(flags)&LCFS_EROFS_FLAGS_HAS_ACL != 0, nil +} + func mountComposefsBlob(dataDir, mountPoint string) error { blobFile := getComposefsBlob(dataDir) loop, err := loopback.AttachLoopDevice(blobFile) @@ -136,5 +172,14 @@ func mountComposefsBlob(dataDir, mountPoint string) error { } defer loop.Close() - return unix.Mount(loop.Name(), mountPoint, "erofs", unix.MS_RDONLY, "ro") + hasACL, err := hasACL(blobFile) + if err != nil { + return err + } + mountOpts := "ro" + if !hasACL { + mountOpts += ",noacl" + } + + return unix.Mount(loop.Name(), mountPoint, "erofs", unix.MS_RDONLY, mountOpts) }