diff mbox series

[walnascar,3/3] systemd.bbclass: Make systemd_postinst run as intended

Message ID 20250912155712.3340513-3-pkj@axis.com
State Accepted
Delegated to: Steve Sakoman
Headers show
Series [walnascar,1/3] systemd-systemctl-native: Use += instead of :append | expand

Commit Message

Peter Kjellerstedt Sept. 12, 2025, 3:57 p.m. UTC
After the switch from using a systemctl written in Python to using the
official version of systemctl from the systemd project, the
systemd_postinst function has effectively not been executed during the
rootfs creation. The reason is that systemctl provided by
systemctl-native fails if run without arguments (as systemd_postinst
does):

  Failed to connect to system scope bus via local transport: Operation
  not permitted (consider using --machine=<user>@.host --user to connect
  to bus of other user)

This is not seen in the logs since stderr is sent to /dev/null, and the
only way to tell that there is a problem is because systemd services
that are expected to be enabled aren't running.

The reason this has gone unnoticed is because systemd_handle_machine_id
in rootfs-postcommands.bbclass will call systemctl preset-all, which in
most cases will create the missing links to enable the systemd services.

This change effectively reverts commit
a52e66762c0c51918b1ba3d4622759637b6e920a (systemd.bbclass: update
command to check systemctl available) and instead only runs systemctl
without arguments (to determine that it can communicate with systemd)
when executed on target.

Signed-off-by: Peter Kjellerstedt <peter.kjellerstedt@axis.com>
---
 meta/classes-recipe/systemd.bbclass | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

Comments

Martin Siegumfeldt Sept. 24, 2025, 6:03 p.m. UTC | #1
Hi Peter,

After pulling poky [walnascar] today, our image build broke with the below:

WARNING: nanomind-dev-image-1.0-r0 do_rootfs: nanomind-gpio-ctrl.postinst returned 1, marking as unpacked only, configuration required on target.
WARNING: nanomind-dev-image-1.0-r0 do_rootfs: nanomind-bank-ctrl.postinst returned 1, marking as unpacked only, configuration required on target.
ERROR: nanomind-dev-image-1.0-r0 do_rootfs: Postinstall scriptlets of ['nanomind-gpio-ctrl', 'nanomind-bank-ctrl'] have failed. If the intention is to defer them to first boot,
then please place them into pkg_postinst_ontarget:${PN} ().
Deferring to first boot via 'exit 1' is no longer supported.

I noticed this particular commit, and reverting it resolves the breakage. The recipe is quite trivial IMO:

inherit systemd
RDEPENDS:${PN} = "libgpiod-tools"
SYSTEMD_SERVICE:${BPN} = "${BPN}@.service"
SRC_URI = "file://${SYSTEMD_SERVICE:${BPN}}"
S = "${WORKDIR}/sources"
UNPACKDIR = "${S}"
do_install () {
install -d ${D}${systemd_system_unitdir}
install -m 0644 ${UNPACKDIR}/${SYSTEMD_SERVICE:${BPN}} ${D}${systemd_system_unitdir}
}
We are building a readonly rootfs, could this be an issue combined with your patch?

Thanks,
Martin
Peter Kjellerstedt Sept. 24, 2025, 7:44 p.m. UTC | #2
You will have to look into the log.do_rootfs file to figure out why the postinst functions are failing. Before my patch, the postinst functions from systemd were not running so any existing problems would have gone unnoticed.

//Peter

From: openembedded-core@lists.openembedded.org <openembedded-core@lists.openembedded.org> On Behalf Of Martin Siegumfeldt via lists.openembedded.org
Sent: den 24 september 2025 20:03
To: openembedded-core@lists.openembedded.org
Subject: Re: [OE-core] [walnascar][PATCH 3/3] systemd.bbclass: Make systemd_postinst run as intended

Hi Peter,

After pulling poky [walnascar] today, our image build broke with the below:

WARNING: nanomind-dev-image-1.0-r0 do_rootfs: nanomind-gpio-ctrl.postinst returned 1, marking as unpacked only, configuration required on target.
WARNING: nanomind-dev-image-1.0-r0 do_rootfs: nanomind-bank-ctrl.postinst returned 1, marking as unpacked only, configuration required on target.
ERROR: nanomind-dev-image-1.0-r0 do_rootfs: Postinstall scriptlets of ['nanomind-gpio-ctrl', 'nanomind-bank-ctrl'] have failed. If the intention is to defer them to first boot,
then please place them into pkg_postinst_ontarget:${PN} ().
Deferring to first boot via 'exit 1' is no longer supported.

