Powered By Blogger

Saturday, June 2, 2007

Toshiba Satellite A100-811: Ubuntu & power management

Странное дело, но после апгрейда до KUbuntu 7.04 Feisty Fawn на ноутбуке сломался hibernate suspend-to-disk. Правка /etc/hibernate/common.conf ничего не давала. Процесс сброса образа RAM на диск, кажется, шёл вполне нормально, но после возобновления (resume) X оказывался запорот. Система не висит - в неё даже можно залогиниться по ssh, но работа непосредственно на ноутбуке невозможна. Итак, немного подумав, я открыл для себя uswsusp и входящий сюда s2disk. Однако, и тут не всё было гладко. Одно время s2disk работал для меня вполне прекрасно, даже с некоторыми особенностями. Так, например, после слива образа на диск и закрытия крышки лаптопа при её отркывании система включалась сама, без нажатия кнопки power и linux возобновлялся. Но, позже появилась проблема. При открытии крышки ноутбук включался, появлялся сплэш и... всё. Сплэш замерзал на одном месте и система не возобновлялась. Немного подумав, я полез шерстить по конфигам. Итак, найдя файл /etc/uswsusp.conf, я сделал такую правку:

# /etc/uswsusp.conf(8) -- Configuration file for s2disk/s2both 
resume device = /dev/sda5
compress = y
early writeout = y
image size = 512000000
compute checksum = y
RSA key file = /etc/uswsusp.key
shutdown method = platform
splash = y
Поясню: до этого параметр splash в конфиге не был определён вообще, а image size был равен 236Мб с копейками. Как видно, я явно установил splash = y, для фидбэка в процессе слива образа RAM на диск и в процессе его считывания с диска, а image size в пол-гигабайта (объём RAM на моём ноутбуке - 512Мб). Как ни странно, но после этого всё заработало. Скажу честно, я исходил из ни на чём не обоснованного предположения, что всё дело именно в том, что на диск сливается не весь образ памяти. Это было довольно интуитивное решение. Экспериментировать со значением 0 я не стал, но в man uswsusp.conf написано, что при нулевом значении s2disk будет пытаться сделать образ как можно меньше, сохраняя только самый необходимый минимум.

Теперь s2disk работал. И работал прекрасно. Единственное, чего мне ещё не хватало, это чтобы он срабатывал автоматически при критическом уровне батареи (такая настройка у меня была и ранее - в целях предотвращения потерь данных. Вполне вероятна такая ситуация, когда Вы отойдёте, задержитесь где-то, а тем временем аккумулятор благополучно иссякнет и...). К сожалению, отрабатывало оно так же, как и усыпление через диалог KDE "Завершить сеанс" -> "Спящий режим", или точнее сказать, не работало вовсе. Linux просто гасил экран, блокировал сеанс KDE, а засыпать даже не думал. Я пользуюсь KLaptop. Так сложилось традиционно, да и просто, он субъективно нравится мне больше всяких там KPowersave. Там вполне можно было прописать, какую команду следует выполнить при критически малом уровне аккумулятора, но мне хотелось универсального решения, ведь для кнопки в KDE'шном завершении сеанса такой параметр не прописан. Механизм работы здесь однако был один. Это я знал по опыту - по одинаковому поведению при попытке усыпить ноутбук через KLaptop и "Завершение сеанса". Немного пошарив по google я нашёл решение. Оказалось, что hibernation здесь срабатывает через hal. Для того, чтобы исправить ситуацию, необходимо было заменить модуль hal, который отвечал за усыпление по требованию клиента. Этот модуль представляет собой нечто иное, как скрипт, лежащий в /usr/lib/halscripts/linux - hal-system-power-hibernate-linux. Моей целью было заставить этот скрипт отрабатывать через s2disk. Первоначально скрипт выглядёл следующим образом:

#!/bin/sh

POWERSAVED_SUSPEND2DISK="dbus-send --system --dest=com.novell.powersave \
                         --print-reply /com/novell/powersave \
                         com.novell.powersave.action.SuspendToDisk"

unsupported() {
 echo org.freedesktop.Hal.Device.SystemPowerManagement.NotSupported >&2
 echo No hibernate script found >&2
 exit 1
}

#SuSE and ALTLinux only support powersave
if [ -f /etc/altlinux-release ] || [ -f "/etc/SuSE-release" ] ; then
 if [ -x /usr/bin/powersave ] ; then
         $POWERSAVED_SUSPEND2DISK
  RET=$?
 else
  unsupported
 fi

#Mandriva support suspend-scripts 
elif [ -f /etc/mandriva-release ] ; then 
    if [ -x /usr/sbin/pmsuspend ] ; then 
 /usr/sbin/pmsuspend disk 
 RET=$? 
    else 
 unsupported 
    fi 

#RedHat/Fedora only support pm-utils
elif [ -f /etc/redhat-release ] || [ -f /etc/fedora-release ] ; then
 if [ -x /usr/sbin/pm-hibernate ] ; then
  /usr/sbin/pm-hibernate
  RET=$?
 else
  unsupported
 fi

