about summary refs log tree commit diff
path: root/nixos/lib/make-disk-image.nix
diff options
context:
space:
mode:
authorSamuel Dionne-Riel <samuel@dionne-riel.com>2021-04-23 23:18:08 -0400
committerSamuel Dionne-Riel <samuel@dionne-riel.com>2021-04-24 14:49:04 -0400
commit9b18a78c739a2a43c3ed386a4a9c52e4f7360650 (patch)
tree2812780c29e489b4e14d9ca1d7a3c2a66f727302 /nixos/lib/make-disk-image.nix
parent05c13a03e2fb27186d8d1f2825807bf156512111 (diff)
make-disk-image: Account for the ext4 reserved space
Reserved space includes:

 - inodes space in use (2 blocks per)
 - about 5.2% of the space

The 5.2% reserved space was computed empirically when working on a
previous EXT4 image builder. It seems to stabilize around 5% even for
much larger filesystems.
Diffstat (limited to 'nixos/lib/make-disk-image.nix')
-rw-r--r--nixos/lib/make-disk-image.nix26
1 files changed, 20 insertions, 6 deletions
diff --git a/nixos/lib/make-disk-image.nix b/nixos/lib/make-disk-image.nix
index 164f2f0f0be8e..f1c942181f040 100644
--- a/nixos/lib/make-disk-image.nix
+++ b/nixos/lib/make-disk-image.nix
@@ -186,6 +186,13 @@ let format' = format; in let
       echo "$acc"
     }
 
+    # Approximative percentage of reserved space in an ext4 fs over 512MiB.
+    # 0.05208587646484375
+    #  × 1000, integer part: 52
+    compute_fudge() {
+      echo $(( $1 * 52 / 1000 ))
+    }
+
     mkdir $out
 
     root="$PWD/root"
@@ -252,15 +259,22 @@ let format' = format; in let
       ''}
 
       # Compute required space in filesystem blocks
-      requiredSpace=$(find . ! -type d -exec 'du' '--apparent-size' '--block-size' "${blockSize}" '{}' ';' | cut -f1 | sum_lines)
-      # Convert to bytes
-      requiredSpace=$(( requiredSpace * ${blockSize} ))
-
-      diskSize=$(( requiredSpace  + additionalSpace ))
+      diskUsage=$(find . ! -type d -exec 'du' '--apparent-size' '--block-size' "${blockSize}" '{}' ';' | cut -f1 | sum_lines)
+      # Each inode takes space!
+      numInodes=$(find . | wc -l)
+      # Convert to bytes, inodes take two blocks each!
+      diskUsage=$(( (diskUsage + 2 * numInodes) * ${blockSize} ))
+      # Then increase the required space to account for the reserved blocks.
+      fudge=$(compute_fudge $diskUsage)
+      requiredFilesystemSpace=$(( diskUsage + fudge ))
+
+      diskSize=$(( requiredFilesystemSpace  + additionalSpace ))
       truncate -s "$diskSize" $diskImage
 
       printf "Automatic disk size...\n"
-      printf "  Space needed: %d bytes\n" $requiredSpace
+      printf "  Closure space use: %d bytes\n" $diskUsage
+      printf "  fudge: %d bytes\n" $fudge
+      printf "  Filesystem size needed: %d bytes\n" $requiredFilesystemSpace
       printf "  Additional space: %d bytes\n" $additionalSpace
       printf "  Disk image size: %d bytes\n" $diskSize
     '' else ''