Мы с Linux этим ложимся и с Linux этим встаем — последствия гибернации::Журнал СА 2.2004
www.samag.ru
Льготная подписка для студентов      
Поиск   
              
 www.samag.ru    Web  0 товаров , сумма 0 руб.
E-mail
Пароль  
 Запомнить меня
Регистрация | Забыли пароль?
О журнале
Журнал «БИТ»
Подписка
Где купить
Авторам
Рекламодателям
Магазин
Архив номеров
Вакансии
Контакты
   

Jobsora

ЭКСПЕРТНАЯ СЕССИЯ 2019


  Опросы

Какие курсы вы бы выбрали для себя?  

Очные
Онлайновые
Платные
Бесплатные
Я и так все знаю

 Читать далее...

1001 и 1 книга  
28.05.2019г.
Просмотров: 1894
Комментарии: 2
Анализ вредоносных программ

 Читать далее...

28.05.2019г.
Просмотров: 1936
Комментарии: 1
Микросервисы и контейнеры Docker

 Читать далее...

28.05.2019г.
Просмотров: 1497
Комментарии: 0
Django 2 в примерах

 Читать далее...

28.05.2019г.
Просмотров: 1097
Комментарии: 0
Введение в анализ алгоритмов

 Читать далее...

27.03.2019г.
Просмотров: 1667
Комментарии: 1
Arduino Uno и Raspberry Pi 3: от схемотехники к интернету вещей

 Читать далее...

Друзья сайта  

Форум системных администраторов  

sysadmins.ru

Электронка - 2020!

 Мы с Linux этим ложимся и с Linux этим встаем — последствия гибернации

Архив номеров / 2004 / Выпуск №2 (15) / Мы с Linux этим ложимся и с Linux этим встаем — последствия гибернации

Рубрика: Администрирование /  Продукты и решения

 АНТОН БОРИСОВ

Мы с Linux этим ложимся
и с Linux этим встаем – последствия гибернации

Сегодня мы рассмотрим такой вопрос, как программная гибернация (hibernation) в ОС Linux. Поддержка засыпания была начата для серий 2.4 Linux, но т.к. время не стоит на месте, на сегодняшний момент выпущена новая серия 2.6 (где, в частности, переработана подсистема управления энергосбережением), поэтому и мы будем работать именно под этой серией. Теперь в 2.6.xx Linux-ядрах существует полноценная поддержка, то, что раньше было только в экспериментальном исполнении. Для приверженцев 2.4.xx ядер рекомендуется наложить патчи, чтобы получить то, что по умолчанию поставляется в новой ветке.

Ну что же, краткая предыстория рассказа о гибернации. Первый раз мне пришлось столкнуться с этой увлекательной функцией в 2002 году, когда вышли первые релизы Windows XP Professional. Любопытство одержало верх, и некоторое время я проработал в данной ОС, тем паче, что задачи, решаемые в тот момент, требовали среду разработки именно Windows-платформы. Кроме отличного дизайна интерфейса в системе была функция сбережения питания, так называемое hibernate state.

Это означает, что в любой момент времени можно перевести систему вместе со всеми приложениями, которые работают, в состояние, когда все ОЗУ персоналки записывается на диск и производится отключение питания. При этом в момент включения питания, ОЗУ, которое было записано на диск, переписывается обратно в память (точнее не ОЗУ, а его содержимое) и передается управление на тот код, который работал перед самым отключением питания. Чем эта схема любопытна? В первую очередь тем, что мы не закрываем/открываем заново приложения, состояния в программных продуктах остаются неизменными. Во-вторых, не требуется вспоминать, что же конкретно мы делали в предыдущий день, все остается на рабочем столе, как и в прошлый раз. Тем самым, уходя с работы и переведя систему в такое состояние, мы не беспокоимся, а выдержат ли наши бесперебойники, а не сгорит ли рабочее место из-за повышенной температуры, в общем, масса хлопот с плеч долой. Тем более, если мы работаем с ноутбуком, где в первую очередь стоит энергосбережение. Поэтому возможность эту мы запомнили, поставили под контроль.