#Other distros just need to have *any* tools installed
else
 if [ -x "/usr/bin/powersave" ] ; then
         $POWERSAVED_SUSPEND2DISK
  RET=$?
 elif [ -x "/usr/sbin/pmi" ] ; then
  /usr/sbin/pmi action hibernate force
  RET=$?
 elif [ -x "/usr/sbin/pm-hibernate" ] ; then
  /usr/sbin/pm-hibernate
  RET=$?
 elif [ -x "/usr/sbin/hibernate" ] ; then
  # Suspend2 tools installed
  /usr/sbin/hibernate --force
  RET=$?
 elif [ -x "/sbin/s2disk" ] ; then
  # uswsusp tools installed
  /sbin/s2disk
  RET=$?
 elif [ -x "/etc/acpi/hibernate.sh" ] ; then
  # acpi-support installed
  /etc/acpi/hibernate.sh force
  RET=$?
 elif [ -w "/sys/power/state" ] ; then
  # Use the raw kernel sysfs interface
  echo "disk" > /sys/power/state
  RET=$?
 else
  unsupported
  fi
 fi

#Refresh devices as a resume can do funny things
for type in button battery ac_adapter
do
 devices=`hal-find-by-capability --capability $type`
 for device in $devices
 do
  dbus-send --system --print-reply --dest=org.freedesktop.Hal \
     $device org.freedesktop.Hal.Device.Rescan
 done
done

exit $RET

Из приведённого листинга видно, что сперва скрипт пытается определить дистрибутив, а далее действует исходя из реалий данного дистрибутива. В моём случае hal пытался отработать через pmi - абстактный интерфейс управления энергосбережением. Мне же нужно было, чтобы первым и последним срабатывал s2disk. После исправления скрипт обрёл такой вид:

#!/bin/sh

[ SKIPPED ]

#Other distros just need to have *any* tools installed
else
 if [ -x "/sbin/s2disk" ] ; then
  # uswsusp tools installed
  /sbin/s2disk
  RET=$?
 elif [ -x "/usr/sbin/pmi" ] ; then
  /usr/sbin/pmi action hibernate force
  RET=$?
 elif [ -x "/usr/bin/powersave" ] ; then
         $POWERSAVED_SUSPEND2DISK
  RET=$?
 elif [ -x "/usr/sbin/pm-hibernate" ] ; then
  /usr/sbin/pm-hibernate
  RET=$?
 elif [ -x "/usr/sbin/hibernate" ] ; then
  # Suspend2 tools installed
  /usr/sbin/hibernate --force
  RET=$?
 elif [ -x "/etc/acpi/hibernate.sh" ] ; then
  # acpi-support installed
  /etc/acpi/hibernate.sh force
  RET=$?
 elif [ -w "/sys/power/state" ] ; then
  # Use the raw kernel sysfs interface
  echo "disk" > /sys/power/state
  RET=$?
 else
  unsupported
 fi
fi

[ SKIPPED ]
После этого и KLaptop и "Завершение сеанса" работают безупречно.

Кстати, режим suspend-to-ram у меня работал хорошо из коробки (после апгрейда до Feisty Fawn). s2ram напротив работать не хочет, ссылаясь на то, что модель ноута ему не знакома. Поэтому мои настройки энергосбережения закончились доведением до ума режима suspend-to-disk a.k.a. hibernation.

"Вот так мы победили сырость!" (с) Однако, есть ещё над чем поработать. Так, например, мне до сих пор не удалось заставить работать русский в консоли. Самое странное, что на десктопе с установленным Debian 4.0 Etch всё прекрасно работает (console-cyrillic не установлен). При такой же конфигурации на лаптопе оно не работает. Странность в том, что из коробки путём лишь небольших манипуляций после замены дистрибутивного ядра на собственное русский текст в UTF8 отображается в консоли без проблем, но нет возможности набирать русский текст. Вместо него не набирается вообще ничего. Одним словом, проблема всё ещё требует решения. В Edgy Eft в этом плане всё было отлично. Примечательно, что такие проблемы после перехода на Feisty Fawn наблюдаются не только у меня.

Вторая проблема более странная. С ней я пока не разбирался вплотную. Я наконец решил заставить работать встроенный модем. Поставил sl-modem-daemon, sl-modem-source для компиляции модулей под моё кастом-билт ядро. Но тут я столкнулся с тем, что sl-modem-source на уровне исходного кода не совместим с новыми ядрами. К примеру, в коде kernel-ver.c делается попытка подключить заголовок linux/version.h чтобы использовать макрос UTS_RELEASE, который в 2.6.20 (и не только в нём) уже определяется в другом файле - linux/utsrelease.h. Можно, конечно, и вручную подправить сырцы драйвера... Кстати, смешной момент, связанный с установкой драйвера. Если сказать apt-get install sl-modem-source, то в Вашем /usr/src появится тарбол sl-modem.tar.bz2 - это и есть сырцы драйвера. Далее, пытаемся ставить его с помощью module-assistant (хех, Debian-way): module-assistant prepare sl-modem; module-assistant install sl-modem и тут происходит ошибка. По вышеупомянутой причине. Правим сырцы, устраняем явные противоречия и снова пускаем m-a install sl-modem и... снова ошибка! В том же месте! :) Лезем в исходники и видим, наших изменений там нет! Так что, мораль в том, что если Вы собираетесь править сырцы sl-modem вручную, то Вам нужно будет из подправленных сырцов создать такой же тарбол с тем же именем, что и оригинал и заменить оригинал. Правда, я пошёл по другому пути - просто выкачал sl-modem-source из пула Debian Sid. Всё собралось без сучка и задоринки, но slmodemd всё равно не видит модули, хотя они и установлены в /lib/modules/`uname -r`/misc. Говорит: FATAL: Module slamr not found. Странно, короче. Можно было бы обойтись без модулей, используя alsa, но это, ИМХО - крайний случай.

No comments:

ПОСЕТИТЕЛИ

free counters