有没有办法在不修改 Yocto 的情况下为机器 ID 创建 link?

Is there a way to create a link for the machine ID without modifying Yocto?

我是用 Yocto Zeus (3.0.0) 构建的 运行 Linux 4.14.149。我是 运行 一个只读文件系统,最近发现一个问题,我的 UID (/etc/machine-id) 每次启动都会更改(这个问题的结果 - https://superuser.com/questions/1668481/dhcpd-doesnt-issue-the-same-lease-after-reboot)。

我正在尝试将该文件设为用户数据分区的 link,以便它在重新启动后仍然存在。我尝试将 link 作为 base-files_%.bbappend 的一部分,这是我为主机名制作 link 的方式(有效)。这是该文件的内容(/var/local 是我们的用户数据分区,在初始化脚本中以 RW 方式挂载):

FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"

hostname = ""
machine-id = ""

do_install_append() {
    ln -sfn /var/local/etc/hostname ${D}/${sysconfdir}/hostname
    ln -sfn /var/local/etc/machine-id ${D}/${sysconfdir}/machine-id
}

但是当我尝试构建它时看到以下错误:

Exception: bb.process.ExecutionError: Execution of '/home/gen-ccm-root/workdir/tools/poky/build-dev/tmp/work/mi_nhep-poky-linux-gnueabi/mi-dev/1.0-r0/temp/run.read_only_rootfs_hook.50286' failed with exit code 1:
touch: cannot touch '/home/gen-ccm-root/workdir/tools/poky/build-dev/tmp/work/mi_nhep-poky-linux-gnueabi/mi-dev/1.0-r0/rootfs/etc/machine-id': No such file or directory
WARNING: exit code 1 from a shell command.

事实证明有两件事涉及该文件; rootfs-postcommands.bbclasssystemctl python 脚本(在 meta/recipes-core/systemd/systemd-systemctl/systemctl 中找到),前者(我认为)导致了错误。它在 do_rootfs 步骤中失败。

创建此 link 的最佳方法是什么?如果可以选择,我宁愿不修改 Yocto 源代码。

您可以通过定义自己的 rootfs post-command 并将其附加到 ROOTFS_POSTPROCESS_COMMAND 以便它运行 after Yocto 的内置read_only_rootfs_hook 使用 touch.

创建空的 /etc/machine-id 文件
# setup-machine-id-symlink.bbclass

ROOTFS_POSTPROCESS_COMMAND += "install_machine_id_symlink ;"
install_machine_id_symlink () {
    ln -sfn /var/local/etc/machine-id ${IMAGE_ROOTFS}/etc/machine-id
}


# your-image.bb

inherit setup-machine-id-symlink

Image Generation 文档更详细地介绍了如何在构建过程中应用 post 处理命令。

注意:您需要确保您的持久分区已提前挂载,以便读取 /etc/machine-id 不会导致符号链接损坏。


或者,使用绑定安装:

您也可以在运行时通过安装在引导序列早期运行的 systemd 服务来执行此操作,并将您的持久机器 ID 绑定到根文件系统中 Yocto 提供的空白机器 ID 上。

使用 systemd 服务(而不是 /etc/fstab 中的绑定挂载条目)是必要的,因为在创建绑定挂载之前您需要确保持久机器 ID 文件实际存在。不过,您可以使用 tmpfiles.d 来代替。