apple / apple/containerization

[Bug]: Support a partial last block group to avoid expanding the EXT4 filesystem size

Open
#647 4 comments 0 reactions 1 assignee Claimed by @siddh34 View on GitHub
Dominant language
Swift
Stars
8.9k
Forks
359
Avg merge
2d 20h
Merged PRs (30d)
13

Description

### I have done the following

- [x] I have searched the existing issues
- [x] If possible, I've reproduced the issue using the 'main' branch of this project

### Steps to reproduce

Create an EXT4 filesystem with 160 MiB:
```
container volume create -s 160M size-test
stat -f%z ~/Library/Application\ Support/com.apple.container/volumes/size-test/volume.img
```

### Current behavior

When creating an EXT4 filesystem, the requested size is expanded to the nearest block group boundary. A filesystem whose requested size falls between two block group boundaries ends up larger than requested - 256 MiB:
```
268435456
```

### Expected behavior

The fix is to support a partial last block group so the filesystem uses exactly the requested size - 160 MiB:
```
167772160
```

### Environment

```markdown
N/A
```

### Relevant log output

Test results across the size/content matrix, cross-checked with `e2fsck`:

```shell
Requested Size: 32KiB
Content: none
Size: FAIL
audit.imageSize == testCase.requested = false; audit.imageSize = 134217728; testCase.requested = 32768
e2fsck: PASS
----------------------------------------
Requested Size: 64MiB
Content: none
Size: FAIL
audit.imageSize == testCase.requested = false; audit.imageSize = 134217728; testCase.requested = 67108864
e2fsck: PASS
----------------------------------------
Requested Size: 128MiB
Content: none
Size: PASS
e2fsck: PASS
----------------------------------------
Requested Size: 128MiB+4KiB
Content: none
Size: FAIL
audit.imageSize == testCase.requested = false; audit.imageSize = 268435456; testCase.requested = 134221824
e2fsck: PASS
----------------------------------------
Requested Size: 130MiB+8KiB
Content: none
Size: FAIL
audit.imageSize == testCase.requested = false; audit.imageSize = 268435456; testCase.requested = 136323072
e2fsck: PASS
----------------------------------------
Requested Size: 160MiB
Content: none
Size: FAIL
audit.imageSize == testCase.requested = false; audit.imageSize = 268435456; testCase.requested = 167772160
e2fsck: PASS
----------------------------------------
Requested Size: 256MiB
Content: none
Size: PASS
e2fsck: PASS
----------------------------------------
Requested Size: 1GiB
Content: none
Size: PASS
e2fsck: PASS
----------------------------------------
Requested Size: 4GiB
Content: none
Size: PASS
e2fsck: PASS
----------------------------------------
Requested Size: 63x128MiB
Content: none
Size: PASS
e2fsck: PASS
----------------------------------------
Requested Size: 63x128MiB+4KiB
Content: none
Size: FAIL
audit.imageSize == testCase.requested = false; audit.imageSize = 8589934592; testCase.requested = 8455720960
e2fsck: PASS
----------------------------------------
Requested Size: 8GiB
Content: none
Size: PASS
e2fsck: PASS
----------------------------------------
Requested Size: 16GiB
Content: none
Size: PASS
e2fsck: PASS
----------------------------------------
Requested Size: 160MiB
Content: 10MiB
Size: FAIL
audit.imageSize == testCase.requested = false; audit.imageSize = 268435456; testCase.requested = 167772160
e2fsck: PASS
----------------------------------------
Requested Size: 128MiB
Content: 50MiB
Size: PASS
e2fsck: PASS
----------------------------------------
Requested Size: 160MiB
Content: 120MiB
Size: FAIL
audit.imageSize == testCase.requested = false; audit.imageSize = 268435456; testCase.requested = 167772160
e2fsck: PASS
----------------------------------------
Requested Size: 160MiB
Content: 124MiB
Size: FAIL
audit.imageSize == testCase.requested = false; audit.imageSize = 268435456; testCase.requested = 167772160
e2fsck: PASS
----------------------------------------
Requested Size: 160MiB
Content: 126MiB
Size: PASS
e2fsck: PASS
----------------------------------------
Requested Size: 256MiB
Content: 130MiB
Size: PASS
e2fsck: PASS
----------------------------------------
Requested Size: 1GiB
Content: 200MiB
Size: PASS
e2fsck: PASS
----------------------------------------
Requested Size: 300MiB
Content: 260MiB
Size: FAIL
audit.imageSize == testCase.requested = false; audit.imageSize = 402653184; testCase.requested = 314572800
e2fsck: PASS
----------------------------------------
Requested Size: 4GiB
Content: 260MiB
Size: PASS
e2fsck: PASS
----------------------------------------
Requested Size: 63x128MiB
Content: 500MiB
Size: PASS
e2fsck: PASS
----------------------------------------
Requested Size: 8GiB
Content: 300MiB
Size: PASS
e2fsck: PASS
----------------------------------------
Requested Size: 16GiB
Content: 1000MiB
Size: PASS
e2fsck: PASS
----------------------------------------
```

### Code of Conduct

- [x] I agree to follow this project's Code of Conduct

Related to https://github.com/apple/containerization/pull/640.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.