Power management (Русский)/Suspend and hibernate (Русский)
Существует несколько режимов приостановки работы компьютера, в частности:
- Suspend to idle
- Intel называет его S0ix, Microsoft — Modern Standby (ранее «Connected Standby»), а ядро — S2Idle. Предназначен для использования вместо состояния S3 в поддерживаемых системах, обеспечивая идентичное энергосбережение, но значительно сокращая время пробуждения.
- Suspend to RAM (ждущий режим)
- Состояние S3 по определению ACPI. Отключает питание большинства устройств компьютера, кроме оперативной памяти, которая продолжает хранить в себе состояние компьютера для его восстановления при пробуждении. Из-за большой экономии энергии рекомендуется, чтобы ноутбуки автоматически входили в этот режим при работе от батареи и закрытой крышке (или когда пользователь неактивен в течение некоторого времени).
- Suspend to disk (спящий режим, гибернация)
- Состояние S4 по определению ACPI. Сохраняет состояние машины в подкачку и полностью выключает её. При включении питания состояние восстанавливается. До этого момента энергопотребление равно нулю.
- Hybrid suspend (гибридный спящий режим)
- Гибрид ждущего и спящего режимов, иногда называется suspend to both. Сохраняет состояние машины в подкачку, но не выключает её. Вместо этого выполняется переход в обычный ждущий режим. Поэтому, если батарея не разряжена, система может возобновить работу мгновенно. Если батарея разряжена, система может восстановить своё состояние с диска, что намного медленнее, чем возобновление работы из ОЗУ, но состояние не будет потеряно.
Ядро обеспечивает базовые функции, а некоторые интерфейсы высокого уровня выполняют дополнительные действия для обработки проблемных аппаратных драйверов / модулей ядра (например, повторная инициализация видеокарты).
Низкоуровневый интерфейс (swsusp)
Можно отправить сигнал перехода в сон напрямую во встроенный в ядро программный код (swsusp); точный метод и состояние зависят от уровня аппаратной поддержки. В современных ядрах основным механизмом является запись соответствующих значений в /sys/power/state.
Смотрите документацию ядра для подробностей.
Интерфейс высокого уровня (systemd)
systemd предоставляет собственные команды для ждущего, спящего и гибридного режимов сна. Это интерфейс, используемый в Arch Linux по умолчанию.
Команда systemctl suspend должна работать из коробки. Для systemctl hibernate может понадобиться предварительная настройка, описанная в разделе #Гибернация.
Также есть ещё два режима, комбинирующих ждущий и спящий режимы:
-
systemctl hybrid-sleepсохраняет состояние системы одновременно и в оперативной памяти, и на диске, благодаря чему отключение питания не приводит к потере данных. Этот режим также называют suspend to both. -
systemctl suspend-then-hibernateизначально переводит систему в ждущий режим на максимально возможное время, затем по сигналу от аппаратных часов она просыпается и переходит в гибернацию. Время срабатывания аппаратных часов указывается в настройкеHibernateDelaySecв файле systemd-sleep.conf(5). Значение по умолчанию вычисляется на основе скорости разряда батареи так, чтобы к моменту пробуждения оставалось 5% заряда; если батареи нет, то значение по умолчанию 2 часа. Вычисление производится на основе измерения уровня заряда батареи после времени, указанного в настройкеSuspendEstimationSecв systemd-sleep.conf(5): после истечения указанного времени система ненадолго проснётся для выполнения измерения (измерение также производится при пробуждении пользователем).
systemctl sleep. По умолчанию она пытается использовать suspend-then-hibernate, в случае отсутствия его поддержки пробует suspend, а если не поддерживается и он, то hibernate. Смотрите systemctl(1) для более подробной информации.Смотрите раздел #Хуки сна для получения дополнительной информации о настройке хуков, связанных с режимами сна. Также смотрите systemctl(1), systemd-sleep(8) и systemd.special(7).
Изменение режима сна
В системах, где режим S0ix не обеспечивает такой же экономии энергии, как обычный ждущий режим S3, или когда экономия энергии предпочтительнее быстрого возобновления работы, возможно изменение режима сна, используемого по умолчанию.
Выполните следующую команду, чтобы увидеть все режимы, о поддержке которых заявляет оборудование (текущий режим показан в квадратных скобках[1]):
$ cat /sys/power/mem_sleep
[s2idle] shallow deep
| Строка в mem_sleep | Режим сна |
|---|---|
| s2idle | suspend-to-idle |
| shallow | standby |
| deep | suspend-to-RAM |
Если deep отсутствует, для начала проверьте, нет ли в UEFI каких-нибудь настроек для него, обычно в разделе Power или Sleep state или похожей формулировке, с опциями Windows 10, Windows and Linux или S3/Modern standby support для режима S0ix, и Legacy, Linux, Linux S3 или S3 enabled для режима S3. В противном случае можно продолжать использовать s2idle, рассмотрите возможность использования гибернации (спящего режима) или исправления таблицы DSDT (или поиска исправленной версии в интернете).
Убедитесь, что оборудование не испытывает проблем с режимом S3, протестировав несколько циклов сна после изменения режима:
# echo deep > /sys/power/mem_sleep
Если проблем не обнаружено, можно сделать изменение постоянным с помощью параметра MemorySleepMode в systemd-sleep.conf(5):
/etc/systemd/sleep.conf.d/mem-deep.conf
[Sleep] MemorySleepMode=deep
или с помощью параметра ядра mem_sleep_default=deep.
Иногда сломанная прошивка сообщает о поддержке deep, в то время как реально поддерживается только s2idle. В этом случае альтернативный способ использования s2idle доступен через параметр SuspendState:
/etc/systemd/sleep.conf.d/freeze.conf
[Sleep] SuspendState=freeze
Гибернация
Чтобы использовать спящий режим, вам нужно создать раздел или файл подкачки, настроить initramfs так, чтобы процесс возобновления был инициирован в раннем пользовательском пространстве, и указать местоположение подкачки способом, доступным для initramfs, например, через переменную EFI HibernateLocation, которую создаст systemd, или параметр ядра resume=. Эти три этапа подробно описаны ниже.
- Если вы используете шифрование, смотрите dm-crypt (Русский)/Swap encryption (Русский)#С поддержкой гибернации.
- linux-hardened не поддерживает спящий режим, смотрите FS#63648.
- Подкачка в zram не поддерживается, даже если zram настроен на использование резервного устройства в постоянной памяти. Хотя logind предотвратит попытки перехода в спящий режим с подкачкой на zram, в качестве альтернативы можно создать несколько подкачек. Память будет сохраняться в файл подкачки, а другое доступное пространство подкачки будет зарезервировано для zram. Подробнее в разделе #Использование файла подкачки для гибернации вместе с zram.
Про размер раздела/файла подкачки
Даже если ваш раздел подкачки меньше ОЗУ, всё ещё еще есть большая вероятность успешно перейти в спящий режим. Согласно документации ядра:
-
/sys/power/image_sizeуправляет размером образа, создаваемого механизмом приостановки на диск. Это может быть строка, представляющая неотрицательное целое число, которое будет использоваться в качестве верхнего предела размера образа в байтах. Механизм приостановки сделает всё возможное, чтобы размер образа не превышал это число. Однако, если это окажется невозможным, он всё равно попытается приостановить систему, используя наименьший возможный размер образа. В частности, если в этот файл записать «0», размер образа будет настолько мал, насколько это возможно. Чтение из этого файла отображает текущее ограничение размера образа, которое по умолчанию установлено на 2/5 доступного ОЗУ.
Вы можете либо уменьшить значение /sys/power/image_size, чтобы сделать образ как можно меньшим (для небольших разделов подкачки) или увеличить его, чтобы ускорить процесс гибернации.
На системах с большим объёмом оперативной памяти меньшие значения могут существенно увеличить скорость пробуждения. Чтобы сделать изменение постоянным, можно использовать systemd-tmpfiles:
/etc/tmpfiles.d/hibernation_image_size.conf
# Path Mode UID GID Age Argument w /sys/power/image_size - - - - 0
Создаваемый образ не может охватывать несколько разделов/файлов подкачки. Он должен полностью помещаться в один раздел/файл подкачки.[2]
Настройка initramfs
- Когда используется initramfs с хуком
systemd(по умолчанию это так), механизм возобновления уже есть и дополнительные хуки не нужны.
- Когда используется initramfs основанный на busybox, с хуком
base, в файл/etc/mkinitcpio.confнужно добавить хукresume. Независимо от того, используется ли метка или UUID, раздел подкачки идентифицируется как устройство udev, поэтому хукresumeдолжен идти после хукаudev. Пример, основанный на стандартных параметрах хуков (до включения хука systemd по умолчанию):
HOOKS=(base udev autodetect microcode modconf kms keyboard keymap consolefont block filesystems resume fsck)
- Не забудьте пересобрать образ initramfs чтобы эти изменения вступили в силу.
- Примечание Если доступ к подкачке выполняется через стековые блочные устройства, например, dm-crypt, RAID или LVM, конечное устройство должно быть доступно в раннем пользовательском пространстве и до начала процесса возобновления. То есть в таких установках хук
resumeдолжен располагаться после соответствующих хуков, таких какencrypt,lvm2и т. д.
Передача расположения гибернации в initramfs
Когда система переходит в режим гибернации, содержимое оперативной памяти записывается в подкачку, и в нём также содержится состояние смонтированных файловых систем. Поэтому для возобновления работы из гибернации местоположение записанного содержимого памяти должно быть доступно для initramfs, то есть до монтирования корневой файловой системы.
Если система загружена в режиме UEFI, systemd-sleep(8) автоматически выберет подходящее пространство подкачки для гибернации, и информация об используемом пространстве подкачки сохраняется в переменной EFI HibernateLocation. При следующей загрузке systemd-hibernate-resume(8) считывает расположение из этой переменной, и система возобновляет работу. Это означает, что выполнение описанных далее шагов необходимо только на системах с BIOS или если вы хотите выбрать конкретную подкачку вручную.
Указание расположения гибернации вручную
Можно использовать параметр ядра resume=устройство_подкачки. В качестве устройства можно указать любые постоянные имена для блочных устройств, например:
resume=UUID=4209c845-f495-4c43-8a03-5363dd433153resume="PARTLABEL=Swap partition"-
resume=/dev/archVolumeGroup/archLogicalVolume— если подкачка расположена на логическом томе LVM (UUID и Label тоже должны работать)
resume= должен указывать на конечное/разблокированное устройство, непосредственно содержащее файловую систему с файлом подкачки (также смотрите совет ниже).Параметры ядра вступят в силу только после перезагрузки. Для немедленного перехода в спящий режим получите из lsblk major и minor номера устройства, на котором находится нужный том, и запишите их в формате major:minor в /sys/power/resume.
Например, если устройство подкачки имеет номер 8:3:
# echo 8:3 > /sys/power/resume
Если используется файл подкачки, также выполните шаги, описанные в разделе #Получение смещения файла подкачки.
Получение смещения файла подкачки
Чтобы использовать файл подкачки для гибернации, нужно в параметре ядра resume= указать устройство, содержащее файловую систему, в которой находится этот файл подкачки, а также добавить ещё один параметр resume_offset=, содержащий физическое смещение файла подкачки. [3]
В файловых системах, отличных от Btrfs, значение resume_offset= можно получить, выполнив filefrag -v файл_подкачки. Вывод осуществляется в виде таблицы, а искомое значение находится в первой строке столбца physical_offset.
Например:
# filefrag -v файл_подкачки
Filesystem type is: ef53 File size of файл_подкачки is 4294967296 (1048576 blocks of 4096 bytes) ext: logical_offset: physical_offset: length: expected: flags: 0: 0.. 0: 38912.. 38912: 1: 1: 1.. 22527: 38913.. 61439: 22527: unwritten 2: 22528.. 53247: 899072.. 929791: 30720: 61440: unwritten ...
В данном примере смещение — это 38912 с двумя точками, и параметр ядра может выглядеть так: resume_offset=38912.
Чтобы сразу получить смещение:
# filefrag -v файл_подкачки | awk '$1=="0:" {print substr($4, 1, length($4)-2)}'
Для Btrfs не пытайтесь использовать filefrag, поскольку «физическое» смещение, полученное с помощью filefrag, не является реальным физическим смещением на диске; здесь используется виртуальное адресное пространство ради поддержки нескольких устройств.[4] Вместо этого используйте команду btrfs-inspect-internal(8). Например:
# btrfs inspect-internal map-swapfile -r файл_подкачки
198122980
В данном примере параметр ядра может выглядеть так: resume_offset=198122980.
Чтобы применить изменение сразу (без перезагрузки), запишите это значение в файл /sys/power/resume_offset. Например, если смещение равно 38912:
# echo 38912 > /sys/power/resume_offset
findmnt -no UUID -T файл_подкачки
Изменение алгоритма сжатия образа при гибернации
Начиная с Linux 6.9[5] можно изменить алгоритм сжатия образа памяти, сохраняемого при переходе в спящий режим. Алгоритм, используемый по умолчанию, задаётся параметром CONFIG_HIBERNATION_DEF_COMP во время компиляции ядра, но его можно переопределить во время работы системы.
Различные алгоритмы сжатия имеют разные характеристики и могут улучшить работу спящего режима в определённых ситуациях. Например, алгоритм LZ4 обеспечивает лучшую скорость распаковки по сравнению с алгоритмом по умолчанию (LZO), что в свою очередь сокращает время пробуждения.
Выбрать алгоритм сжатия можно двумя способами:
1) Передав hibernate.compressor в качестве параметра ядра:
hibernate.compressor=lzo hibernate.compressor=lz4
2) Указав алгоритм во время выполнения:
# echo lzo > /sys/module/hibernate/parameters/compressor # echo lz4 > /sys/module/hibernate/parameters/compressor
В настоящее время поддерживаются алгоритмы lzo и lz4, при этом LZO является алгоритмом по умолчанию.
Использование файла подкачки для гибернации вместе с zram
Если для подкачки вы используете zram, но при этом хотите, чтобы работала гибернация, можно подключить два пространства подкачки одновременно — при переходе в спящий режим systemd всегда будет игнорировать блочные устройства zram [6], поэтому поддержание обоих пространств включенными должно работать без дополнительного вмешательства.
После настройки файла подкачки для гибернации следуйте инструкциям в статье zram (Русский). Убедитесь, что подкачка на zram имеет более высокий приоритет (например, pri=100).
- Не создавайте swap-юнит в systemd на лету непосредственно перед переходом в гибернацию, это официально не поддерживается (смотрите systemd issues #16708 и #30083 на GitHub).
- Только ядро отвечает за восстановление анонимных страниц памяти и их подкачку; отсутствие подкачки может привести к нерациональному использованию памяти. Пользователь может управлять приоритетами в задействовании (reclaiming) памяти определённых приложений с помощью параметра
memory.lowв control groups. В целом это более эффективно, чем настройка параметра swappiness. - Смотрите также Swap Management в документации ядра и статью В защиту свопа: распространенные заблуждения.
Гибернация в тонкий том LVM
Гибернация в тонкий том LVM (thinly-provisioned LVM volume) возможна, но необходимо убедиться, что том полностью выделен (fully allocated). В противном случае возобновление работы с него будет неудачным; смотрите FS#50703.
Вы можете полностью выделить том LVM, просто заполнив его нулями. Например:
# dd if=/dev/zero of=/dev/vg0/swap bs=1M status=progress
Для проверки того, что том полностью выделен, можно использовать:
# lvs
LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert swap vg0 Vwi-aot--- 10.00g pool 100
Полностью выделенный том будет отображаться как использующий 100% данных.
discard в /etc/fstab и опцию -d/--discard в swapon. В противном случае используемое пространство будет деаллоцировано.Отключение zswap writeback и использование подкачки только для гибернации
По умолчанию при переполнении пула zswap начинает выгружать страницы памяти в подкачку (writeback), но в Linux 6.8 появилась возможность отключения writeback через cgroup. В юнитах systemd это можно настроить через параметр MemoryZSwapWriteback (документация: systemd.resource-control(5) § Memory Accounting and Control). Можно полностью отключить writeback и предотвратить выгрузку страниц памяти в подкачку, если прописать этот параметр для всех типов юнитов. Таким образом zswap станет работать по сути как zram, но при этом подключенная подкачка позволит использовать гибернацию.
Чтобы не создавать двенадцать drop-in файлов вручную (для общесистемых и пользовательских типов юнитов scope, service, slice, socket, mount, swap), можно установить пакет zswap-disable-writebackAUR, который сделает это сам. Затем включите zswap и перезагрузитесь для применения изменений.
После перезагрузки запустите какую-нибудь нагружающую память задачу и проверьте, что zswap действительно ничего не записывает в подкачку:
# cat /sys/kernel/debug/zswap/written_back_pages
0
Хуки сна
Пользовательские юниты systemd
systemd запускает suspend.target, hibernate.target, hybrid-sleep.target или suspend-then-hibernate.target для каждого режима сна соответственно. Также все они подтягивают sleep.target. Вы можете написать свой файл юнита и связать его с этими target-юнитами, чтобы он запускался перед уходом в сон или после пробуждения из сна. Для общесистемных и пользовательских действий нужно создавать отдельные файлы. Примеры:
/etc/systemd/system/user-suspend@.service
[Unit] Description=User suspend actions Before=sleep.target [Service] User=%I Type=forking Environment=DISPLAY=:0 ExecStartPre= -/usr/bin/pkill -u %u unison ; /usr/local/bin/music.sh stop ExecStart=/usr/bin/sflock ExecStartPost=/usr/bin/sleep 1 [Install] WantedBy=sleep.target
/etc/systemd/system/user-resume@.service
[Unit] Description=User resume actions After=suspend.target hibernate.target [Service] User=%I Type=simple ExecStart=/usr/local/bin/ssh-connect.sh [Install] WantedBy=suspend.target hibernate.target
Для использования включайте юниты user-suspend@пользователь.service и/или user-resume@пользователь.service.
ExecStartPost=/usr/bin/sleep 1 помогает предотвратить это, позволяя блокировщику экрана успеть заблокировать экран.Пример для общесистемных действий:
/etc/systemd/system/root-suspend.service
[Unit] Description=Local system suspend actions Before=sleep.target [Service] Type=simple ExecStart=-/usr/bin/pkill sshfs [Install] WantedBy=sleep.target
/etc/systemd/system/root-resume.service
[Unit] Description=Local system resume actions After=suspend.target hibernate.target [Service] Type=simple ExecStart=/usr/bin/systemctl restart mnt-media.automount [Install] WantedBy=suspend.target hibernate.target
Комбинированный юнит
При использовании комбинированного файла юнита один и тот же хук выполняет всю работу для разных фаз (переход в сон и пробуждение) и для разных целей.
Пример и объяснение:
/etc/systemd/system/wicd-sleep.service
[Unit] Description=Wicd sleep hook Before=sleep.target StopWhenUnneeded=yes [Service] Type=oneshot RemainAfterExit=yes ExecStart=-/usr/share/wicd/daemon/suspend.py ExecStop=-/usr/share/wicd/daemon/autoconnect.py [Install] WantedBy=sleep.target
-
RemainAfterExit=yes: После запуска служба считается активной до тех пор, пока её явно не остановят. -
StopWhenUnneeded=yes: Если служба активна, она будет остановлена, если ни одна другая активная служба не нуждается в ней. В данном конкретном примере она будет остановлена после остановкиsleep.target. - Поскольку
sleep.targetимеетStopWhenUnneeded=yes, хук гарантированно запустится/остановится правильно для различных режимов.
Хуки в /usr/lib/systemd/system-sleep
systemd-sleep запускает все исполняемые файлы из каталога /usr/lib/systemd/system-sleep/, передавая каждому из них два аргумента:
-
preилиpostв зависимости от того, переходит ли машина в режим сна или пробуждается. -
suspend,hibernate,hybrid-sleepилиsuspend-then-hibernateв зависимости от конкретного режима сна.
Переменная окружения SYSTEMD_SLEEP_ACTION будет содержать конкретное действие сна, выполняемое в данный момент. В первую очередь это полезно для режима suspend-then-hibernate, при котором значение переменной может быть suspend или hibernate, а также suspend-after-failed-hibernate в случаях, когда гибернация не удалась.
Вывод любого пользовательского скрипта будет записан в журнал службы systemd-suspend.service, systemd-hibernate.service или systemd-hybrid-sleep.service, который можно посмотреть с помощью journalctl:
# journalctl -b -u systemd-suspend.service
Пример пользовательского скрипта сна:
/usr/lib/systemd/system-sleep/example.sh
#!/bin/sh
case $1/$2 in
pre/*)
echo "Going to $2..."
;;
post/*)
echo "Waking up from $2..."
;;
esac
Не забудьте сделать скрипт исполняемым.
Советы и рекомендации
Автоматическая разблокировка при пробуждении в доверенных местах
При пробуждении из сна можно автоматически разблокировать систему, если она подключена к определённым устройствам или доверенным сетям Wi-Fi.
/etc/local-scripts/resume-unlock.sh
#!/usr/bin/bash
# Разблокировка сеанса при нахождении в доверенных местах
function trusted() {
# Проверка подключения к доверенной сети Wi-Fi
[[ $(iwgetid -r) == ssid_домашней_сети ]] \
&& return 0
# Проверка подключения доверенного USB-устройства
#lsusb -d xxxx:xxxx && return 0
return 1 # Не доверенное
}
for (( i=0; i < 10; i++ )); do
if trusted; then
loginctl unlock-sessions
exit
fi
sleep 0.5
done
Настройте среду рабочего стола на блокировку сеанса при переходе в сон, а затем создайте хук сна, который запускает вышеуказанный скрипт после пробуждения. Для проверки статуса Wi-Fi установите пакет wireless_tools. Если вы также хотите проверять наличие подключенных USB-устройств, раскомментируйте строку lsusb -d ... в скрипте и введите ID доверенного устройства. Узнать ID подключенных устройств можно с помощью команды lsusb.
Полное отключение сна
При использовании устройства в качестве, например, сервера уход в сон может быть не нужен или даже нежелателен. Любое состояние сна можно отключить через systemd-sleep.conf(5):
/etc/systemd/sleep.conf.d/disable-sleep.conf
[Sleep] AllowSuspend=no AllowHibernation=no AllowHybridSleep=no AllowSuspendThenHibernate=no
Технология Intel Rapid Start (IRST)
Intel Rapid Start Technology — это работающий на уровне прошивки метод сна, который позволяет перейти в спящий режим из ждущего через заданный интервал времени или в зависимости от состояния батареи. Он должен быть быстрее и надёжнее, чем обычный спящий режим, поскольку выполняется прошивкой, а не на уровне операционной системы. Как правило, эта функция должна быть включена в прошивке, и она же позволяет выбрать длительность ждущего режима или событие батареи, после которых будет выполнен переход в спящий режим. Однако некоторые устройства, несмотря на поддержку IRST в прошивке, позволяют настраивать его только через драйверы Intel для Windows. В таких случаях модуль ядра intel-rst должен обеспечить настройку событий в Linux.
При включенной технологии Intel Rapid Start Technology (IRST) для выхода из глубокого сна требуется «на несколько секунд больше, чем для выхода из S3, но намного меньше, чем для выхода из спящего режима».
Многие системы на базе Intel имеют встроенную поддержку IRST, но для этого требуется специальный раздел на SSD (а не на HDD). OEM-установки Windows могут иметь уже существующий раздел IRST, который можно оставить при установке Arch Linux (вместо очистки и переразметки всего SSD). Он должен отображаться как неотформатированный раздел, равный размеру ОЗУ системы.
Однако если вы собираетесь стереть и переразметить весь диск (или уже сделали это), то раздел IRST необходимо создать заново, если вы планируете использовать эту технологию. Это можно сделать, создав пустой раздел, равный размеру ОЗУ системы, и установив для него тип раздела GUID D3BFE2DE-3DAF-11DF-BA40-E3A556D89593 для GPT или ID 0x84 для MBR. Вам также может потребоваться включить поддержку IRST в настройках прошивки вашей системы.
Продолжительность процесса гибернации IRST (то есть копирования «всего содержимого ОЗУ в специальный раздел») зависит от размера ОЗУ системы и скорости SSD и, таким образом, может занять 20–60 секунд. Некоторые системы могут сигнализировать о завершении процесса светодиодным индикатором (LED), например, когда он перестаёт мигать.
Для настройки IRST через Linux требуется ядро, собранное с CONFIG_INTEL_RST. После загрузки модуля через modprobe intel_rst он должен создать файлы wakeup_events и wakeup_time в каталоге /sys/bus/acpi/drivers/intel_rapid_start/*/, которые можно использовать для настройки. Данный модуль имеет скудную документацию, подробности можно посмотреть в его исходном коде: drivers/platform/x86/intel/rst.c.
Смотрите также общие вопросы и ответы и руководства пользователей для технологии Intel Rapid Start.
Отслеживание заряда батареи во время сна
Для отслеживания потребления энергии во время сна можно использовать скрипт Batenergy. Он записывает в журнал systemd информацию о текущем заряде батареи перед переходом в сон и после пробуждения из сна. Это также позволяет сравнить потребление энергии между разными режимами S3 / S0x и заметить возможные регрессии после обновления BIOS или ядра. Для работы скрипта нужно установить bc.
Решение проблем
ACPI_OS_NAME
Возможно, вы захотите настроить свою таблицу DSDT, чтобы заставить её работать. Смотрите статью DSDT.
Ждущий или спящий режим не работает или сбоит
Часто сообщают о том, что при переходе в ждущий или спящий режим экран становится чёрным, на нём не видно ошибок и ничего нельзя сделать. Эти проблемы наблюдались как на ноутбуках, так и на настольных компьютерах. Переход на более старое ядро, особенно на LTS-ядро, хоть и не является официальным решением, но может исправить ситуацию.
Проблема может возникнуть при использовании аппаратного сторожевого таймера (по умолчанию отключен, смотрите RuntimeWatchdogSec= в systemd-system.conf(5) § OPTIONS). Некорректная работа сторожевого таймера может привести к перезагрузке компьютера до того, как система завершит создание образа.
Иногда экран становится чёрным из-за инициализации устройств из initramfs. Удаление всех модулей из массива MODULES, удаление хука kms и пересборка образа initramfs могут решить эту проблему, в частности, с графическими драйверами для раннего запуска KMS. Инициализация таких устройств перед восстановлением состояния системы может привести к неконсистентности, что не позволит системе восстановиться. Это не влияет на пробуждение из ждущего режима. Также посмотрите статью Best practices to debug suspend issues.
Переход с видеодрайвера ATI на более новый AMDGPU также может способствовать корректной работе сна.
Проприетарный драйвер NVIDIA сохраняет содержимое видеопамяти на диск при переходе в сон.[8] Убедитесь, что у вас достаточно места на диске, иначе после пробуждения вы можете получить чёрный экран. При других проблемах может помочь запрет загрузки модуля nvidiafb. [9]
На ноутбуках с процессором Intel, в которых загружен модуль intel_lpss_pci для тачпада, может случиться паника ядра при восстановлении (мигающий caps lock) [10]. Модуль нужно добавить в initramfs:
/etc/mkinitcpio.conf
MODULES=(... intel_lpss_pci ...)
После чего пересоберите образ initramfs.
Ошибки устройств USB
Система может не уходить в сон из-за какого-нибудь USB-устройства. Вы можете увидеть такую ошибку:
PM: Some devices failed to suspend, or early wake event detected ... xhci_hcd 0000:02:00.0: PM: failed to suspend async: error -16
lspci может дать больше информации о проблемном устройстве:
$ lspci -s 02:00.0
02:00.0 USB controller: Advanced Micro Devices, Inc. [AMD] 500 Series Chipset USB 3.1 XHCI Controller
Попробуйте отключить устройства, подключенные к этому порту.
Wake-on-LAN
Если функция Wake-on-LAN включена, сетевая карта будет потреблять энергию, даже если компьютер находится в спящем режиме.
Система мгновенно пробуждается из ждущего режима
Смотрите Wakeup triggers#Instantaneous wakeup after suspending.
Система не выключается после перехода в спящий режим
При переходе в спящий режим система должна полностью выключиться (после сохранения состояния на диск). На некоторых прошивках режим S4 работает ненадёжно. Например, вместо выключения система может перезагрузиться или зависнуть. Если у вас происходит что-то подобное, попробуйте в файле sleep.conf.d(5) установить для HibernateMode значение shutdown:
/etc/systemd/sleep.conf.d/hibernatemode.conf
[Sleep] HibernateMode=shutdown
Если всё остальное настроено правильно, после выполнения systemctl hibernate машина должна полностью выключиться, сохранив при этом своё состояние на диск.
Операционная система не найдена (или загружается не та ОС) при включении после спящего режима
Это может происходить, когда загрузочным диском является внешний диск, и, по-видимому, вызвано ограничением BIOS/прошивки. Прошивка пытается загрузиться с внутреннего диска, в то время как гибернация была выполнена из ОС на внешнем (или другом) диске.
Установите HibernateMode=shutdown, как показано в разделе #Система не выключается после перехода в спящий режим, чтобы окончательно решить проблему. Если система уже заблокировалась, можно попробовать перезагрузить её 4 раза (каждый раз дожидаясь появления ошибки), что в некоторых BIOS'ах приводит к нормальной загрузке.
Файл подкачки в /home
Если файл подкачки находится в /home/, systemd-logind не сможет получить к нему доступ и выдаст предупреждение Call to Hibernate failed: No such file or directory, а для выполнения systemctl hibernate потребуется аутентификация. Такая конфигурация официально не поддерживается. Два возможных обходных пути описаны в systemd issue 15354.
ПК не пробуждается из сна на материнских платах A520I и B550I
На некоторых материнских платах с чипсетами A520i и B550i система не может полностью войти в состояние сна или выйти из него. Среди симптомов — система уходит в сон и монитор выключается, в то время как внутренние светодиоды на материнской плате или индикатор питания продолжают гореть. Затем система не выходит из этого состояния и требует «жёсткого» выключения. Если у вас похожие проблемы на AMD-системе, сначала убедитесь, что система полностью обновлена, и проверьте, установлен ли пакет с микрокодом для AMD.
Проверьте, что строка, начинающаяся с GPP0, имеет статус enabled:
$ cat /proc/acpi/wakeup
Device S-state Status Sysfs node GP12 S4 *enabled pci:0000:00:07.1 GP13 S4 *enabled pci:0000:00:08.1 XHC0 S4 *enabled pci:0000:0b:00.3 GP30 S4 *disabled GP31 S4 *disabled PS2K S3 *disabled GPP0 S4 *enabled pci:0000:00:01.1 GPP8 S4 *enabled pci:0000:00:03.1 PTXH S4 *enabled pci:0000:05:00.0 PT20 S4 *disabled PT24 S4 *disabled PT26 S4 *disabled PT27 S4 *disabled PT28 S4 *enabled pci:0000:06:08.0 PT29 S4 *enabled pci:0000:06:09.0
Если enabled, вы можете выполнить следующую команду для отключения:
# echo GPP0 > /proc/acpi/wakeup
Теперь протестируйте, выполнив systemctl suspend и дав системе уйти в сон. Затем попробуйте вывести систему из сна через несколько секунд. Если это сработало, вы можете сделать обходной путь постоянным. Создайте файл юнита systemd:
/etc/systemd/system/toggle-gpp0-to-fix-wakeup.service
[Unit] Description="Disable GPP0 to fix suspend issue" [Service] ExecStart=/bin/sh -c "/bin/echo GPP0 > /proc/acpi/wakeup" [Install] WantedBy=multi-user.target
Выполните daemon-reload и запустите/включите этот юнит.
Другой вариант — создать правило udev. Например, если для GPP0 соответствует sysfs-узел pci:0000:00:01.1 как в примере выше, выполните udevadm info -a -p /sys/bus/pci/devices/0000\:00\:01.1 для получения нужной информации и создайте примерно такое правило:
/etc/udev/rules.d/10-gpp0-acpi-fix.rules
KERNEL=="0000:00:01.1", SUBSYSTEM=="pci", DRIVERS=="pcieport", ATTR{vendor}=="0x1022", ATTR{device}=="0x1483", ATTR{power/wakeup}="disabled"
Демон udev по умолчанию уже отслеживает изменения в системе. При необходимости вы можете перезагрузить правила вручную.
Fn-кнопка сна на ноутбуке не работает
Если независимо от настроек в logind.conf кнопка сна не работает (её нажатие даже не приводит к появлению сообщения в syslog), то logind, вероятно, не отслеживает клавиатуру. [11] Выполните:
# journalctl --grep="Watching system buttons"
Вы увидите что-то подобное:
May 25 21:28:19 vmarch.lan systemd-logind[210]: Watching system buttons on /dev/input/event2 (Power Button) May 25 21:28:19 vmarch.lan systemd-logind[210]: Watching system buttons on /dev/input/event3 (Sleep Button) May 25 21:28:19 vmarch.lan systemd-logind[210]: Watching system buttons on /dev/input/event4 (Video Bus)
И клавиатуры здесь скорее всего не окажется. В таком случае посмотрите список подключенных клавиатур:
$ stat -c%N /dev/input/by-id/*-kbd
... /dev/input/by-id/usb-SIGMACHIP_USB_Keyboard-event-kbd -> ../event6 ...
Теперь получите ATTRS{name} родительского устройства [12]:
# udevadm info -a /dev/input/event6
...
KERNEL=="event6"
...
ATTRS{name}=="SIGMACHIP USB Keyboard"
Теперь напишите пользовательское правило udev для добавления тега "power-switch":
/etc/udev/rules.d/70-power-switch-my.rules
ACTION=="remove", GOTO="power_switch_my_end"
SUBSYSTEM=="input", KERNEL=="event*", ATTRS{name}=="SIGMACHIP USB Keyboard", TAG+="power-switch"
LABEL="power_switch_my_end"
Перезагрузите правила udev и перезапустите службу systemd-logind.service, после чего в журнале должна появиться строка, связанная с клавиатурой: Watching system buttons on /dev/input/event6.
Система зависает на 60 секунд, а затем просыпается или зависает после пробуждения
Начиная с версии 256, systemd замораживает user.slice перед уходом в сон. Этот процесс может завершиться неудачей из-за ошибок ядра, особенно при использовании KVM.[13][14]
При этом в журнале будут сообщения Failed to freeze unit 'user.slice'. При возникновении такой проблемы попытка войти в систему (начать другой сеанс) завершится неудачей:
pam_systemd(процесс:session): Failed to create session: Job 9876 for unit 'session-6.scope' failed with 'frozen'
Чтобы временно вернуться к старому поведению, отредактируйте юниты systemd-suspend.service, systemd-hibernate.service, systemd-hybrid-sleep.service и systemd-suspend-then-hibernate.service, создав для каждого drop-in файлы со следующим содержимым:
[Service] Environment=SYSTEMD_SLEEP_FREEZE_USER_SESSIONS=false
Однако сам этот drop-in файл тоже может помешать системе перейти в режим сна.[15]
Спящий режим при использовании нескольких операционных систем
Если вы используете несколько операционных систем на одном устройстве (включая, но не ограничиваясь, двойную загрузку с Windows) и хотите иметь возможность загружаться в другую систему, пока Arch Linux находится в гибернации, нужно быть очень осторожным и не монтировать те разделы, которые примонтированы в системе, ушедшей в сон. Перед монтированием необходимо убедиться, что файловая система была размонтирована перед переходом системы в гибернацию. Это можно сделать с помощью хуков сна.
Эта проблема особенно актуальна для системного раздела EFI, поскольку ESP обычно используется совместно несколькими системами. В разделе EFI system partition#Hibernation and multi boot systems описаны возможные способы решения проблемы, которые также можно адаптировать для других файловых систем.