WSL2にArch Linuxをインストールする
あけましておめでとうございます🎍
先日、WSLで動かすLinuxのディストロをUbuntuからArch Linuxにしたのでその手順を残しておきます。
また、systemdを有効化しようとしたら一筋縄ではいかなかったのでその解決方法も示しておきます。
(Linuxについてあまり詳しくないので、一部不正確な点があるかもしれません)
Arch Linuxの導入
Arch Linuxはwsl --list --online
にないのでwsl --install
でインストールできません。
そこで、この記事を参考にwsl --import
からインポートする手法を取ります。
ブートストラップイメージのダウンロード/編集
既存のUbuntu環境上で作業します。
以下のリンクから適当なサーバを選び、archlinux-bootstrap-~~~-x86_64.tar.zst
をダウンロードします。
解凍します。
$ 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
に書きます。
# 起動時にログインするユーザを指定
# デフォルトはroot
[user]
default=username
# systemdの有効化
[boot]
systemd=true
# (Optional) hostnameの変更
[network]
hostname=Arch
設定を反映させるため、Arch Linuxを再起動します。
> 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
で止まっています。
ググってもなかなか解決方法が出てこない中、こちらの記事に遭遇しました。
こちらの記事を参考に対処していきます。
対処方法
既存の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.service
がinactive (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
については、以下の方の記事が参考になりました。
この記事に従って、systemd-networkd
をdisableします。
$ sudo systemctl disable systemd-networkd
WSLを再起動し、degraded
からrunning
になっていればOKです!お疲れ様でした🫡
余談
WSLの起動が遅いなと感じるときは、/etc/wsl.conf
のboot
セクションにinitTimeout
を追加すると短縮することができます。
[boot]
initTimeout=1000
Discussion