電源管理/サスペンドとハイバネート
現在サスペンドには3つの手法が存在します: suspend to RAM (通常はサスペンドとだけ呼ばれます)、suspend to disk (通常はハイバネートと呼ばれます)、そして hybrid suspend (suspend to both とも呼ばれます):
- Suspend to RAM は RAM を除くマシンのほとんど全てのパーツの電源を切ります。RAM への電源はマシンの状態を保存するために必要です。電力を多く節約できるので、ラップトップでは、バッテリーでコンピュータが稼働していてフタが閉じられた時 (もしくはユーザーが長い間操作しなかった時) は自動的にこのモードに移行するのが得策でしょう。
- Suspend to disk はマシンの状態をスワップ領域に保存してマシンの電源を完全にオフにします。マシンに電源を入れた時、状態が復元されます。それまでは、電力消費量はゼロです。
- Suspend to both はマシンの状態をスワップ領域に保存しますが、マシンの電源を切りません。代わりに、通常の suspend to RAM を呼び出します。これによって、バッテリーを使いきっても、システムを RAM から復帰することが可能です。バッテリーが枯渇した時は、システムはディスクから復帰し、RAM からの復帰に比べて時間がかかりますが、システムの状態が失われることはありません。
基本的な機能を提供する低レベルなインターフェイス (バックエンド) が複数存在し、問題のあるハードウェアドライバ・カーネルモジュール (例: ビデオカードの再初期化) を扱う機能を提供する高レベルなインターフェイスもいくつかあります。
低レベルインターフェイス
これらのインターフェイスは直接使うこともできますが、通常は高レベルインターフェイスを使ってサスペンド・ハイバネートを行うとよいでしょう。低レベルなインターフェイスを直接使うと、サスペンドの前や後に行うフック処理を全て実行する高レベルインターフェイスよりもかなり早くサスペンドが可能です。ただしフックはハードウェアクロックの設定や、ワイヤレスの復旧などを正しく処理することができます。
カーネル (swsusp)
直球の方法はカーネル内のソフトウェアサスペンドコード (swsusp) にサスペンド状態に入るよう直接伝えることです。実際の方法と状態はハードウェアサポートのレベルによります。最近のカーネルでは、サスペンドにするために /sys/power/state
に適切な文字列を書くことが主な方法になっています。
詳しくは カーネルドキュメント を参照してください。
uswsusp
uswsusp ('Userspace Software Suspend') はカーネルの suspend-to-RAM のラッパーで、サスペンドの前と復帰の後にユーザー空間からグラフィックアダプタの操作を行います。
Uswsusp の記事を参照してください。
tuxonice
TuxOnIce はサスペンド・ハイバネートのカーネル実装のフォークで、デフォルトの実装を改善するカーネルパッチを提供しています。これを使うためにはカスタムカーネルが必要です。
TuxOnIce の記事を参照してください。
高レベルインターフェイス
systemd
systemd はサスペンド・ハイバネート・ハイブリッドサスペンドを行うためのネイティブのコマンドを提供しています。詳しくは 電源管理#systemd による電源管理 を見て下さい。これは Arch Linux で使われているデフォルトのインターフェースです。
サスペンド・ハイバネートのフックの設定に関する情報は電源管理#スリープフックに載っています。man systemctl
, man systemd-sleep
, man systemd.special
もあわせて参照してください。
pm-utils
pm-utils はバックエンドのサスペンド・ハイバネート機能をカプセル化するシェルスクリプトのセットです。サスペンドの前後に行う設定やプロセスをカスタマイズするための様々なフックも入っています。
pm-utils の記事を参照してください。
ハイバネーション
ハイバネーションを使うには、スワップパーティションかスワップファイルを作成する必要があります。そして resume=
カーネルパラメータを使ってスワップを指定してください。カーネルパラメータはブートローダで設定します。initramfs の設定も必要になります。設定によってカーネルは初期ユーザー空間で指定されたスワップからの復帰を試みます。以下ではスワップの作成・カーネルパラメータの設定・initramfs の設定について詳細に説明します。
スワップパーティション(ファイル)のサイズについて
スワップパーティションが RAM より小さかったとしても、ハイバネートが成功する可能性は高いと思われます。カーネルドキュメント によると:
/sys/power/image_size
は suspend-to-disk によって作成されるイメージのサイズを制御します。イメージサイズの上限として使われる負ではない整数 (バイト) を示す文字列で書くことが出来ます。suspend-to-disk はイメージサイズがその数字を超えないように出来る限りのことをします。ただし、それが無理だということがわかったら、とにかく出来る限り小さいイメージを使ってサスペンドを試みます。特に、このファイルに "0" と書かれていた場合、サスペンドのイメージは目一杯小さくなります。このファイルを読むと現在のイメージのサイズ制限が表示され、デフォルトでは利用可能な RAM の2/5に設定されています。
(スワップパーティションを小さくして) /sys/power/image_size
の値を減らしてサスペンドのイメージを出来る限り小さくすることも、値を増やしてハイバネーションを高速化することも可能です。
必要なカーネルパラメータ
カーネルパラメータ resume=swap_partition
を使う必要があります。swap_partition
にはカーネルが割り当てたスワップパーティションの名前か、スワップパーティションの UUID を使うことができます。例:
resume=/dev/sda1
resume=UUID=4209c845-f495-4c43-8a03-5363dd433153
resume=/dev/mapper/archVolumeGroup-archLogicVolume
-- LVM を使う場合の例
resume
パラメータで使用する命名法は基本的に root
パラメータで使用する命名法と同じにしてください。
設定は使用しているブートローダーによって異なります。詳しくはカーネルパラメータを参照してください。
スワップファイルにハイバネーション
スワップパーティションの代わりにスワップファイルを使うには追加のカーネルパラメータ resume_offset=swap_file_offset
が必要です。
swap_file_offset
の値は filefrag -v swap_file
を実行することで取得できます。テーブル形式で出力され、必要な値は physical_offset
カラムの一番上の段にあります。例えば:
# filefrag -v /swapfile
Filesystem type is: ef53 File size of /swapfile is 4294967296 (1048576 blocks of 4096 bytes) ext: logical_offset: physical_offset: length: expected: flags: 0: 0.. 0: 38912.. 38912: 1: 1: 1.. 22527: 38913.. 61439: 22527: unwritten 2: 22528.. 53247: 899072.. 929791: 30720: 61440: unwritten ...
この例では swap_file_offset
の値は2つのピリオドが付いている最初の 38912
です。
swap_file_offset
の値は swap-offset swap_file
でも取得することができます。swap-offset バイナリは uswsusp-gitAUR パッケージに含まれています。
initramfs の設定
- initramfs で
base
フックを使っている場合 (Arch ではデフォルトで使っています)、/etc/mkinitcpio.conf
にresume
フックを追加する必要があります。ラベルあるいは UUID どちらを使用している場合でもスワップパーティションは udev デバイスノードによって参照されるので、resume
フックは必ずudev
の後に追加してください。デフォルトのフック設定にresume
フックを追加すると以下のようになります:
HOOKS="base udev resume autodetect modconf block filesystems keyboard fsck"
- 変更を適用するために initramfs の再生成を忘れずに行ってください。
- initramfs で
systemd
フックを使っている場合は、復帰機構が既に提供されているので、フックを追加する必要はありません。
トラブルシューティング
ACPI_OS_NAME
DSDT table を動作するように設定することができます。DSDT の記事を参照してください。
VAIO ユーザー
acpi_sleep=nonvs
カーネルフラグをブートローダに追加してください、これで OK です!
サスペンド/ハイバネートが動作しない、あるいはたまに動作しなくなる
サスペンドやハイバネートをした場合、あるいは復帰した場合に画面が表示されなくなるという報告が多数存在します。ノートパソコンとデスクトップの両方で問題は確認されています。正式な解決方法ではありませんが、古いカーネル、特に LTS カーネルに切り替えることで問題は解決することがあります。
initramfs からのデバイスの初期化によって画面が表示されなくなっていることもあります。Mkinitcpio#MODULES に追加したモジュールを削除して initramfs を再生成することで問題が解決するかもしれません。特にグラフィックドライバのモジュールは問題を起こしがちです。復帰するまえにデバイスが初期化されると矛盾状態になってシステムがハイバネートから復帰できなくなります。サスペンドからの復帰の場合は関係ありません。サスペンドやハイバネートの問題をデバッグする際のベストプラクティスが こちらの記事 に記載されています。
Wake-on-LAN
Wake-on-LAN が有効になっている場合、コンピュータがハイバネート状態になっていてもネットワークインターフェイスカードによって電力が消費されます。
サスペンドからすぐに復帰する
LynxPoint や LynxPoint-LP チップセットが搭載された Intel Haswell の場合、サスペンドからすぐに復帰してしまうと報告されています。BIOS の ACPI 実装に問題があり起動時に xhci_hcd
モジュールによって ACPI イベントが解釈されてしまうのが原因です。解決策としてカーネルによってケースバイケースで問題のあるシステムがブラックリスト (XHCI_SPURIOUS_WAKEUP
) に追加されています [1]。
サスペンド中に USB デバイスを接続したときなどに ACPI の復帰トリガーが有効になって復帰してしまいます。ブラックリストに追加されるまで一時的な応急処置としては復帰トリガーを無効化する方法があります。以下の設定で USB による復帰を無効化することができます [2]。
現在の設定を確認:
$ cat /proc/acpi/wakeup
Device S-state Status Sysfs node ... EHC1 S3 *enabled pci:0000:00:1d.0 EHC2 S3 *enabled pci:0000:00:1a.0 XHC S3 *enabled pci:0000:00:14.0 ...
問題のデバイスは EHC1
, EHC1
, XHC
(USB 3.0) です。状態を変更するには root でデバイス名をファイルに echo してください:
# echo EHC1 > /proc/acpi/wakeup # echo EHC2 > /proc/acpi/wakeup # echo XHC > /proc/acpi/wakeup
上記のコマンドでサスペンドが再度機能するようになります。ただし、設定は一時的なものなので再起動するたびに設定し直す必要があります。自動化したい場合は systemd#カスタム .service ファイルを書くを見てください。詳しくは BBS スレッド を参照。