34
Help us understand the problem. What are the problem?

posted at

updated at

WSL2+Ubuntu22.04に標準で入ったsystemdを試す

先日リリースされたUbuntu 22.04には/usr/libexec/wsl-systemdというシェルスクリプトが同梱されています。中身を覗くとunshareで名前空間を分けてsystemdを起動するようです。過去様々なところで紹介されていた手法のようですね。

systemdを起動する

早速試してみましょう。

wsl-systemdを実行する
$ sudo /usr/libexec/wsl-systemd
$ ps ax
    PID TTY      STAT   TIME COMMAND
      1 ?        Sl     0:00 /init
      7 ?        Ss     0:00 /init
      8 ?        R      0:00 /init
      9 pts/0    Ss     0:00 -bash
     98 ?        S      0:00 /usr/bin/unshare --fork --mount-proc --pid --propagation unchanged -- sh -c  exec /lib/systemd/systemd --unit=multi-user.target
     99 ?        Ss     0:00 /lib/systemd/systemd --unit=multi-user.target
    139 ?        S<s    0:00 /lib/systemd/systemd-journald
    163 ?        Ss     0:00 /lib/systemd/systemd-udevd
    187 ?        Ss     0:00 @dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation --syslog-only
    190 ?        Ss     0:00 /usr/bin/python3 /usr/bin/networkd-dispatcher --run-startup-triggers
    191 ?        Ssl    0:00 /usr/libexec/polkitd --no-debug
    192 ?        Ssl    0:00 /usr/sbin/rsyslogd -n -iNONE
    193 ?        Ss     0:00 /lib/systemd/systemd-logind
    194 ?        Ss     0:00 /lib/systemd/systemd-networkd
    217 ?        Ssl    0:00 /usr/sbin/ModemManager
    291 ?        Ss     0:00 /lib/systemd/systemd-resolved
    301 ?        Ss     0:00 /usr/sbin/cron -f -P
    305 ?        Ssl    0:00 /usr/bin/python3 /usr/share/unattended-upgrades/unattended-upgrade-shutdown --wait-for-signal
    309 tty1     Ss+    0:00 /sbin/agetty -o -p -- \u --noclear --keep-baud console 115200,38400,9600 linux
    311 ?        Ss     0:00 sshd: /usr/sbin/sshd -D [listener] 0 of 10-100 startups
    314 ?        Ss     0:00 /sbin/agetty -o -p -- \u --noclear tty1 linux

起動しました。cronやsshd,systemd-resolvedなど様々起動しています。

systemctlで操作する

sshdを止めてみましょう。

sshdを止めようとする
$ sudo systemctl stop ssh
Failed to stop ssh.service: 通信端点が接続されていません
See system logs and 'systemctl status ssh.service' for details.

エラーです。systemd がPID 1ではないのが原因でしょうか?

先ほどの /usr/libexec に nslogin というファイルがあります。こちらはスクリプトではなくバイナリのようです。マニュアルは見当たりませんが、きっと nslogin = name space login でしょう。

実行してみます。

nsloginを実行
$  /usr/libexec/nslogin

何も起こりません。
名前空間に入ったに違いないという淡い期待でプロセスを確認してみます。

プロセスを確認する
$ ps ax | grep system
      1 ?        Ss     0:00 /lib/systemd/systemd --unit=multi-user.target

systemdがPID 1になってます。

再度systemctlで操作してみます。

$ sudo systemctl stop ssh

エラーが出なくなりました。
停止できたかどうか確認してみます。

systemctl確認
$ /usr/libexec/nslogin sudo systemctl stop ssh
ThinkCentre:~$ /usr/libexec/nslogin sudo systemctl status ssh
○ ssh.service - OpenBSD Secure Shell server
     Loaded: loaded (/lib/systemd/system/ssh.service; enabled; vendor preset: enabled)
     Active: inactive (dead) since Wed 2022-04-27 04:49:56 JST; 4s ago
       Docs: man:sshd(8)
             man:sshd_config(5)
    Process: 204 ExecStartPre=/usr/sbin/sshd -t (code=exited, status=0/SUCCESS)
    Process: 219 ExecStart=/usr/sbin/sshd -D $SSHD_OPTS (code=exited, status=0/SUCCESS)
   Main PID: 219 (code=exited, status=0/SUCCESS)

 4月 27 04:49:40 ThinkCentre systemd[1]: Starting OpenBSD Secure Shell server...
 4月 27 04:49:41 ThinkCentre sshd[219]: Server listening on 0.0.0.0 port 22.
 4月 27 04:49:41 ThinkCentre sshd[219]: Server listening on :: port 22.
 4月 27 04:49:41 ThinkCentre systemd[1]: Started OpenBSD Secure Shell server.
 4月 27 04:49:56 ThinkCentre sshd[219]: Received signal 15; terminating.
 4月 27 04:49:56 ThinkCentre systemd[1]: Stopping OpenBSD Secure Shell server...
 4月 27 04:49:56 ThinkCentre systemd[1]: ssh.service: Deactivated successfully.
 4月 27 04:49:56 ThinkCentre systemd[1]: Stopped OpenBSD Secure Shell server.

ちゃんと停止しています。
nslogin の引数にコマンドラインを並べても実行できるようです。

ちなみに、、wsl-systemdを実行していない(=systemdを起動していない)状態でnsloginを実行すると以下のようにdistroを一旦停止させてやり直しなさいとエラーが出ます。

$ /usr/libexec/nslogin ls
ERROR: Systemd is not running. Please terminate this instance by running "wsl -t <distro>" from Windows shell and try again.

以前、Ubuntuのブログに我々はWSLでsystemdを動かす方法を検討している。今も方法はいろいろあるけどそれは標準じゃないぞ的なことが書かれていましたが、ちゃんと実現したようですね。

2022.04.30追記)
https://github.com/microsoft/WSL/issues/5126#issuecomment-1111957720 によると、

launch your shells with "/usr/libexec/nslogin /bin/bash", eg from Windows:

wsl -e /usr/libexec/nslogin /bin/bash

ubuntu2204.exeだとこうなっているそうです。インストーラーを使ってインストールしていれば実は自動だったんですね。Terminalのコマンドラインをこちらに書き換えておくと、特に意識することなく常に systemd が PID 1 の環境で使えるようですね。

2022.05.04追記)
wsl -e /usr/libexec/nslogin /bin/bashでWSLに接続すると環境変数SHELLが/usr/libexec/nsloginになってしまうようです。ssh_configのMatchのように環境変数SHELLに対してコマンドを引き渡すような場合はエラーになってしまいます。.bashrcでSHELLを再定義するというのもありですが、今はsystemdがPID 1でないといけないケースだけnsloginを使うのが良いかもしれません。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
34
Help us understand the problem. What are the problem?