Skip to content

systemd disable returns 'Failed to disable unit: Invalid argument' #26568

Closed
@solsticedhiver

Description

@solsticedhiver

systemd version the issue has been seen with

253

Used distribution

ARchlinux ARM

Linux kernel version used

6.1.12-1-rpi-ARCH

CPU architectures issue was seen on

arm

Component

systemctl

Expected behaviour you didn't see

After running systemctl enable wpa_supplicant@wlu1u2, I would have expect the command to return successfully and that it removed the symlink wpa_supplicant@wlu1u2.service in /etc/systemd/system/multi-user.target.wants/

But the command returns an error without removing the symlink

Unexpected behaviour you saw

The command returns 'Failed to disable unit: Invalid argument' and did not remove the symlink

Steps to reproduce the problem

  1. Enable the service
# systemctl enable wpa_supplicant@wlan0.service
  1. Try to disable the service
# systemctl disable wpa_supplicant@wlan0.service
Failed to disable unit: Invalid argument

Additional program output to the terminal or log subsystem illustrating the issue

No response

This is on a rpi2b running archlinuxARM for armv7

Activity

added
regression ⚠️A bug in something that used to work correctly and broke through some recent commit
on Feb 23, 2023
added this to the v254 milestone on Feb 23, 2023
mrc0mmand

mrc0mmand commented on Mar 1, 2023

@mrc0mmand
Member

Could you run the offending systemctl disable command with SYSTEMD_LOG_LEVEL=debug and also paste the wpa_supplicant@.service unit?

solsticedhiver

solsticedhiver commented on Mar 1, 2023

@solsticedhiver
Author
# SYSTEMD_LOG_LEVEL=debug systemctl disable wpa_supplicant@wlu1u2
Bus n/a: changing state UNSET → OPENING
sd-bus: starting bus by connecting to /run/systemd/private...
Bus n/a: changing state OPENING → AUTHENTICATING
Bus n/a: changing state AUTHENTICATING → RUNNING
Sent message type=method_call sender=n/a destination=org.freedesktop.systemd1 path=/org/freedesktop/systemd1 interface=org.freedesktop.systemd1.Manager member=DisableUnitFilesWithFlagsAndInstallInfo cookie=1 reply_cookie=0 signature=ast error-name=n/a error-message=n/a
Got message type=error sender=org.freedesktop.systemd1 destination=n/a path=n/a interface=n/a member=n/a  cookie=1 reply_cookie=1 signature=s error-name=org.freedesktop.DBus.Error.InvalidArgs error-message=Invalid argument
Failed to disable unit: Invalid argument
Bus n/a: changing state RUNNING → CLOSED

In the mean time, interface changed name.

# cat /usr/lib/systemd/system/wpa_supplicant@.service
[Unit]
Description=WPA supplicant daemon (interface-specific version)
Requires=sys-subsystem-net-devices-%i.device
After=sys-subsystem-net-devices-%i.device
Before=network.target
Wants=network.target

# NetworkManager users will probably want the dbus version instead.

[Service]
Type=simple
ExecStart=/usr/bin/wpa_supplicant -c/etc/wpa_supplicant/wpa_supplicant-%I.conf -i%I

[Install]
WantedBy=multi-user.target

mrc0mmand

mrc0mmand commented on Mar 2, 2023

@mrc0mmand
Member

This is interesting. After an unsuccessful battle with my old rPi I got my hands on a F36 armv7hl machine, and after rebuilding the Rawhide systemd RPM I can reproduce the issue there as well.

Further digging revealed that this reproducible on the latest main, as well as that it seems to be caused by something going wrong during optimization, because:

Build with -O0 (meson build):

# build/systemctl disable asdfasfaf
Failed to disable unit: Unit file asdfasfaf.service does not exist.

Build with -O1 (meson build --optimization=1):

# build-o1/systemctl disable asdfasfaf
Failed to disable unit: Invalid argument

