必要なときだけ電源オン
主にバックアップをとらせているPCでrtcwake + sleepdでそういうのをやってみている。
ハードウェアのタイマーで定時に電源オン、ジョブ(バックアップ)の終わりに電源オフを仕込む、というのがシンプルなのだろうけど
- ハードウェア側の設定画面をいじるのは面倒なのでPC上でなんとかしたい
- 電源オンと電源オフの設定場所が異なるのがそもそもいやな感じ
- バックアップ以外で使うことがたまにある(たとえばPC自体の管理作業)
- そういう作業中に突然電源が落ちたらとても悲しい(そういうときは事前に電源オフしないようにしてけばいいのだが、どうせ忘れる)
とかあって、何とかならないかなと考えてみた。
rtcwakeは、次の起動日時を設定した後にACPIのステートを変更するためのコマンド。実質的には/sys/class/rtc/〜
と/sys/power/state
に文字列を書き込んでいる。
ACPIというか、PMのステートを変更するのにはpm-suspendが使われることのほうが多いかもしれないが、これらにしてもわりと多くの環境で同じような処理になるのではないかと思う。いずれにしてもpm-suspendでは起動日時を指定できないっぽい。よってrtcwakeを使う。(rtcwakeで起動日時だけ設定し、ステート変更はpm-hogehogeで行うというやり方も可能。)
sleepdは、いくつかの条件が成立したときにpm-suspendを実行してPCをスリープさせる。もともとはノートPCで(ラップトップPCかも)使うために作られた。
指定できる条件としては
- キー・マウスからの入力がない
- wtmpの更新がない
- loadavgが指定値以下のまま
- ネットワークトラフィックが指定値以下のまま
- それとバッテリー残量が指定値以下になった
と必要なものがそろっている。バックアップはloadavgを上げるし、ネットワークトラフィックも多い。バックアップ以外の作業をしているときはwtmpの更新がある程度はあるはずで、状況によっては通信も発生する。他方、これという作業をしていなくてもときおり発生するちょっとした通信(DNS参照とか)を無視させることもできないではない。(閾値の加減しだいだが。)
ただ、ちょっとやっかいなのが次の起動日時を決める方法。定時に起動するというのは、たとえば基本的に毎日3:00に起動させたいとすると、個々の起動日時指定では「次にやってくる3:00」を与えなくてはならない。1:00に電源オフしたなら同時の3:00、4:00に電源オフしたなら翌日の3:00。
それから、2:59に電源オフして直後の3:00に電源オンというのは避けたい気がする。となると、2:59に電源オフになりそうだったら、それはちょっとよしといて起動したままにしておきたい。
というような事情があって、sleepdからはちょっとしたRubyスクリプトを実行するようにして、その中からrtcwakeを実行させることにした。
ついでに言えば電源オフ→オンの前後でやらせたい処理がいくらかありもする。そういうのはpm-suspendを使えば用意された仕組みの中で対処できるのだが、そうしたらしたで設定がsleepdとpmとにわかれてしまう。バックアップ以外のいろいろをやっている状況ならば、それでもメリットがある。しかし今のところほぼバックアップのみなのでsleepd内で済ませる形で運用してみることにした。(/etc/defaults/sleepd
と前述のRubyスクリプトに起述する。環境変数を除いてなければdefaultsだけに寄せることもできそうだが未確認。)
で、だいたいのところでやりたいことを実現できているのだけど、時々、PCがささってしまうのが今の悩み。これが原因がよくわからない。ログには特別なものは出てないし。
なんとなくNFSにがつっとアクセスが入ったタイミングでささっているようにも見えるのでumont; mount; sync
とかやらせてみたりしたところ、少し状況が良くなったのだけど、解決とまではいかない。それで、まったく根拠はないのだけどkernelをtestingから引っぱってみたりしているところ。これでダメだとステートをS5にして復帰してくれるかを確認して〜とやるしかないか。
あ、あと、電源オン・オフを毎日繰り返すことになってしまうのもちょっと気掛かりなところ。やっぱ壊れやすくなるのるかしら。