Что же касается Windows XP, то может быть из-за того, что версия была слишком сырой на тот момент или просто из-за того, что за 100 рублей Genuine Windows-продукты не купить, а получать извещения о завершенных приложениях необходимостив этой связи направить письмо в службу поддержки, совершенно меня стали огорчать, пришлось совмещать полезное с приятным или даже, наоборот, приятное с полезным, slackware с VMware+Windows 2000 Pro.

Это была преамбула, нас же интересует реализация режима сна именно в Linux.

Так что история начинается.

Для тех, кто ни разу не сталкивался с гибернацией (засыпанием), следует ознакомиться с документацией, которая идет вместе с 2.6 ядром (директория /usr/src/linux/Documentation/power). Не стану подробно останавливаться на всех файлах. Отмечу, что «swsusp.txt» – начальная точка для понимания проблемы.

Итак, что в первую очередь следует сделать? Подготовить swap-раздел таким образом, чтобы его размер превышал в 2 раза объем установленной RAM в системе. Если вы опытный администратор, то именно так вы и поступаете, не мне вас учить. Для чего это нужно?

Именно в swap-раздел производится сброс содержимого RAM в процессе засыпания и дальнейшее его восстановление во время пробуждения.

Второе, добавляем в /etc/lilo.conf следующую строку:

append="apm=power-off resume=/dev/hdc5 acpi=force"

Это означает, что при старте ядру будут переданы данные параметры.

Если ваш box изготовлен не позднее 1999 года, то «acpi=force», как правило, не требуется. Однако на моей рабочей машине, приходится добавлять, ибо без нее ACPI-подсистема не хочет подниматься.

Сочетание «resume=/dev/hdc5» означает, что раздел для гибернации называется /dev/hdc5 (он же swap-раздел). В дальнейшем мы увидим, что во время нормальной работы сигнатура swap-раздела меняется на свою нормальную сигнатуру SWAPSPACE2. (В cпящем режиме она устанавливается как S2SUSP).

Не забудем установить заново lilo-загрузчик:

lilo -v

Теперь мы готовы для засыпания. Перезагрузимся, чтобы новые параметры были знакомы ядру. reboot. Итак, производим следующую простую операцию:

echo 4 > /proc/acpi/sleep

(за цифрами обращайтесь к документации, прилагаемой к исходникам ядра – ссылка была дана выше в статье). Таким образом мы не совершаем какие-то магические пасы, а через псевдофайловую систему proc записываем данные в служебные структуры ядра.

Заметьте, что если ACPI-подсистема не стартовала, то директории /proc/acpi у нас в системе не будет.

Далее ядро начинает сбрасывать дамп памяти в swap-раздел. При этом в syslog появляются следующие сообщения:

