From 8a67dfa9863163c72fd4c405463592a02add6501 Mon Sep 17 00:00:00 2001 From: Krzesimir Nowak Date: Thu, 28 Jan 2021 10:09:51 +0100 Subject: [PATCH] sys-apps/systemd: Fix unit installation The systemd.eclass was not finding the systemd pkg-config file to figure out the system unit directory, so it was falling back to a hardcoded default (`/lib/systemd/system`). In one case (when overriding the `default.target` symlink), we tried to fix that by specifying the `PKG_CONFIG_LIBDIR` environment variable, but that still did not help. Using functions from `systemd.eclass` in a systemd ebuild is working only by chance here. This eclass is usually meant for ebuilds that depend on systemd and rely on systemd being already installed in the root filesystem. The functions in `systemd.eclass` that need to figure out some values from systemd's pkg-config file (like system unit directory) assume that systemd is already installed in the root filesystem, which is not the case when we actually are building and installing systemd. To add an insult to the injury, `systemd.eclass` is not using pkg-config directly, but rather a shell script that wraps pkg-config (for example `/usr/bin/x86_64-cros-linux-gnu-pkg-config`). The script clobbers the environment variables like `PKG_CONFIG_PATH` or `PKG_CONFIG_LIBDIR`, which is why overriding them did not work when fixing up the `default.target` symlink. Thus `systemd.eclass` was actually falling back to a hardcoded default value. The only way to control the script is through either SYSROOT or ROOT environment variables. So do so. This fixes merging the installed files into root file system using a newer version of portage. The failure was that systemd build system installs the `default.target` symlink in `/usr/lib/systemd/system` pointing to `graphical.target`, while we later try to override it to point it to `multi-user.target`. But instead of overriding a symlink, we installed a new symlink in `/lib/systemd/system`. Both `/lib` and `/usr/lib` are separate directories in the temporary installation directory, but in root filesystem, both are symlinks pointing to the same directory. Which means that we ended up with two different symlinks in temporary installation directory, and the new portage version could not decide which one to use during the merge into the root filesystem. I'm not sure what old portage version did here, likely worked by chance too. --- .../sys-apps/systemd/systemd-9999.ebuild | 42 ++++++++++++------- 1 file changed, 28 insertions(+), 14 deletions(-) diff --git a/sdk_container/src/third_party/coreos-overlay/sys-apps/systemd/systemd-9999.ebuild b/sdk_container/src/third_party/coreos-overlay/sys-apps/systemd/systemd-9999.ebuild index 8b1a642e79..93a0aaae08 100644 --- a/sdk_container/src/third_party/coreos-overlay/sys-apps/systemd/systemd-9999.ebuild +++ b/sdk_container/src/third_party/coreos-overlay/sys-apps/systemd/systemd-9999.ebuild @@ -439,7 +439,7 @@ multilib_src_install_all() { systemd_dotmpfilesd "${FILESDIR}"/systemd-resolv.conf # Flatcar: Don't default to graphical.target. - local unitdir=$(PKG_CONFIG_LIBDIR="${PWD}/src/core" systemd_get_systemunitdir) + local unitdir=$(builddir_systemd_get_systemunitdir) dosym multi-user.target "${unitdir}"/default.target # Flatcar: Don't set any extra environment variables by default. @@ -449,35 +449,35 @@ multilib_src_install_all() { # preset file (90-systemd.preset). We do it that way, to avoid # putting symlink in /etc. Please keep the lines in the same # order as the "enable" lines appear in the preset file. - systemd_enable_service multi-user.target remote-fs.target - systemd_enable_service multi-user.target remote-cryptsetup.target - systemd_enable_service multi-user.target machines.target + builddir_systemd_enable_service multi-user.target remote-fs.target + builddir_systemd_enable_service multi-user.target remote-cryptsetup.target + builddir_systemd_enable_service multi-user.target machines.target # Flatcar: getty@.service is enabled manually below. - systemd_enable_service sysinit.target systemd-timesyncd.service - systemd_enable_service multi-user.target systemd-networkd.service + builddir_systemd_enable_service sysinit.target systemd-timesyncd.service + builddir_systemd_enable_service multi-user.target systemd-networkd.service # Flatcar: For systemd-networkd.service, it has it in Also, which also # needs to be enabled - systemd_enable_service sockets.target systemd-networkd.socket + builddir_systemd_enable_service sockets.target systemd-networkd.socket # Flatcar: For systemd-networkd.service, it has it in Also, which also # needs to be enabled - systemd_enable_service network-online.target systemd-networkd-wait-online.service - systemd_enable_service multi-user.target systemd-resolved.service + builddir_systemd_enable_service network-online.target systemd-networkd-wait-online.service + builddir_systemd_enable_service multi-user.target systemd-resolved.service if use homed; then - systemd_enable_service multi-user.target systemd-homed.target + builddir_systemd_enable_service multi-user.target systemd-homed.target # Flatcar: systemd-homed.target has # Also=systemd-userdbd.service, but the service has no # WantedBy entry. It's likely going to be executed through # systemd-userdbd.socket, which is enabled in upstream's # presets file. - systemd_enable_service sockets.target systemd-userdbd.socket + builddir_systemd_enable_service sockets.target systemd-userdbd.socket fi - systemd_enable_service sysinit.target systemd-pstore.service + builddir_systemd_enable_service sysinit.target systemd-pstore.service # Flatcar: not enabling reboot.target - it has no WantedBy # entry. # Flatcar: Enable getty manually. - mkdir --parents "${ED}/usr/lib/systemd/system/getty.target.wants" - dosym ../getty@.service "/usr/lib/systemd/system/getty.target.wants/getty@tty1.service" + dodir "${unitdir}/getty.target.wants" + dosym ../getty@.service "${unitdir}/getty.target.wants/getty@tty1.service" # Flatcar: Use an empty preset file, because systemctl # preset-all puts symlinks in /etc, not in /usr. We don't use @@ -499,6 +499,20 @@ multilib_src_install_all() { # dropped it. } +builddir_systemd_enable_service() { + ( + export SYSROOT="${ED}" + systemd_enable_service "$@" + ) +} + +builddir_systemd_get_systemunitdir() { + ( + export SYSROOT="${ED}" + systemd_get_systemunitdir + ) +} + migrate_locale() { local envd_locale_def="${EROOT}/etc/env.d/02locale" local envd_locale=( "${EROOT}"/etc/env.d/??locale )