Power management (Русский)/Suspend and hibernate (Русский) - ArchWiki

Jump to content

# Power management (Русский)/Suspend and hibernate (Русский)

From ArchWiki
< Power management (Русский)
Состояние перевода: На этой странице представлен перевод статьи Power management/Suspend and hibernate. Дата последней синхронизации: 26 января 2026. Вы можете помочь синхронизировать перевод, если в английской версии произошли изменения.

Ссылки по теме

- systemd (Русский)
- Управление питанием
- Wakeup triggers
- Пространство подкачки

Существует несколько режимов приостановки работы компьютера, в частности:

Suspend to idle
  Intel называет его S0ix, Microsoft — Modern Standby (ранее «Connected Standby»), а ядро — S2Idle. Предназначен для использования вместо состояния S3 в поддерживаемых системах, обеспечивая идентичное энергосбережение, но значительно сокращая время пробуждения.
  Совет Хотя в Windows или macOS это состояние может привести к разряду батареи, поскольку они могут пробуждать устройства для подключения к сети, Linux эту функцию в настоящее время не использует и не должен быть подвержен этой проблеме.
Suspend to RAM (ждущий режим)
  Состояние S3 по определению ACPI. Отключает питание большинства устройств компьютера, кроме оперативной памяти, которая продолжает хранить в себе состояние компьютера для его восстановления при пробуждении. Из-за большой экономии энергии рекомендуется, чтобы ноутбуки автоматически входили в этот режим при работе от батареи и закрытой крышке (или когда пользователь неактивен в течение некоторого времени).
Suspend to disk (спящий режим, гибернация)
  Состояние S4 по определению ACPI. Сохраняет состояние машины в подкачку и полностью выключает её. При включении питания состояние восстанавливается. До этого момента энергопотребление равно нулю.
Hybrid suspend (гибридный спящий режим)
  Гибрид ждущего и спящего режимов, иногда называется suspend to both. Сохраняет состояние машины в подкачку, но не выключает её. Вместо этого выполняется переход в обычный ждущий режим. Поэтому, если батарея не разряжена, система может возобновить работу мгновенно. Если батарея разряжена, система может восстановить своё состояние с диска, что намного медленнее, чем возобновление работы из ОЗУ, но состояние не будет потеряно.

Ядро обеспечивает базовые функции, а некоторые интерфейсы высокого уровня выполняют дополнительные действия для обработки проблемных аппаратных драйверов / модулей ядра (например, повторная инициализация видеокарты).

## Низкоуровневый интерфейс (swsusp)

Примечание Хотя интерфейс ядра можно использовать напрямую (и это будет работать быстрее, поскольку не выполняется дополнительная обработка в userspace), рекомендуется использовать интерфейс высокого уровня. Он лучше справляется с выполнением дополнительных проверок безопасности, а также предоставляет механизмы хуков, которые помогают наладить работу системы перед сном и после него: например, настроить аппаратные часы, восстановить подключение к беспроводной сети и т. д.

Можно отправить сигнал перехода в сон напрямую во встроенный в ядро программный код (swsusp); точный метод и состояние зависят от уровня аппаратной поддержки. В современных ядрах основным механизмом является запись соответствующих значений в `/sys/power/state`.

Смотрите документацию ядра для подробностей.

## Интерфейс высокого уровня (systemd)

Примечание Задача интерфейса высокого уровня — предоставить программы и скрипты, которые могут быть запущены для перехода в сон, а также способы выполнения дополнительных действий перед переходом в сон и после пробуждения из сна. Для автоматического перехода в сон по нажатию кнопок питания, щелчкам в меню или событиям, связанным с крышкой ноутбука, обратитесь к разделу Управление питанием#События ACPI.

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): после истечения указанного времени система ненадолго проснётся для выполнения измерения (измерение также производится при пробуждении пользователем).

