about summary refs log tree commit diff
path: root/nixos
diff options
context:
space:
mode:
authornikstur <nikstur@outlook.com>2024-04-08 18:48:53 +0200
committerGitHub <noreply@github.com>2024-04-08 18:48:53 +0200
commit80cafa6a29c1d9fd383ccdd51dbb1b6e6eadcbfb (patch)
treeda0666f925d0685deab4951a6a2e651993a2cd63 /nixos
parent9a7afcba4cd7b1f9ffd3893d23cc3e2fc54b83d2 (diff)
parentad19cee09cca703b4da9e084fffec2fab8b55f02 (diff)
Merge pull request #302590 from nikstur/repart-image-label-length
nixos/image/repart: assert maximum label length
Diffstat (limited to 'nixos')
-rw-r--r--nixos/lib/systemd-lib.nix5
-rw-r--r--nixos/modules/image/repart.nix38
-rw-r--r--nixos/modules/system/boot/systemd/repart.nix6
3 files changed, 46 insertions, 3 deletions
diff --git a/nixos/lib/systemd-lib.nix b/nixos/lib/systemd-lib.nix
index 832160111da4e..b67495609ff5a 100644
--- a/nixos/lib/systemd-lib.nix
+++ b/nixos/lib/systemd-lib.nix
@@ -525,4 +525,9 @@ in rec {
       )}
     '';
 
+  # The maximum number of characters allowed in a GPT partition label. This
+  # limit is specified by UEFI and enforced by systemd-repart.
+  # Corresponds to GPT_LABEL_MAX from systemd's gpt.h.
+  GPTMaxLabelLength = 36;
+
 }
diff --git a/nixos/modules/image/repart.nix b/nixos/modules/image/repart.nix
index 1a43297f4b432..569d4a4b00215 100644
--- a/nixos/modules/image/repart.nix
+++ b/nixos/modules/image/repart.nix
@@ -6,6 +6,8 @@
 let
   cfg = config.image.repart;
 
+  inherit (utils.systemdUtils.lib) GPTMaxLabelLength;
+
   partitionOptions = {
     options = {
       storePaths = lib.mkOption {
@@ -224,6 +226,42 @@ in
 
   config = {
 
+    assertions = lib.mapAttrsToList (fileName: partitionConfig:
+      let
+        inherit (partitionConfig) repartConfig;
+        labelLength = builtins.stringLength repartConfig.Label;
+      in
+      {
+        assertion = repartConfig ? Label -> GPTMaxLabelLength >= labelLength;
+        message = ''
+          The partition label '${repartConfig.Label}'
+          defined for '${fileName}' is ${toString labelLength} characters long,
+          but the maximum label length supported by UEFI is ${toString
+          GPTMaxLabelLength}.
+        '';
+      }
+    ) cfg.partitions;
+
+    warnings = lib.filter (v: v != null) (lib.mapAttrsToList (fileName: partitionConfig:
+      let
+        inherit (partitionConfig) repartConfig;
+        suggestedMaxLabelLength = GPTMaxLabelLength - 2;
+        labelLength = builtins.stringLength repartConfig.Label;
+      in
+        if (repartConfig ? Label && labelLength >= suggestedMaxLabelLength) then ''
+          The partition label '${repartConfig.Label}'
+          defined for '${fileName}' is ${toString labelLength} characters long.
+          The suggested maximum label length is ${toString
+          suggestedMaxLabelLength}.
+
+          If you use sytemd-sysupdate style A/B updates, this might
+          not leave enough space to increment the version number included in
+          the label in a future release. For example, if your label is
+          ${toString GPTMaxLabelLength} characters long (the maximum enforced by UEFI) and
+          you're at version 9, you cannot increment this to 10.
+        '' else null
+    ) cfg.partitions);
+
     image.repart =
       let
         version = config.image.repart.version;
diff --git a/nixos/modules/system/boot/systemd/repart.nix b/nixos/modules/system/boot/systemd/repart.nix
index 6cc387cb6f43f..7771f5fe06789 100644
--- a/nixos/modules/system/boot/systemd/repart.nix
+++ b/nixos/modules/system/boot/systemd/repart.nix
@@ -13,14 +13,14 @@ let
 
   partitionAssertions = lib.mapAttrsToList (fileName: definition:
     let
-      maxLabelLength = 36; # GPT_LABEL_MAX defined in systemd's gpt.h
+      inherit (utils.systemdUtils.lib) GPTMaxLabelLength;
       labelLength = builtins.stringLength definition.Label;
     in
     {
-      assertion = definition ? Label -> maxLabelLength >= labelLength;
+      assertion = definition ? Label -> GPTMaxLabelLength >= labelLength;
       message = ''
         The partition label '${definition.Label}' defined for '${fileName}' is ${toString labelLength}
-        characters long, but the maximum label length supported by systemd is ${toString maxLabelLength}.
+        characters long, but the maximum label length supported by systemd is ${toString GPTMaxLabelLength}.
       '';
     }
   ) cfg.partitions;