# Power Management (日本語)

関連記事

- Power saving
- Display Power Management Signaling
- サスペンドとハイバネート

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

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

- カーネルパラメータ
- カーネルモジュール
- udev ルール

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

- systemd
- pm-utils
- Laptop Mode Tools
- TLP
- acpid

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

## 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`。

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

Note:

- 変更を適用するには `systemctl restart systemd-logind` を実行してください。
- Systemd は AC やバッテリの ACPI イベントを取り扱うことはできません、Laptop Mode Tools などのツールを使うには、依然として acpid が必要になります。
- 外付けモニターが接続されている場合、フタが閉じられても `HandleLidSwitch` オプションはアクションを実行しません。

Warning: systemd バージョン 210 以上では、`HandleLidSwitch` オプションは NVIDIA バイナリドライバーがインストールされている環境では使用できません。systemd のバグトラッカーや BBS のトピックを参照してください。

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

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

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

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

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

`systemctl suspend` は何も設定しなくても動きますが、あなたの環境で `systemctl hibernate` を使うには Suspend and 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 が停止した後に止められます。
- Because sleep.target は suspend.target, hibernate.target, hybrid-sleep.target から呼ばれ sleep.target 自身は StopWhenUnneeded サービスなので、タスクごとにフックが正しく起動・停止することが保証されています。

##### /usr/lib/systemd/system-sleep のフック

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

- 引数 1: `pre` か `post`。マシンが停止するときと起動するとき。
- 引数 2: `suspend` か `hibernate` か `hybrid-sleep`。呼び出されるものによる。

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

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

    # journalctl -b -u systemd-suspend

Note: カスタムスクリプトを使うかわりに `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.special` や `man 8 systemd-sleep` を見て下さい。

## 参照

- Laptop (日本語)#電源管理 ではラップトップでの電源管理（特にバッテリー状態の監視）を説明しています。
- General Recommendations (日本語)#電源管理

Category:

- Power management (日本語)