通过 ChatGPT 协助解决软件安装问题
2023-10-07 09:00:00

问题描述

近日在刷帖子时,发现 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 目录的一些关键信息和作用:

  1. 运行时服务配置/run/systemd/system 目录包含正在运行的 systemd 服务单元的配置文件。这些配置文件描述了系统上当前活动的服务,以及它们的属性、依赖关系和其他相关信息。

  2. 动态生成:与传统的 /etc/systemd/system 目录不同,/run/systemd/system 目录中的配置文件通常是动态生成的。当系统启动时,systemd 根据需要启动各种服务,并在运行时创建相应的服务单元配置文件。这些配置文件存储在 /run/systemd/system 目录中。

  3. 临时性质/run/systemd/system 目录中的配置文件是临时的,它们在系统重新启动时会被清除。这是因为它们是根据当前系统状态和需要生成的,而不是静态的配置文件。重新启动后,新的配置文件将再次根据系统状态生成。

  4. 管理正在运行的服务:通过查看和编辑 /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