I noticed this particular commit, and reverting it resolves the breakage. The recipe is quite trivial IMO:
inherit systemd
RDEPENDS:${PN} = "libgpiod-tools"
SYSTEMD_SERVICE:${BPN} = "${BPN}@.service<mailto:$%7bBPN%7d@.service>"
SRC_URI = "file://${SYSTEMD_SERVICE:${BPN}}"
S = "${WORKDIR}/sources"
UNPACKDIR = "${S}"
do_install () {
        install -d ${D}${systemd_system_unitdir}
        install -m 0644 ${UNPACKDIR}/${SYSTEMD_SERVICE:${BPN}} ${D}${systemd_system_unitdir}
}
We are building a readonly rootfs, could this be an issue combined with your patch?

Thanks,
Martin
Martin Siegumfeldt Sept. 25, 2025, 6:36 a.m. UTC | #3
Thanks Peter,

Below is what I expect to be the relevant part of the log file:

Created symlink '/home/martin/work/distro-gomspace_tmp/build/tmp/work/nanomind_z7020_zed-gomspace-linux-gnueabi/nanomind-dev-image/1.0/rootfs/etc/systemd/system/multi-user.target.wants/busybox-klogd.service' → '/usr/lib/systemd/system/busybox-klogd.service'.
Created symlink '/home/martin/work/distro-gomspace_tmp/build/tmp/work/nanomind_z7020_zed-gomspace-linux-gnueabi/nanomind-dev-image/1.0/rootfs/etc/systemd/system/multi-user.target.wants/sysstat.service' → '/usr/lib/systemd/system/sysstat.service'.
Failed to enable unit: Refusing to operate on template unit nanomind-gpio-ctrl@.service when destination unit multi-user.target is a non-template unit
Failed to enable unit: Refusing to operate on template unit nanomind-bank-ctrl@.service when destination unit multi-user.target is a non-template unit
Created symlink '/home/martin/work/distro-gomspace_tmp/build/tmp/work/nanomind_z7020_zed-gomspace-linux-gnueabi/nanomind-dev-image/1.0/rootfs/etc/systemd/system/multi-user.target.wants/redis.service' → '/usr/lib/systemd/system/redis.service'.
.
.
.
Configuring sysstat.
Configuring nanomind-gpio-ctrl.
nanomind-gpio-ctrl.postinst returned 1, marking as unpacked only, configuration required on target.
Configuring nanomind-bank-ctrl.
nanomind-bank-ctrl.postinst returned 1, marking as unpacked only, configuration required on target.
Configuring bash-completion.
Configuring libiio-bash-completion.

The particular service file is described as:

[Unit]
Description=GPIO Control Service (%i)
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/bin/gpioset --daemonize --chip gpiochip0 %i=1
ExecStartPost=/bin/sleep .3
ExecStopPost=/usr/bin/gpioset --toggle 0 --chip gpiochip0 %i=0
ExecStopPost=/bin/sleep .3
[Install]
WantedBy=multi-user.target

AFAICT, the issue only applies for template units - other seem to install/configure fine.

What puzzles me is why I am seemingly the only one running into this - I consider both the recipe and service file to be quite standard...
Martin Siegumfeldt Sept. 29, 2025, 5:52 a.m. UTC | #4
Just fyi, issue appears related to non-instantiated template services - i.e. the below contruct:

SYSTEMD_SERVICE:${BPN} = "${BPN}@.service"

which in the past was not an issue for the rootfs creation.

It may have been an "undocumented feature" so far, and I guess such services in fact should be disabled (SYSTEMD_AUTO_ENABLE = "disable"). At least, doing so enables the rootfs to succeed.

Thanks
diff mbox series

Patch

diff --git a/meta/classes-recipe/systemd.bbclass b/meta/classes-recipe/systemd.bbclass
index 12c59647be..3d8ca24a68 100644
--- a/meta/classes-recipe/systemd.bbclass
+++ b/meta/classes-recipe/systemd.bbclass
@@ -29,7 +29,7 @@  python __anonymous() {
 }
 
 systemd_postinst() {
-if systemctl >/dev/null 2>/dev/null; then
+if type systemctl >/dev/null 2>/dev/null; then
 	OPTS=""
 
 	if [ -n "$D" ]; then
@@ -46,7 +46,7 @@  if systemctl >/dev/null 2>/dev/null; then
 		done
 	fi
 
-	if [ -z "$D" ]; then
+	if [ -z "$D" ] && 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
@@ -66,8 +66,8 @@  fi
 }
 
 systemd_prerm() {
-if systemctl >/dev/null 2>/dev/null; then
-	if [ -z "$D" ]; then
+if type systemctl >/dev/null 2>/dev/null; then
+	if [ -z "$D" ] && systemctl >/dev/null 2>/dev/null; then
 		if [ -n "${@systemd_filter_services("${SYSTEMD_SERVICE_ESCAPED}", False, d)}" ]; then
 			systemctl stop ${@systemd_filter_services("${SYSTEMD_SERVICE_ESCAPED}", False, d)}
 			systemctl disable ${@systemd_filter_services("${SYSTEMD_SERVICE_ESCAPED}", False, d)}