From cf3adb42b9427b76bb68c1263466429560962272 Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Thu, 18 Aug 2022 22:51:53 +0200 Subject: [PATCH] Replace blockdev --reread-pt by manually adding partitions Instead of relying on blockdev, let's use our own infra to make sure all partitions have appeared after we modify the partition table. This should hopefully reduce the number of race conditions involved with modifying the partition table and loop devices. --- mkosi/__init__.py | 9 --------- mkosi/backend.py | 31 +++++++------------------------ 2 files changed, 7 insertions(+), 33 deletions(-) diff --git a/mkosi/__init__.py b/mkosi/__init__.py index 892601a82..a8d6143ff 100644 --- a/mkosi/__init__.py +++ b/mkosi/__init__.py @@ -3685,15 +3685,6 @@ def insert_partition( with complete_step(f"Inserting partition of {format_bytes(part_size)}{ss}..."): args.partition_table.run_sfdisk(loopdev) - # Required otherwise the partition removal will fail - with open(loopdev, 'rb+') as f: - ioctl_partition_add( - f.fileno(), - part.number, - args.partition_table.partition_offset(part), - args.partition_table.partition_size(part) - ) - with complete_step("Writing partition..."): if ident == PartitionIdentifier.root: luks_format_root(args, loopdev, False, False, True) diff --git a/mkosi/backend.py b/mkosi/backend.py index abb4da98b..fcc8ab795 100644 --- a/mkosi/backend.py +++ b/mkosi/backend.py @@ -36,6 +36,8 @@ from typing import ( cast, ) +from .syscall import ioctl_partition_add + PathString = Union[Path, str] @@ -415,7 +417,11 @@ class PartitionTable: if device.is_block_device(): run(["sync"]) - run_with_backoff(["blockdev", "--rereadpt", device], attempts=10) + + # Make sure we re-add all partitions after modifying the partition table. + with open(device, 'rb+') as f: + for p in self.partitions.values(): + ioctl_partition_add(f.fileno(), p.number, self.partition_offset(p), self.partition_size(p)) @dataclasses.dataclass @@ -823,29 +829,6 @@ def run( die(f"{cmdline[0]} not found in PATH.") -def run_with_backoff( - cmdline: Sequence[PathString], - check: bool = True, - delay_interrupt: bool = True, - stdout: _FILE = None, - stderr: _FILE = None, - *, - attempts: int, - **kwargs: Any, -) -> CompletedProcess: - delay = 0.0 - for attempt in range(attempts): - try: - return run(cmdline, check, delay_interrupt, stdout, stderr, **kwargs) - except subprocess.CalledProcessError: - if attempt == attempts - 1: - raise - time.sleep(delay) - delay = min(delay * 2 + 0.01, 1) - - assert False # make mypy happy - - def tmp_dir() -> Path: path = os.environ.get("TMPDIR") or "/var/tmp" return Path(path) -- 2.47.2