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 <[email protected]> --- meta/classes-recipe/systemd.bbclass | 30 ++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/meta/classes-recipe/systemd.bbclass b/meta/classes-recipe/systemd.bbclass index 26eaaf1..bdbfb7c 100644 --- a/meta/classes-recipe/systemd.bbclass +++ b/meta/classes-recipe/systemd.bbclass @@ -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 -- 2.54.0
-=-=-=-=-=-=-=-=-=-=-=- Links: You receive all messages sent to this group. View/Reply Online (#241655): https://lists.openembedded.org/g/openembedded-core/message/241655 Mute This Topic: https://lists.openembedded.org/mt/120391669/21656 Group Owner: [email protected] Unsubscribe: https://lists.openembedded.org/g/openembedded-core/unsub [[email protected]] -=-=-=-=-=-=-=-=-=-=-=-
