Подробный гайд по настройке Swap, GRUB и initramfs для сохранения состояния: Гибернация в Linux
Гайд по настройке гибернации (Suspend to Disk) в Linux. Наличие Swap (раздела или файла) достаточного размера является строгим обязательным условием, поскольку именно туда ядро сбрасывает полное содержимое оперативной памяти (RAM) перед полным обесточиванием системы.
Важные предварительные замечания
1. Размер Swap:
Он должен быть не меньше объема вашей оперативной памяти (RAM). Если у вас 16 ГБ RAM, создайте Swap минимум на 16 ГБ (лучше 17–18 ГБ для запаса).
2. Файловые системы:
Гибернация в swap-файл отлично работает на ext4. На Btrfs и ZFS использование swap-файла для гибернации либо не поддерживается, либо требует сложных обходных путей. Для Btrfs/ZFS настоятельно рекомендуется использовать отдельный swap-раздел.
3. Шифрование диска (LUKS):
Требует дополнительных настроек (см. раздел "Решение проблем" в конце).
Шаг 1: Проверка и создание Swap
1. Проверьте текущий объем подкачки:
free -h
Если Swap отсутствует или его размер меньше объема вашей RAM, его нужно создать или увеличить.
2. Создание swap-файла (пример для 16 ГБ, измените 16G на нужное значение):
# Создаем файл нужного размера
sudo fallocate -l 16G /swapfile
# Если fallocate не работает (например, на некоторых ФС), используйте dd:
# sudo dd if=/dev/zero of=/swapfile bs=1M count=16384 status=progress
# Устанавливаем безопасные права доступа (только для root)
sudo chmod 600 /swapfile
# Форматируем файл как swap
sudo mkswap /swapfile
# Активируем его
sudo swapon /swapfile
3. Добавьте запись в /etc/fstab, чтобы swap-файл подключался автоматически при загрузке:
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
Шаг 2: Получение UUID и смещения (Offset)
Ядру нужно знать, где именно на диске искать сохраненное состояние памяти.
1. Узнайте UUID раздела, на котором находится swap (это работает и для раздела, и для файла):
findmnt -no UUID -T /swapfile
Запишите этот UUID (например, 12345678-1234-1234-1234-123456789abc).
2. Узнайте физическое смещение (offset) ( Только если вы используете swap-файл! Для swap-раздела этот шаг не нужен):
sudo filefrag -v /swapfile | awk '{if($1=="0:"){print $4}}' | cut -d. -f1
Запишите полученное число (например, 34816). Это начальный физический блок файла.
Шаг 3: Настройка загрузчика (GRUB)
Теперь нужно передать ядру параметры resume и resume_offset.
1. Откройте конфигурационный файл GRUB:
sudo nano /etc/default/grub
2. Найдите строку GRUB_CMDLINE_LINUX_DEFAULT и добавьте в нее параметры.
Для swap-файла:
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash resume=UUID=ваш_uuid resume_offset=ваш_offset"
Для swap-раздела:
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash resume=UUID=ваш_uuid"
(Замените ваш_uuid и ваш_offset на значения из Шага 2. Не удаляйте другие параметры, которые уже там есть, просто добавьте эти через пробел).
3. Обновите конфигурацию GRUB:
- Ubuntu / Debian / Linux Mint:
sudo update-grub - Fedora:
sudo grub2-mkconfig -o /boot/grub2/grub.cfg - Arch Linux:
sudo grub-mkconfig -o /boot/grub/grub.cfg
Шаг 4: Обновление образа Initramfs
Ядро должно уметь читать Swap на раннем этапе загрузки, до монтирования корневой файловой системы.
- Ubuntu / Debian / Pop!_OS:
sudo update-initramfs -u -k all
- Arch Linux / Manjaro:
1. Откройте /etc/mkinitcpio.conf.
2. Найдите строку HOOKS и добавьте resume после udev (и после encrypt, если диск зашифрован):
HOOKS=(base udev autodetect modconf kms keyboard keymap consolefont block filesystems fsck resume)
3. Пересоберите образ: sudo mkinitcpio -P
- Fedora:
sudo dracut -f --regenerate-all
Шаг 5: Разрешение гибернации в systemd
Иногда гибернация заблокирована на уровне менеджера питания.
1. Откройте файл конфигурации logind:
sudo nano /etc/systemd/logind.conf
2. Найдите и раскомментируйте (уберите #) или измените следующие строки:
HandleHibernateKey=hibernate
HandleLidSwitch=hibernate # Опционально: гибернация при закрытии крышки ноутбука
3. Перезапустите службу:
sudo systemctl restart systemd-logind
4. Убедитесь, что цель гибернации не замаскирована:
sudo systemctl unmask hibernate.target
Шаг 6: Тестирование
1. Сохраните все открытые документы.
2. Выполните команду гибернации:
systemctl hibernate
- Компьютер должен полностью выключиться (индикаторы погаснут, вентиляторы остановятся).
- Включите компьютер кнопкой питания. Система должна загрузиться, показать экран заставки (splash) и восстановить все открытые окна и приложения ровно в том состоянии, в котором они были.
Решение частых проблем
1. Шифрование диска (LUKS / LVM)
Если корневой раздел зашифрован, ядро не сможет прочитать Swap-файл/раздел до расшифровки диска.
- Убедитесь, что в
/etc/crypttabдля зашифрованного раздела добавлен параметрresume. - В Arch Linux: хук
resumeвmkinitcpio.confдолжен стоять после хукаencrypt. - В Ubuntu: иногда требуется добавить
RESUME=UUID=ваш_swap_uuidв файл/etc/initramfs-tools/conf.d/resume, а затем выполнитьsudo update-initramfs -u.
2. Btrfs и Swap-файлы
Если вы используете Btrfs, гибернация в swap-файл часто приводит к повреждению данных или отказу загрузки.
Решение:
Создайте отдельный раздел под swap (например, /dev/nvme0n1p3), отформатируйте его как swap и используйте его UUID в GRUB без resume_offset.
3. Secure Boot
Подписанные ядра (например, в Ubuntu с включенным Secure Boot) могут отказываться загружать модифицированный initramfs с хуками resume.
Решение:
Временно отключите Secure Boot в BIOS/UEFI для проверки. Если гибернация заработает, вам потребуется вручную подписать ядро и initramfs своими ключами MOK (Machine Owner Key).
4. Проприетарные драйверы Nvidia
Иногда модуль nvidia мешает корректному сохранению состояния VRAM.
Решение:
Убедитесь, что у вас установлены свежие драйверы. В некоторых случаях помогает добавление параметра ядра nvidia.NVreg_PreserveVideoMemoryAllocations=1.
5. Ошибка "Not enough swap space for hibernation"
Ядро отказывается гибернировать, если доступный Swap меньше объема используемой RAM.
Решение:
Увеличьте размер swap-файла (предварительно выполнив sudo swapoff /swapfile, затем заново fallocate, mkswap, swapon).
Важно:
Если вы столкнетесь с конкретной ошибкой при выполнении команды systemctl hibernate, проверьте логи:
journalctl -b -1 -p 3 (показывает ошибки предыдущей загрузки, когда система пыталась выйти из гибернации) или journalctl -u systemd-hibernate.service.
Мы делимся этой технической информацией, чтобы помочь вам в решении задач — используйте её с пониманием. Статья носит рекомендательный характер, поэтому, пожалуйста, применяйте описанные методы осмотрительно.