Jan 11 22:15:07 athlon kernel: Stopping tasks: ======exiting...exiting...=================
================|
Jan 11 22:15:07 athlon kernel: Freeing memory: .........|
Jan 11 22:15:07 athlon kernel: hdd: start_power_step(step: 0)
Jan 11 22:15:07 athlon kernel: hdd: completing PM request, suspend
Jan 11 22:15:07 athlon kernel: hdc: start_power_step(step: 0)
Jan 11 22:15:07 athlon kernel: hdc: completing PM request, suspend
Jan 11 22:15:07 athlon kernel: hdb: start_power_step(step: 0)
Jan 11 22:15:07 athlon kernel: hdb: completing PM request, suspend
Jan 11 22:15:07 athlon kernel: hda: start_power_step(step: 0)
Jan 11 22:15:07 athlon kernel: hda: completing PM request, suspend
Jan 11 22:15:07 athlon kernel: /critical section: Counting pages to copy[nosave c04a6000]
(pages needed: 3642+512=4154 free: 61889)
Jan 11 22:15:07 athlon kernel: Alloc pagedir
Jan 11 22:15:07 athlon kernel: [nosave c04a6000]<4>Freeing prev allocated pagedir
Jan 11 22:15:07 athlon kernel: Debug: sleeping function called from invalid context at inc
lude/asm/semaphore.h:119
Jan 11 22:15:07 athlon kernel: in_atomic():1, irqs_disabled():0
Jan 11 22:15:07 athlon kernel: Call Trace:
Jan 11 22:15:07 athlon kernel:  [] __might_sleep+0xab/0xd0
Jan 11 22:15:07 athlon kernel:  [] common_interrupt+0x18/0x20
Jan 11 22:15:07 athlon kernel:  [] device_resume+0x22/0x50
Jan 11 22:15:07 athlon kernel:  [] drivers_resume+0x3c/0x40
Jan 11 22:15:07 athlon kernel:  [] do_magic_resume_2+0x79/0xe0
Jan 11 22:15:07 athlon kernel:  [] do_magic+0x11f/0x140
Jan 11 22:15:07 athlon kernel:  [] do_software_suspend+0x6b/0x90
Jan 11 22:15:07 athlon kernel:  [] acpi_system_write_sleep+0xc3/0xe6
Jan 11 22:15:07 athlon kernel:  [] vfs_write+0xad/0x120
Jan 11 22:15:07 athlon kernel:  [] sys_write+0x3f/0x60
Jan 11 22:15:07 athlon kernel:  [] syscall_call+0x7/0xb

После этого происходит отключение питания.

На что следует обратить внимание. Когда вы в следующий раз включаете машину, то вы имеете полное право подать параметр «noresume» ядру, которое запрещает восстанавливать состояние гибернации. Делать этого не рекомендуется, так как содержимое на вашем корневом разделе может помахать вам ручкой. Во всяком случае не все содержимое, а только последние изменения. У меня используется ext3 файловая система, поэтому этот вывод был сделан из сообщений, посылаемых обработчиком файловой системы.

Если у вас не было swap-раздела до засыпания, то заснуть вам также не удастся. Так что имейте это в виду. Простое правило – между засыпанием и просыпанием не пишите на раздел. На swap-раздел уж точно писать не надо, т.к. cигнатуры (SWAPSPACE2), показывающей, что там именно swap, нет. Поэтому подключить его пока не получится. А специально проинициализировать его придется, вызвав команду:

/sbin/mkswap /dev/hdc5

Повторюсь, что данные действия не являются обязательными. Мы исследуем то, что может быть при обстоятельствах, когда жесткий диск изъят из системы в состоянии «сна» (гибернации).

Теперь мы приходим из отпуска – включаем рубильник.

