Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
livepatching: add package for livepatches management (#3687)
- Loading branch information
Showing
7 changed files
with
236 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2015,6 +2015,7 @@ | |
"libsafec", | ||
"libuv", | ||
"libxml++", | ||
"livepatching", | ||
"lld", | ||
"lsb-release", | ||
"lttng-consume", | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
[Unit] | ||
Description=Subscribe to kernel livepatches across kernel updates | ||
Before=kpatch.service | ||
|
||
[Service] | ||
Type=notify | ||
NotifyAccess=main | ||
ExecStart=/lib/livepatching/livepatching.systemd | ||
|
||
[Install] | ||
WantedBy=multi-user.target |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
{ | ||
"Signatures": { | ||
"livepatching.service": "7c1a827df2dfdefb795fab2c1417bc6145604c151b32d9d5987e458427ac1b0b", | ||
"livepatching.systemd": "b248eeb126ce212843d75b01a16bd63157bee8e1ca1ac4f86de6573561a5e069" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
%define livepatching_lib_path %{_libdir}/livepatching | ||
|
||
Summary: Set of core livepatching packages for Mariner. | ||
Name: livepatching | ||
Version: 1.0.0 | ||
Release: 1%{?dist} | ||
License: MIT | ||
Vendor: Microsoft Corporation | ||
Distribution: Mariner | ||
Group: Applications/Text | ||
URL: https://aka.ms/cbl-mariner | ||
Source0: livepatching.service | ||
Source1: livepatching.systemd | ||
|
||
BuildArch: noarch | ||
|
||
BuildRequires: systemd | ||
|
||
%description | ||
%{summary} | ||
|
||
%package filesystem | ||
Summary: Basic directory layout for livepatching packages. | ||
|
||
%description filesystem | ||
%{summary} | ||
|
||
%package subscription | ||
Summary: Retain livepatches across kernel upgrades. | ||
|
||
Requires: %{name}-filesystem = %{version}-%{release} | ||
Requires: coreutils | ||
Requires: grep | ||
Requires: inotify-tools | ||
Requires: kpatch | ||
Requires: systemd | ||
Requires: tdnf | ||
|
||
Requires(post): grep | ||
Requires(post): inotify-tools | ||
Requires(post): kpatch | ||
Requires(post): systemd | ||
Requires(post): tdnf | ||
|
||
Requires(postun): systemd | ||
|
||
Requires(preun): systemd | ||
|
||
%description subscription | ||
This package allows your system to retain livepatches across kernel upgrades. | ||
Once a livepatch for the new kernel is installed, it does NOT automatically | ||
pull newer versions of the livepatch for that kernel. | ||
|
||
%prep | ||
|
||
%install | ||
install -vdm755 %{buildroot}%{_libdir}/systemd/system-preset | ||
echo "enable livepatching.service" > %{buildroot}%{_libdir}/systemd/system-preset/50-livepatching.preset | ||
|
||
install -vdm755 %{buildroot}%{_unitdir} | ||
install -D -m 644 %{SOURCE0} %{buildroot}%{_unitdir}/livepatching.service | ||
|
||
install -vdm755 %{buildroot}%{livepatching_lib_path} | ||
install -D -m 744 %{SOURCE1} %{buildroot}%{livepatching_lib_path}/livepatching.systemd | ||
|
||
%post subscription | ||
%systemd_post livepatching.service | ||
# Only start on initial installation. Upgrade restarts handled by %%postun. | ||
if [ $1 -eq 1 ] | ||
then | ||
systemctl start livepatching.service >/dev/null 2>&1 || : | ||
fi | ||
|
||
%preun subscription | ||
%systemd_preun livepatching.service | ||
|
||
%postun subscription | ||
%systemd_postun_with_restart livepatching.service | ||
systemctl try-restart livepatching.service >/dev/null 2>&1 || : | ||
|
||
%files filesystem | ||
%defattr(-,root,root) | ||
%dir %{livepatching_lib_path} | ||
|
||
%files subscription | ||
%defattr(-,root,root) | ||
%{_libdir}/systemd/system-preset/50-livepatching.preset | ||
%{_unitdir}/livepatching.service | ||
%{livepatching_lib_path}/livepatching.systemd | ||
|
||
%changelog | ||
* Fri Sep 02 2022 Pawel Winogrodzki <pawelwi@microsoft.com> - 1.0.0-1 | ||
- Original version for CBL-Mariner. | ||
- License verified. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
#!/bin/bash | ||
# Copyright (c) Microsoft Corporation. | ||
# Licensed under the MIT License. | ||
|
||
install_patch_after_kernel_change() { | ||
local installable_patch="livepatch-$RUNNING_KERNEL_VERSION" | ||
local patch_module_name | ||
local patch_module_path | ||
|
||
echo "Making sure patch is installed after a kernel reboot." | ||
|
||
if [[ "$RUNNING_KERNEL_VERSION" != "$INSTALLED_KERNEL_VERSION" ]] | ||
then | ||
echo "Running kernel ($RUNNING_KERNEL_VERSION) different than installed kernel ($INSTALLED_KERNEL_VERSION). Nothing to do." | ||
return 0 | ||
fi | ||
|
||
if ! rpm --quiet -q --whatprovides "$installable_patch" | ||
then | ||
echo "No livepatch package installed for running kernel ($RUNNING_KERNEL_VERSION)." | ||
return 0 | ||
fi | ||
|
||
patch_module_path=$(rpm -ql --whatprovides "$installable_patch" | grep "ko$") | ||
if [[ ! -f "$patch_module_path" ]] | ||
then | ||
echo "Initial (empty) livepatch installed for kernel ($RUNNING_KERNEL_VERSION) - no livepatch module to install." | ||
return 0 | ||
fi | ||
|
||
patch_module_name=$(basename "$patch_module_path" | cut -d. -f1) | ||
if patch_installed "$patch_module_name" | ||
then | ||
echo "Patch already installed for the running kernel ($RUNNING_KERNEL_VERSION)." | ||
return 0 | ||
fi | ||
|
||
kpatch install "$patch_module_path" | ||
} | ||
|
||
install_livepatch_package() { | ||
local kernel_version | ||
local patch_package | ||
|
||
kernel_version="$1" | ||
patch_package="livepatch = $kernel_version" | ||
|
||
echo "Checking if a livepatch is available for kernel version ($kernel_version)." | ||
if ! tdnf -q list available "$patch_package" >/dev/null | ||
then | ||
echo "No livepatches available for kernel version ($kernel_version)." | ||
return 0 | ||
fi | ||
|
||
echo "Livepatch available for kernel version ($kernel_version). Checking if it's already installed." | ||
if tdnf -q list installed "$patch_package" >/dev/null | ||
then | ||
echo "Livepatch for kernel version ($kernel_version) already installed." | ||
else | ||
echo "Installing livepatch for kernel version ($kernel_version)." | ||
|
||
tdnf -q install -y "$patch_package" >/dev/null | ||
fi | ||
} | ||
|
||
patch_installed() { | ||
kpatch list | grep -qP "$1.*$RUNNING_KERNEL_VERSION" | ||
} | ||
|
||
read_installed_kernel_version() { | ||
realpath /boot/mariner.cfg | grep -oP "(?<=linux-).*(?=\.cfg)" | ||
} | ||
|
||
read_running_kernel_version() { | ||
uname -r | ||
} | ||
|
||
wait_for_kernel_change() { | ||
local new_kernel_version | ||
|
||
echo "Waiting for RPM database changes." | ||
|
||
while inotifywait -e close_write /var/lib/rpm/rpmdb.sqlite &>/dev/null | ||
do | ||
echo "Change detected, checking if different kernel got installed." | ||
|
||
new_kernel_version=$(read_installed_kernel_version) | ||
if [[ "$INSTALLED_KERNEL_VERSION" != "$new_kernel_version" ]] | ||
then | ||
echo "Detected new kernel version ($new_kernel_version)." | ||
|
||
INSTALLED_KERNEL_VERSION=$new_kernel_version | ||
return 0 | ||
fi | ||
|
||
echo "No changes to the kernel. Going back to waiting." | ||
done | ||
} | ||
|
||
RUNNING_KERNEL_VERSION=$(read_running_kernel_version) | ||
INSTALLED_KERNEL_VERSION=$(read_installed_kernel_version) | ||
|
||
echo "Running kernel: $RUNNING_KERNEL_VERSION." | ||
echo "Installed kernel: $INSTALLED_KERNEL_VERSION." | ||
|
||
install_patch_after_kernel_change | ||
|
||
# Letting systemd know the service finished its startup and kpatch can now run. | ||
systemd-notify --ready | ||
|
||
install_livepatch_package "$RUNNING_KERNEL_VERSION" | ||
|
||
if [[ "$RUNNING_KERNEL_VERSION" != "$INSTALLED_KERNEL_VERSION" ]] | ||
then | ||
echo "Kernel will change after reboot ($RUNNING_KERNEL_VERSION -> $INSTALLED_KERNEL_VERSION). Installing patches for post-reboot kernel." | ||
install_livepatch_package "$INSTALLED_KERNEL_VERSION" | ||
fi | ||
|
||
while wait_for_kernel_change | ||
do | ||
install_livepatch_package "$INSTALLED_KERNEL_VERSION" | ||
done |