问题描述 近日在刷帖子时,发现 WSL2 史诗级更新 ,出于好奇便对 WSL 进行了升级,来到了 WSL 2.0.3.0。但是新特性只支持 Windows 11 23H2,现在的系统是 Windows 10 22H2,所以白忙活一场。后来在通过 pacman 安装软件包时,发现以下报错,猜测可能是一些配置文件被破坏。
1 2 3 4 5 6 7 8 ... :: Running post-transaction hooks... (1/3) Reloading system manager configuration... Skipped: Current root is not booted. (2/3) Creating temporary files... /usr/lib/tmpfiles.d/journal-nocow.conf:26: Failed to resolve specifier: uninitialized /etc/ detected, skipping. All rules containing unresolvable specifiers will be skipped. (3/3) Arming ConditionNeedsUpdate...
尝试卸载了 WSL 更新,回退到 WSL 1.2.5.0,但是问题依旧存在。
初步尝试 根据 ChatGPT 对于 Skipped: Current root is not booted.
的描述,这个问题可能是引导配置或者文件系统分区问题。但是一番操作下来没有找到有效的突破口,网络上的资源中也没有找到有效信息。
突发奇想 是否可以利用 ChatGPT 了解 pacman 安装软件包的过程中,在 post-transaction hooks 的过程中都做了一些什么?了解这些过程中的操作,然后对症下药,是否可行呢?
于是询问 ChatGPT 并得到如下回复。
Q:
Arch Linux 的 pacman 在安装软件的过程中,Running post-transaction hooks,这一步是在干什么?
A:
Arch Linux 中的 Pacman 在安装软件包之后会运行一系列的 post-transaction 钩子(post-transaction hooks)。这些钩子是一种机制,允许用户或软件包维护者执行特定的操作或配置更改,以确保软件包的正确安装和系统的一致性。
……
您可以在 /usr/share/libalpm/hooks 目录中找到与 Pacman 默认提供的一些 post-transaction 钩子相关的脚本。您还可以创建自己的自定义钩子来执行特定任务,然后将它们添加到 /etc/pacman.d/hooks 目录中。这些自定义钩子将在 Pacman 的软件包事务中运行。
开始修复 首先可以看到这里给出了一个目录 /usr/share/libalpm/hooks
,可以看看这些目录中有什么。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 ❯ cd /usr/share/libalpm/hooks ❯ ll .rw-r--r-- root root 233 B Wed Sep 27 21:11:01 2023 20-systemd-sysusers.hook .rw-r--r-- root root 226 B Wed Sep 27 21:11:01 2023 30-systemd-binfmt.hook .rw-r--r-- root root 254 B Wed Sep 27 21:11:01 2023 30-systemd-catalog.hook .rw-r--r-- root root 265 B Wed Sep 27 21:11:01 2023 30-systemd-daemon-reload.hook .rw-r--r-- root root 246 B Wed Sep 27 21:11:01 2023 30-systemd-hwdb.hook .rw-r--r-- root root 231 B Wed Sep 27 21:11:01 2023 30-systemd-sysctl.hook .rw-r--r-- root root 228 B Wed Sep 27 21:11:01 2023 30-systemd-tmpfiles.hook .rw-r--r-- root root 261 B Wed Sep 27 21:11:01 2023 30-systemd-udev-reload.hook .rw-r--r-- root root 227 B Wed Sep 27 21:11:01 2023 30-systemd-update.hook .rw-r--r-- root root 243 B Thu Jan 1 08:00:00 1970 40-update-ca-trust.hook .rw-r--r-- root root 273 B Sat Sep 30 04:52:41 2023 60-depmod.hook .rw-r--r-- root root 355 B Sat Sep 2 21:42:07 2023 dbus-reload.hook .rw-r--r-- root root 224 B Tue Jul 25 06:17:30 2023 detect-old-perl-modules.hook .rw-r--r-- root root 245 B Tue Sep 12 04:40:39 2023 gio-querymodules.hook .rw-r--r-- root root 338 B Tue Sep 12 04:40:39 2023 glib-compile-schemas.hook .rw-r--r-- root root 281 B Mon Mar 27 07:16:05 2023 texinfo-install.hook .rw-r--r-- root root 285 B Mon Mar 27 07:16:05 2023 texinfo-remove.hook .rw-r--r-- root root 271 B Tue Oct 3 21:26:46 2023 vimdoc.hook
在这些 hook 文件中搜索 system manager configuration
,可以找到文件 30-systemd-daemon-reload.hook
,来看一看这个文件中的内容。
1 2 3 4 5 6 7 8 9 10 11 [Trigger] Type = Path Operation = Install Operation = Upgrade Operation = Remove Target = usr/lib/systemd/system/* [Action] Description = Reloading system manager configuration... When = PostTransaction Exec = /usr/share/libalpm/scripts/systemd-hook daemon-reload
对这个 hook 文件,猜测一下大概的作用,应该就是 install | upgrade | remove 时以 daemon-reload
作为参数调用脚本 /usr/share/libalpm/scripts/systemd-hook
。但是这些都不是重点,重点关注这个脚本的内容。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 #!/bin/sh -e is_chrooted () { if systemd-detect-virt --chroot ; then echo >&2 " Skipped: Running in chroot." exit 0 fi } systemd_live () { is_chrooted if [ ! -d /run/systemd/system ]; then echo >&2 " Skipped: Current root is not booted." exit 0 fi } udevd_live () { is_chrooted if [ ! -S /run/udev/control ]; then echo >&2 " Skipped: Device manager is not running." exit 0 fi } ......
可以看到这个脚本设置了几个校验函数,重点在于 systemd_live()
,报错信息中有 pacman 更新时遇到的内容。这个函数校验了目录 /run/systemd/system
是否存在。测试发现当前系统中确实不存在。
只需要简单的创建这个目录吗?目录的属主和权限应该是怎样的呢?这些问题都没有答案,没事,可以问一问 ChatGPT。
Q:
Arch Linux 的目录 /run/systemd/system 的作用是什么?这个目录的属主和权限是怎样的?
A:
/run/systemd/system
目录是 Arch Linux 中的一个重要目录,它与 systemd 系统管理守护进程相关。这个目录的作用是存储运行时(runtime)的 systemd 服务单元配置文件,这些配置文件定义了系统上正在运行的各种服务。
以下是有关 /run/systemd/system
目录的一些关键信息和作用:
运行时服务配置 :/run/systemd/system
目录包含正在运行的 systemd 服务单元的配置文件。这些配置文件描述了系统上当前活动的服务,以及它们的属性、依赖关系和其他相关信息。
动态生成 :与传统的 /etc/systemd/system
目录不同,/run/systemd/system
目录中的配置文件通常是动态生成的。当系统启动时,systemd 根据需要启动各种服务,并在运行时创建相应的服务单元配置文件。这些配置文件存储在 /run/systemd/system
目录中。
临时性质 :/run/systemd/system
目录中的配置文件是临时的,它们在系统重新启动时会被清除。这是因为它们是根据当前系统状态和需要生成的,而不是静态的配置文件。重新启动后,新的配置文件将再次根据系统状态生成。
管理正在运行的服务 :通过查看和编辑 /run/systemd/system
目录中的配置文件,您可以查看和管理当前正在运行的 systemd 服务。这对于调试和了解系统中的活动服务非常有用。
以下是有关 /run/systemd/system
目录的属主和权限的一般设置:
属主(Owner):通常为 root
用户,这意味着只有超级用户(root)有对该目录的完全控制权,包括创建、修改和删除文件。
权限(Permissions):通常设置为 755
,这意味着目录的权限如下:
所有者(Owner):读、写、执行权限 (7)
组(Group):读、执行权限 (5)
其他用户:读、执行权限 (5)
总之,/run/systemd/system
目录在 Arch Linux 中用于存储正在运行的 systemd 服务单元的配置文件,它反映了系统的当前状态和正在执行的服务。这个目录的临时性质使得系统能够根据需要动态管理服务,而不必依赖静态的配置文件。
可以看到这是一个动态的、临时的目录。在我手中其他服务器上看了一下这个目录的属主和权限进行验证,结果如下,结果也相符合。
1 2 service@oracle-service:~$ ll /run/systemd | grep system/ drwxr-xr-x 3 root root 80 Oct 4 23:35 system/
那么就可以在 WSL 的系统中创建这个目录,并设置相应的属主和权限。但是问题是创建了这个目录后,执行更新依然有问题;更重要的是,重启后这个目录依然不存在 。这很好理解,这是一个 systemd 管理的临时目录 ,那么在重启后会消失并重新创建。现在的问题是没有重新创建。
发帖子去社区求助!但是在写帖子的过程中,我突然想起来 WSL2 一开始并不支持 systemd,哪怕后来微软官方支持了我也没有开启。于是去 /etc/wsl.conf
中配置 systemd 的启用后,重启 WSL 并尝试安装软件包,没有产生报错信息了。
至此应该就算修复完成了?
一些优化 pacman 的 debug 参数 在社区中准备写帖子时翻了一下别人的问题,发现 pacman 可以通过添加参数 --debug --verbose
来获取一些信息。通过这些参数获得了以下输出。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 ... :: Running post-transaction hooks... (1/3) Reloading system manager configuration... debug: executing "/usr/share/libalpm/scripts/systemd-hook" under chroot "/" Skipped: Current root is not booted. debug: call to waitpid succeeded (2/3) Creating temporary files... debug: executing "/usr/share/libalpm/scripts/systemd-hook" under chroot "/" /usr/lib/tmpfiles.d/journal-nocow.conf:26: Failed to resolve specifier: uninitialized /etc/ detected, skipping. All rules containing unresolvable specifiers will be skipped. debug: call to waitpid succeeded (3/3) Arming ConditionNeedsUpdate... debug: executing "/usr/share/libalpm/scripts/systemd-hook" under chroot "/" debug: call to waitpid succeeded debug: unregistering database 'local' debug: freeing package cache for repository 'local' debug: unregistering database 'core' debug: freeing package cache for repository 'core' debug: unregistering database 'extra' debug: freeing package cache for repository 'extra' debug: unregistering database 'archlinuxcn' debug: freeing package cache for repository 'archlinuxcn'
可以直接看到执行了脚本 /usr/share/libalpm/scripts/systemd-hook
。