電源管理

提供: ArchWiki
2015年1月14日 (水) 14:24時点におけるKusakata (トーク | 投稿記録)による版
ナビゲーションに移動 検索に移動

関連記事

このページでは Arch Linux における電源管理の全体的な外観を説明します。Arch Linux はシステムマネージャとして systemd を使っているため、この記事では systemd に焦点をあてています。

電源管理の設定を変更するのに使える設定箇所は複数存在します:

また、電源管理ツールが多数あります:

ノート: ひとつの設定箇所・ツールで設定した電力設定が他の設定箇所・ツールで上書きされる可能性もあるので注意してください。

systemd による電源管理

ACPI イベント

systemd は電源関連の ACPI イベントを扱えます。/etc/systemd/logind.conf のオプションを使って設定できます:

  • HandlePowerKey: パワーキーが押された時に行う動作を定めます。
  • HandleSuspendKey: サスペンドキーが押された時に行う動作を定めます。
  • HandleHibernateKey: ハイバネートキーが押された時に行う動作を定めます。
  • HandleLidSwitch: フタが閉じられた時に行う動作を定めます。

定めることができる動作は ignore, poweroff, reboot, halt, suspend, hibernate, hybrid-sleep, lock, kexec のいずれかです。

オプションが設定されていない場合、systemd が使うデフォルトは: HandlePowerKey=poweroff, HandleSuspendKey=suspend, HandleHibernateKey=hibernate, HandleLidSwitch=suspend

グラフィカルセットアップを走らせていなかったり i3awesome などシンプルなウィンドウマネージャしか使っていないシステムでは、これで ACPI イベントに反応するものとして使っている acpid デーモンを置き換えることが可能です。

ノート:
  • 変更を適用するには systemctl restart systemd-logind を実行してください。
  • Systemd は AC やバッテリの ACPI イベントを取り扱うことはできません、Laptop Mode Tools などのツールを使うには、依然として acpid が必要になります。
  • 外付けモニターが接続されている場合、フタが閉じられても HandleLidSwitch オプションはアクションを実行しません。
警告: systemd バージョン 211 と 212 では、HandleLidSwitch オプションは NVIDIA バイナリドライバーがインストールされている環境では使用できません。この問題はバージョン 213 で修正されています。systemd のバグトラッカーBBS のトピックを参照してください。

現在のバージョンの systemd では、Handle* オプションは(デスクトップ環境のパワーマネージャなどの)プログラムによって "inhibited" (一時的にオフ) にされない限りシステム全体に適用されます。停止されなければ、systemd がシステムをサスペンドした状態で終わることができ、立ち上がった時に他のパワーマネージャによってもう一度停止されます。

警告: 現在、最新の KDEGNOME の電源マネージャは "inhibited" コマンドを実行します。Xfce や、acpid など他のプログラムで ACPI イベントを管理したい場合は、Handle オプションを ignore に設定する必要があります。

サスペンドとハイバネート

systemd はカーネルに入っているサスペンド・レジューム機能を使ってサスペンド (suspend to RAM)・ハイバネート・ハイブリッドサスペンドを行うコマンドを提供しています。また、サスペンドの前後の行動をカスタマイズするフックを追加する仕組みも存在します。

ノート: systemd はデフォルトのカーネルバックエンドに加えて、他のサスペンドバックエンド (UswsuspTuxOnIce) を使ってコンピュータをサスペンドしたりハイバネートすることもできます。例えば Uswsusp#With systemd を見て下さい。

systemctl suspend は何も設定しなくても動きますが、あなたの環境で systemctl hibernate を使うにはサスペンドとハイバネート#ハイバネーションの指示に従う必要があります。

スリープフック

systemctl suspend, systemctl hibernate, systemctl hybrid-sleep が実行された時、Systemd はマシンをスリープ状態にするのに pm-utils を使いません; カスタムフックを含む、pm-utils フックは実行されません。ただし、こうしたイベントでカスタムスクリプトを動かすための仕組みを systemd は2つ提供しています。

サスペンド/リジューム サービスファイル

サービスファイルを suspend.target, hibernate.target, sleep.target にフックすることでサスペンド・ハイバネート前後に行うアクションを設定できます。ユーザー・システムアクションを行うにはファイルを分割する必要があります。ユーザーサービスファイルを作動させるには、# systemctl enable suspend@<user> && systemctl enable resume@<user>。例:

