Merge pull request #1367 from linux-surface/kernel-watchdog-v3
Another kernel-watchdog update for btrfs
This commit is contained in:
commit
3187d8c8db
87
pkg/fedora/kernel-surface/files/linux-surface-default-watchdog.py
Executable file
87
pkg/fedora/kernel-surface/files/linux-surface-default-watchdog.py
Executable file
|
@ -0,0 +1,87 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
|
||||||
|
def grub2_editenv(*args: Any, **kwargs: Any) -> str:
|
||||||
|
subprocess.run(["grub2-editenv", *args], check=True, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> int:
|
||||||
|
boot: Path = Path("/boot")
|
||||||
|
mid: Path = Path("/etc/machine-id")
|
||||||
|
|
||||||
|
if not boot.exists():
|
||||||
|
print("ERROR: /boot directory does not exist")
|
||||||
|
return 1
|
||||||
|
|
||||||
|
if not mid.exists():
|
||||||
|
print("ERROR: /etc/machine-id does not exist")
|
||||||
|
return 1
|
||||||
|
|
||||||
|
blsdir: Path = boot / "loader" / "entries"
|
||||||
|
|
||||||
|
if not blsdir.exists():
|
||||||
|
print("ERROR: /boot/loader/entries does not exist")
|
||||||
|
return 1
|
||||||
|
|
||||||
|
try:
|
||||||
|
grub2_editenv("--help", capture_output=True)
|
||||||
|
except:
|
||||||
|
print("ERROR: grub2-editenv is not working")
|
||||||
|
return 1
|
||||||
|
|
||||||
|
# Get list of surface kernels sorted by timestamp.
|
||||||
|
#
|
||||||
|
# We use creation time here because it represents when the kernel was installed.
|
||||||
|
# Modification time can be a bit wonky and seems to correspond to the build date.
|
||||||
|
kernels: list[Path] = sorted(
|
||||||
|
boot.glob("vmlinuz-*.surface.*"),
|
||||||
|
key=lambda x: x.stat().st_ctime,
|
||||||
|
reverse=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
if len(kernels) == 0:
|
||||||
|
print("ERROR: Failed to find a surface kernel")
|
||||||
|
return 1
|
||||||
|
|
||||||
|
# The saved_entry property from grubenv determines what kernel is booted by default.
|
||||||
|
# Its value is the filename of the BLS entry in /boot/loader/entries minus the file extension.
|
||||||
|
#
|
||||||
|
# The BLS files are named using a combination of the machine ID and the version string
|
||||||
|
# of the kernel that is being booted. Since we have the vmlinux, we can get the version
|
||||||
|
# from its name, and the machine ID from /etc/machine-id.
|
||||||
|
#
|
||||||
|
# This allows setting the default kernel without calling grubby or having to figure out
|
||||||
|
# which path GRUB will use to boot the kernel.
|
||||||
|
|
||||||
|
kernel: Path = kernels[0]
|
||||||
|
|
||||||
|
machineid: str = mid.read_text().strip()
|
||||||
|
version: str = kernel.name.lstrip("vmlinuz-")
|
||||||
|
|
||||||
|
blscfg: Path = blsdir / "{}-{}.conf".format(machineid, version)
|
||||||
|
|
||||||
|
# Make sure the config really exists
|
||||||
|
if not blscfg.exists():
|
||||||
|
print("ERROR: {} does not exist".format(blscfg))
|
||||||
|
return 1
|
||||||
|
|
||||||
|
print("Kernel: {}".format(kernel))
|
||||||
|
print("BLS entry: {}".format(blscfg))
|
||||||
|
|
||||||
|
grub2_editenv("-", "set", "saved_entry={}".format(blscfg.stem))
|
||||||
|
|
||||||
|
# Update timestamp for rEFInd and ensure it is marked as latest across all kernels
|
||||||
|
kernel.touch(exist_ok=True)
|
||||||
|
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
sys.exit(main())
|
|
@ -3,4 +3,4 @@ Description=linux-surface default kernel watchdog
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
Type=oneshot
|
Type=oneshot
|
||||||
ExecStart=/usr/bin/linux-surface-default-watchdog.sh
|
ExecStart=/usr/bin/linux-surface-default-watchdog.py
|
||||||
|
|
|
@ -1,23 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
set -euo pipefail
|
|
||||||
|
|
||||||
# Get list of surface kernels with timestamp
|
|
||||||
KERNELS="$(
|
|
||||||
find /boot -maxdepth 1 -name 'vmlinuz-*.surface.*' -print0 | xargs -0 -I '{}' \
|
|
||||||
stat -c "%W %n" {}
|
|
||||||
)"
|
|
||||||
|
|
||||||
# Sort by timestamp
|
|
||||||
KERNELS="$(echo "${KERNELS}" | sort -n)"
|
|
||||||
|
|
||||||
# Get latest kernel (last line) and extract the path
|
|
||||||
VMLINUX="$(echo "${KERNELS}" | tail -n1 | cut -d' ' -f2)"
|
|
||||||
|
|
||||||
echo "${VMLINUX}"
|
|
||||||
|
|
||||||
# update GRUB config
|
|
||||||
grubby --set-default "$(grub2-mkrelpath "${VMLINUX}")"
|
|
||||||
|
|
||||||
# Update timestamp for rEFInd
|
|
||||||
# Ensure it's marked as latest across all kernels, not just surface ones
|
|
||||||
touch "${VMLINUX}"
|
|
|
@ -19,7 +19,7 @@ index 43dce82a9d36..28df94e561d4 100644
|
||||||
|
|
||||||
+Source4100: linux-surface-default-watchdog.path
|
+Source4100: linux-surface-default-watchdog.path
|
||||||
+Source4101: linux-surface-default-watchdog.service
|
+Source4101: linux-surface-default-watchdog.service
|
||||||
+Source4102: linux-surface-default-watchdog.sh
|
+Source4102: linux-surface-default-watchdog.py
|
||||||
+Source4103: 90-linux-surface-default-watchdog.preset
|
+Source4103: 90-linux-surface-default-watchdog.preset
|
||||||
+
|
+
|
||||||
## Patches needed for building this package
|
## Patches needed for building this package
|
||||||
|
@ -81,7 +81,7 @@ index 43dce82a9d36..28df94e561d4 100644
|
||||||
%endif
|
%endif
|
||||||
|
|
||||||
+%files default-watchdog
|
+%files default-watchdog
|
||||||
+%{_bindir}/linux-surface-default-watchdog.sh
|
+%{_bindir}/linux-surface-default-watchdog.py
|
||||||
+%{_unitdir}/linux-surface-default-watchdog.path
|
+%{_unitdir}/linux-surface-default-watchdog.path
|
||||||
+%{_unitdir}/linux-surface-default-watchdog.service
|
+%{_unitdir}/linux-surface-default-watchdog.service
|
||||||
+%{_presetdir}/90-linux-surface-default-watchdog.preset
|
+%{_presetdir}/90-linux-surface-default-watchdog.preset
|
||||||
|
|
Loading…
Reference in a new issue