aops-ceres/0002-support-restore-grubby-if-kabi-check-failed.patch
wang-guangge e601ac91f0 support restore grubby if kabi check failed
(cherry picked from commit a81cc81fd42fe66d36f3a80e41ef458ca0890a32)
2023-12-22 12:35:42 +08:00

168 lines
7.0 KiB
Diff

From 2c3dcc5bb5de4d3f83902bb8cb7f0fe1fa9a55b9 Mon Sep 17 00:00:00 2001
From: wang-guangge <wangguangge@huawei.com>
Date: Tue, 19 Dec 2023 21:03:48 +0800
Subject: [PATCH] support restore default boot kernel if kabi check failed
---
hotpatch/hotupgrade.py | 19 ++++++++-----
hotpatch/upgrade_en.py | 61 ++++++++++++++++++++++++++++++++++++++++++
2 files changed, 73 insertions(+), 7 deletions(-)
diff --git a/hotpatch/hotupgrade.py b/hotpatch/hotupgrade.py
index 37497cf..4e1ea96 100644
--- a/hotpatch/hotupgrade.py
+++ b/hotpatch/hotupgrade.py
@@ -43,6 +43,7 @@ class HotupgradeCommand(dnf.cli.Command):
is_need_accept_kernel_hp = False
is_kernel_coldpatch_installed = False
kernel_coldpatch = ''
+ previous_boot_kernel = None
@staticmethod
def set_argparser(parser):
@@ -80,6 +81,9 @@ class HotupgradeCommand(dnf.cli.Command):
commands._checkEnabledRepo(self.base)
def run(self):
+ self.upgrade_en = UpgradeEnhanceCommand(self.cli)
+ self.previous_boot_kernel = self.upgrade_en.get_default_boot_kernel()
+
if self.opts.pkg_specs:
self.hp_list = self.opts.pkg_specs
elif self.opts.cves or self.opts.advisory:
@@ -181,20 +185,21 @@ class HotupgradeCommand(dnf.cli.Command):
Returns:
bool: if hotupgrade task success
"""
- upgrade_en = UpgradeEnhanceCommand(self.cli)
-
is_task_success = True
if self.is_kernel_coldpatch_installed:
if not is_all_kernel_hp_actived:
logger.info(_('Gonna remove %s due to some kernel hotpatch activation failed.'), self.kernel_coldpatch)
- upgrade_en.remove_rpm(str(self.kernel_coldpatch))
+ self.upgrade_en.rebuild_rpm_db()
+ self.upgrade_en.remove_rpm(str(self.kernel_coldpatch))
+ self.upgrade_en.restore_default_boot_kernel(self.previous_boot_kernel)
self.is_need_accept_kernel_hp = False
# process kabi check
- elif not upgrade_en.kabi_check(str(self.kernel_coldpatch)) and not self.opts.force:
+ elif not self.upgrade_en.kabi_check(str(self.kernel_coldpatch)) and not self.opts.force:
logger.info(_('Gonna remove %s due to Kabi check failed.'), self.kernel_coldpatch)
# rebuild rpm database for processing kernel rpm remove operation
- upgrade_en.rebuild_rpm_db()
- upgrade_en.remove_rpm(str(self.kernel_coldpatch))
+ self.upgrade_en.rebuild_rpm_db()
+ self.upgrade_en.remove_rpm(str(self.kernel_coldpatch))
+ self.upgrade_en.restore_default_boot_kernel(self.previous_boot_kernel)
self.is_need_accept_kernel_hp = True
if target_remove_hp:
@@ -203,7 +208,7 @@ class HotupgradeCommand(dnf.cli.Command):
# it indicates that the hotupgrade task failed
is_task_success &= False
for hotpatch in target_remove_hp:
- upgrade_en.remove_rpm(hotpatch)
+ self.upgrade_en.remove_rpm(hotpatch)
return is_task_success
def _apply_hp(self, hp_full_name):
diff --git a/hotpatch/upgrade_en.py b/hotpatch/upgrade_en.py
index 94ba4da..0bd78cc 100644
--- a/hotpatch/upgrade_en.py
+++ b/hotpatch/upgrade_en.py
@@ -12,6 +12,7 @@
# ******************************************************************************/
import gzip
import subprocess
+from typing import Optional
import dnf
from dnf.cli import commands
@@ -36,6 +37,7 @@ def cmd_output(cmd):
@dnf.plugin.register_command
class UpgradeEnhanceCommand(dnf.cli.Command):
SYMVERS_FILE = "/boot/symvers-%s.gz"
+ previous_boot_kernel = None
aliases = ['upgrade-en']
summary = _(
@@ -80,8 +82,65 @@ class UpgradeEnhanceCommand(dnf.cli.Command):
self.skipped_grp_specs = None
def run(self):
+ # if kernel kabi check failed, need change back to the default boot kernel version
+ self.previous_boot_kernel = self.get_default_boot_kernel()
self.upgrade()
+ @staticmethod
+ def get_default_boot_kernel() -> Optional[str]:
+ """
+ Get default boot kernel version.
+
+ Returns:
+ str: default boot kernel
+ """
+ cmd = ["grubby", "--default-kernel"]
+ # 'grubby --default-kernel' shows boot default kernel version in the system
+ # e.g.
+ # [root@openEuler ~]# grubby --default-kernel
+ # /boot/vmlinuz-4.19.90-2112.8.0.0131.oe1.x86_64
+ output, return_code = cmd_output(cmd)
+ default_boot_kernel = output.split('\n')[0]
+ if return_code != SUCCEED:
+ return None
+ return default_boot_kernel
+
+ @staticmethod
+ def restore_default_boot_kernel(target_boot_kernel: str):
+ """
+ Restore default boot kernel version.
+
+ Args:
+ target_boot_kernel(str): target boot kernel
+ """
+ # 'grubby --set-default=/boot/vmlinuz-4.19.90-2112.8.0.0131.oe1.x86_64' can set default boot kernel version
+ # to kernel-4.19.90-2112.8.0.0131.oe1.x86_64
+ if not target_boot_kernel:
+ print("Get default boot kernel before upgrade failed.")
+ return
+
+ cmd = ["grubby", "--set-default=%s" % target_boot_kernel]
+ try:
+ # e.g. 4.19.90-2112.8.0.0131.oe1.x86_64
+ target_boot_kernel_vere = target_boot_kernel.split('-', 1)[1]
+ target_boot_kernel_nevra = "kernel-%s" % target_boot_kernel_vere
+ except IndexError as e:
+ print(
+ "Parse target boot kernel failed. Please check if target boot kernel path is correct: %s."
+ % target_boot_kernel,
+ "\nRestore the default boot kernel failed. Please manually check the default boot kernel to prevent unexpected kernel switching after reboot.",
+ )
+ return
+
+ output, return_code = cmd_output(cmd)
+ if return_code != SUCCEED:
+ print(
+ "Restore the default boot kernel failed: %s. Please manually check the default boot kernel to prevent unexpected kernel switching after reboot."
+ % target_boot_kernel_nevra
+ )
+ return
+ print("Restore the default boot kernel succeed: %s." % target_boot_kernel_nevra)
+
def run_transaction(self):
"""
Process kabi check for kernel rpm package installed this time. If the kernel rpm pakcgae fails kabi check,
@@ -100,6 +159,8 @@ class UpgradeEnhanceCommand(dnf.cli.Command):
# when processing remove operation, do not achieve the expected result of installing related rpm,
# it indicates that the upgrade task failed
self.remove_rpm(kernel_pkg)
+ # change back to the default boot kernel version before upgrade
+ self.restore_default_boot_kernel(self.previous_boot_kernel)
exit(1)
def remove_rpm(self, pkg: str):
--
2.27.0