Усыпляем компьютер
Автор: San АНДРЕЕВ
Источник: linuxportal.ru
1. Аннотация.
Заметка описывает настройку linux (ядра и ОС) для реализации "заморозки" текущего состояния системы. Описание производится на примере x86 Slackware Linux 10, ядра 2.6.14 и версии Suspend2 2.2-rc14.
2. Автор - Александр Андреев (aka San АНДРЕЕВ). Я не даю никаких гарантий (прямых, косвенных, подразумеваемых и т.д.), все нижеследующее вы соглашаетесь использовать исключительно на свой страх и риск. Со мной можно связаться через почту форума (требует регистрации).
3. Ключевые слова для поиска: linux hibernate software suspend acpi acpid slackware
4. Введение.
После появления поддержки железом различных режимов управления питанием и разработки соотв. программных средств, в т.ч. драйверов оборудования, поддерживающих управление питанием (как это делать описано напр. в Linux power management support ), стало возможным производить "заморозку" текущего состояния программной среды с последующим быстрым его восстановлением. По достоинству это могут оценить владельцы ноутбуков - не надо закрывать приложения, сохранять документы, завершать работу специальным образом и т.д., достаточно просто закрыть крышку и система "застынет" в этом состоянии. Причем потерь данных при этом не происходит и энергия аккумуляторов не расходуется (в случае "засыпания" на диск). Для возвращения системы в исходное состояние достаточно просто включить ноутбук.
5. Исходные данные.
Поскольку на моем буке установлен дистрибутив Slackware Linux 10, то на нем (дистрибутиве) я и экспериментировал. Не думаю, что в других дистрибутивах должны быть какие-то принципиальные сложности, не исключено также, что в каких-то из них этот функционал по умолчанию включен, если вы об этом знаете - присылайте описание, включим в заметку.
Для реализации идеи понадобились исходные тексты ядра (я взял 2.6.14), патч для дозаточки механизма засыпания (я использовал Suspend2 2.2-rc14), скрипт усыпления системы (hibernate-1.12), средство под названием zenity для запуска диалогов Gnome из командной строки (опционально, моя версия 2.8.2), для zenity требуются popt, scrollkeeper, intltool, gtk+-2.0, libglade-2.0, gconf-2.0 и libgnomecanvas-2.0, но они в дистрибутиве присутствуют и при необходимости их можно доустановить с диска.
Говоря о дозаточке, я имел в виду то, что в ядра 2.6.х механизм засыпания уже в основном встроен (заморозка процессов, периферийных и внутренних устройств и т.д.), патч только предоставляет дополнительные возможности по управлению этим механизмом.
6. Варианты сна.
Существует несколько вариантов засыпания (с вариациями). Первый и наименее сонный - это усыпление отдельных устройств (периферийных и внутренних) для снижения энергопотребления. Состояние системы в целом нигде не фиксируется, процессы остаются в памяти и работают в пределах железных ограничений (т.е. с использованием оставшегося не усыпленным железа).
Второй - с полным остановом системы и сохранением состояния в оперативной памяти. Энергопотребление здесь ниже, чем в первом случае, но все же имеется - память (RAM) обесточивать нельзя. С другой стороны, это самый быстрый способ усыпления, поскольку операции записи/чтения выполняются на самом быстром устройстве хранения (из доступных программно).
Третий - с полным остановом системы и сохранением состояния (проще говоря, дампа оперативной памяти) в файле либо устройстве (разделе) свопинга. Этот вариант не потребляет энергии, медленнее второго и требует наличия на диске swap-раздела или файла объемом желательно не меньше объема ОЗУ ПК. Объем сохраняемой при засыпании информации можно сократить, применив сжатие, но это скажется на времени засыпания и восстановления. Бонус - при сохранении в файл можно далее этот файл использовать как загрузочный образ на большом количестве одинаковых систем.
7. Патчим ядро.
Сначала свертесь с документацией на ваш дистрибутив - если патч Suspend2 уже наложен на умолчательное дистрибутивное ядро, либо такой вариант ядра просто имеется в дистрибутиве, то проще воспользоваться готовым, пропустить этот и следующие разделы и остановиться на доустановке hibernate (при необходимости) и конфигурировании демона acpid.
Каталог с патчем содержит также скрипты apply и unapply, которыми пользоваться вроде как должно быть удобнее и которые надо обязательно запускать из каталога исходных кодов ядра. Я поступил для себя проще - просто переписал сам патч в корень исходников ядра и наложил:
$ patch -p1 < 100-suspend2-2.2-rc14-for-2.6.14.patch
Если у вас есть какие-то вопросы по работе/использованию команды patch - почитайте документацию на нее (напр. man patch). Патч я накладывал на "чистое" (т.н. vanilla) ядро, поэтому никаких проблем (reject'ов) не возникло, все было "succeeded" (достигло цели то есть).
8. Конфигурируем ядро.
После наложения патча запускаем конфигуратор ядра и идем в раздел "Power management options (ACPI, APM)", в котором должен появиться пункт Suspend2. Если у вас была включена поддержка SMP (хотя бы для процессора с гипертредингом), то здесь может возникнуть неприятный момент - опции Suspend2 не будет. Согласно информации на сайте проекта, SMP-конфигурации вроде как поддерживаются, поэтому такая ситуация мне непонятна, однако ее можно обойти, если немного похачить. :)
От корня исходников ядра идем в kernel/power, открываем на редактирование файл Kconfig и в разделе "config SOFTWARE_SUSPEND" примерно в 32ой строке ("depends on PM && SWAP ...") надо убрать воскл. знак перед SMP после второй скобки и в самом конце строки. Эту процедуру надо повторить и примерно в 106ой строке (раздел "menuconfig SUSPEND2"). Теперь засыпание будет доступно только для конфигураций с SMP. Если вы вообще не хотите зависеть от мультипроцессорности, то в двух вышеуказанных строках упоминание про SMP надо убрать, чтобы они выглядели примерно следующим образом:
depends on PM && SWAP && X86 || (FVR || PPC32)
для строки 32
и depends on PM
для строки 106.
В любом случае это хак, который может вызвать нестабильную работу системы.
Итак, опцию мы все-таки нарисовали, теперь ее надо включить и зайти в ее подменю. Там для начала достаточно выбрать пункт "Swap writer" и указать раздел со свопом, на который будет сохраняться состояние системы. Здесь все, не забываем не включать APM (acpi и apm использовать одновременно не надо), можно еще в "Device Drivers" -> "USB support" от корня конфигурации выбрать пункт "USB suspend/resume" для поддержки замораживания USB-устройств.
Конфигурироем оставшееся в ядре если есть необходимость, сохраняем, пересобираем, ставим, дописываем в меню загрузчика если необходимо и перезагружаемся с новым ядром.
9. Настройка и проверка.
Если все прошло хорошо, то после загрузки нового ядра в /proc появится каталог suspend2 и в нем ряд файлов, в частности - do_suspend. Проверяем наличие на диске ('fdisk -l /dev/hdX | grep swap' от рута) и активность (напр. при помощи top или 'grep Swap /proc/meminfo') swap-раздела указанного выше объема (не меньше объема ОЗУ). Для автоматического задействования имеющегося свопа при загрузке системы достаточно прописать в /etc/fstab что-нибудь вроде такого:
/dev/hda2 none swap sw 0 0
Теперь можно переключиться в чисто консольный runlevel (telinit 3 в каком-нибудь терминале от рута) и скомандовать
echo > /proc/suspend2/do_suspend
После этого должны побежать по экрану всякие строки про "freeze" и похожие на нее, ряды увеличивающихся процентов и питание должно отключиться. Включаем питание - обратно строки и проценты и в результате довольно быстро мы должны оказаться в консоли в том виде, в каком она была на момент выполнения команды заморозки. В случае успеха - с безбашенной консольной заморозкой все получилось.
10. Аккуратное засыпание.
Аккуратное засыпание заключается в остановке процессов, отключении сетевых интерфейсов, выгрузке модулей и т.д. Всем этим занимается скрипт hibernate. Он почему-то написан с использованием zenity и мне оказалось проще доставить последнее, чем хачить первое. Не исключено также, что в чисто консольном режиме скрипт работает и без графических диалогов - я не пробовал. У этого скрипта имеется конфигурационный файл (в процессе установки кладется в /etc/hibernate вместе с другими файлами), в котором как раз и указывается что и как делать. Для моих целей особо переправлять его не пришлось, сам он находится во вложении к этой заметке. Для установки скрипта достаточно распаковать его архив и запустить файл install.sh. После правки конфига переходим к настройке собственно засыпания по разным поводам.
11. Настройка acpid.
Реагированием на все события, связанные с электропитанием, занимается демон acpid. Поэтому если мы хотим какой-то реакции системы на закрытие крышки, то надо демону это объяснить. Для начала идем в /etc/acpi/events и открываем на редактирование файл default, в котором комментируем все незакоментированное. После перезапускаем демона (для slackware - '/etc/rc.d/rc.acpid restart') и дальше наблюдаем за событиями в системе:
# tail -f /var/log/acpid
Нажимаем руками датчик закрытия крышки (или закрываем/открываем крышку). Должно появиться что-то вроде
[Thu Dec 8 01:12:04 2005] received event "button/lid LID 00000080 00000003"
"button/lid" как раз и является интересующим нас событием, на которое нам в данном случае надо отреагировать. Обратно редактируем /etc/acpid/events/default и добавляем (или правим, если есть) в него след. сроки:
event=button/lid
action=/usr/local/sbin/hibernate
Здесь после event указывается отлавливаемое событие, а после action - что делать при появлении этого события, в данном случае запускается скрипт hibernate. Сохраняем, закрываем и снова перезапускаем acpid. Давим на датчик закрытия крышки - должен выскочить графический прогресс-бар, после мы должны вывалиться в консоль и дальше все как и при консольном засыпании. После выключения бука обратно его включаем, он сам подтягивает ядро, детектит железо, загружает из свопа образ памяти и запускает систему из замороженного состояния. Все.
12. Край для работы.
Интересной особенностью является сохранение дампа памяти в файл. Я с этим не экспериментировал, потому как нет надобности и времени, но если у кого есть успешный опыт - присылайте описание, добавим сюда.
Также любопытно настроить засыпание на разные события, напр. на разряд батареи - здесь можно почитать документацию на acpid и посмотреть на его логи.
13. Источники информации.
- man acpid
- www.suspend2.net/HOWTO
- www.opennet.ru/base/sys/hibernate.txt.html
- www.suspend2.net/downloads/
исходный код Suspend2 и hibernate
- directory.fsf.org/zenity.html
исходный код zenity