「電源管理」の版間の差分
(→サスペンドとハイバネート: 同期) |
(→スリープフック: 同期) |
||
157行目: | 157行目: | ||
=== スリープフック === |
=== スリープフック === |
||
− | + | ==== サスペンド/リジュームのサービスファイル ==== |
|
− | サービスファイルを suspend.target |
+ | サービスファイルを ''suspend.target''、''hibernate.target''、''sleep.target''、''hybrid-sleep.target''、そして ''suspend-then-hibernate.target'' にフックすることで、サスペンド/ハイバネート前や後に行うアクションを設定できます。ユーザのアクションと root/システムのアクションを設定するには、別々のファイルを作成する必要があります。{{ic|suspend@''user''}} と {{ic|resume@''user''}} サービスを[[有効化]]してこれらをブート時に起動させてください。例: |
− | {{hc|/etc/systemd/system/suspend@.service|2= |
+ | {{hc|/etc/systemd/system/suspend@.service|2= |
[Unit] |
[Unit] |
||
Description=User suspend actions |
Description=User suspend actions |
||
170行目: | 170行目: | ||
Type=forking |
Type=forking |
||
Environment=DISPLAY=:0 |
Environment=DISPLAY=:0 |
||
− | ExecStartPre= -/usr/bin/pkill -u %u unison ; /usr/local/bin/music.sh stop |
+ | ExecStartPre= -/usr/bin/pkill -u %u unison ; /usr/local/bin/music.sh stop |
ExecStart=/usr/bin/sflock |
ExecStart=/usr/bin/sflock |
||
ExecStartPost=/usr/bin/sleep 1 |
ExecStartPost=/usr/bin/sleep 1 |
||
[Install] |
[Install] |
||
− | WantedBy=sleep.target |
+ | WantedBy=sleep.target |
+ | }} |
||
− | {{hc|/etc/systemd/system/resume@.service|2= |
+ | {{hc|/etc/systemd/system/resume@.service|2= |
[Unit] |
[Unit] |
||
Description=User resume actions |
Description=User resume actions |
||
185行目: | 186行目: | ||
User=%I |
User=%I |
||
Type=simple |
Type=simple |
||
− | + | ExecStart=/usr/local/bin/ssh-connect.sh |
|
− | ExecStart=/usr/bin/mysql -e 'slave start' |
||
[Install] |
[Install] |
||
− | WantedBy=suspend.target |
+ | WantedBy=suspend.target |
+ | }} |
||
+ | {{Note|スクリーンが"ロックされる"前にスクリーンロックが返ってきてしまい、サスペンドから復帰するときに画面が点滅することがあります。{{ic|1=ExecStartPost=/usr/bin/sleep 1}} で小さな遅延を追加することでこれを防止できます。}} |
||
− | {{Note| |
||
− | * [[アプリケーション一覧/セキュリティ#スクリーンロック|slock]] を使用する場合、スリープする前にサービスを起動してはいけません。デフォルトの simple サービスタイプを使って下さい。でないと、先に ''slock'' が起動して、ロックを解除しないとスリープに入らないようになってしまいます。forking タイプを指定しても解決しません。 |
||
− | * スクリーンがロックされる前にスクリーンロックが返ってきてしまい、サスペンドから復帰するときに画面が点滅することがあります。{{ic|1=ExecStartPost=/usr/bin/sleep 1}} で遅延を追加することで解決します。}} |
||
− | root |
+ | root/システムのアクションの場合 ({{ic|root-resume}} と {{ic|root-suspend}} を[[有効化]]してこれらをブート時に起動させてください): |
− | {{hc|/etc/systemd/system/root- |
+ | {{hc|/etc/systemd/system/root-suspend.service|2= |
[Unit] |
[Unit] |
||
− | Description=Local system |
+ | Description=Local system suspend actions |
− | + | Before=sleep.target |
|
[Service] |
[Service] |
||
Type=simple |
Type=simple |
||
− | ExecStart=/usr/bin/ |
+ | ExecStart=-/usr/bin/pkill sshfs |
[Install] |
[Install] |
||
− | WantedBy= |
+ | WantedBy=sleep.target |
+ | }} |
||
− | {{hc|/etc/systemd/system/root- |
+ | {{hc|/etc/systemd/system/root-resume.service|2= |
[Unit] |
[Unit] |
||
− | Description=Local system |
+ | Description=Local system resume actions |
− | + | After=suspend.target |
|
[Service] |
[Service] |
||
Type=simple |
Type=simple |
||
− | ExecStart= |
+ | ExecStart=/usr/bin/systemctl restart mnt-media.automount |
[Install] |
[Install] |
||
− | WantedBy= |
+ | WantedBy=suspend.target |
+ | }} |
||
− | サービスファイルについてのヒント (詳しくは {{man|5|systemd.service}}): |
+ | {{Tip|サービスファイルについてのヒント (詳しくは {{man|5|systemd.service}}): |
− | * {{ic|1= |
+ | * {{ic|1=Type=oneshot}} の場合、複数の {{ic|1=ExecStart=}} 行を使うことができます。それ以外の場合は使える {{ic|ExecStart}} は一行だけです。{{ic|ExecStartPre}} を使ったりコマンドをセミコロンで分割することでコマンドを追加することができます (最初の例を見て下さい -- セミコロンの前後にはスペースが''必要''です)。 |
− | * コマンドの前に |
+ | * コマンドの前に {{ic|-}} を付けると、0以外の終了ステータスは無視され、コマンドは成功したとして扱われます。 |
− | * サービスファイルのトラブルシューティングのときにエラーを見つけるには [[ |
+ | * サービスファイルのトラブルシューティングのときにエラーを見つけるには [[journalctl]] を使うのがベストです。 |
+ | }} |
||
− | + | ==== サスペンド/レジュームのサービスファイルの統合 ==== |
|
− | サスペンド/レジューム |
+ | サスペンド/レジュームのサービスファイルを統合すれば、様々なフェイズ (スリープ/レジューム) やターゲット (サスペンド/ハイバネート/ハイブリッドスリープ) でやることをひとつのフックで行うことができます。 |
例と説明: |
例と説明: |
||
− | {{hc|/etc/systemd/system/wicd-sleep.service|2= |
+ | {{hc|/etc/systemd/system/wicd-sleep.service|2= |
[Unit] |
[Unit] |
||
Description=Wicd sleep hook |
Description=Wicd sleep hook |
||
245行目: | 247行目: | ||
[Install] |
[Install] |
||
− | WantedBy=sleep.target |
+ | WantedBy=sleep.target |
+ | }} |
||
− | * {{ic|1= |
+ | * {{ic|1=RemainAfterExit=yes}}: 起動後、明示的に止められるまでサービスは常時 active とみなされます。 |
− | * {{ic|1= |
+ | * {{ic|1=StopWhenUnneeded=yes}}: active 時、他のサービスから必要とされなくなった場合、サービスは停止されます。この例では、''sleep.target'' が停止されるとこのサービスは停止されます。 |
− | * sleep.target は suspend.target |
+ | * ''sleep.target'' は ''suspend.target''、''hibernate.target''、''hybrid-sleep.target'' から呼ばれ、''sleep.target'' 自身は ''StopWhenUnneeded'' サービスなので、タスクごとにフックが正しく起動・停止することが保証されています。 |
− | ==== |
+ | ===== 汎用のサービステンプレート ===== |
+ | この例では、既存の systemd サービスを電源イベントにフックさせるために使用できる[http://0pointer.net/blog/projects/instances.html テンプレートサービス]を作ります:[https://narkive.com/mYzxSIDN.6] |
||
− | 遅延ハイバネーションではスリープフックを利用して通常通りにサスペンドしますが、その後にハイバネーションを実行するタイマーをセットします。ハイバネーションを最初に実行しないためスリープに入るのが {{ic|systemctl hybrid-sleep}} よりも早くなります。ただし、"hybrid-sleep" とは違って、サスペンド中にハイバネーションを使うことで電源喪失から保護するようなことはできません。そのため遅延ハイバネーションはデスクトップなどよりもノートパソコンで使うほうが適しています。ハイバネーションが遅延されるため、サスペンド中はノートパソコンのバッテリーだけが使われ、それからハイバネーションが実行されます。バッテリーがなくなるまでサスペンドし続ける "hybrid-sleep" よりも消費電力を抑えることが可能です。ノートパソコンにハードディスクが搭載されている場合、ハイバネートするためにサスペンドから復帰したとき、ノートパソコンを数秒間は動かさないほうがよいでしょう。遅延ハイバネーションは消費電力だけでなくセキュリティに関しても利点があります (例: 完全なディスク暗号化を使っている場合)。サンプルスクリプトは [https://superuser.com/questions/298672/linuxhow-to-hibernate-after-a-period-of-sleep こちら] にあります。systemd のスリープフックについては [https://bbs.archlinux.org/viewtopic.php?pid=1420279#p1420279 こちらの投稿] も参照してください。 |
||
− | {{hc|/etc/systemd/system/ |
+ | {{hc|/etc/systemd/system/sleep@.service|2= |
[Unit] |
[Unit] |
||
− | Description= |
+ | Description=%I sleep hook |
− | Documentation=https://bbs.archlinux.org/viewtopic.php?pid=1420279#p1420279 |
||
− | Documentation=https://wiki.archlinux.org/index.php/Power_management |
||
− | Conflicts=hibernate.target hybrid-sleep.target |
||
Before=sleep.target |
Before=sleep.target |
||
− | StopWhenUnneeded= |
+ | StopWhenUnneeded=yes |
[Service] |
[Service] |
||
Type=oneshot |
Type=oneshot |
||
RemainAfterExit=yes |
RemainAfterExit=yes |
||
+ | ExecStart=-/usr/bin/systemctl stop %i |
||
− | Environment="WAKEALARM=/sys/class/rtc/rtc0/wakealarm" |
||
+ | ExecStop=-/usr/bin/systemctl start %i |
||
− | Environment="SLEEPLENGTH=+2hour" |
||
− | ExecStart=-/usr/bin/sh -c 'echo -n "alarm set for "; date +%%s -d$SLEEPLENGTH | tee $WAKEALARM' |
||
− | ExecStop=-/usr/bin/sh -c '\ |
||
− | alarm=$(cat $WAKEALARM); \ |
||
− | now=$(date +%%s); \ |
||
− | if [ -z "$alarm" ] || [ "$now" -ge "$alarm" ]; then \ |
||
− | echo "hibernate triggered"; \ |
||
− | systemctl hibernate; \ |
||
− | else \ |
||
− | echo "normal wakeup"; \ |
||
− | fi; \ |
||
− | echo 0 > $WAKEALARM; \ |
||
− | ' |
||
[Install] |
[Install] |
||
WantedBy=sleep.target |
WantedBy=sleep.target |
||
− | </nowiki> |
||
}} |
}} |
||
+ | 次に、{{ic|@}} の後に既存の systemd サービスの basename を指定して、このテンプレートのインスタンスを[[有効化]]してください (つまり、{{ic|sleep@'''''service-file-basename'''''.service}})。テンプレートに関する詳細は {{man|5|systemd.unit|DESCRIPTION}} を参照してください。 |
||
− | {{ic|Before}} と {{ic|Conflicts}} オプションはハイバネートでは動作させないようにするために必要です。そうしないと遅延ハイバネーションが実行されたときにサービスが2回実行されてしまいます。{{ic|WantedBy}} と {{ic|StopWhenUnneeded}} オプションはスリープの前に実行して復帰時に停止するように設定しています。サービスを[[有効化]]してください。 |
||
+ | |||
+ | {{Tip|テンプレートは systemd サービスに限らず、他のプログラムと一緒に使うこともできます。例は [https://fedoramagazine.org/systemd-template-unit-files/] を見てください。}} |
||
==== /usr/lib/systemd/system-sleep のフック ==== |
==== /usr/lib/systemd/system-sleep のフック ==== |
||
− | + | ''systemd'' は {{ic|/usr/lib/systemd/system-sleep/}} 内の全ての実行可能ファイルを実行するときに、2つの引数を渡します: |
|
+ | |||
+ | * 引数 1: {{ic|pre}} か {{ic|post}}。マシンがスリープしようとしているのか、復帰しようとしているのかによります。 |
||
+ | * 引数 2: {{ic|suspend}} か {{ic|hibernate}} か {{ic|hybrid-sleep}}。どれが行われようとしているのかによります。 |
||
+ | ''systemd'' はスクリプトを (ひとつずつではなく) 並行に実行します。 |
||
− | * 引数 1: {{ic|pre}} か {{ic|post}}。マシンが停止するときと起動するとき。 |
||
− | * 引数 2: {{ic|suspend}} か {{ic|hibernate}} か {{ic|hybrid-sleep}}。呼び出されるものによる。 |
||
+ | カスタムスクリプトの出力は ''systemd-suspend.service'' か ''systemd-hibernate.service'' か ''systemd-hybrid-sleep.service'' によって記録されます。出力を見るには ''systemd'' の [[journalctl]] を使って下さい: |
||
− | systemd はスクリプトを(ひとつずつではなく)同時に実行します。 |
||
+ | # journalctl -b -u systemd-suspend.service |
||
− | カスタムスクリプトの出力は {{ic|systemd-suspend.service}}, {{ic|systemd-hibernate.service}}, {{ic|systemd-hybrid-sleep.service}} によって記録されます。出力を見るには systemd の [[Systemd#Journal|journal]] を使って下さい: |
||
− | # journalctl -b -u systemd-suspend |
||
− | {{Note|カスタムスクリプトを使うかわりに |
+ | {{Note|カスタムスクリプトを使うかわりに ''sleep.target''、''suspend.target''、''hibernate.target''、''hybrid-sleep.target'' を使ってユニットをスリープステートロジックにフックさせることもできます。}} |
カスタムスリープスクリプトの例: |
カスタムスリープスクリプトの例: |
||
314行目: | 304行目: | ||
echo "Waking up from $2..." |
echo "Waking up from $2..." |
||
;; |
;; |
||
− | esac |
+ | esac |
+ | }} |
||
− | スクリプトを実行可能にするのを忘れないで下さい |
+ | スクリプトを[[実行可能属性|実行可能]]にするのを忘れないで下さい。 |
− | # chmod a+x /usr/lib/systemd/system-sleep/example.sh |
||
詳しくは {{man|7|systemd.special}} や {{man|8|systemd-sleep}} を見てください。 |
詳しくは {{man|7|systemd.special}} や {{man|8|systemd-sleep}} を見てください。 |
2023年7月4日 (火) 21:28時点における版
関連記事
電源管理とは、アクティブでない時に電源を切ったりシステムのコンポーネントを低電力状態にする機能です。
Arch Linux では、電源管理は主に2つの部分からなります:
- Linux カーネルの設定。ハードウェアと対話します。
- ユーザスペースのツールの設定。カーネルと対話し、カーネルのイベントに応答します。ユーザスペースのツールの多くは、"ユーザフレンドリー"な方法でカーネルの設定を変更することもできます。利用可能なツールは #ユーザースペースツール を参照してください。
目次
ユーザースペースツール
以下のツールを使うことで、大量の設定を手動で設定しなくて済みます。どのツールも多かれ少なかれ同じような動作をするので、衝突を避けるためにツールはどれか一つだけを実行してください。電源管理カテゴリを見れば、Arch Linux にどんな電源管理の選択肢が存在するかわかります。
以下は省電力設定をするために作られた人気のあるスクリプトやツールです:
コンソール
- acpid — ACPI の電源管理イベントを届けるデーモン。netlink をサポート。
- Laptop Mode Tools — ノートパソコンの省電力設定をするユーティリティ。多少設定が要りますが省電力設定ユーティリティのデファクトスタンダードとされています。
- libsmbios — Dell SMBIOS テーブルと対話するためのライブラリおよびツール。
- powertop — 消費電力や電源管理の問題を診断して省電力設定を補助するツール。
- systemd — システムおよびサービスマネージャ。
- TLP — Linux 向けの先進的な電源管理。
グラフィカル
- batsignal — libnotify を使用してバッテリレベルの低下を警告する軽量バッテリモニタ。
- cbatticon — 軽量で高速なバッテリアイコンをシステムトレイに表示。
- GNOME Power Statistics — GNOME のシステム電力情報および統計。
- KDE Power Devil — Plasma 用の電源管理モジュール。
- LXQt Power Management — LXQt 用の電源管理モジュール。
- MATE Power Management — MATE 用電源管理ツール。
- MATE Power Statistics — MATE のシステム電力情報と統計。
- poweralertd — UPower 通知を伝播するデーモン。
- powerkit — デスクトップに依存しない電源マネージャー。
- Xfce Power Manager — Xfce 用の電源マネージャ。
- vattery — システムトレイ内のラップトップバッテリのステータスを表示する、 Vala で書かれたバッテリ監視アプリケーション。
電源管理
ACPI イベント
systemd は一部の電源関連の ACPI イベントを処理します。これらのイベントの動作は /etc/systemd/logind.conf
や /etc/systemd/logind.conf.d/*.conf
で設定できます (logind.conf(5) を参照)。専用の電源マネージャを持たないシステムでは、この方法は acpid デーモンの代わりになりえます。ちなみに、acpid は通常、ACPI イベントに対応するために使われるデーモンです。
イベントの動作には、ignore
、poweroff
、reboot
、halt
、suspend
、hibernate
、hybrid-sleep
、suspend-then-hibernate
、lock
、kexec
のいずれかを指定することができます。ハイバーネートとサスペンドの場合は、適切にセットアップしなければなりません。イベントが設定されていない場合、systemd はデフォルトの動作を使用します。
イベントハンドラ | 説明 | デフォルトの動作 |
---|---|---|
HandlePowerKey
|
電源キー/ボタンが押された時にトリガされます。 | poweroff
|
HandleSuspendKey
|
サスペンドキー/ボタンが押された時にトリガされます。 | suspend
|
HandleHibernateKey
|
ハイバネートキー/ボタンが押された時にトリガされます。 | hibernate
|
HandleLidSwitch
|
ラップトップPCなどの蓋が閉じられた時に (以下のケースを除いて) トリガされます。 | suspend
|
HandleLidSwitchDocked
|
システムがドッキングステーションに繋がれている場合や、複数のディスプレイに繋がれている場合に蓋が閉じられるとトリガされます。 | ignore
|
HandleLidSwitchExternalPower
|
システムが外部電源に接続されている状況で蓋が閉じられた時にトリガされます。 | HandleLidSwitch に対して設定されている動作
|
変更を適用するには systemd-logind
に対して HUP
シグナルを発行して下さい:
# systemctl kill -s HUP systemd-logind
電源マネージャ
一部のデスクトップ環境には、systemd の ACPI 設定の一部あるいは全てを inhibit する (一時的にオフにする) 電源マネージャが含まれています。そのような電源マネージャが実行されている場合、電源マネージャだけで ACPI イベントに対する動作を設定することができます。/etc/systemd/logind.conf
や /etc/systemd/logind.conf.d/*.conf
を変更する必要があるのは、電源マネージャによって inhibit されていないイベントに対する挙動を設定したい場合のみです。
注意点として、電源マネージャが適切なイベントに対して systemd を inhibit しないと、systemd がシステムをサスペンドし、その後サスペンドから復帰すると今度は電源マネージャがシステムを再びサスペンドしてしまうという状況に陥る可能性があります。KDE、GNOME、Xfce、そして MATE の電源マネージャは、必要な inhibited コマンドを発行します。inhibited コマンドが発行されない場合 (acpid などを使って ACPI イベントを処理している場合)、Handle
オプションを ignore
に設定してください。systemd-inhibit(1) も参照してください。
xss-lock
xss-lock は systemd の suspend
、hibernate
、lock-session
、unlock-session
イベントで適切なアクションを実行します (ロッカーを実行し、ユーザがロッカーをアンロックまたは kill するまで待機する)。xss-lock は DPMS イベントにも反応し、それに応じてロッカーを実行したり kill したりします。
例えば、以下のコマンドを自動起動します:
$ xss-lock -- i3lock -n -i background_image.png &
サスペンドとハイバネート
systemd は、カーネルのネイティブなサスペンド/レジューム機能を使用して、サスペンド (suspend to RAM) を行うコマンドや、ハイバネートを行うコマンドを提供しています。また、サスペンド前や後の動作をカスタマイズするためのフックを追加する機構も存在しています。
systemctl suspend
は何も設定しなくても動くはずですが、あなたの環境で systemctl hibernate
を使うには 電源管理/サスペンドとハイバネート#ハイバネーション の指示に従う必要があります。
また、サスペンドとハイバネートを組み合わせたモードが 2 つ存在します:
systemctl hybrid-sleep
は、システムを RAM とディスクの両方にサスペンドします。なので、電源が完全に失われても、データ損失が発生しません。このモードは suspend to both とも呼ばれています。systemctl suspend-then-hibernate
は、最初は可能な限り長くシステムを RAM にサスペンドし、RTC アラームで復帰し、そしてハイバネートします。RTC アラームは systemd-sleep.conf(5) 内のHibernateDelaySec
で設定します。デフォルトの値は、システムのバッテリーレベルが 5% に下がるまでの推定された時間に設定されます。システムにバッテリーが存在しない場合は、デフォルトで2時間に設定されます。推定時間は、systemd-sleep.conf(5) 内のSuspendEstimationSec
によって指定された時間後のバッテリーレベルの変化から計算されます。SuspendEstimationSec
の時間後、システムは短い間サスペンドから復帰し、計測を行います (システムが手動でサスペンドから復帰された場合も、計測が行われます)。
サスペンドやハイバネートのリクエスト時にハイブリッドスリープを行う
サスペンドやハイバネートのリクエスト時にも、ハイブリッドスリープを常に行うように systemd を設定することができます。
サスペンドとハイバネートのデフォルトの動作は、/etc/systemd/sleep.conf.d/
内の .conf ファイルで設定することができます。両方の動作を ハイブリッドスリープ に設定するには:
/etc/systemd/sleep.conf.d/hybrid-sleep.conf
[Sleep] # suspend=hybrid-sleep SuspendMode=suspend SuspendState=disk # hibernate=hybrid-sleep HibernateMode=suspend HibernateState=disk
詳細は sleep.conf.d(5) man ページと linux カーネルの電源状態に関するドキュメントを参照してください。
サスペンドを無効化する
デバイスをサーバなどとして使用している場合、サスペンドは必要ないかもしれませんし、かえって望ましくない可能性もあります。 任意のスリープ状態を設定することができます:
/etc/systemd/sleep.conf.d/disable-suspend.conf
[Sleep] AllowSuspend=no AllowHibernation=no AllowSuspendThenHibernate=no AllowHybridSleep=no
スリープフック
サスペンド/リジュームのサービスファイル
サービスファイルを suspend.target、hibernate.target、sleep.target、hybrid-sleep.target、そして suspend-then-hibernate.target にフックすることで、サスペンド/ハイバネート前や後に行うアクションを設定できます。ユーザのアクションと root/システムのアクションを設定するには、別々のファイルを作成する必要があります。suspend@user
と 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 ExecStart=/usr/bin/sflock ExecStartPost=/usr/bin/sleep 1 [Install] WantedBy=sleep.target
/etc/systemd/system/resume@.service
[Unit] Description=User resume actions After=suspend.target [Service] User=%I Type=simple ExecStart=/usr/local/bin/ssh-connect.sh [Install] WantedBy=suspend.target
root/システムのアクションの場合 (root-resume
と root-suspend
を有効化してこれらをブート時に起動させてください):
/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
/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/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 サービスなので、タスクごとにフックが正しく起動・停止することが保証されています。
汎用のサービステンプレート
この例では、既存の systemd サービスを電源イベントにフックさせるために使用できるテンプレートサービスを作ります:[1]
/etc/systemd/system/sleep@.service
[Unit] Description=%I sleep hook Before=sleep.target StopWhenUnneeded=yes [Service] Type=oneshot RemainAfterExit=yes ExecStart=-/usr/bin/systemctl stop %i ExecStop=-/usr/bin/systemctl start %i [Install] WantedBy=sleep.target
次に、@
の後に既存の systemd サービスの basename を指定して、このテンプレートのインスタンスを有効化してください (つまり、sleep@service-file-basename.service
)。テンプレートに関する詳細は systemd.unit(5) § DESCRIPTION を参照してください。
/usr/lib/systemd/system-sleep のフック
systemd は /usr/lib/systemd/system-sleep/
内の全ての実行可能ファイルを実行するときに、2つの引数を渡します:
- 引数 1:
pre
かpost
。マシンがスリープしようとしているのか、復帰しようとしているのかによります。 - 引数 2:
suspend
かhibernate
かhybrid-sleep
。どれが行われようとしているのかによります。
systemd はスクリプトを (ひとつずつではなく) 並行に実行します。
カスタムスクリプトの出力は systemd-suspend.service か systemd-hibernate.service か systemd-hybrid-sleep.service によって記録されます。出力を見るには systemd の journalctl を使って下さい:
# journalctl -b -u systemd-suspend.service
カスタムスリープスクリプトの例:
/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
スクリプトを実行可能にするのを忘れないで下さい。
詳しくは systemd.special(7) や systemd-sleep(8) を見てください。
トラブルシューティング
フタのスイッチのアクションの遅延
短期間に連続してフタのスイッチが反応した場合、logind はドッキングを検出するために90秒までサスペンドを遅延します [3] この遅延時間は systemd v220 から設定ができます [4]:
/etc/systemd/logind.conf
... HoldoffTimeoutSec=30s ...
ノートパソコンをサスペンドする Fn キーが動作しない
logind.conf
をどう設定してもスリープボタンが動作しない場合 (ボタンを押しても syslog にメッセージすら表示されない)、おそらく logind がキーボードデバイスを監視していません [5] 次のコマンドを実行してください:
# journalctl | grep "Watching system buttons"
すると以下のような表示がされます:
May 25 21:28:19 vmarch.lan systemd-logind[210]: Watching system buttons on /dev/input/event2 (Power Button) May 25 21:28:19 vmarch.lan systemd-logind[210]: Watching system buttons on /dev/input/event3 (Sleep Button) May 25 21:28:19 vmarch.lan systemd-logind[210]: Watching system buttons on /dev/input/event4 (Video Bus)
キーボードデバイスがないことに気づいて下さい。したがってキーボードデバイスの ATTRS{name} を取得します [6]:
# udevadm info -a /dev/input/by-path/*-kbd ... KERNEL=="event0" ... ATTRS{name}=="AT Translated Set 2 keyboard"
カスタム udev ルールを作成して "power-switch" タグを追加:
/etc/udev/rules.d/70-power-switch-my.rules
ACTION=="remove", GOTO="power_switch_my_end" SUBSYSTEM=="input", KERNEL=="event*", ATTRS{name}=="AT Translated Set 2 keyboard", TAG+="power-switch" LABEL="power_switch_my_end"
サービスを再起動してルールをリロードしてください:
# systemctl restart systemd-udevd # udevadm trigger # systemctl restart systemd-logind
これで syslog に Watching system buttons on /dev/input/event0
と表示されるようになるはずです。
A520I および B550I マザーボードで PC がスリープから復帰しない
A520i および B550i チップセットを搭載した一部のマザーボードでは、システムが完全にスリープ状態に入らない、またはスリープ状態から復帰しないことがあります。症状は、システムがスリープ状態に入り、マザーボード上の内部 LED または電源 LED が点灯したまま、モニターの電源が切れるというものです。その後、システムはこの状態から復帰することができず、ハードパワーオフが必要となります。AMD で同様の問題が発生した場合、まずシステムが完全にアップデートされていることを確認し、AMD マイクロコード パッケージがインストールされているかどうかをチェックしてください。
GPP0
で始まる行のステータスが有効になっていることを確認します。
$ cat /proc/acpi/wakeup
Device S-state Status Sysfs node GP12 S4 *enabled pci:0000:00:07.1 GP13 S4 *enabled pci:0000:00:08.1 XHC0 S4 *enabled pci:0000:0b:00.3 GP30 S4 *disabled GP31 S4 *disabled PS2K S3 *disabled GPP0 S4 *enabled pci:0000:00:01.1 GPP8 S4 *enabled pci:0000:00:03.1 PTXH S4 *enabled pci:0000:05:00.0 PT20 S4 *disabled PT24 S4 *disabled PT26 S4 *disabled PT27 S4 *disabled PT28 S4 *enabled pci:0000:06:08.0 PT29 S4 *enabled pci:0000:06:09.0
これが有効になっている場合は、次のコマンドを実行できます。
# echo GPP0 > /proc/acpi/wakeup
systemctl suspend
を実行してテストし、システムをスリープ状態にします。次に、数秒後にシステムを起動してみてください。うまくいく場合は、回避策を永続的にすることができます。systemd ユニットファイル を 作成 します。:
/etc/systemd/system/toggle.ggp0.to.fix.suspend.issue.service
[Unit] Description="Disable GGP0 to fix suspend issue" [Service] ExecStart=/bin/sh -c "/bin/echo GPP0 > /proc/acpi/wakeup" [Install] WantedBy=multi-user.target
新しく作成したユニットを daemon-reload および 起動/有効化 します。
省電力設定
このセクションでは省電力機能を使用するのに必要な設定を扱います。コンピュータが AC 電源またはバッテリーで動作しているかに関わらず、ここに記載されているほとんど全ての機能には使用する価値があります。パフォーマンスへの影響は軽微ですが、大抵壊れているハードウェアやドライバーのためにデフォルトでは有効になっていません。電力の使用量を減らすことは熱を減らすことでもあり、動的なオーバークロックによって、最近の Intel や AMD の CPU ではパフォーマンスの向上につながることもあります。
udev ルールなどを使ってスクリプトや省電力設定を自分で作成したい場合は以下の設定を参考にすることができます。
Intel HWP (Intel Hardware P-state) をサポートする CPU
HWP 対応プロセッサで利用可能なエネルギー設定は、default
, performance
, balance_performance
, balance_power
}, power
です。
実行することで検証することができます。
$ cat /sys/devices/system/cpu/cpufreq/policy?/energy_performance_available_preferences
より多くのエネルギーを節約するには、次のファイルを作成して設定できます。
/etc/tmpfiles.d/energy_performance_preference.conf
w /sys/devices/system/cpu/cpufreq/policy?/energy_performance_preference - - - - balance_power
詳細については、systemd-tmpfiles(8) および tmpfiles.d(5) の man ページを参照してください。
オーディオ
カーネル
デフォルトでは、オーディオの省電力機能はほとんどのドライバーで無効になっています。power_save
パラメータを設定することで有効にすることができます。アイドルモードに移行するまでの時間を秒数で指定します。1秒後にサウンドカードをアイドル状態にするには、Intel の場合、以下を作成:
/etc/modprobe.d/audio_powersave.conf
options snd_hda_intel power_save=1
ac97 の場合は以下を使って下さい:
options snd_ac97_codec power_save=1
HDMI の音声出力を無効化することで消費電力を下げることもできます。適切なカーネルモジュールを ブラックリスト に追加してください (例: snd_hda_codec_hdmi
)
PulseAudio
PulseAudio はデフォルトで、長時間アイドル状態になったオーディオソースを一時停止します。外部 USB マイクを使用する場合、録音がポップ音で開始されることがあります。回避策として、/etc/pulse/default.pa
の次の行をコメントアウトしてください。
load-module module-suspend-on-idle
その後、systemctl restart --user pulseaudio
で PulseAudio を再起動させてください。
バックライト
バックライトを見て下さい。
Bluetooth
Bluetooth を完全に無効化するには、btusb
と bluetooth
モジュールをブラックリストに入れてください。
一時的にだけ bluetooth をオフにするには、rfkill を使用します:
# rfkill block bluetooth
もしくは udev ルールを使って:
/etc/udev/rules.d/50-bluetooth.rules
# disable bluetooth SUBSYSTEM=="rfkill", ATTR{type}=="bluetooth", ATTR{state}="0"
ウェブカメラ
内蔵のウェブカメラを使わない場合、uvcvideo
モジュールをブラックリストに入れてください。
カーネルパラメータ
このセクションでは /etc/sysctl.d/
の設定を使います。このディレクトリはカーネルの sysctl パラメータと対応するディレクトリです。詳しくは The New Configuration Files や、より正確な sysctl.d(5) を見てください。
NMI watchdog の無効化
NMI watchdog はカーネルパニックを引き起こすハードウェアのハングアップをキャッチするデバッグ機能です。システムによっては大量の割り込みが発生するため、消費電力の増加につながっていることがあります:
/etc/sysctl.d/disable_watchdog.conf
kernel.nmi_watchdog = 0
もしくは起動の初期で完全に無効化するにはカーネル行に nmi_watchdog=0
を追加してください。
ライトバック時間
仮想メモリのダーティなライトバック時間を増やすことでディスク I/O がまとめられて、断続的なディスクの書き込みが減って、消費電力が抑えられます。この値を60秒に設定するには (デフォルトは5秒です):
/etc/sysctl.d/dirty.conf
vm.dirty_writeback_centisecs = 6000
ジャーナルをサポートしているファイルシステム (ext4 や btrfs など) でジャーナルコミットでも同じことをするには、fstab でオプションとして commit=60
を使用します。
I/O パフォーマンスや省電力に影響する他のパラメータは sysctl#仮想メモリ を参照。
Laptop Mode
ラップトップモードの'ノブ'についてはカーネルドキュメントを見て下さい。"このノブの適切な値は5秒です。"
/etc/sysctl.d/laptop.conf
vm.laptop_mode = 5
ネットワークインターフェイス
Wake-on-LAN は便利な機能ですが、利用しない場合はサスペンド中にマジックパケットが来るのを待つのに無駄な電力を消耗するだけです。全ての Ethernet インターフェイスで Wake-on-LAN を無効化:
/etc/udev/rules.d/70-disable_wol.rules
ACTION=="add", SUBSYSTEM=="net", KERNEL=="eth*", RUN+="/usr/bin/ethtool -s %k wol d"
全ての無線インターフェイスで省電力機能を有効にするには:
/etc/udev/rules.d/70-wifi-powersave.rules
ACTION=="add", SUBSYSTEM=="net", KERNEL=="wlan*", RUN+="/usr/bin/iw dev %k set power_save on"
上記の例では、%k
がマッチするデバイスのカーネル名を示します。例えば、ルールが wlan0
に適用可能とわかった場合、%k
は wlan0
に置き換えられます。特定のインターフェイスにだけルールを適用するには、パターン eth*
と修飾子 %k
を適当なインターフェイスの名前に置き換えて下さい。詳しくは、Writing udev rules を参照。
Intel ワイヤレスカード (iwlwifi)
Intel 製ワイヤレスカードの省電力機能は iwlwifi
ドライバーに適切なパラメータを渡すことで有効にできます。/etc/modprobe.d/iwlwifi.conf
ファイルに以下の行を追加することで永続的に有効にできます:
options iwlwifi power_save=1 d0i3_disable=0 uapsd_disable=0 options iwldvm force_cam=0
上記の省電力オプションは実験的であり、システムが不安定になる可能性があります。
バスパワーの管理
Active State Power Management
コンピュータが ASPM をサポートしているという信頼が得られなかった場合、起動時に無効化されます:
$ lspci -vv | grep ASPM.*abled\;
ASPM は BIOS によって扱われるため、ASPM が無効化される理由は以下の通りです [7]:
- BIOS が何らかの理由で ASPM を無効化した (コンフリクトが起こるから?)。
- PCIE が L0s 以外の ASPM を必要とする (L0s は無効化され L1 だけが有効化される)。
- ASPM について BIOS がプログラムされていない。
- BIOS にバグが存在する。
コンピュータが ASPM をサポートしていると信じられる場合は、pcie_aspm=force
カーネルパラメータを使うことで強制的にオンにすることができます。
powersave
に調整するには次を実行 (以下のコマンドは ASPM が有効になっていないと機能しません):
echo powersave | tee /sys/module/pcie_aspm/parameters/policy
デフォルトでは以下のようになります:
$ cat /sys/module/pcie_aspm/parameters/policy
[default] performance powersave
PCI Runtime Power Management
/etc/udev/rules.d/pci_pm.rules
ACTION=="add", SUBSYSTEM=="pci", ATTR{power/control}="auto"
デバイスの電源管理
USB を含む、(ほぼ) 全てのデバイスの電源管理を有効化:
/etc/udev/rules.d/dev_power_save.rules
# Various subsystems runtime power management (by bus or class) ACTION=="add", SUBSYSTEMS=="*", TEST=="power/control", ATTR{power/control}="auto" # Various subsystems power saving (by module) ACTION=="add", SUBSYSTEMS=="*", TEST=="parameters/power_save", ATTR{parameters/power_save}="1"
影響を受けるデバイスを表示するには:
ls /sys/bus/*/devices/*/power/control ls /sys/class/*/*/power/control ls /sys/module/*/parameters/power_save
USB を除く全てのシステムで電源管理を有効にするには、最初のルールをサブシステムごとのルールに置き換えます (/sys/bus/some_subsystem, /sys/class/some_subsystem):
ACTION=="add", SUBSYSTEM=="some_subsystem", TEST=="power/control", ATTR{power/control}="auto"
USB の自動サスペンド
Linux カーネルは USB デバイスが使用されていないときに USB デバイスを自動的にサスペンドさせることができます。これによって電力を相当カットできるときもありますが、USB の省電力機能に対応していない USB デバイスではおかしな挙動が起こる可能性もあります (特に USB マウスやキーボード)。ホワイトリストとブラックリストでフィルタリングする udev ルールを使うことで問題は軽減されます。
最も単純であまり役に立たない、全ての USB デバイスで自動サスペンドを有効にする例:
/etc/udev/rules.d/50-usb_power_save.rules
ACTION=="add", SUBSYSTEM=="usb", TEST=="power/control", ATTR{power/control}="auto"
自動サスペンドが動作するデバイスにだけ自動サスペンドを有効にするには、ベンダーとプロダクト ID でマッチングを行います (lsusb を使って値を取得):
/etc/udev/rules.d/50-usb_power_save.rules
# whitelist for usb autosuspend ACTION=="add", SUBSYSTEM=="usb", TEST=="power/control", ATTR{idVendor}=="05c6", ATTR{idProduct}=="9205", ATTR{power/control}="auto"
もしくは、USB 自動サスペンドが使えないデバイスをブラックリストに入れて、他の全てのデバイスで自動サスペンドを有効にするには:
/etc/udev/rules.d/50-usb_power_save.rules
# blacklist for usb autosuspend ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="05c6", ATTR{idProduct}=="9205", GOTO="power_usb_rules_end" ACTION=="add", SUBSYSTEM=="usb", TEST=="power/control", ATTR{power/control}="auto" LABEL="power_usb_rules_end"
自動サスペンドに入るデフォルトのアイドル遅延時間は usbcore
カーネルモジュールの autosuspend
パラメータによって制御されています。遅延時間をデフォルトの2秒から5秒に設定するには:
/etc/modprobe.d/usb-autosuspend.conf
options usbcore autosuspend=5
power/control
と同じように、power/autosuspend
属性を設定することで遅延時間はデバイスごとに細かく設定することができます。
USB の電源管理に関する詳細は Linux カーネルドキュメントを見て下さい。
SATA Active Link Power Management
/etc/udev/rules.d/hd_power_save.rules
ACTION=="add", SUBSYSTEM=="scsi_host", KERNEL=="host*", ATTR{link_power_management_policy}="min_power"
ハードディスクドライブ
設定できるドライブのパラメータについては hdparm を見て下さい。
多数のプログラムがディスクに頻繁に書き込みをおこなう場合は省電力は効率的ではありません。全てのプログラムを調査して、いつどのようにプログラムがディスクに書き込むを行うのか調べるのがディスクの使用量を減らす道です。iotop を使えばどのプログラムがディスクに頻繁に書き込みしているかわかります。他のヒントはソリッドステートドライブ#SSD の読み書きを最小化するヒントを見て下さい、ほとんどのヒントは SSD に限ったものではありません。
noatime オプションを設定するなどの小さなことも馬鹿にできません。十分な RAM がある場合、swappiness を無効化したり制限することでディスクへの書き込みが減る可能性があります。
CD/DVD のスピンダウン
udisks を使用してしばらくしてから CD/DVD ロムをスピンダウンさせるには:
# udisks --inhibit-polling /dev/sr0
ツールとスクリプト
スクリプトと udev ルールを使う
systemd ユーザーは systemctl suspend
や systemctl hibernate
でサスペンドとハイバネートを行うことができ、/etc/systemd/logind.conf
で acpi イベントを処理することができるので、pm-utils と acpid を削除するということに興味を引かれるかもしれません。systemd が行えないことがたったひとつだけ存在します (systemd-204 現在): システムが AC 電源またはバッテリーで動作しているのかで別れる電源管理です。このギャップをなくすには、AC アダプタが抜き差しされたときにスクリプトを実行する udev ルールを作成します:
/etc/udev/rules.d/powersave.rules
SUBSYSTEM=="power_supply", ATTR{online}=="0", RUN+="/path/to/your/script true" SUBSYSTEM=="power_supply", ATTR{online}=="1", RUN+="/path/to/your/script false"
powersave スクリプトのサンプル: powerdown, powersave。
上記の udev ルールはちゃんと動作するはずですが、電源設定がサスペンドやハイバネートをした後に更新されない場合、以下の内容で /usr/lib/systemd/system-sleep/
にスクリプトを追加してください:
/usr/lib/systemd/system-sleep/00powersave
#!/bin/sh case $1 in pre) /path/to/your/script false ;; post) if cat /sys/class/power_supply/AC0/online | grep 0 > /dev/null 2>&1 then /path/to/your/script true else /path/to/your/script false fi ;; esac exit 0
忘れずに実行可能属性を付与してください。
電源設定の表示
以下のスクリプトは USB や PCI デバイスの電源設定などのプロパティを表示します。全ての設定を見るには root 権限が必要なので注意して下さい。
#!/bin/bash for i in $(find /sys/devices -name "bMaxPower") do busdir=${i%/*} busnum=$(<$busdir/busnum) devnum=$(<$busdir/devnum) title=$(lsusb -s $busnum:$devnum) printf "\n\n+++ %s\n -%s\n" "$title" "$busdir" for ff in $(find $busdir/power -type f ! -empty 2>/dev/null) do v=$(cat $ff 2>/dev/null|tr -d "\n") [[ ${#v} -gt 0 ]] && echo -e " ${ff##*/}=$v"; v=; done | sort -g; done; printf "\n\n\n+++ %s\n" "Kernel Modules" for mod in $(lspci -k | sed -n '/in use:/s,^.*: ,,p' | sort -u) do echo "+ $mod"; systool -v -m $mod 2> /dev/null | sed -n "/Parameters:/,/^$/p"; done