/etc/systemd/system/suspend@.service
[Unit]
Description=User suspend actions
Before=sleep.target

[Service]
User=%I
Type=forking
Environment=DISPLAY=:0
ExecStartPre= -/usr/bin/pkill -u %u unison ; /usr/local/bin/music.sh stop ; /usr/bin/mysql -e 'slave stop'
ExecStart=/usr/bin/sflock

[Install]
WantedBy=sleep.target
/etc/systemd/system/resume@.service
[Unit]
Description=User resume actions
After=suspend.target

[Service]
User=%I
Type=simple
ExecStartPre=/usr/local/bin/ssh-connect.sh
ExecStart=/usr/bin/mysql -e 'slave start'

[Install]
WantedBy=suspend.target

root アクションでは (# systemctl enable root-suspend で有効にしてください):

/etc/systemd/system/root-resume.service
[Unit]
Description=Local system resume actions
After=suspend.target

[Service]
Type=simple
ExecStart=/usr/bin/systemctl restart mnt-media.automount

[Install]
WantedBy=suspend.target
/etc/systemd/system/root-suspend.service
[Unit]
Description=Local system suspend actions
Before=sleep.target

[Service]
Type=simple
ExecStart=-/usr/bin/pkill sshfs

[Install]
WantedBy=sleep.target

サービスファイルについてのヒント (詳しくは man systemd.service):

  • Type=oneshot の場合、複数の ExecStart= 行を使うことができます。それ以外の場合は使える ExecStart は一行だけです。ExecStartPre を使ったりコマンドをセミコロンで分割することでコマンドを追加することができます(最初の例を見て下さい -- セミコロンの前後にはスペースが必要です)。
  • コマンドの前に '-' を付けるとエラーが起こっても(終了ステータスが0以外でも)無視され、コマンドは成功したとして扱われます。
  • サービスファイルのトラブルシューティングのときにエラーを見つけるには journalctl を使うのがベストです。
サスペンド/レジューム サービスファイルの統合

サスペンド/レジューム サービスファイルを統合すれば、様々なフェイズ(スリープ・レジューム)やターゲット(サスペンド・ハイバネート・ハイブリッドスリープ)でやることをひとつのフックで行うことができます。

例と説明:

/etc/systemd/system/wicd-sleep.service
[Unit]
Description=Wicd sleep hook
Before=sleep.target
StopWhenUnneeded=yes

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=-/usr/share/wicd/daemon/suspend.py
ExecStop=-/usr/share/wicd/daemon/autoconnect.py

[Install]
WantedBy=sleep.target
  • RemainAfterExit=yes: 起動後、明示的に止められるまでサービスは常時 active になります。
  • StopWhenUnneeded=yes: active のとき、サービスは sleep.target が停止した後に止められます。
  • sleep.target は suspend.target, hibernate.target, hybrid-sleep.target から呼ばれ sleep.target 自身は StopWhenUnneeded サービスなので、タスクごとにフックが正しく起動・停止することが保証されています。
/usr/lib/systemd/system-sleep のフック

Systemd は /usr/lib/systemd/system-sleep/ 内の全ての実行可能ファイルを実行するときに、2つの引数を渡します:

  • 引数 1: prepost。マシンが停止するときと起動するとき。
  • 引数 2: suspendhibernatehybrid-sleep。呼び出されるものによる。

pm-utils とは対照的に、systemd はスクリプトを(一つずつではなく)同時に実行します。

カスタムスクリプトの出力は systemd-suspend.service, systemd-hibernate.service, systemd-hybrid-sleep.service によって記録されます。出力を見るには systemd の journal を使って下さい:

# journalctl -b -u systemd-suspend
ノート: カスタムスクリプトを使うかわりに sleep.target, suspend.target, hibernate.target, hybrid-sleep.target を使ってユニットをスリープステートロジックにフックさせることもできます。

カスタムスリープスクリプトの例:

/usr/lib/systemd/system-sleep/example.sh
#!/bin/sh
case $1/$2 in
  pre/*)
    echo "Going to $2..."
    ;;
  post/*)
    echo "Waking up from $2..."
    ;;
esac

スクリプトを実行可能にするのを忘れないで下さい:

# chmod a+x /usr/lib/systemd/system-sleep/example.sh

詳しくは man 7 systemd.specialman 8 systemd-sleep を見て下さい。

参照