]> git.ipfire.org Git - thirdparty/mkosi.git/commitdiff
Support older versions of sfdisk without "grain" support
authorDaan De Meyer <daan.j.demeyer@gmail.com>
Mon, 3 Jan 2022 16:29:12 +0000 (08:29 -0800)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Tue, 4 Jan 2022 11:45:29 +0000 (12:45 +0100)
If "grain" is not available, let's fall back to the default grain
size of 1 MiB. To check if "grain" is available, let's run sfdisk
against /dev/full and try to configure the "grain" which will fail
if "grain" is not supported.

mkosi/backend.py

index 3c3e82e8f66c1e19e2111e8d95d7d81b1d59f515..786845c369e1f9736388e2642a59de702ead52df 100644 (file)
@@ -6,6 +6,7 @@ import argparse
 import contextlib
 import dataclasses
 import enum
+import functools
 import math
 import os
 import resource
@@ -260,6 +261,18 @@ class Partition:
         return ', '.join(filter(None, desc))
 
 
+@functools.lru_cache(maxsize=None)
+def sfdisk_grain_is_supported() -> bool:
+    cmd: List[PathString] = ["sfdisk", "--no-reread", "--no-act", "--quiet", "/dev/full"]
+
+    try:
+        run(cmd, text=True, input='\n'.join(["label: gpt", "grain: 4096", "quit"]), stderr=subprocess.DEVNULL)
+    except subprocess.CalledProcessError:
+        return False
+
+    return True
+
+
 @dataclasses.dataclass
 class PartitionTable:
     partitions: Dict[PartitionIdentifier, Partition] = dataclasses.field(default_factory=dict)
@@ -269,6 +282,10 @@ class PartitionTable:
 
     grain: int = 4096
 
+    def __post_init__(self) -> None:
+        if not sfdisk_grain_is_supported():
+            self.grain = 1024 ** 2 # Use sfdisk default grain size of 1 MiB.
+
     def first_partition_offset(self, max_partitions: int = 128) -> int:
         if self.first_lba is not None:
             # No rounding here, we honour the specified value exactly.
@@ -323,7 +340,7 @@ class PartitionTable:
 
     def sfdisk_spec(self) -> str:
         table = ["label: gpt",
-                 f"grain: {self.grain}",
+                 f"grain: {self.grain}" if sfdisk_grain_is_supported() else '\n',
                  f"first-lba: {self.first_partition_offset() // self.sector_size}",
                  *(p.sfdisk_spec() for p in self.partitions.values())]
         return '\n'.join(table)