Turns out "parsing" uint64_t via va_arg, while passing an int to it has some unforeseen consequences:

diff --git a/src/libsystemd/sd-bus/bus-message.c b/src/libsystemd/sd-bus/bus-message.c
index 9719f97c02..8d982b3fca 100644
--- a/src/libsystemd/sd-bus/bus-message.c
+++ b/src/libsystemd/sd-bus/bus-message.c
@@ -1931,6 +1931,7 @@ _public_ int sd_bus_message_appendv(
                         uint64_t x;
 
                         x = va_arg(ap, uint64_t);
+                        printf("%s: Got uint64_t: %llu\n", __func__, x);
                         r = sd_bus_message_append_basic(m, *t, &x);
                         break;
                 }
diff --git a/src/systemctl/systemctl-enable.c b/src/systemctl/systemctl-enable.c
index 4ebe5888ac..55ddf5ab0f 100644
--- a/src/systemctl/systemctl-enable.c
+++ b/src/systemctl/systemctl-enable.c
@@ -211,7 +211,7 @@ int verb_enable(int argc, char *argv[], void *userdata) {
 
                 if (send_runtime) {
                         if (streq(method, "DisableUnitFilesWithFlagsAndInstallInfo"))
-                                r = sd_bus_message_append(m, "t", arg_runtime ? UNIT_FILE_RUNTIME : 0);
+                                r = sd_bus_message_append(m, "t", 0);
                         else
                                 r = sd_bus_message_append(m, "b", arg_runtime);
                         if (r < 0)
# build-o1/systemctl disable asdfasfaf
sd_bus_message_appendv: Got uint64_t: 7954875719681572864
Failed to disable unit: Invalid argument

Casting the argument to uint64_t makes it happy again:

diff --git a/src/systemctl/systemctl-enable.c b/src/systemctl/systemctl-enable.c
index 4ebe5888ac..e17ed6239c 100644
--- a/src/systemctl/systemctl-enable.c
+++ b/src/systemctl/systemctl-enable.c
@@ -211,7 +211,7 @@ int verb_enable(int argc, char *argv[], void *userdata) {
 
                 if (send_runtime) {
                         if (streq(method, "DisableUnitFilesWithFlagsAndInstallInfo"))
-                                r = sd_bus_message_append(m, "t", arg_runtime ? UNIT_FILE_RUNTIME : 0);
+                                r = sd_bus_message_append(m, "t", arg_runtime ? (uint64_t)UNIT_FILE_RUNTIME : 0LL);
                         else
                                 r = sd_bus_message_append(m, "b", arg_runtime);
                         if (r < 0)
# build-o1/systemctl disable asdfasfaf
sd_bus_message_appendv: Got uint64_t: 0
Failed to disable unit: Unit file asdfasfaf.service does not exist.

This reminds me of a similar issue we had regarding va_arg() and type conversion: #14470 (comment).

@poettering is the casting solution enough or there is some other (and more elegant) way to fix this?

added a commit that references this issue on Mar 3, 2023
baab2f2
added 2 commits that reference this issue on Mar 3, 2023
2e914dd
aaf1688
added a commit that references this issue on Mar 3, 2023
c63bfd0
semeion

semeion commented on Mar 20, 2023

@semeion

Yeah i got same isue here trying to disable systemd-networkd.service.
"'Failed to disable unit: Invalid argument'".

Using Arch Linux - ARM on a RPI3B.

gcd0318

gcd0318 commented on Mar 24, 2023

@gcd0318

me too, also archlinuxarm, just updated to linux-armv7-6.2.8-1-armv7h

2 remaining items

Loading
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bug 🐛Programming errors, that need preferential fixingregression ⚠️A bug in something that used to work correctly and broke through some recent commitsystemctl

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      systemd disable returns 'Failed to disable unit: Invalid argument' · Issue #26568 · systemd/systemd