Bug 1218551

Summary: systemd: Unable to override ConditionACPower=true
Product: [openSUSE] openSUSE Tumbleweed Reporter: dopice <0xdopice>
Component: BasesystemAssignee: systemd maintainers <systemd-maintainers>
Status: RESOLVED INVALID QA Contact: E-mail List <qa-bugs>
Severity: Normal    
Priority: P5 - None CC: fbui
Version: Current   
Target Milestone: ---   
Hardware: x86-64   
OS: openSUSE Tumbleweed   
Whiteboard:
Found By: --- Services Priority:
Business Priority: Blocker: ---
Marketing QA Status: --- IT Deployment: ---
Attachments: terminal output

Description dopice 2024-01-04 23:43:42 UTC
If a unit has ConditionACPower=true set, it's not possible to override the setting with ConditionACPower=false.

Reproduce:
1. Create /usr/lib/systemd/system/testing123.service with content
    [Unit]
    Description=Testing
    ConditionACPower=true
    Wants=network.target
    After=network.target
    [Service]
    Type=oneshot
    ExecStart=/usr/bin/echo 'I am running'
2. Run 'systemctl daemon-reload'
3. Create override file with 'systemctl edit testing123.service' with content
    [Unit]
    ConditionACPower=false
4. Run 'systemctl daemon-reload'
5. Follow the journal output with 'journalctl -fu testing123.service'
6. Start the service with 'systemctl start testing123.service'
7. The journal shows "...was skipped because of an unmet condition check (ConditionACPower=true)"

In my testing, I reversed the scenario so the testing123.service had ConditionACPower=false and the override file ConditionACPower=true. That scenario works just fine. But not when you want to disable it if it's enabled.

