💻

WSL2にArch Linuxをインストールする

2025/01/02に公開

あけましておめでとうございます🎍

先日、WSLで動かすLinuxのディストロをUbuntuからArch Linuxにしたのでその手順を残しておきます。
また、systemdを有効化しようとしたら一筋縄ではいかなかったのでその解決方法も示しておきます。

(Linuxについてあまり詳しくないので、一部不正確な点があるかもしれません)

Arch Linuxの導入

Arch Linuxはwsl --list --onlineにないのでwsl --installでインストールできません。
そこで、この記事を参考にwsl --importからインポートする手法を取ります。

https://wiki.archlinux.jp/index.php/既存の_Linux_からインストール

ブートストラップイメージのダウンロード/編集

既存のUbuntu環境上で作業します。
以下のリンクから適当なサーバを選び、archlinux-bootstrap-~~~-x86_64.tar.zstをダウンロードします。

https://www.archlinux.jp/download/

解凍します。

$ tar xvf archlinux-bootstrap-~~~-x86_64.tar.zst

mirrorlistを編集します。適当なJapanらへんのサーバのコメントを外します。

$ cd root.x86_64
$ vim ./etc/pacman.d/mirrorlist

圧縮します。root.x86_64にいる状態で次のコマンドを実行します。

$ tar cvf archlinux.tar.gz *

WSLにインポート

先ほど作ったarchlinux.tar.gzを適当なWindows上のディレクトリに配置します。
今回はC:\WSL\Arch上に置きます。

$ mv archlinux.tar.gz /mnt/c/WSL/Arch/

インポートします。

> wsl --import ArchLinux C:\WSL\Arch C:\WSL\Arch\archlinux.tar.gz
インポート中です。この処理には数分かかることがあります。
この操作を正しく終了しました。

初期設定

wsl -d ArchLinuxしてArch Linuxの初期設定をします。

$ pacman-key --init
$ pacman-key --populate archlinux

$ pacman -Syyu base base-devel git vim wget

$ useradd -m -G wheel username
$ passwd
$ passwd username

# %wheel ALL=(ALL:ALL) ALLのコメントを外す
$ EDITOR=vim visudo

WSL向けの設定を/etc/wsl.confに書きます。

/etc/wsl.conf
# 起動時にログインするユーザを指定
# デフォルトはroot
[user]
default=username

# systemdの有効化
[boot]
systemd=true

# (Optional) hostnameの変更
[network]
hostname=Arch

設定を反映させるため、Arch Linuxを再起動します。

powershell
> wsl -t ArchLinux
この操作を正しく終了しました。
> wsl -d ArchLinux

自分のユーザでログインできていたらひとまず終了です。お疲れ様でした🎉

systemdが機能しない?

さて、Arch Linuxはセットアップできましたが、実はsystemdが正常に起動できていません (たぶん)。

$ sudo systemctl status
● Arch
    State: initializing
    Units: 319 loaded (incl. loaded aliases)
     Jobs: 31 queued
   Failed: 0 units
    Since: Thu 2025-01-02 03:30:35 JST; 4min 11s ago
  systemd: 257.1-1-arch
  Tainted: cgroupsv1
   CGroup: /
           ├─init.scope
           │ ├─  1 /sbin/init
           │ ├─  2 /init
           │ ├─  6 plan9 --control-socket 6 --log-level 4 --server-fd 7 --pipe-fd 9 --log-truncate
           │ ├─284 /init
           │ ├─285 /init
           │ ├─291 -bash
           │ ├─316 sudo systemctl status
           │ ├─318 sudo systemctl status
           │ ├─320 systemctl status
           │ └─321 "(pager)"
           └─system.slice
             ├─systemd-firstboot.service
             │ └─174 "(irstboot)"
             ├─systemd-journald.service
             │ └─44 /usr/lib/systemd/systemd-journald
             ├─systemd-networkd.service
             │ └─108 /usr/lib/systemd/systemd-networkd
             ├─systemd-nsresourced.service
             │ ├─ 57 /usr/lib/systemd/systemd-nsresourced
             │ ├─ 80 "systemd-nsresourcework: waiting..."
             │ ├─ 81 "systemd-nsresourcework: waiting..."
             │ ├─ 82 "systemd-nsresourcework: waiting..."
             │ ├─ 83 "systemd-nsresourcework: waiting..."
             │ └─319 "systemd-nsresourcework: waiting..."
             ├─systemd-resolved.service
             │ └─97 /usr/lib/systemd/systemd-resolved
             ├─systemd-udevd.service
             │ └─udev
             │   └─103 /usr/lib/systemd/systemd-udevd
             └─systemd-userdbd.service
               ├─ 59 /usr/lib/systemd/systemd-userdbd
               ├─169 "systemd-userwork: waiting..."
               ├─170 "systemd-userwork: waiting..."
               └─171 "systemd-userwork: waiting..."

と、Stateがinitizlizingで止まっています。

ググってもなかなか解決方法が出てこない中、こちらの記事に遭遇しました。

https://blog.hinaloe.net/2024/01/24/wsl2-dbus-wslg/

こちらの記事を参考に対処していきます。

対処方法

既存のUbuntu環境で、systemd-binfmt.serviceのstatusを調べます。

$ sudo systemctl status systemd-binfmt.service
○ systemd-binfmt.service - Set Up Additional Binary Formats
     Loaded: loaded (/lib/systemd/system/systemd-binfmt.service; static)
    Drop-In: /usr/lib/systemd/system/systemd-binfmt.service.d
             └─wsl.conf
     Active: inactive (dead)
  Condition: start condition failed at Thu 2025-01-02 03:39:02 JST; 35s ago
             └─ ConditionVirtualization=!wsl was not met
       Docs: man:systemd-binfmt.service(8)
             man:binfmt.d(5)
             https://www.kernel.org/doc/html/latest/admin-guide/binfmt-misc.html
             https://www.freedesktop.org/wiki/Software/systemd/APIFileSystems

/usr/lib/systemd/system/systemd-binfmt.service.d/wsl.confを見てみるとConditionVirtualizationが指定されていて、これによりsystemd-binfmt.serviceinactive (dead)になっているらしいです。

この設定をArch Linuxへ移植します。

$ sudo mkdir /lib/systemd/system/systemd-binfmt.service.d
$ sudo vim /lib/systemd/system/systemd-binfmt.service.d/wsl.conf
# [Unit]
# ConditionVirtualization=!wsl

WSLを再起動して、再度sudo systemctl statusしたときにStateがrunningになっていれば成功です!

runningにならない

さて、中にはrunningじゃなくてstarting/degradedになった!という人もいるでしょう。
(たぶんstartingの人はそのまま放置するとdegradedになると思います)

journalctl -xbしてみると、systemd-networkd-wait-onlineがコケていることが確認できるかと思います。

systemd-networkd-wait-online[147]: Timeout occurred while waiting for network connectivity.

このsystemd-networkd-wait-onlineについては、以下の方の記事が参考になりました。

https://zenn.dev/kenchan/articles/5f3d53182f0a75

この記事に従って、systemd-networkdをdisableします。

$ sudo systemctl disable systemd-networkd

WSLを再起動し、degradedからrunningになっていればOKです!お疲れ様でした🫡

余談

WSLの起動が遅いなと感じるときは、/etc/wsl.confbootセクションにinitTimeoutを追加すると短縮することができます。

wsl.conf
[boot]
initTimeout=1000

Discussion