From: Daan De Meyer Date: Thu, 18 Aug 2022 20:51:53 +0000 (+0200) Subject: Replace blockdev --reread-pt by manually adding partitions X-Git-Tag: v14~74^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F1130%2Fhead;p=thirdparty%2Fmkosi.git 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. --- 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)