Совет systemd с версии 256 поддерживает автоматический выбор наиболее подходящего режима сна с помощью новой команды `systemctl sleep`. По умолчанию она пытается использовать `suspend-then-hibernate`, в случае отсутствия его поддержки пробует `suspend`, а если не поддерживается и он, то `hibernate`. Смотрите systemctl(1) для более подробной информации.

Смотрите раздел #Хуки сна для получения дополнительной информации о настройке хуков, связанных с режимами сна. Также смотрите systemctl(1), systemd-sleep(8) и systemd.special(7).

## Изменение режима сна

В системах, где режим S0ix не обеспечивает такой же экономии энергии, как обычный ждущий режим S3, или когда экономия энергии предпочтительнее быстрого возобновления работы, возможно изменение режима сна, используемого по умолчанию.

Совет S0ix призван обеспечивать такую же или лучшую экономию энергии, как и S3. Для проверки, сможете вы заставить его работать как задумано, смотрите записи в блоге Intel: How to achieve S0ix states in Linux, Linux S0ix Troubleshooting и Idling Efficiently on Linux: A Case Study. Пользователи систем Intel могут использовать S0ixSelftestTool. Пользователи систем AMD могут использовать amd-debug-tools.

Выполните следующую команду, чтобы увидеть все режимы, о поддержке которых заявляет оборудование (текущий режим показан в квадратных скобках[1]):

    $ cat /sys/power/mem_sleep

    [s2idle] shallow deep

Поддерживаемые режимы сна в mem_sleep
Строка в 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 с тех пор, как системы, поставляемые с Windows, стали по умолчанию использовать «Modern standby»; если они сами не предлагают этот режим, то, вероятно, он сломан.

Убедитесь, что оборудование не испытывает проблем с режимом 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-5363dd433153`
- `resume="PARTLABEL=Swap partition"`
- `resume=/dev/archVolumeGroup/archLogicalVolume` — если подкачка расположена на логическом томе LVM (UUID и Label тоже должны работать)

Примечание Если доступ к подкачке выполняется через стековые блочные устройства, например, зашифрованный контейнер (LUKS), RAID или LVM, параметр `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

Совет Получить UUID блочного устройства, на котором находится файл подкачки, можно такой командой: `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

Совет Вместо того, чтобы создавать несколько пространств подкачки как описано далее, можно использовать zswap и при этом получить похожее поведение.

Если для подкачки вы используете 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% данных.

Важно Не используйте TRIM на тонких томах подкачки, используемых для спящего режима, то есть не используйте параметр `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(8), использование этого метода считается хаком. systemd-sleep будет запускать все хуки одновременно, а не последовательно друг за другом. Для более чётко определённого интерфейса с поддержкой указания порядка запуска используйте #Пользовательские юниты systemd.

systemd-sleep запускает все исполняемые файлы из каталога `/usr/lib/systemd/system-sleep/`, передавая каждому из них два аргумента:

1. `pre` или `post` в зависимости от того, переходит ли машина в режим сна или пробуждается.
2. `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). Он должен отображаться как неотформатированный раздел, равный размеру ОЗУ системы.

Важно Раздел Intel Rapid Start не зашифрован; «Intel рекомендует отключить технологию Intel Rapid Start, если вы используете программное шифрование диска». [7]

Однако если вы собираетесь стереть и переразметить весь диск (или уже сделали это), то раздел IRST необходимо создать заново, если вы планируете использовать эту технологию. Это можно сделать, создав пустой раздел, равный размеру ОЗУ системы, и установив для него тип раздела GUID `D3BFE2DE-3DAF-11DF-BA40-E3A556D89593` для GPT или ID `0x84` для MBR. Вам также может потребоваться включить поддержку IRST в настройках прошивки вашей системы.

Совет Время до срабатывания 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 описаны возможные способы решения проблемы, которые также можно адаптировать для других файловых систем.

Category:

- Power management (Русский)

Power management (Русский)/Suspend and hibernate (Русский)
Add topic