Skip to content

Commit

Permalink
Merge pull request #1663 from giuseppe/support-erofs-noacl
Browse files Browse the repository at this point in the history
overlay: store if there are no ACLs in the layer
  • Loading branch information
rhatdan committed Jul 7, 2023
2 parents dc79a0d + 0d28d3e commit 3a91ecd
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 27 deletions.
4 changes: 2 additions & 2 deletions drivers/overlay/composefs_notsupported.go
Original file line number Diff line number Diff line change
Expand Up @@ -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")
}

Expand Down
61 changes: 58 additions & 3 deletions drivers/overlay/composefs_supported.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package overlay

import (
"bytes"
"encoding/binary"
"errors"
"fmt"
"io/fs"
Expand Down Expand Up @@ -75,7 +76,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)
Expand Down Expand Up @@ -119,12 +129,57 @@ func generateComposeFsBlob(toc []byte, destFile string) error {
return nil
}

func mountErofsBlob(blobFile, mountPoint string) error {
/*
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)
if err != nil {
return err
}
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)
}
44 changes: 22 additions & 22 deletions drivers/overlay/overlay.go
Original file line number Diff line number Diff line change
Expand Up @@ -1518,42 +1518,42 @@ 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
}

skipIDMappingLayers := make(map[string]string)

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
Expand All @@ -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
Expand Down Expand Up @@ -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
}

Expand Down Expand Up @@ -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
}
}
Expand Down Expand Up @@ -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) {
Expand Down

0 comments on commit 3a91ecd

Please sign in to comment.