Hibernacja używa systemctl
i uruchamia go w trudnych przypadkach
Dla mnie pm-hibernate
zawsze zawodzi. Po kilku poprawkach mogłem hibernować za pomocą interfejsu systemd (system init w wersji 16.04 i nowszej). Udało mi się również uruchomić go 17.04 z plikiem wymiany. To studium przypadku może być przydatne dla osób z problemami.
Pierwsza próba:
sudo systemctl hibernate
Jeśli to się nie powiedzie, rozpocznij rozwiązywanie problemów: w stanie hibernacji (HTD lub ACPI S4) stan komputera jest zapisywany na dysku, więc nie jest potrzebne zasilanie, aby go zachować. Stan jest zapisywany na partycji wymiany lub w pliku wymiany. Uwaga: jeśli używasz BTRFS, NIE próbuj używać pliku wymiany, ponieważ może to spowodować uszkodzenie systemu plików
Partycja wymiany lub plik wymiany mogą wymagać tego samego rozmiaru co pamięć RAM, aby umożliwić hibernację, ale istnieje duża szansa, że będziesz w stanie hibernacji, jeśli jest co najmniej 2/5 wielkości pamięci RAM, zgodnie ze stroną wiki Arch , więc najpierw spróbuj wykonać inne kroki, zanim zwiększysz rozmiar wymiany.
Jeśli problem polega na tym, że zamiast czystego wznowienia otrzymujesz czysty rozruch, najprawdopodobniej musisz ustawić parametr rozruchowy, aby znaleźć obraz dysku
Znajdź partycję wymiany:
grep swap /etc/fstab
dla mnie to zwraca (częściowe wyjście)
# swap was on /dev/mmcblk0p3 during installation
gdzie /dev/mmcblk0p3
jest określona partycja
Dodaj parametr rozruchowy:
sudoedit /etc/default/grub
Do wiersza zaczynającego się GRUB_CMDLINE_LINUX_DEFAULT
dodaj resume=/dev/YourSwapPartition
do sekcji w cudzysłowie (zamień na partycję, którą zidentyfikowałeś wcześniej). Korzystając z mojego przykładu:
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash resume=/dev/mmcblk0p3"
Za każdym razem, gdy zmienisz ten plik, musisz uruchomić sudo update-grub
lub zmiany nie przyniosą efektu.
Teraz musisz zrestartować komputer. Następnie możesz spróbować hibernacji, wydając polecenie:
sudo systemctl hibernate
Aby wznowić, naciśnij przycisk zasilania, a system uruchomi się.
Jeśli nadal masz problemy, rozpocznij debugowanie.
Podaję mój przypadek poniżej jako przykład, ale szczegółowe informacje na temat debugowania stanów S można znaleźć na tym blogu, a także na tym blogu .
Ustaw więcej parametrów rozruchowych, aby przechwytywać więcej informacji. Usunąć quiet
i splash
dodać initcall_debug
i no_console_suspend
co spowoduje nazywa system init mają być drukowane na konsoli, dzięki czemu można obserwować, co się dzieje źle. Ustawiam to:
GRUB_CMDLINE_LINUX_DEFAULT="resume=/dev/mmcblk0p3 no_console_suspend initcall_debug"
Co pomogło mi zobaczyć, co poszło nie tak po wznowieniu hibernacji.
W moim przypadku po wznowieniu straciłem Wi-Fi, a jądro było wyraźnie zdenerwowane, ponieważ większość poleceń (na przykład odczytywanie czegokolwiek /sys
, przeładowywanie modułów lub dowolne systemctl
polecenie) nie działała - proces wydawałby się rozpocząć i po prostu zawiesić (wszystko to byłoby oczywiście powrócił do normy po ponownym uruchomieniu). Obserwując, jak system powoli się zamyka i czyta wszystkie komunikaty debugowania, zauważyłem, że było wiele problemów z „brcm”, więc zgadłem, że mój moduł bezprzewodowy sterownika Broadcom był winny. Oczywiście dostosowałem procedurę hibernacji, aby najpierw rozładować moduł:
sudo modprobe -r brcmfmac
sudo systemctl hibernate
po wznowieniu wkładam ponownie moduł
sudo modprobe brcmfmac
I wszystko działało idealnie. Muszę również btsdio
umieścić na czarnej liście moduł, który wydaje się być niezgodnybrcmfmac
Aktualizacja: Hibernacja przy użyciu pliku wymiany 17.04.
Po raz kolejny z pomocą strony Arch Arch i dodatkowego majsterkowania udało mi się uzyskać hibernację do pracy 17.04 z plikiem wymiany. Wymagało to dodatkowego parametru rozruchowego, resume_offset=n
gdzie n jest pierwszą liczbą poniżej physical_offset
w wyniku sudo filefrag -v /swapfile
:
$ sudo filefrag -v /swapfile
Filesystem type is: ef53
File size of /swapfile is 1425873920 (348114 blocks of 4096 bytes)
ext: logical_offset: physical_offset: length: expected: flags:
0: 0.. 32767: 34816.. 67583: 32768:
1: 32768.. 63487: 67584.. 98303: 30720:
....
Dlatego dodatkowym parametrem rozruchowym w moim przypadku jest resume_offset=34816
. Nadal musisz ustawić parametr rozruchowy, aby partycja mogła wznowić. Będzie to partycja główna (lub dowolna inna, na której znajduje się plik wymiany). Moje parametry to teraz:
GRUB_CMDLINE_LINUX_DEFAULT="no_console_suspend initcall_debug resume=/dev/mmcblk1p2 resume_offset=34816"
Gdzie /dev/mmcblk1p2
jest moja partycja root (twoja jest bardziej podobna /dev/sda2
).
Podczas wznawiania zobaczyłem, że obraz ładuje się pomyślnie, ale w moim przypadku (tylko przykład - YMMVAPD) potem kilka innych sterowników ( i2c_designware
) rzuciło kilka błędów i po wznowieniu całkowicie zawiesiłem system. Hibernacja działa, jeśli dodatkowo zwolnię te moduły brcmfmac
, ale system szybko stanie się bezużyteczny bez tych modułów. Dlatego stworzyłem coś w rodzaju skryptu, aby zwolnić błędne moduły i natychmiast włożyć je ponownie po wznowieniu:
# remove buggy modules
modprobe -r brcmfmac i2c_designware_platform i2c_designware_core &&
# hibernate
echo disk > /sys/power/state
# reinsert
modprobe i2c_designware_core i2c_designware_platform brcmfmac
Kiedy chcę hibernować, biegnę sudo bash script
. To działa świetnie.
TL; DR
Użyj systemd, ustaw parametr rozruchu, aby wznowić od wymiany, zidentyfikuj błędne sterowniki i zwolnij je przed zainicjowaniem hibernacji. Jeśli system nie może długo działać bez tych modułów lub trzeba rozładować kilka, może być łatwiej użyć prostego skryptu, aby zainicjować hibernację.