From: Clayton Craft Date: Wed, 4 Jun 2025 22:44:50 +0000 (-0700) Subject: Detect kernel ver from modules sub dir if unable to extract from filename X-Git-Tag: v26~112^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5e38eec863e72e5fd789aa977dbcd6bffe5887d8;p=thirdparty%2Fmkosi.git Detect kernel ver from modules sub dir if unable to extract from filename postmarketOS doesn't include the kernel version in the filename of the kernel image. It would be cleaner to update kernel packages to make a symlink for the kernel under /usr/lib/modules/, but this would be difficult to implement in postmarketOS where we ship something like >400 kernel packages for a huge array of different devices / kernel versions. Currently Alpine/pmOS only support having 1 kernel / version installed at one time, so this fails if, for some reason, multiple kernel dirs are found since there's no way to determine which one maps to the kernel binary mkosi is using. --- diff --git a/mkosi/__init__.py b/mkosi/__init__.py index 8a95a72e8..566e8ce54 100644 --- a/mkosi/__init__.py +++ b/mkosi/__init__.py @@ -170,6 +170,9 @@ from mkosi.util import ( from mkosi.versioncomp import GenericVersion from mkosi.vmspawn import run_vmspawn +# Allowed characters from https://uapi-group.org/specifications/specs/version_format_specification +KERNEL_VERSION_PATTERN = r"\d+\.\d+[\w.\-~^+]*" + @contextlib.contextmanager def mount_base_trees(context: Context) -> Iterator[None]: @@ -1292,6 +1295,23 @@ def gzip_binary(context: Context) -> str: return "pigz" if context.config.find_binary("pigz") else "gzip" +def kernel_get_ver_from_modules(context: Context) -> Optional[str]: + # Try to get version from the first dir under usr/lib/modules but fail if multiple versions are found + versions = [ + p.name + for p in (context.root / "usr/lib/modules").glob("*") + if re.match(KERNEL_VERSION_PATTERN, p.name) + ] + if len(versions) > 1: + die( + "Multiple kernel module directories found in /usr/lib/modules, unable to determine correct version to use" # noqa: E501 + ) + elif len(versions) == 0: + return None + + return versions[0] + + def fixup_vmlinuz_location(context: Context) -> None: # Some architectures ship an uncompressed vmlinux (ppc64el, riscv64) for type in ("vmlinuz", "vmlinux"): @@ -1299,7 +1319,14 @@ def fixup_vmlinuz_location(context: Context) -> None: if d.is_symlink(): continue - kver = d.name.removeprefix(f"{type}-") + # Extract kernel version pattern from filename + filename = d.name.removeprefix(f"{type}-") + match = re.search(KERNEL_VERSION_PATTERN, filename) + kver = match.group(0) if match else kernel_get_ver_from_modules(context) + if kver is None: + logging.debug("Unable to get kernel version from modules directory") + continue + vmlinuz = context.root / "usr/lib/modules" / kver / type if not vmlinuz.parent.exists(): continue