Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

overlay: store if there are no ACLs in the layer #1663

Merged
merged 2 commits into from
Jul 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/composefsBlob/composefsDataDir/g?

_, 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)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

… and something like s/blob/subdirectory/ here.


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