• Windows Subsystem for Linuxガイド 第18回 systemd 基本編

Microsoftストア版WSL Ver.0.67.6から、systemdが利用可能になった。systemdとは「初期化システム」の1つで、Linuxで広く使われているものだ。

「初期化システム」は、Unix由来の技術で、起動時に必要なデーモン(バックグラウンド処理を行なうプログラム。Windowsのサービスに相当)の起動や初期化処理を行なうもの。最初に起動するUnix/Linuxのプロセス名であるinitを引き継いで処理することから、「initシステム」などとも呼ばれる。著名なものには、System V系UnixのSysV init(System V init。あるいはランレベルと呼ぶこともある)やBSD系Unixで使われたBSD initなどがある。

初期のLinuxでは、SysV initが使われていたが、2010年にRedHat社で開発されたsystemdを採用するディストリビューションが増えてきた。議論もあるが、現在では、多くのディストリビューションが標準としてsystemdを組み込んでいる。このため、HTTPサーバーのようなデーモンとして動作するプログラム、あるいはデーモンの事前起動が必要なプログラムの多くがsystemdを前提に開発されている。

Microsoftは、こうした状況に対応すべく、systemdを稼働できるようにWSL2を改良した。今回と次回の2回にわたって、systemdの有効化や利用方法を解説する。ただし、systemdは、かなり大規模な仕組みであり、ちょっと話を聞いたからといって使いこなせるものでもない。ここで解説できるのはほんの「とっかかり」である。

評価は、Windows 11 Ver.22H2でMicrosoftストア版WSLのVer.1.2.5.0で行なった。後述するが、systemdを稼働させるためには、Microsoftストア版のWSLが必須である。Windows 11などに付属のWSLの場合には、過去記事「Windows Subsystem for Linuxガイド 第13回 Microsoftストア版WSL」などを参照の上、アップデートなどを行なってほしい。

対象のWSLディストリビューションは、Ubuntu 22.04 LTSを使った。systemdは、ディストリビューションやバージョンに依存する部分も多く、特にsystemdから起動されるサービスなどが異なる。他のディストリビューションやバージョンを利用する場合には、異なる結果になる可能性もあることをご理解いただきたい。

systemdの有無によるWSL2の起動時間

まずは、systemdを有効にすることのメリット、デメリットをはっきりさせておこう。メリットは、前述のようにsystemdに依存しているプログラムの利用が可能になる点だが、デメリットとして、WLS2ディストリビューションの起動時間が遅くなることが上げられる。

(表01)は、systemdの有効無効を切り替えた場合のWSL2ディストリビューションの起動時間を測定したものだ。

  • ■表1

WSLでは、まず、軽量ユーティリティ仮想マシン環境が作られ、その中でWSL2ディストリビューションが起動する。このとき、systemdが有効になっていれば、初期化処理が行なわれる。ただし、一回WSL2ディストリビューションが起動すると、ディストリビューションのセッションが終了するまでは、systemdによる初期化処理は行なわれない(一部の処理を除く)。

測定では、別のWSL2ディストリビューションを起動しておき、軽量ユーティリティ仮想マシン環境を動作させておく。その後、systemdの有効無効を切り替え、終了状態(wsl.exe --terminateによりディストリビューションを完全に停止した状態)から、WSL2ディストリビューション(測定には、Ubuntu-22.04を利用した)を起動し、wsl.exeによるコマンド実行を2回、1秒の時間を置いて実行し、それぞれのコマンド実行時間を測定した。

具体的には、Windows PowerShellで(リスト01)のようなコマンドを実行した。

■リスト01

wsl --terminate Ubuntu-22.04 ; Measure-Command {wsl.exe -d ubuntu-22.04 -- echo 1 } | select TotalMilliseconds ; Start-Sleep -Seconds 1 ; Measure-Command {wsl.exe -d ubuntu-22.04 -- echo 1 } | select TotalMilliseconds

