WSL2 中 Systemd 处于降级状态的原因分析及解决方案
WSL2 现已官方支持 Systemd,可实际上手体验后发现 WSL2 中 Systemd 处于降级状态。本文将分析 WSL2 中 Systemd 处于降级状态的原因并附上解决方案。
序言
2022年11月22日,Microsoft 终于宣布 WSL 脱离预览阶段并带来了人们翘首以盼的 Systemd 官方支持。
然而实际上手体验后,我发现 WSL2 中 Systemd 处于降级状态,希望 Microsoft 尽快修复此 BUG。
> systemctl status
● Anonimowy
State: degraded
Jobs: 0 queued
Failed: 1 units
接下来,本文将分析问题原因并附上解决方案。
问题何在?
首先,我们找出导致 Systemd 进入降级状态的罪魁祸首:
> systemctl --failed
UNIT LOAD ACTIVE SUB DESCRIPTION
● systemd-sysusers.service loaded failed failed Create System Users
LOAD = Reflects whether the unit definition was properly loaded.
ACTIVE = The high-level unit activation state, i.e. generalization of SUB.
SUB = The low-level unit activation state, values depend on unit type.
1 loaded units listed.
显而易见的,systemd-sysusers.service
启动失败导致了 Systemd 降级。
查看 systemd-sysusers.service
错误日志:
> journalctl --boot -u systemd-sysusers.service
Nov 30 00:00:00 Anonimowy systemd[58]: systemd-sysusers.service: Failed at step CREDENTIALS spawning systemd-sysusers: Protocol error
Nov 30 00:00:00 Anonimowy systemd[1]: systemd-sysusers.service: Main process exited, code=exited, status=243/CREDENTIALS
Nov 30 00:00:00 Anonimowy systemd[1]: systemd-sysusers.service: Failed with result 'exit-code'.
Nov 30 00:00:00 Anonimowy systemd[1]: Failed to start Create System Users.
查看 systemd-sysusers.service
单元文件:
> systemctl cat systemd-sysusers.service
# /lib/systemd/system/systemd-sysusers.service
# SPDX-License-Identifier: LGPL-2.1-or-later
#
# This file is part of systemd.
#
# systemd is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
[Unit]
Description=Create System Users
Documentation=man:sysusers.d(5) man:systemd-sysusers.service(8)
DefaultDependencies=no
Conflicts=shutdown.target
After=systemd-remount-fs.service
Before=sysinit.target shutdown.target systemd-update-done.service
ConditionNeedsUpdate=/etc
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=systemd-sysusers
TimeoutSec=90s
# Optionally, pick up a root password and shell for the root user from a
# credential passed to the service manager. This is useful for importing this
# data from nspawn's --set-credential= switch.
LoadCredential=passwd.hashed-password.root
LoadCredential=passwd.plaintext-password.root
LoadCredential=passwd.shell.root
systemd-sysusers.service
的作用是创建系统用户和系统组,而导致该系统服务单元失败的原因是以下几行配置:
LoadCredential=passwd.hashed-password.root
LoadCredential=passwd.plaintext-password.root
LoadCredential=passwd.shell.root
LoadCredential
和其他凭证选项若想要正常工作,Shared Memory Virtual Filesystem 必须挂载在 Systemd 期望的位置,也就是 /dev/shm
。然而目前,WSL2 却将其挂载在 /run/shm
并将 /dev/shm
链接到 /run/shm
。
> l /dev/shm
lrwxrwxrwx 1 root root 8 Nov 30 00:00 /dev/shm -> /run/shm
这意味着任意使用这些选项的单元都将无法正常运作。
例如,Snap 就将受 shm
位置影响。
解决方案
创建 /etc/systemd/system/fix-shm.service
> sudo systemctl edit --force --full fix-shm.service
> systemctl cat fix-shm.service
# /etc/systemd/system/fix-shm.service
[Unit]
Description=Fix /dev/shm Issue
Before=sysinit.target
DefaultDependencies=no
ConditionPathExists=/dev/shm
ConditionPathIsSymbolicLink=/dev/shm
ConditionPathIsMountPoint=/run/shm
[Service]
Type=oneshot
ExecStart=/usr/bin/rm /dev/shm
ExecStart=/bin/mount --bind -o X-mount.mkdir /run/shm /dev/shm
[Install]
WantedBy=sysinit.target
开机自动启用单元
> sudo systemctl enable fix-shm.service
立即终止所有正在运行的发行版和 WSL2 轻型实用程序虚拟机
> wsl --shutdown
重新启动 WSL2 并查看 Systemd 状态
> systemctl status
● Anonimowy
State: running
Jobs: 0 queued
Failed: 0 units
现在 Systemd 正常运作,问题完美解决,希望 Microsoft 尽快修复此 BUG。