[PATCH 14/22] host/initramfs/extfs.nix: tar2ext4 -> mkfs.ext4 -d

Alyssa Ross
2022-10-10T23:32:54Z

tar2ext4 is designed for making read-only, minimally-sized ext4
images. That's great for the Spectrum host system's root filesystem,
but it doesn't make sense for the user data partition, because even if
we mark it read/write after running tar2ext4, there will be very few
inodes available, so it won't be very useful for storing data.

To fix this, we use the normal tools for creating an ext4 filesystem.
We create a sparse image of an extremely large size to ensure there's
enough space available for metadata and things for the partition to
grow to fit any disk a user might want to to use Spectrum on, then
shrink the image down to its minimum size.

Doing it this way assumes that the build environment will always
support sparse files. If this turns out not to be the case, we can
use mkfs.ext4's -E resize= option to set the maximum expected disk
size, and use a smaller size for the initial image size. I haven't
done that here to avoid having to pick that smaller number.

Now that the filesystem is no longer marked as read-only, we need to
fsck it before every mount, or it won't mount any more after the first
time.

Signed-off-by: Alyssa Ross <hi@alyssa.is>
---
host/initramfs/extfs.nix | 16 +++++++++++-----
host/rootfs/etc/s6-rc/ext/up | 1 +
2 files changed, 12 insertions(+), 5 deletions(-)

diff --git a/host/initramfs/extfs.nix b/host/initramfs/extfs.nix
index 0ee337b..a510c02 100644
--- a/host/initramfs/extfs.nix
+++ b/host/initramfs/extfs.nix
@@ -1,7 +1,7 @@
# SPDX-FileCopyrightText: 2021-2022 Alyssa Ross <hi@alyssa.is>
# SPDX-License-Identifier: MIT

-{ config, runCommand, tar2ext4 }:
+{ config, runCommand, e2fsprogs, tar2ext4 }:

let
netvm = import ../../vm/sys/net {
@@ -15,9 +15,10 @@ let
in

runCommand "ext.ext4" {
- nativeBuildInputs = [ tar2ext4 ];
+ nativeBuildInputs = [ e2fsprogs ];
} ''
- mkdir -p svc/data/appvm-{catgirl,lynx,mg}
+ mkdir -p root/svc/data/appvm-{catgirl,lynx,mg,nix}
+ cd root

tar -C ${netvm} -c data | tar -C svc -x
chmod +w svc/data
@@ -26,6 +27,11 @@ runCommand "ext.ext4" {
tar -C ${appvm-lynx} -c . | tar -C svc/data/appvm-lynx -x
tar -C ${appvm-mg} -c . | tar -C svc/data/appvm-mg -x

- tar -cf ext.tar svc
- tar2ext4 -i ext.tar -o $out
+ mkfs.ext4 -d . $out 16T
+ resize2fs -M $out
+
+ # The generated image will have all files owned by the uid and gid
+ # mkfs.ext4 was run as, so we need to normalize ownership to root.
+ find -exec echo $'set_inode_field {} uid 0\nset_inode_field {} gid 0' ';' |
+ debugfs -wf - $out
''
diff --git a/host/rootfs/etc/s6-rc/ext/up b/host/rootfs/etc/s6-rc/ext/up
index c189471..78b2637 100644
--- a/host/rootfs/etc/s6-rc/ext/up
+++ b/host/rootfs/etc/s6-rc/ext/up
@@ -2,5 +2,6 @@
# SPDX-FileCopyrightText: 2021-2022 Alyssa Ross <hi@alyssa.is>

if { /etc/mdev/wait ext }
+foreground { fsck.ext4 -fp /dev/ext }
if { resize2fs /dev/ext }
mount /dev/ext /ext
--
2.37.1