初回の測定では、systemdの処理時間が加わり、2回目の実行では、systemdは初期化を終えている。systemdを有効にすると、筆者の環境では、初回の起動に 約4850ミリ秒(約4.9秒)かかったのに対して、systemdを無効にした場合、535ミリ秒(約0.5秒)になっている。

ただし、2回目のコマンド実行に関しては、278ミリ秒と258ミリ秒とほとんど差がなく、この程度であれば、利用時に問題になることはないだろう。

ここから言えることは、WSLをWin32側からコマンドのパイプラインで呼び出すような使い方の場合、systemdを入れると、初回のコマンド実行がかなり遅くなる可能性がある。コマンド実行での数秒は長く感じられ、多くのユーザーからはあまり好まれないと思われる。このような使い方場合、コマンド実行終了後、しばらくすると、WSLの実行環境自体も終了してしまい、さらに起動時間を要する可能性もある。測定結果には、含めなかったが、軽量ユーティリティ仮想マシン環境の起動には、3~4秒が必要で、初回の起動には8秒ほどかかった。

wsl.exeでディストリビューションを起動して、Linuxをコマンドラインで利用するような場合には、4.8秒と0.5秒の差が許容範囲かどうかは個人に依存する。この程度の時間なら、多少負荷のあるときに、Windowsのアプリケーションを起動してウィンドウが開くまでの時間として普段体験する範囲だからだ。

このあたりをまとめると、WSLをコマンドパイプラインで使うことが多い場合には、systemdは有効にしないほうがよい、といえる。

Linuxをコマンドラインを直接使うような場合には、systemdの有効無効の差はあまり目立たないが、WSL環境を最初に立ち上げる場合には、8秒程度が必要となる。ユーザーが長いと感じる待ち時間について、俗に8秒ルールなどとも言われていることを考えると、起動時間としては、「長い」と言わざるを得ない。

現状、systemdの利用は必須ではないため、Linux側で利用するプログラムに依存して利用の可否を決定する必要がある。

なお、WSLでのsystemdの設定は、あくまでも標準状態であり、チューニングの余地はある。具体的な方法は別途解説するが、systemdで起動されているサービスの一部を停止することで起動時間の短縮は可能ではあるが、そのためにはサービスの利用を断念せざるを得ない場合がある。

とりあえずは、systemdを取るか、短い起動時間を取るかの二者択一であると考えたほうがよく、使うかもしれない程度の理由で有効化することはデメリットが大きいといえる。

systemdとは?

systemdは、Unit(ユニット)と呼ばれる初期化処理を定義する情報を処理することでシステムの初期化を行なう。この初期化処理は、大半がLinuxの起動時に行なわれるが、ユニットの中には、Linuxの稼働中にタイマーやイベントなどで起動されるものもある。

ユニットには、対象に応じた「タイプ」(表02)があり、他のユニットの依存関係や、前後関係、実行のタイミングなどの属性情報や実行すべき初期化プログラムが記述してある。

  • ■表2

systemdは、ユニットを読み込んで解釈すると、ユニットをできる限り並列に実行できるようにスケジューリングを行なって初期化処理を完了させる。ユーザーは、このユニットに対して、開始/終了、再起動、有効化、無効化などを行なうことができる。

ユニットは、ユニットファイルに記述されている。それぞれのユニットファイルに対して、読み込みの可否を管理者が指定できる。読み込まれたユニットのみが処理の対象になる。なお、ユニットの中には動的に生成されるものもあり、ユニットは存在していてもユニットファイルが必ずしも存在しているとは限らない。

systemdの基本的な設定や起動に必要なユニットの定義などは、ディストリビューションを構築するベンダーがディストリビューションの作成時に構成しておく。その意味では、systemdは、ディストリビューションの起動プロセスの一部である。