Jan 19 05:13:07 athlon kernel: hda: Wakeup request inited, waiting for !BSY...
Jan 19 05:13:07 athlon kernel: hda: start_power_step(step: 1000)
Jan 19 05:13:07 athlon kernel: blk: queue c135a200, I/O limit 4095Mb (mask 0xffffffff)
Jan 19 05:13:07 athlon kernel: hda: completing PM request, resume
Jan 19 05:13:07 athlon kernel: hdb: Wakeup request inited, waiting for !BSY...
Jan 19 05:13:07 athlon kernel: hdb: start_power_step(step: 1000)
Jan 19 05:13:07 athlon kernel: hdb: completing PM request, resume
Jan 19 05:13:07 athlon kernel: hdc: Wakeup request inited, waiting for !BSY...
Jan 19 05:13:07 athlon kernel: hdc: start_power_step(step: 1000)
Jan 19 05:13:07 athlon kernel: blk: queue c1334600, I/O limit 4095Mb (mask 0xffffffff)
Jan 19 05:13:07 athlon kernel: hdc: completing PM request, resume
Jan 19 05:13:07 athlon kernel: hdd: Wakeup request inited, waiting for !BSY...
Jan 19 05:13:07 athlon kernel: hdd: start_power_step(step: 1000)
Jan 19 05:13:07 athlon kernel: blk: queue c1334200, I/O limit 4095Mb (mask 0xffffffff)
Jan 19 05:13:07 athlon kernel: hdd: completing PM request, resume
Jan 19 05:13:07 athlon kernel: Fixing swap signatures... <3>bad: scheduling while atomic!
Jan 19 05:13:07 athlon kernel: Call Trace:
Jan 19 05:13:07 athlon kernel:  [] schedule+0x566/0x570
Jan 19 05:13:07 athlon kernel:  [] generic_unplug_device+0x72/0x80
Jan 19 05:13:07 athlon kernel:  [] blk_run_queues+0xad/0xc0
Jan 19 05:13:07 athlon kernel:  [] io_schedule+0xe/0x20
Jan 19 05:13:07 athlon kernel:  [] wait_on_page_bit+0xa2/0xd0
Jan 19 05:13:07 athlon kernel:  [] autoremove_wake_function+0x0/0x50
Jan 19 05:13:07 athlon kernel:  [] autoremove_wake_function+0x0/0x50
Jan 19 05:13:07 athlon kernel:  [] swap_readpage+0x5b/0x80
Jan 19 05:13:07 athlon kernel:  [] rw_swap_page_sync+0xba/0x110
Jan 19 05:13:07 athlon kernel:  [] mark_swapfiles+0x7e/0x1b0
Jan 19 05:13:07 athlon kernel:  [] do_magic_resume_2+0x99/0xe0
Jan 19 05:13:07 athlon kernel:  [] do_magic+0x11f/0x140
Jan 19 05:13:07 athlon kernel:  [] do_software_suspend+0x6b/0x90
Jan 19 05:13:07 athlon kernel:  [] acpi_system_write_sleep+0xc3/0xe6
Jan 19 05:13:07 athlon kernel:  [] vfs_write+0xad/0x120
Jan 19 05:13:07 athlon kernel:  [] sys_write+0x3f/0x60
Jan 19 05:13:07 athlon kernel:  [] syscall_call+0x7/0xb
Jan 19 05:13:07 athlon kernel: ok
Jan 19 05:13:07 athlon kernel: Restarting tasks...<3>bad: scheduling while atomic!
 
Jan 19 05:13:07 athlon kernel:  done
Jan 19 05:13:07 athlon kernel: bad: scheduling while atomic!
Jan 19 05:13:07 athlon kernel: Call Trace:
Jan 19 05:13:07 athlon kernel:  [] schedule+0x566/0x570
Jan 19 05:13:07 athlon kernel:  [] sys_write+0x3f/0x60
Jan 19 05:13:07 athlon kernel:  [] work_resched+0x5/0x16
Jan 19 05:13:07 athlon kernel:
Jan 19 05:13:07 athlon kernel: bad: scheduling while atomic!
Jan 19 05:13:07 athlon kernel: Call Trace:
Jan 19 05:13:07 athlon kernel:  [] schedule+0x566/0x570
Jan 19 05:13:07 athlon kernel:  [] do_page_fault+0x11d/0x579
Jan 19 05:13:07 athlon kernel:  [] release_console_sem+0xd3/0xe0
Jan 19 05:13:07 athlon kernel:  [] sys_sched_yield+0x87/0xd0
Jan 19 05:13:07 athlon kernel:  [] coredump_wait+0x33/0xa0
Jan 19 05:13:07 athlon kernel:  [] __print_symbol+0x12a/0x160
Jan 19 05:13:07 athlon kernel:  [] do_coredump+0x10f/0x1f5
Jan 19 05:13:07 athlon kernel:  [] specific_send_sig_info+0xc8/0x140
Jan 19 05:13:07 athlon kernel:  [] __dequeue_signal+0xf5/0x1a0
Jan 19 05:13:07 athlon kernel:  [] dequeue_signal+0x2d/0x90
Jan 19 05:13:07 athlon kernel:  [] get_signal_to_deliver+0x205/0x380
Jan 19 05:13:07 athlon kernel:  [] do_signal+0xb4/0xf0
Jan 19 05:13:07 athlon kernel:  [] recalc_task_prio+0x90/0x1a0
Jan 19 05:13:07 athlon kernel:  [] schedule+0x2fe/0x570
Jan 19 05:13:07 athlon kernel:  [] do_page_fault+0x0/0x579
Jan 19 05:13:07 athlon kernel:  [] do_notify_resume+0x59/0x5c
Jan 19 05:13:07 athlon kernel:  [] work_notifysig+0x13/0x15