All this is tested with systemd-254.5-8.1.x86_64
Comment 1 Franck Bui 2024-01-08 09:39:24 UTC
(In reply to dopice from comment #0)
> 7. The journal shows "...was skipped because of an unmet condition check
> (ConditionACPower=true)"

what does `systemctl status testing123.service` report at this point ?

> In my testing, I reversed the scenario so the testing123.service had
> ConditionACPower=false and the override file ConditionACPower=true. That
> scenario works just fine. But not when you want to disable it if it's
> enabled.

I'm not sure to understand. Can you please reword this part ?
Comment 2 dopice 2024-01-08 22:42:44 UTC
An user in the Aeon telegram channel came across this bug and I helped out verifying and reporting it. I'm able to recreate it in both Aeon and Tumbleweed. I've used the testing123.service on my Aeon machine, hence the difference in path to the service file. But the result is the same.

> what does `systemctl status testing123.service` report at this point ?

○ testing123.service - Testing
     Loaded: loaded (/etc/systemd/system/testing123.service; static)
    Drop-In: /etc/systemd/system/testing123.service.d
             └─override.conf
     Active: inactive (dead)

jan 08 23:17:40 qwerty systemd[1]: Testing was skipped because of an unmet condition check (ConditionACPower=true).
jan 08 23:18:36 qwerty systemd[1]: Testing was skipped because of an unmet condition check (ConditionACPower=true).


> I'm not sure to understand. Can you please reword this part ?
Of course, no problem!
When testing123.service have ConditionACPower=true and override.conf ConditionACPower=false, this doesn't work. But if testing123.service have ConditionACPower=false and override.conf ConditionACPower=true it does work. That was all I tried to say. I hope it became more clear. If not, let me know and I'll try again.

Thanks!
Comment 3 Franck Bui 2024-01-09 13:51:57 UTC
(In reply to dopice from comment #2)
> That was all I tried to say. I hope it became more clear. If not, let me
> know and I'll try again.

It's clearer now thanks.

I can't reproduce your issue and ConditionACPower is always set to the value specified by the drop-in in my case.

Can you show the output of `journalctl -fu testing123.service` after enabling the debug logs with `systemctl log-level debug` ?

Before doing the test again please make sure that the unit is not loaded by PID1. You can check it with `systemd-analyze dump testing123.service`, which should not report any output.

Thanks.
Comment 4 dopice 2024-01-09 23:06:59 UTC
You can't reproduce it? That is interesting. For the sake of it I'll attach a screenshot to show how it actually looks and not just a copy/paste.

After changing to debug logging I get the following,
jan 09 23:58:29 aeon-x1 systemd[1]: testing123.service: Trying to enqueue job testing123.service/start/replace
jan 09 23:58:29 aeon-x1 systemd[1]: testing123.service: Installed new job testing123.service/start as 8619
jan 09 23:58:29 aeon-x1 systemd[1]: testing123.service: Enqueued job testing123.service/start as 8619
jan 09 23:58:29 aeon-x1 systemd[1]: testing123.service: ConditionACPower=false succeeded.
jan 09 23:58:29 aeon-x1 systemd[1]: testing123.service: ConditionACPower=true failed.
jan 09 23:58:29 aeon-x1 systemd[1]: testing123.service: Starting requested but condition not met. Not starting unit.
jan 09 23:58:29 aeon-x1 systemd[1]: testing123.service: Job 8619 testing123.service/start finished, result=done
jan 09 23:58:29 aeon-x1 systemd[1]: Testing was skipped because of an unmet condition check (ConditionACPower=true).
jan 09 23:58:29 aeon-x1 systemd[1]: testing123.service: Collecting.
jan 09 23:58:29 aeon-x1 systemd[1]: testing123.service: Collecting.
jan 09 23:58:37 aeon-x1 systemd[1]: testing123.service: Collecting.

I'm the one that should thank you!
Comment 5 dopice 2024-01-09 23:07:40 UTC
Created attachment 871727 [details]
terminal output
Comment 6 dopice 2024-01-09 23:29:24 UTC
I did the reversed test again out of curiosity when I had the debug logging enabled and I can see a difference.

What seems to happen is that ConditionACPower is evaluated twice as you can see in the log above. But when reversing the condition,
/etc/systemd/system/testing123.service:ConditionACPower=false
/etc/systemd/system/testing123.service.d/override.conf:ConditionACPower=true
It's only evaluated once.
jan 10 00:22:53 aeon-x1 systemd[1]: testing123.service: Trying to enqueue job testing123.service/start/replace
jan 10 00:22:53 aeon-x1 systemd[1]: testing123.service: Installed new job testing123.service/start as 3999
jan 10 00:22:53 aeon-x1 systemd[1]: testing123.service: Enqueued job testing123.service/start as 3999
jan 10 00:22:53 aeon-x1 systemd[1]: testing123.service: ConditionACPower=true failed.
jan 10 00:22:53 aeon-x1 systemd[1]: testing123.service: Starting requested but condition not met. Not starting unit.
jan 10 00:22:53 aeon-x1 systemd[1]: testing123.service: Job 3999 testing123.service/start finished, result=done
jan 10 00:22:53 aeon-x1 systemd[1]: Testing was skipped because of an unmet condition check (ConditionACPower=true).
jan 10 00:22:53 aeon-x1 systemd[1]: testing123.service: Collecting.
jan 10 00:22:53 aeon-x1 systemd[1]: testing123.service: Collecting.
jan 10 00:22:56 aeon-x1 systemd[1]: testing123.service: Collecting.
Comment 7 dopice 2024-01-10 12:38:18 UTC
I the Telegram group for Aeon, Neil Darlow shared that this is working by setting 'ConditionACPower=' instead of 'ConditionACPower=false' in the override file. I've just verified and it's working. Below is the debug output with this setup.

jan 10 13:34:40 aeon-x1 systemd[1]: testing123.service: Trying to enqueue job testing123.service/start/replace
jan 10 13:34:40 aeon-x1 systemd[1]: testing123.service: Installed new job testing123.service/start as 5360
jan 10 13:34:40 aeon-x1 systemd[1]: testing123.service: Enqueued job testing123.service/start as 5360
jan 10 13:34:40 aeon-x1 systemd[1]: testing123.service: Will spawn child (service_enter_start): /usr/bin/echo
jan 10 13:34:40 aeon-x1 systemd[1]: testing123.service: Passing 0 fds to service
jan 10 13:34:40 aeon-x1 systemd[1]: testing123.service: About to execute: /usr/bin/echo "I'm running!"
jan 10 13:34:40 aeon-x1 systemd[1]: testing123.service: Forked /usr/bin/echo as 5720
jan 10 13:34:40 aeon-x1 (echo)[5720]: Found cgroup2 on /sys/fs/cgroup/, full unified hierarchy
jan 10 13:34:40 aeon-x1 systemd[1]: testing123.service: Changed dead -> start
jan 10 13:34:40 aeon-x1 systemd[1]: Starting Testing...
jan 10 13:34:40 aeon-x1 (echo)[5720]: testing123.service: Executing: /usr/bin/echo "I'm running!"
jan 10 13:34:40 aeon-x1 echo[5720]: I'm running!
jan 10 13:34:40 aeon-x1 systemd[1]: testing123.service: Child 5720 belongs to testing123.service.
jan 10 13:34:40 aeon-x1 systemd[1]: testing123.service: Main process exited, code=exited, status=0/SUCCESS (success)
jan 10 13:34:40 aeon-x1 systemd[1]: testing123.service: Deactivated successfully.
jan 10 13:34:40 aeon-x1 systemd[1]: testing123.service: Service will not restart (restart setting)
jan 10 13:34:40 aeon-x1 systemd[1]: testing123.service: Changed start -> dead
jan 10 13:34:40 aeon-x1 systemd[1]: testing123.service: bpf-lsm: Failed to delete cgroup entry from LSM BPF map: No such file or directory
jan 10 13:34:40 aeon-x1 systemd[1]: testing123.service: Job 5360 testing123.service/start finished, result=done
jan 10 13:34:40 aeon-x1 systemd[1]: Finished Testing.
jan 10 13:34:40 aeon-x1 systemd[1]: testing123.service: Consumed 5ms CPU time.
jan 10 13:34:40 aeon-x1 systemd[1]: testing123.service: Releasing resources...
jan 10 13:34:40 aeon-x1 systemd[1]: testing123.service: Failed to send unit change signal for testing123.service: Connection reset by peer
jan 10 13:34:40 aeon-x1 systemd[1]: testing123.service: Collecting.
Comment 8 dopice 2024-01-10 12:48:41 UTC
I just came to realization and while this doesn't work I ask myself how many times anyone would like to do this... Since with 'ConditionACPower=false' the service will only run when on battery, with 'ConditionACPower=true' only when connected to AC power. It's of course 'ConditionACPower=' that should be used to allow the service to run in both scenarios.

Now I'm asking myself if this is even worth fixing... I mean, you cannot not even reproduce it and this is a non-issue as I see it.

You have my blessing in closing this. I'm not doing it myself since you might be of another opinion.


Thanks for everything!
Comment 9 Franck Bui 2024-01-10 17:54:22 UTC
Ah right now that you mentioned that the condition is evaluated twice, it reminds me that you have to reset the condition before assigning it to a new value otherwise the multiple values are all checked (like if a logical AND is applied).

That's pretty counter-intuitive in the case of `ConditionACPower=` where specifying multiple value doesn't really make sense...

So I guess that initializing override.conf with

    [Unit]
    ConditionACPower=
    ConditionACPower=false

should do the trick.

Can you give it try ?
Comment 10 Franck Bui 2024-01-10 17:56:09 UTC
(In reply to Franck Bui from comment #9)
> Ah right now that you mentioned that the condition is evaluated twice, it
> reminds me that you have to reset the condition before assigning it to a new
> value otherwise the multiple values are all checked (like if a logical AND
> is applied).

It's actually documented in systemd.unit man page at "Conditions and Asserts" section:

   If multiple conditions are specified, the unit will be executed if all of
   them apply (i.e. a logical AND is applied). [...]
Comment 11 dopice 2024-01-10 21:57:16 UTC
Yes it works fine using,
    [Unit]
    ConditionACPower=
    ConditionACPower=false

At this point I feel that I've wasted your time. And for that I'm truly sorry! It  was a real brain fart from my side, before I reached a eureka moment today thanks to Neil.

Thank you very much for everything! I did at least learn something from all this.
Comment 12 Franck Bui 2024-01-11 07:28:15 UTC
Don't worry, no problem.

I'm closing the bug as INVALID since the problem was a misunderstanding of the concept of unit setting overriding.