6
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

systemdによる電源管理下で, SSH接続中のユーザーがいるときにスリープさせない

Posted at

systemdが動いている一般的なLinuxで, SSH接続しているユーザーが存在するときにスリープ (サスペンド, ハイバネート) させない方法です.

systemdが標準で入っている昨今のLinuxディストーション (Ubuntuとか) であれば, 適用可能です. ただ, デスクトップ向けにセットアップしたLinuxマシンでもなければ, サスペンド/ハイバネートといった設定はしないので, ややニッチな話題です.

背景

デスクトップ用途で稼働させているLinuxの場合, 省電力のための設定を有効にしておくことが多いかと思います (操作が行われないまま一定時間経過したら, サスペンド/ハイバネートさせるとか).

書斎にあるLinuxがインストールされたデスクトップPCへ, リビングのノートパソコンからちょっとした用事があるときにSSH接続することがありますが, ここが問題. そういったSSH接続しての作業中は無操作状態とみなされて, 時間がきたらサスペンドされてしまうのです.

横着せずに省電力設定を止めるなりすればいいだけのことですが, ここはsystemdらしいアプローチでの解決方法をとってみました.

確認に使った環境

Archlinuxで動作確認しています. デスクトップ環境はGNOMEで, GNOME標準の設定画面から省電力設定をおこなってます.
systemdが入っている昨今のほとんどのLinuxディストリビューションなら同じことができるはず.

やりかた

次のようなファイルを作成します. systemdのユニットファイルと呼ばれるものです.
作るディレクトリは記載の通り /etc/systemd/system.

[kosuke@cf-sx1 ~]$ cat /etc/systemd/system/inhibit-sleep.service
[Unit]
Description=Inhibit sleep when ssh logged
Before=sleep.target

[Service]
Type=oneshot
ExecStart=/usr/bin/sh -c '! who | grep -q "(\([0-9]\{1,3\}\.\)\{3\}[0-9]\{1,3\})"'

[Install]
RequiredBy=sleep.target

スリープフックと呼ばれるもので, スリープ (サスペンド, ハイバネート) する前にExecStartで指定したコマンドが実行されるようになります.
whoコマンドSSHログイン中のユーザーがいないかチェックして, もしいたら終了コード0以外にして後続処理を動かさないことで実現します.

ファイルを作成したら, 次のコマンドでユニットを有効にします.

# systemctl enable inhibit-sleep.service

これで準備OKです.

動作確認してみる

対象のマシンは20分でサスペンドするように設定されています.

動作確認したあとのログを見てみましょう.

[kosuke@cf-sx1 ~]$ journalctl -f -usleep.target
-- Journal begins at Fri 2020-07-24 20:13:01 JST. --
 3月 03 23:06:33 cf-sx1 systemd[1]: Reached target Sleep.
 3月 03 23:06:45 cf-sx1 systemd[1]: Stopped target Sleep.
 3月 03 23:07:18 cf-sx1 systemd[1]: Dependency failed for Sleep.
 3月 03 23:07:18 cf-sx1 systemd[1]: sleep.target: Job sleep.target/start failed with result 'dependency'.
 3月 03 23:28:38 cf-sx1 systemd[1]: Dependency failed for Sleep.
 3月 03 23:28:38 cf-sx1 systemd[1]: sleep.target: Job sleep.target/start failed with result 'dependency'.
 3月 03 23:48:39 cf-sx1 systemd[1]: Reached target Sleep.
 3月 03 23:49:14 cf-sx1 systemd[1]: Stopped target Sleep.

これだけだとわからないので, 少しずつ説明してみます.

これは設定を入れた後にSSHログインユーザーがいない状態でサスペンドコマンド systemctl suspend でサスペンドさせてみた結果です.
Reached でサスペンド, Stopped で復帰です.

 3月 03 23:06:33 cf-sx1 systemd[1]: Reached target Sleep.
 3月 03 23:06:45 cf-sx1 systemd[1]: Stopped target Sleep.

次にSSHでログインしているユーザーがいるときに, 同じコマンドでサスペンドを試みます. すると, sleep.targetに依存させるよう追加/設定した前述のユニットファイルが失敗するので, スリープも実行されなくなります.

 3月 03 23:07:18 cf-sx1 systemd[1]: Dependency failed for Sleep.
 3月 03 23:07:18 cf-sx1 systemd[1]: sleep.target: Job sleep.target/start failed with result 'dependency'.

このまま20分ほど放置……. ここでも同じようにスリープされません.

 3月 03 23:28:38 cf-sx1 systemd[1]: Dependency failed for Sleep.
 3月 03 23:28:38 cf-sx1 systemd[1]: sleep.target: Job sleep.target/start failed with result 'dependency'.

ここでSSH接続しているユーザーをログアウトさせます. さらに20分ほど経過すると, 今度はサスペンドされました.

 3月 03 23:48:39 cf-sx1 systemd[1]: Reached target Sleep.
 3月 03 23:49:14 cf-sx1 systemd[1]: Stopped target Sleep.

参考資料

電源管理 - ArchWIki

たいていのことはArchWikiに書いてある気がする.

6
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?