Ура! Все работает. Ну или почти все.

Если вам интересно, то смотрите свой syslog.

Единственное замечание, которое возникает, – запись «while atomic». Ядро находится в режиме, когда нельзя обрабатывать прерывания – разделять работу. Также рекомендуется не иметь «активных» процессов в системе во время подготовки ко сну. Под «активными» процессами я подразумеваю те, которые на момент засыпания ведут активные операции по переработке данных (пусть, например, это будет операция select в mysql-базе).

Перед засыпанием мы запускали dmesg:

Resume Machine: resuming from /dev/hdc5
Resuming from device hdc5
Resume Machine: This is normal swap space
PM: Reading pmdisk image.
PM: Resume from disk failed.
ACPI: (supports S0 S1 S3 S4 S5)

Подсистема гибернации обнаружила, что в swap-разделе запись «SWAPSPACE2»:

dd if=/dev/hdc5 bs=1k count=4 2> /dev/null | strings | grep SWAP

поэтому возобновление не было произведено.

После просыпания опять запустим dmesg:

Fixing swap signatures... ok
Restarting tasks... done

Все прошло удачно. Поздравляю!

Теперь немного пошалим. После очередного засыпания укажем ядру, что возобновление из swap-раздела делать не надо.

Передаем параметры ядру:

"noresume init=/bin/sh"

Мы не в полноценном режиме, поэтому процессы из /etc/rc.d не запустились.

dd if=/dev/hdc5 bs=1k count=4 2> /dev/null | strings | grep SUSP

На выходе у нас строчка «S2SUSP», означающая, что swap-раздел работает в качестве хранилища для содержимого RAM.

Поэтому, когда вы увидите строку «Fixing swap signatures... ok», не удивляйтесь, так и должно быть.

С подменой сигнатур мы разобрались. Теперь идем дальше. А что если усыпить систему на одном железе, а разбудить на другом? Ну что ж, скажу сразу, мне пока этого не удалось. Опишу свои действия.

Я пересобрал ядро, чтобы оптимизация была под 586MMX-архитектуру. Это позволит загрузиться как под Athlon XP, так и под Intel MMX процессорами.

Перед сессией засыпания под Athlon XP 1700+ процессором я указал ядру, что памяти у меня немного, всего лишь 32 Мб (mem=32M). Это необходимо, так как на системе, где я собираюсь проснуться (точнее не я, а мой slackware-винт), всего-то 32 Мб памяти.

Смотрим в syslog после просыпания:

Jan 24 11:47:44 athlon kernel: Resume Machine: resuming from /dev/hdc5
Jan 24 11:47:44 athlon kernel: Resuming from device hdc5
Jan 24 11:47:44 athlon kernel: Resume Machine: Signature found, resuming
Jan 24 11:47:44 athlon kernel: Resume Machine: Incorrect machine type
Jan 24 11:47:44 athlon kernel: Resume Machine: Error -1 resuming

Очень жаль, попытка не удалась.

Попробуем теперь произвести на сходной системе, процессор, правда, не Athlon XP 1700+, а чуть пониже – 1600+.

Еще раз «усыпляю» на родном железе и просыпаемся на новой машине. Скажу сразу – сообщений от ядра я не получил, так как «Resume Machine» при восстановлении регистров процессора приказала долго жить. Так что в этом направлении можно еще работать. Теоретически никто не запрещает, вариант вполне зрелый.

Обращаю ваше внимание, что когда винт с установленной системой перемещаете по разным машинам, не забывайте указывать, сколько памяти у вас есть. Иначе получите следующие сообщения:

