diff mbox series

[v3] systemd.bbclass: fix service enablement for cross-install scenarios

Message ID 20260722101408.3225399-1-HimaniRamesh.Barde@windriver.com
State New
Headers show
Series [v3] systemd.bbclass: fix service enablement for cross-install scenarios | expand

Commit Message

Himani Ramesh Barde July 22, 2026, 10:14 a.m. UTC
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(-)
diff mbox series

Patch

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