@@ -27,24 +27,36 @@ python __anonymous() {
}
systemd_postinst() {
-if type systemctl >/dev/null 2>/dev/null; then
- OPTS=""
-
- if [ -n "$D" ]; then
- OPTS="--root=$D"
+if [ -n "$D" ]; then
+ # Image-build/cross-install: apply presets to the target rootfs.
+ # This handles multistrap, debootstrap, and similar tools that
+ # install packages outside of Yocto's normal image creation.
+ if [ "${SYSTEMD_AUTO_ENABLE}" = "enable" ]; then
+ if type systemctl >/dev/null 2>/dev/null; then
+ for service in ${@systemd_filter_services("${SYSTEMD_SERVICE_ESCAPED}", False, d)}; do
+ systemctl --root=$D preset "$service" 2>/dev/null || \
+ systemctl --root=$D enable "$service" 2>/dev/null || true
+ done
+
+ for service in ${@systemd_filter_services("${SYSTEMD_SERVICE_ESCAPED}", True, d)}; do
+ systemctl --global --root=$D preset "$service" 2>/dev/null || \
+ systemctl --global --root=$D enable "$service" 2>/dev/null || true
+ done
+ fi
fi
-
+elif type systemctl >/dev/null 2>/dev/null; then
+ # On-target: running on the actual device
if [ "${SYSTEMD_AUTO_ENABLE}" = "enable" ]; then
for service in ${@systemd_filter_services("${SYSTEMD_SERVICE_ESCAPED}", False, d)}; do
- systemctl ${OPTS} enable "$service"
+ systemctl enable "$service"
done
for service in ${@systemd_filter_services("${SYSTEMD_SERVICE_ESCAPED}", True, d)}; do
- systemctl --global ${OPTS} enable "$service"
+ systemctl --global enable "$service"
done
fi
- if [ -z "$D" ] && systemctl >/dev/null 2>/dev/null; then
+ if systemctl >/dev/null 2>/dev/null; then
# Reload only system service manager
# --global for daemon-reload is not supported: https://github.com/systemd/systemd/issues/19284
systemctl daemon-reload
When packages are installed outside of Yocto's normal image creation (e.g., using multistrap, debootstrap, or dpkg directly on a host), the postinst script fails to enable systemd services. The issue is that the entire enable logic is gated behind "if type systemctl >/dev/null 2>/dev/null". In cross-install scenarios: - If systemctl is absent on the host: the check fails, script is skipped - If host systemctl is present: it cannot find target unit files Fix this by separating the image-build ($D set) and on-target ($D unset) code paths into distinct branches. The previous code used a single OPTS variable to switch between "--root=$D" (image-build) and "" (on-target) within one unified block. This variable is removed because the two scenarios now have dedicated branches with different logic: - Image-build ($D set): Uses "systemctl --root=$D preset" per service, which reads preset files from the target rootfs and creates symlinks without needing the host systemctl to understand the target's unit files. Falls back to "systemctl --root=$D enable" per service. - On-target ($D unset): Same as before - enable, daemon-reload, preset, restart. No behavioral change for on-target installs. The OPTS variable is no longer needed because each branch now directly uses the appropriate systemctl invocation for its context, making the intent clearer and the image-build path functional. Fixes [YOCTO #14118] Signed-off-by: Himani Ramesh Barde <HimaniRamesh.Barde@windriver.com> --- meta/classes-recipe/systemd.bbclass | 30 ++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-)