Jan 22 16:59:02 athlon kernel: Resume Machine: Signature found, resuming
Jan 22 16:59:02 athlon kernel: Resume Machine: Incorrect memory size
Jan 22 16:59:02 athlon kernel: Resume Machine: Error -1 resuming

Теперь о самом интересном – о возможных последствиях при возобновлении работы.

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

cat /etc/mtab | grep smbfs

Узнали точки монтирования и знаем, что необходимо перемонтировать заново.

Второе. Приложения, которые перед засыпанием использовали звуковую карту, при возобновлении работы хранят молчание. Не произошла инициализация контроллера?

Укажу, что за система у меня.

bash-2.05b# lspci
00:00.0 Host bridge: VIA Technologies, Inc. VT8377 [KT400 AGP] Host Bridge
00:01.0 PCI bridge: VIA Technologies, Inc. VT8235 PCI Bridge
00:10.0 USB Controller: VIA Technologies, Inc. USB (rev 80)
00:10.1 USB Controller: VIA Technologies, Inc. USB (rev 80)
00:10.2 USB Controller: VIA Technologies, Inc. USB (rev 80)
00:10.3 USB Controller: VIA Technologies, Inc. USB 2.0 (rev 82)
00:11.0 ISA bridge: VIA Technologies, Inc. VT8235 ISA Bridge
00:11.1 IDE interface: VIA Technologies, Inc. VT82C586/B/686A/B PIPC Bus Master IDE (rev 06)
00:11.5 Multimedia audio controller: VIA Technologies, Inc. VT8233 AC97 Audio Controller (rev 50)
00:12.0 Ethernet controller: VIA Technologies, Inc. VT6102 [Rhine-II] (rev 74)
01:00.0 VGA compatible controller: nVidia Corporation NV18 [GeForce4 MX 440 AGP 8x] (rev a2)

USB-свистка у меня нет, поэтому ничего сказать не могу про поведение USB-шины. Однако сообщения ниже меня смутили.

Jan 24 15:03:29 athlon kernel: drivers/usb/host/uhci-hcd.c: d800: host controller halted. very bad
Jan 24 15:03:29 athlon kernel: drivers/usb/host/uhci-hcd.c: d400: host system error, PCI problems?
Jan 24 15:03:29 athlon kernel: drivers/usb/host/uhci-hcd.c: d400: host controller halted. very bad
Jan 24 15:03:29 athlon kernel: drivers/usb/host/uhci-hcd.c: d800: host controller halted. very bad
Jan 24 15:03:29 athlon kernel: drivers/usb/host/uhci-hcd.c: d400: host controller halted. very bad
Jan 24 15:03:29 athlon kernel: drivers/usb/host/uhci-hcd.c: d000: host system error, PCI problems?
Jan 24 15:03:29 athlon kernel: drivers/usb/host/uhci-hcd.c: d000: host controller halted. very bad

Под X-Window лично меня смущает, что библиотека GNOME неправильно отрисовывает некоторые элементы. Так как, некоторые приложения у меня на основе GNOME, то приведенные ниже картинки позволяют увидеть, что некоторые элементы отсутствуют. Видимо это ошибка в самой GNOME-библиотеке, хотя данный факт сейчас рассматривается на приложениях, использующих другие библиотеки.

Рисунок 1

Рисунок 2

Как видим, некоторые элементы отсутствуют.

Рестарт X-сервера решает эти проблемы.

Итог

В целом, мне понравилась реализация «сна». При более детальном подходе, может быть, кто-то уже и решил указанные в статье недочеты, во всяком случае http://www.google.com – ваш надежный путеводитель.


Комментарии отсутствуют

Добавить комментарий

Комментарии могут оставлять только зарегистрированные пользователи

               Copyright © Системный администратор

Яндекс.Метрика
Tel.: (499) 277-12-41
Fax: (499) 277-12-45
E-mail: sa@samag.ru