systemctl hibernate, WARNING: no kernelfile matching the running kernel found - Workaround
Im Gegensatz zum letzten Beitrag bin ich mir hier nicht wirklich sicher, ob es sich um einen Bug oder eher um einen "corner case" handelt.
Ich verwende auf meiner 13.1 immer noch Grub in der Version 0.97 (grub-legacy), der Standardbootloader ist aber schon seit längerem Grub2, vielleicht hat es damit zu tun.
Beim Versuch mein System mittels
in den Ruhezustand (suspend to DISK) zu versetzen, gab es eine Meldung, dass dies aufgrund fehlender Abhängigkeiten nicht möglich wäre.
Ein Blick in den zuständigen Dienst, genauer die Datei
/usr/lib/systemd/system/systemd-hibernate.service zeigt Folgendes:
Code:
# This file is part of systemd.
#
# systemd is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
[Unit]
Description=Hibernate
Documentation=man:systemd-suspend.service(8)
DefaultDependencies=no
Requires=sleep.target
After=sleep.target
ConditionKernelCommandLine=resume
[Service]
Type=oneshot
ExecStart=/usr/bin/systemd-sleep-grub pre
ExecStart=/usr/lib/systemd/systemd-sleep hibernate
ExecStopPost=/usr/bin/systemd-sleep-grub post
Beim Aufruf von "
journalctl -xn" wurde der Befehl "
/usr/bin/systemd-sleep-grub pre" als Ursache der fehlenden Abhängigkeit genannt.
Abhängigkeit bedeutet hier "schlägt Befehl x fehl, dann wird Befehl x+1 nicht mehr ausgeführt, da der Erfolg des gesamten Dienstes nicht mehr gewährleistet ist".
Händisches Ausführen ergab
Code:
/usr/bin/systemd-sleep-grub pre
INFO: running prepare-grub
WARNING: no kernelfile matching the running kernel found
running kernel: '4.1.15-8-pae', probably booting kernel: '4.4.1-1.g283b562-pae'
Zunächst mal handelt es sich nur um eine Warnung und ja, beide Kernel sind bei mir installiert, es wird aber nur der neuste gefunden.
Witzigerweise erhielt ich diese Warnmeldung auch nach einem Reboot mit dem neusten installierten Kernel
Code:
/usr/bin/systemd-sleep-grub pre
INFO: running prepare-grub
WARNING: no kernelfile matching the running kernel found
running kernel: '4.4.1-1.g283b562-pae', probably booting kernel: '4.4.1-1.g283b562-pae'
was hier nicht eines gewissen Humors entbehrt und zur Krönung des Ganzen wurde hier zwar diese Meldung ausgespuckt, die Kiste legte sich aber ohne Probleme schlafen und wachte auch wieder auf.
//Nachtrag
Es gibt doch einen Unterschied in den ausgegebenen Meldungen beim Ausführen von
"/usr/bin/systemd-sleep-grub pre", den ich wohl bei meinem ersten Test übersehen habe.
1) Kernel 4.4.1 (=neuster der installierten Kernel)
Code:
/usr/bin/systemd-sleep-grub pre ; echo $?
INFO: running prepare-grub
WARNING: no kernelfile matching the running kernel found
running kernel: '4.4.1-1.g283b562-pae', probably booting kernel: '4.4.1-1.g283b562-pae'
0
Die Warnung ist wirklich nur eine Warnung, der Rückgabewert ist 0 (=erfolgreich).
2) Kernel 4.1.15 (=nicht der neuste der installierten Kernel)
Code:
/usr/bin/systemd-sleep-grub pre ; echo $?
INFO: running prepare-grub
WARNING: no kernelfile matching the running kernel found
running kernel: '4.1.15-8-pae', probably booting kernel: '4.4.1-1.g283b562-pae'
ERROR: kernel version mismatch, cannot suspend to disk
7
Die Warnung ist immer noch nur eine Warnung, aber danach kommt eine Fehlermeldung und der Rückgabewert ist damit logischerweise ungleich 0 (=fehlgeschlagen), weshalb die weitere Ausführung abgebrochen wird.
Das erklärt dann auch das unterschiedliche Verhalten je nach Kernelversion und warum mein Workaround (Glückstreffer!) die richtige Idee war.
//Nachtrag Ende
Die Vermutung lag nahe, daß die Zeile "
/usr/bin/systemd-sleep-grub pre" für den eigentlichen Vorgang des s2disk nicht zwingend notwendig ist, vermutlich hat sie eine ähnliche Funktion wie der Befehl "
grubonce" bei Grub-legacy und wählt den laufenden Kernel aus, damit dieser beim Aufwachen automatisch und ohne Auswahlmenü gebootet wird, was bei s2disk Sinn macht, da man beim Aufwecken unbedingt den selben Kernel starten sollte, mit welchem das System auch schlafen gelegt wurde.
Da beim Aufwecken, nachdem das System mit dem neusten der installierten Kernel schlafen gelegt wurde, auch dieser Kernel automatisch ausgewählt und das System damit gestartet wurde, war es zumindest nicht ausgeschlossen, dass diese "fehlgeschlagene" Zeile keine wirklich negative Auswirkung hat.
Der Workaround für dieses Problem ist denkbar einfach und mit ein wenig "systemd-Magie" verbunden.
Als root kopiert man "
/usr/lib/systemd/system/systemd-hibernate.service" nach "
/etc/systemd/system/sytemd-hibernate.service" und ändert die problematische Zeile minimal ab:
Code:
ExecStart=-/usr/bin/systemd-sleep-grub pre
Das vorangestellte "-" bedeutet sinngemäß "führe den Befehl aus, aber selbst wenn dieser Befehl fehlschlägt, geht es trotzdem weiter" und genau das will ich hier ja haben.
Nun die Kiste mit dem älteren Kernel (4.1.15) gestartet und siehe da, ein "
systemctl hibernate" läuft ohne Probleme durch, beim Aufwecken wird automatisch dieser Kernel ausgewählt und gestartet, also alles wie gehabt und erwünscht.
Wie gesagt, ob ich hier nur aufgrund meines etwas ungewöhnlichen Setups einen corner case erwischt habe, oder ob es sich wirklich um einen Bug handelt, ich weiß es nicht, aber sollte das Problem bei der Benutzung von Grub2 nicht mehr auftreten (ich werde das jetzt auf Grund meines an weiteren Stellen sehr "speziellen Setups" nicht testen), dann dürfte das wohl so sein.
//Nachtrag2 (11.02.2016):
Nach einem genaueren Blick in "
/usr/bin/systemd-sleep-grub" (=bash script), sieht die Sache etwas klarer aus.
Das Script kümmert sich hauptsächlich um eine genauere Erkennung des laufenden Kernels, sofern GRUB2 als Bootloader verwendet wird, für andere (Grub-legacy, lilo, etc.) gibt es nur eine recht rudimentäre Unterstützung:
Code:
#############################################################################
# if we did not find a kernel (or BOOT_LOADER is not GRUB) check,
# if the running kernel is still the one that will (probably) be booted for
# resume (default entry in menu.lst or, if there is none, the kernel file
# /boot/vmlinuz points to.)
Tja, und da bei mir sowohl der default-Eintrag in der menu.lst als auch der symlink /boot/vmlinuz auf den gerade aktuellen Kernel 4.4.1 verweisen, klappt es mit diesem ohne Probleme, während es bei Verwendung eines anderen Kernels (übrigens der aus openSUSE 42.1) zu dieser "mismatch"-Meldung kommt und die Sache schief geht.
Dann findet man noch das hier
Code:
###### main()
if [ "$1" = pre ] ; then
prepare-grub || exit 7
fi
if [ "$1" = post ] ; then
grub-once-restore
fi
was den exit-Status 7 bei Fehlschlag erklärt.
In sofern, "Pech gehabt RM, klassischer corner case, damit musste leben mein Junge..." (und der Workaround ist ja nicht wirklich kompliziert).
Greetz,
RM