From: Daan De Meyer Date: Mon, 22 Jul 2024 13:19:16 +0000 (+0200) Subject: Make sure mkosi works in the initramfs X-Git-Tag: v24~16 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2ccdafd991fb72a12241233720c050e8ce3ad1ca;p=thirdparty%2Fmkosi.git Make sure mkosi works in the initramfs bubblewrap uses pivot_root() which doesn't work in the initramfs as pivot_root() requires / to be a mountpoint which is not the case in the initramfs. So, to make sure mkosi works from within the initramfs, let's make / a mountpoint by recursively bind-mounting / (the directory) to another location and then switching root into the bind mount directory. --- diff --git a/mkosi/__init__.py b/mkosi/__init__.py index faafce049..a987a6c6a 100644 --- a/mkosi/__init__.py +++ b/mkosi/__init__.py @@ -4756,6 +4756,34 @@ def run_build(args: Args, config: Config, *, resources: Path, package_dir: Optio build_image(Context(args, config, workspace=workspace, resources=resources, package_dir=package_dir)) +def ensure_root_is_mountpoint() -> None: + """ + bubblewrap uses pivot_root() which doesn't work in the initramfs as pivot_root() requires / to be a mountpoint + which is not the case in the initramfs. So, to make sure mkosi works from within the initramfs, let's make / a + mountpoint by recursively bind-mounting / (the directory) to another location and then switching root into the bind + mount directory. + """ + fstype = run( + ["findmnt", "--target", "/", "--output", "FSTYPE", "--noheadings"], + stdout=subprocess.PIPE, + ).stdout.strip() + + if fstype != "rootfs": + return + + if os.getuid() != 0: + die("mkosi can only be run as root from the initramfs") + + unshare(CLONE_NEWNS) + run(["mount", "--make-rslave", "/"]) + mountpoint = Path("/run/mkosi/mkosi-root") + mountpoint.mkdir(parents=True, exist_ok=True) + run(["mount", "--rbind", "/", mountpoint]) + os.chdir(mountpoint) + run(["mount", "--move", ".", "/"]) + os.chroot(".") + + def run_verb(args: Args, images: Sequence[Config], *, resources: Path) -> None: images = list(images) @@ -4800,6 +4828,8 @@ def run_verb(args: Args, images: Sequence[Config], *, resources: Path) -> None: page(text, args.pager) return + ensure_root_is_mountpoint() + if args.verb in (Verb.journalctl, Verb.coredumpctl, Verb.ssh): # We don't use a tools tree for verbs that don't need an image build. last = dataclasses.replace(images[-1], tools_tree=None)