From ed4117d926c5361cefd09a4ad283ad8fcfce1280 Mon Sep 17 00:00:00 2001 From: Thales Maciel Date: Sat, 18 Apr 2026 14:58:42 -0300 Subject: [PATCH] imagepull/BuildExt4: omit positional fs-size; rely on file truncation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit mkfs.ext4's positional fs-size is documented in 1 KiB units (not the filesystem's 4 KiB block size), so passing sizeBytes/4096 made filesystems 1/4 the intended size. A 4 GiB request became a 1 GiB ext4 in a 4 GiB file, packed to 0 free blocks — VM create then failed with 'Could not allocate block' when patchRootOverlay tried to write guest config. The file is truncated to the target size before mkfs runs; without the positional arg, mkfs uses the whole device. Co-Authored-By: Claude Opus 4.7 (1M context) --- internal/imagepull/ext4.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/internal/imagepull/ext4.go b/internal/imagepull/ext4.go index 9c31ed5..9c2ef15 100644 --- a/internal/imagepull/ext4.go +++ b/internal/imagepull/ext4.go @@ -5,7 +5,6 @@ import ( "errors" "fmt" "os" - "strconv" "banger/internal/system" ) @@ -53,6 +52,11 @@ func BuildExt4(ctx context.Context, runner system.CommandRunner, srcDir, outFile return err } + // mkfs.ext4's positional `fs-size` is documented in 1 KiB units + // (NOT the filesystem's 4 KiB block size), so dividing by 4096 + // produces a filesystem 1/4 the intended size. Omit the positional + // entirely — the file was truncated to sizeBytes above, and mkfs + // with no fs-size arg uses the whole device. out, runErr := runner.Run(ctx, "mkfs.ext4", "-F", "-q", @@ -60,7 +64,6 @@ func BuildExt4(ctx context.Context, runner system.CommandRunner, srcDir, outFile "-L", "banger-rootfs", "-E", "root_owner=0:0", outFile, - strconv.FormatInt(sizeBytes/4096, 10), // size in 4 KiB blocks ) if runErr != nil { _ = os.Remove(outFile)