最初に“ default.target”ユニットが読み込まれ、ここに記述してあるユニットやそれらと依存関係のあるユニットが読み込まれていく。読み込まれたのち、systemdは最終的なユニットの処理順を決定して処理していく。

systemdにおけるユーザーの基本操作は、ユニットの実行可否や、ユニットの起動、再起動、停止などによるサービスの制御である。主に利用するコマンドはsystemctlで、ユニットに関する設定などは、このコマンドから行なう。このため、systemctlコマンドには多くのサブコマンドとオプションがある。

初めてsystemdを触るユーザーが注意すべき点は、systemdでは、ユニットファイルを直接編集するのは、適切ではないことだ。というのも、systemdはLinuxの起動プロセスの一部で、ユニットの処理は、慎重に検討されてディストリビューションに組み込まれたものだからだ。もし、書き換えねばならないと思えたら、何か別の適切な方法がある可能性が高く、それを探すべきである。

もちろん、ユニットファイルやそこで指定されている初期化プログラムもファイルにすぎないので書き換えることは不可能ではない。しかし、systemdには、ユニットファイルを直接書き換えなくてもいいように、差分を別ファイルに記録する、ユニットファイルのコピーを別ディレクトリに記録して優先して読み込むといった方法が提供されている。これらもsystemctlコマンドで行えるため、ユニットファイルを直に触る必要はほとんどない。

systemdでは、ユニットファイルの記述間違いにより、システムの起動が行えなくなる可能性がある。たとえば、ユニットが相互に終了を待つように指定してしまうとデッドロックが発生し、systemdの初期化処理が終了しなくなる。

systemdを設定する

最近インストールしたWSLディストリビューションでは、systemdが標準で有効になっているものと、そうでないものがある。筆者が調べた範囲では、2023年5月5日現在でsystemdが有効になった状態で、配布が行なわれているWSLディストリビューション(wsl.exe -l --onlineで表示可能なもの)は、“Ubuntu”と“Ubuntu-22.04”のみ(現時点では、この2つは同じディストリビューション)。これ以外のディストリビューションは、すべてsystemdは無効化されたままだ。なお、前記2つのディストリビューションでも、systemdが有効化された2022年9月以前にインストールしたWSLディストリビューションの場合、systemdが無効になっていることがある。

現在利用中のディストリビューションでsystemdが有効かどうかは、/etc/wsl.confを確認する。ここに以下の行があれば、systemdが有効化されている。


[boot]
systemd=true

ただし、場合によっては、“[boot]”と“systemd=true”の間に他の行が入る可能性がある。

systemdを有効化したい場合、管理者権限を使って、上記のように/etc/wsl.confの“[boot]”セクションに“systemd=true”を追加する。

その後、WSLを抜け、ディストリビューションを一回終了させる。具体的には、“wsl.exe --terminate <ディストリビューション名>”として、完全に終了させたあと、再度起動することでsystemdが起動時に有効となる。

wsl.confの編集の詳細に関しては、「Windows Subsystem for Linuxガイド 第6回 ドライブファイルシステムの設定と挙動 その1」の「/etc/wsl.confとドライブファイルシステム」を参照されたい。

実際にsystemdが動作しているかどうかは、systemctlコマンドを使って確認ができる(写真01)。以下のコマンドは、読み込まれたユニットファイルの状態を表示する。


systemctl list-units

ただし、通常systemdには大量のユニットが登録されており、多数のユニットが表示される。このとき、コンソール画面右側に反転表示の“>”が表示されている場合、1行がすべて表示されていないことを示し、カーソルの左右キーで横スクロールさせることが可能だ。

  • 写真01: systemdのユニットは、systemctlを介して管理を行なう。systemctlには多くの機能があり、最初の引数に動作を指定する「コマンド」を指定する

次回は、具体的にsystemctlコマンドの使い方などを解説する。

> Windows Subsystem for Linuxガイド 連載バックナンバー https://news.mynavi.jp/tag/winsubsystem/