From fdcfb49d1179d05b7672727bfa6b6e761ca27636 Mon Sep 17 00:00:00 2001 From: Songpol Anannetikul Date: Mon, 13 Oct 2025 00:33:58 +0700 Subject: [PATCH 1/2] fix: allow using virtiofs share as writable /nix/store overlay --- nixos-modules/microvm/mounts.nix | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/nixos-modules/microvm/mounts.nix b/nixos-modules/microvm/mounts.nix index 6587eef9..00228f85 100644 --- a/nixos-modules/microvm/mounts.nix +++ b/nixos-modules/microvm/mounts.nix @@ -27,6 +27,12 @@ let else "/dev/vda" else throw "No disk letter when /nix/store is not in disk"; + # Check if the writable store overlay is a virtiofs share + isRwStoreVirtiofsShare = builtins.any ({mountPoint, proto, ... }: + mountPoint == config.microvm.writableStoreOverlay + && proto == "virtiofs" + ) config.microvm.shares; + in lib.mkIf config.microvm.guest.enable { fileSystems = lib.mkMerge [ ( @@ -82,6 +88,8 @@ lib.mkIf config.microvm.guest.enable { "lowerdir=${roStore}" "upperdir=${writableStoreOverlay}/store" "workdir=${writableStoreOverlay}/work" + ] ++ lib.optionals isRwStoreVirtiofsShare [ + "userxattr" ]; depends = [ roStore writableStoreOverlay ]; }; @@ -132,11 +140,13 @@ lib.mkIf config.microvm.guest.enable { where = "/sysroot/nix/store"; what = "overlay"; type = "overlay"; - options = builtins.concatStringsSep "," [ + options = builtins.concatStringsSep "," ([ "lowerdir=/sysroot${roStore}" "upperdir=/sysroot${writableStoreOverlay}/store" "workdir=/sysroot${writableStoreOverlay}/work" - ]; + ] ++ lib.optionals isRwStoreVirtiofsShare [ + "userxattr" + ]); wantedBy = [ "initrd-fs.target" ]; before = [ "initrd-fs.target" ]; requires = [ "rw-store.service" ]; From 45a21d173c2eb2c8594f2a17fcc4e8eae52bce65 Mon Sep 17 00:00:00 2001 From: Songpol Anannetikul Date: Mon, 13 Oct 2025 23:20:56 +0700 Subject: [PATCH 2/2] refactor: use the new overlay fileSystems API --- nixos-modules/microvm/mounts.nix | 60 +++++--------------------------- 1 file changed, 8 insertions(+), 52 deletions(-) diff --git a/nixos-modules/microvm/mounts.nix b/nixos-modules/microvm/mounts.nix index 00228f85..ff5e55e2 100644 --- a/nixos-modules/microvm/mounts.nix +++ b/nixos-modules/microvm/mounts.nix @@ -59,7 +59,7 @@ lib.mkIf config.microvm.guest.enable { ) { "/nix/store" = { device = hostStore.mountPoint; - options = [ "bind" ]; + options = [ "ro" "bind" ]; neededForBoot = true; }; } @@ -72,7 +72,7 @@ lib.mkIf config.microvm.guest.enable { "/nix/.ro-store" = { device = roStoreDisk; fsType = storeDiskType; - options = [ "x-systemd.requires=systemd-modules-load.service" ]; + options = [ "ro" "x-systemd.requires=systemd-modules-load.service" ]; neededForBoot = true; noCheck = true; }; @@ -81,17 +81,13 @@ lib.mkIf config.microvm.guest.enable { # mount store with writable overlay lib.optionalAttrs (writableStoreOverlay != null) { "/nix/store" = { - device = "overlay"; - fsType = "overlay"; neededForBoot = true; - options = [ - "lowerdir=${roStore}" - "upperdir=${writableStoreOverlay}/store" - "workdir=${writableStoreOverlay}/work" - ] ++ lib.optionals isRwStoreVirtiofsShare [ - "userxattr" - ]; - depends = [ roStore writableStoreOverlay ]; + overlay = { + lowerdir = [ roStore ]; + upperdir = "${writableStoreOverlay}/store"; + workdir = "${writableStoreOverlay}/work"; + }; + options = lib.optional isRwStoreVirtiofsShare "userxattr"; }; } ) { @@ -133,44 +129,4 @@ lib.mkIf config.microvm.guest.enable { }; }) {} config.microvm.shares ) ]; - - # boot.initrd.systemd patchups copied from - boot.initrd.systemd = lib.mkIf (config.boot.initrd.systemd.enable && writableStoreOverlay != null) { - mounts = [ { - where = "/sysroot/nix/store"; - what = "overlay"; - type = "overlay"; - options = builtins.concatStringsSep "," ([ - "lowerdir=/sysroot${roStore}" - "upperdir=/sysroot${writableStoreOverlay}/store" - "workdir=/sysroot${writableStoreOverlay}/work" - ] ++ lib.optionals isRwStoreVirtiofsShare [ - "userxattr" - ]); - wantedBy = [ "initrd-fs.target" ]; - before = [ "initrd-fs.target" ]; - requires = [ "rw-store.service" ]; - after = [ "rw-store.service" ]; - unitConfig.RequiresMountsFor = "/sysroot/${roStore}"; - } ]; - services.rw-store = { - unitConfig = { - DefaultDependencies = false; - RequiresMountsFor = "/sysroot${writableStoreOverlay}"; - }; - serviceConfig = { - Type = "oneshot"; - ExecStart = "/bin/mkdir -p -m 0755 /sysroot${writableStoreOverlay}/store /sysroot${writableStoreOverlay}/work /sysroot/nix/store"; - }; - }; - }; - - # Fix for hanging shutdown - systemd.mounts = lib.mkIf config.boot.initrd.systemd.enable [ { - what = "store"; - where = "/nix/store"; - # Generate a `nix-store.mount.d/overrides.conf` - overrideStrategy = "asDropin"; - unitConfig.DefaultDependencies = false; - } ]; }