Не так давно я начал пользоваться режимом
Suspend-to-RAM на своем домашнем компьютере, это гораздо удобней и быстрей, чем его постоянно включать и выключать. По началу все было хорошо, но потом я начал замечать странности которые заставляли грустить.
Первая проблема была очень для меня неожиданна, компьютер засыпал нормально, но стоило мне включить или выключить рядом с ним какой нибудь электроприбор, компьютер сразу же просыпался.
Выяснилось все методом исключения, виновником оказалась клавиатура, видимо плата улавливала электроволны и посылала компьютеру сигнал, он просыпался. Клавиатуру заменил, проблему решил.
Вторая проблема оказалась более геморройная, с ней я возился пару дней, и до сих пор не уверен, что она решена, при каждом
suspend'e ожидаю зависона.
Не понятно при каких условиях компьютер не до конца уходил в
Ждущий режим и зависал, кулеры крутились, экран был черный с неподвижным вверху слева курсором. Гуглил ночи напролет, нашел лишь нечто подобное в вики Arch'a [
https://wiki.archlinux.org/index.php/pm-utils#Black_screen_with_unblinking_cursor_when_trying_to_suspend ], но у меня не было
pm-utils, в
suspend компьютер отправлял
systemd. И я даже пробовал запилить скрипт который будет выгружать рекомендованный в вики модуль, и запилил его, но он зараз тоже не помог, проблема оставалась. Скрипт, вдруг кому пригодится прикрепил в конце заметки.
В общем выяснил,
systemd-suspend всего лишь делает отправляет текст
mem(если у вас suspend to ram) в
/sys/power/state, ну и естественно я начал пробовать в ручную загонять в ждущий режим компьютер командой:
sudo sh -c "echo mem > /sys/power/state"
На мое удивление компьютер успешно засыпал и ни разу не завис.
Ну я и решил переопределить службу
systemd-suspend.service, для этого создал файл
/etc/systemd/system/systemd-suspend.service
[Unit]
Description="Custom suspend service"
DefaultDependencies=no
Requires=sleep.target
After=sleep.target
[Service]
Type=oneshot
Environment=SYSTEMD_LOG_LEVEL=debug
ExecStart=/bin/sh -c "echo mem > /sys/power/state"
Выполнил команду перезагрузки служб
systemctl daemon-reload
, и стал наслаждаться Ждущим режимом без зависаний, чего и вам советую.
На дату написания заметки у меня следующее ядро
4.4.5-1-ARCH и версия
systemd 229-3
UPD 08.04.2016:
Случился зависон, я опять в поисках решения :-D
UPD 21.04.2016
Уже прошло около недели, аптайм компьютера показывает 5дней...5 дней успешных «засыпаний» и «пробуждени», все что сделал, это выставил в BIOS частоту и тайминги оперативной памяти в режим
Auto, вычитал это на форуме, на удивление помогло.
UPD 06.06.2016
Случайно поймал очередной завис, решил затестить память, одна из планок оказалось глючной, списался с корсарами, предложили мне ее поменять, но оказалось доставка до Нидерландов планки памяти ~7.5к через DHL, дешевле купить новую, так и сделал, и вновь была неделя без зависов, но все же он случился, докупил еще планку и вернул глючную на место…
Загоняю в спящий режим используя
pm-suspend, тьфу тьфу, полет нормальный.
А это обещанный скрипт выгрузки модулей взятый из
pm-utils
/lib/systemd/system-sleep/modules.sh
#!/bin/sh
SUSPEND_MODULES="ehci_hcd"
STORAGEDIR="/var/run/suspend"
mkdir -p ${STORAGEDIR}
modunload()
{
local MOD D C USED MODS I
local UNL="$(echo $1 |tr - _)" RET=1
while read MOD D C USED D; do
[ "$MOD" = "$UNL" ] || continue
if [ "$USED" = "-" ]; then
# no dependent modules, just try to remove this one.
_rmmod "$MOD" $C
RET=$?
else
# modules depend on this one. try to remove them first.
MODS=",${USED%,}"
while [ -n "${MODS}" ]; do
# try to unload the last one first
MOD="${MODS##*,}"
modunload $MOD && RET=0
# prune the last one from the list
MODS="${MODS%,*}"
done
# if we unloaded at least one module, then let's
# try again!
[ $RET -eq 0 ] && modunload $MOD
RET=$?
fi
return $RET
done < /proc/modules
# if we came this far, there was nothing to do,
# the module is no longer loaded.
return 0
}
_rmmod()
{
if modprobe -r "$1"; then
touch "${STORAGEDIR}/module:$1"
return 0
else
log "# could not unload '$1', usage count was $2"
return 1
fi
}
modreload()
{
for x in "${STORAGEDIR}"/module:* ; do
[ -O "${x}" ] || continue
modprobe "${x##*:}" >/dev/null 2>&1 || \
log "Could not reload module ${x##*:}."
done
}
case $1/$2 in
pre/suspend)
for x in $SUSPEND_MODULES ; do
printf "Unloading kernel module %s..." "$x"
modunload $x && echo Done. || echo Failed.
done
;;
post/suspend)
modreload
echo "Reloaded unloaded modules."
;;
esac
Комментарии ()