leapp-repository/SOURCES/0108-el8toel9-checkkernelarm-Install-64k-kernel.patch
2026-07-17 04:37:07 -04:00

188 lines
7.2 KiB
Diff

From f7ccf5aefdd87856c4dda80c2c410d5cb34d0c1d Mon Sep 17 00:00:00 2001
From: Petr Stodulka <pstodulk@redhat.com>
Date: Wed, 24 Jun 2026 08:58:38 +0200
Subject: [PATCH 108/108] el8toel9: checkkernelarm: Install 64k kernel
On RHEL 8 for ARM, the default kernel is 64k (pagesize) and there is
no 4k alternative. On RHEL 9 it's the opposite nowadays (since 9.4?),
where the default kernel is 4k, but for 64k the kernel-64k RPMs
need to be installed.
So for the upgrade 8 -> 9 on ARM, it's important to create explicit
instruction for the installation of kernel-64k packages. On other
systems we do not have this problem so leaving it just in el8toel9
repository.
Also, we cannot prevent installation of standard kernel packages,
so the system after the upgrade will have both kernels installed
(4k & 64k versions).
At this moment, no report is generated to informing user about the
need of manual 4k kernel removal. But it's a better situation than
in case of the requirement to manually install 64k kernel, reboot,
and then remove the 4k one. The report can be eventually created
as a follow up.
Note that without this fix, the upgrade 8 -> 9 would end in emergency
mode on ARM machines after previously introduced changes dealing with
various kernel flavours - where a specific kernel is expected to be
discovered after the upgrade.
Used AI to prepare unit-tests.
JIRA: RHEL-111860
Assisted-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Petr Stodulka <pstodulk@redhat.com>
---
.../el8toel9/actors/checkkernelarm/actor.py | 22 ++++++
.../libraries/checkkernelarm.py | 28 ++++++++
.../tests/unit_test_checkkernelarm.py | 72 +++++++++++++++++++
3 files changed, 122 insertions(+)
create mode 100644 repos/system_upgrade/el8toel9/actors/checkkernelarm/actor.py
create mode 100644 repos/system_upgrade/el8toel9/actors/checkkernelarm/libraries/checkkernelarm.py
create mode 100644 repos/system_upgrade/el8toel9/actors/checkkernelarm/tests/unit_test_checkkernelarm.py
diff --git a/repos/system_upgrade/el8toel9/actors/checkkernelarm/actor.py b/repos/system_upgrade/el8toel9/actors/checkkernelarm/actor.py
new file mode 100644
index 00000000..9fa9eaa1
--- /dev/null
+++ b/repos/system_upgrade/el8toel9/actors/checkkernelarm/actor.py
@@ -0,0 +1,22 @@
+from leapp.actors import Actor
+from leapp.libraries.actor import checkkernelarm
+from leapp.models import KernelInfo, RpmTransactionTasks
+from leapp.tags import ChecksPhaseTag, IPUWorkflowTag
+
+
+class CheckKernelARM(Actor):
+ """
+ Instruct the installation of 64k kernel on ARM machines.
+
+ On RHEL 8 all ARM machines use kernel with the 64k pagesize.
+ However, in case of RHEL 9 the default ARM kernel has 4k pagesize instead.
+ Ensure that 64k kernel is installed on the target system for ARM.
+ """
+
+ name = 'check_kernel_arm'
+ consumes = (KernelInfo,)
+ produces = (RpmTransactionTasks,)
+ tags = (IPUWorkflowTag, ChecksPhaseTag)
+
+ def process(self):
+ checkkernelarm.process()
diff --git a/repos/system_upgrade/el8toel9/actors/checkkernelarm/libraries/checkkernelarm.py b/repos/system_upgrade/el8toel9/actors/checkkernelarm/libraries/checkkernelarm.py
new file mode 100644
index 00000000..78bf0bb6
--- /dev/null
+++ b/repos/system_upgrade/el8toel9/actors/checkkernelarm/libraries/checkkernelarm.py
@@ -0,0 +1,28 @@
+from leapp.exceptions import StopActorExecutionError
+from leapp.libraries.common import kernel as kernel_lib
+from leapp.libraries.common.config import architecture
+from leapp.libraries.stdlib import api
+from leapp.models import KernelInfo, RpmTransactionTasks
+
+
+def process():
+ if not architecture.matches_architecture(architecture.ARCH_ARM64):
+ # Nothing to do.
+ return
+
+ kernel_info = next(api.consume(KernelInfo), None)
+ if not kernel_info:
+ raise StopActorExecutionError('Could not retrieve KernelInfo message.')
+
+ target_pkgs = kernel_lib.get_target_kernel_pkg_names(
+ kernel_info.type,
+ kernel_info.page_size,
+ api.current_actor().configuration.architecture
+ )
+
+ api.current_logger().debug(
+ "Register expected target kernel RPMs for installation on ARM."
+ )
+ api.produce(RpmTransactionTasks(
+ to_install=sorted(list(target_pkgs)))
+ )
diff --git a/repos/system_upgrade/el8toel9/actors/checkkernelarm/tests/unit_test_checkkernelarm.py b/repos/system_upgrade/el8toel9/actors/checkkernelarm/tests/unit_test_checkkernelarm.py
new file mode 100644
index 00000000..9d34fd4a
--- /dev/null
+++ b/repos/system_upgrade/el8toel9/actors/checkkernelarm/tests/unit_test_checkkernelarm.py
@@ -0,0 +1,72 @@
+import pytest
+
+from leapp.exceptions import StopActorExecutionError
+from leapp.libraries.actor import checkkernelarm
+from leapp.libraries.common.config.architecture import ARCH_ARM64, ARCH_X86_64
+from leapp.libraries.common.kernel import KernelPageSize, KernelType
+from leapp.libraries.common.testutils import CurrentActorMocked, produce_mocked
+from leapp.libraries.stdlib import api
+from leapp.models import KernelInfo, RPM, RpmTransactionTasks
+
+_KERNEL_PKG = RPM(name='kernel-core', arch='aarch64', version='4.18.0', release='1.el8',
+ epoch='0', packager='', pgpsig='SIG')
+
+
+def _make_kernel_info(kernel_type=KernelType.ORDINARY, page_size=KernelPageSize.PAGE_SIZE_64K):
+ return KernelInfo(
+ pkg=_KERNEL_PKG, type=kernel_type, page_size=page_size, uname_r='4.18.0-1.el8.aarch64'
+ )
+
+
+def test_skip_non_arm_architecture(monkeypatch):
+ monkeypatch.setattr(api, 'current_actor', CurrentActorMocked(arch=ARCH_X86_64))
+ monkeypatch.setattr(api, 'produce', produce_mocked())
+
+ checkkernelarm.process()
+
+ assert not api.produce.called
+
+
+def test_raises_when_no_kernel_info(monkeypatch):
+ monkeypatch.setattr(api, 'current_actor', CurrentActorMocked(arch=ARCH_ARM64))
+
+ with pytest.raises(StopActorExecutionError, match='Could not retrieve KernelInfo'):
+ checkkernelarm.process()
+
+
+@pytest.mark.parametrize(
+ ('kernel_type', 'page_size', 'expected_pkgs'),
+ [
+ (
+ KernelType.ORDINARY,
+ KernelPageSize.PAGE_SIZE_64K,
+ ['kernel-64k', 'kernel-64k-core', 'kernel-64k-modules'],
+ ),
+ (
+ KernelType.ORDINARY,
+ KernelPageSize.PAGE_SIZE_4K,
+ ['kernel', 'kernel-core', 'kernel-modules'],
+ ),
+ (
+ KernelType.REALTIME,
+ KernelPageSize.PAGE_SIZE_64K,
+ ['kernel-rt-64k', 'kernel-rt-64k-core', 'kernel-rt-64k-modules'],
+ ),
+ (
+ KernelType.REALTIME,
+ KernelPageSize.PAGE_SIZE_4K,
+ ['kernel-rt', 'kernel-rt-core', 'kernel-rt-modules'],
+ ),
+ ]
+)
+def test_produces_rpm_transaction_tasks(monkeypatch, kernel_type, page_size, expected_pkgs):
+ kernel_info = _make_kernel_info(kernel_type=kernel_type, page_size=page_size)
+ monkeypatch.setattr(api, 'current_actor', CurrentActorMocked(arch=ARCH_ARM64, msgs=[kernel_info]))
+ monkeypatch.setattr(api, 'produce', produce_mocked())
+
+ checkkernelarm.process()
+
+ assert api.produce.called == 1
+ produced = api.produce.model_instances[0]
+ assert isinstance(produced, RpmTransactionTasks)
+ assert sorted(produced.to_install) == sorted(expected_pkgs)
--
2.54.0