さて、以前から問題にしていたUbuntu 14.04におけるサスペンド機能不全問題。 もしかしてオイラのところだけで起きているのではないか…とすら思えるのですが*1
なお、NEC(現ルネサス)のUSB3.0チップを搭載するP67A-GD55では、この問題は発生していませんので、USB3.0増設カードを買うのも一興かもです。
うちの環境で確実に再現する手段は
以後、サスペンドに入るとモニタの電源を一瞬だけ落とす感じですぐにレジュームするという現象です。なお、USB3.0のHDDをアンマウントする前にサスペンドすると何故か大丈夫というオモシロ現象まで起きているのでした。
確か12.04の時は起きていなかったと思うのですが、かなりうろ覚え…
とりあえずの対策は全てのUSBからのウェイクアップをdisableする、すなわちrootにて
echo 'disabled' > /sys/bus/pci/devices/0000:00:1d.0/power/wakeup
echo 'disabled' > /sys/bus/pci/devices/0000:00:1a.0/power/wakeup
echo 'disabled' > /sys/bus/pci/devices/0000:00:14.0/power/wakeup
というものでした。*2
そこでもうキーボードなどからのレジュームは諦め、daemonを作って常にdisableしてやろうかなと思ったのですがなんか迂遠な気がするし、不慣れな自分ではトライ&エラーが必須で面倒くさい。
そこで、ハッとひらめきました。
/etc/pm/sleep.d/に自分専用の設定を作り、そこでサスペンド直前にdisableしてしまえばお手軽確実なのでは?
と。
USBのウェイクアップを停止するのは、既に専用スクリプトは組んであるのでそれを呼び出すだけでいい。
そして専用スクリプトも多少手を加えて、既にdisabledであればそれ以上echoしない(別に問題はないと思うのだけど、気持ち悪いので)ように改造したのが、以下のものです。
change_usb_wakeup.sh
#!/bin/bash cmdstr="disabled" while [ "$1" != "" ];do case $1 in -e | --enable) cmdstr="enabled" ;; -d | --disable) cmdstr="disabled" ;; * ) echo $1 is unrecognized option ;; esac shift 1 done function exec_disable { local syspath=/sys/bus/pci/devices/0000\:00\:${1}.0/power/wakeup local state=`cat $syspath` if [ "$state" != "$cmdstr" ];then echo "echo '${cmdstr}' > $syspath" echo "${cmdstr}" > $syspath else echo $syspath has been already set as $cmdstr fi } exec_disable 1d exec_disable 1a exec_disable 14
これを、/etc/pm/sleep.d/99-disable-usb-wakeup とする、以下のファイルにから呼び出します
#!/bin/sh case "$1" in suspend) /usr/local/scripts/change_usb_wakeup.sh ;; resume) ;; esac
当然ながらchange_usb_wakeup.shのパスは環境に応じて変更してくださいw
これで電源ボタンからしかレジュームできなくなりましたが、まぁ、いいかぁと。