[systemd-devel] ConditionBatteryPower

Oleksii Shevchuk alxchk at gmail.com
Tue Nov 20 07:49:59 PST 2012


I totally agree, that targets in current state is not enough to support
such thing. I try to write here my motivation about using 
the targets anyway, sorry for my English and long text.

When I first tried systemd, I thought about the .target units, as the
states in which the system resides. This is quite natural in the context
of use of the system, which controls the entire life cycle of
services. When I boot the system, I expect the default behavior and
functionality (default.target). When I shutdown it, I expect opposite
functionality. When I have bluetooth device or network up, I expect the
extension functionality, mixed up with the current one. That's how about
regular user like me meets systemd at first time.

My first understanding of the misunderstanding of the situation came
during the creation of my first target unit. I wanted to start some
services, when my NFC reader attached to the laptop. So i write
something like

.. ENV{SYSTEMD_WANTS}="nfc.target"

When I remove device, nfc.target stays active. Then I found, that
targets were more like startup barriers, but not states. That was
strange. How on earth shutdown.target when? Then I found
DefaultDependencies, StopWhenUnneeded and other workarounds to achive
some functionality of state system on barrier-targeted system.

I understand fundamental difference between barriers and states, but
don't have an idea why they should be used. Anyway, my feelings about
targets behavior is my very own, and not a point of discussion. 

As laptop user, I want to have my system was flexible. What does it mean
for me? I want to get different behavior in different environments and
conditions. For example, I want to have (and successfully have with
systemd base user session) such functionality:
+ My network shares (depends on place or VPN connection) automatically
mounted and pulse default sink changes, when I arrived to work/home, and 
unmounts/changes when I leave that place
+ When I have arrived, my mpop client begins to checking for new mail 
from local mail server (depends on place)
+ My trusted VPN ups, when I'm not at home/work
+ Development services (like ADB) ups when I have device connected to my
laptop, and stopped when not
+ Depends on place,power situation and network connection level
different browsers should be started by default:
   + firefox, when I'm at home/work or in place, where I have a chance to
     get stable AC power
   + opera, when I'm at train, with awful GPRS without AC 

and so on

Most of these features could be successfully completed with systemd
push/conflicts model. I use StopWhenUnneeded= to clean services with
targets and Conflicts to clean targets. There are some problems with
this approach. 
- Services with StopWhenUnneeded= couldn't be started as
  orphans. So, if I want to get service up in some conditions, I should 
  find some target, that wants it, and start it. And that starts
  something, that I'm not actually need for..

> - the current target units are currently mostly of the type where
>   loading things matters, but unloading them is not really that
>   important. This is different where AC is a state that people care
>   about in both cases.

So:

- Bottom-Top configuration. To get behavior of state system, I must
  change every single component of that system. 
  I.e. add StopWhenUnneeded= to every unit.

That is not very big problem to clean something with raised unit with current
functionality - Conflicts= will do the job. The problem is - how
to restore previous state. So, I stop using powersaving.target as
grouping tool, and start using is like a negative Tag (in
Conflicts=). To do so I write some patches (
http://lists.freedesktop.org/archives/systemd-devel/2012-November/007307.html
http://lists.freedesktop.org/archives/systemd-devel/2012-November/007304.html
). 

How it works for me now: 
1. powersaving tartget drop the units, that conflicted with it, and push them to restore list
2. When powersaving.target stops, units from list started again

I think that is bad approach. This is hacks and workarounds, not the
solution. I think, more straight ways to solve this should be found. 

So, why I think, that additional conditions in units are not among them?
- Grouping. It will be impossible with current implementation of core
  things to have a group of units, that should stop, in case of
  powersaving state achived. (If I place condition to target, than it
  stops, but other units will be alive)

- Hardcoded special case. Why I think this is not ok? 
  Because the problem of power management can be extrapolated to other cases, 
  that takes into account the state of the host. I.e. networking
  substate, user defined logical substates etc (ones from my use-cases,
  for example).

> if you have a broken EC, I think a good solution would be to copy the
> unit with the ConditionBatteryPower= you don't like to /etc and comment
> the condition there? No?

- Weak configuration capabilities. As notebook user, I prepared to use
  it without AC. It's normal condition for this device. What does it
  means? There could be different conditions, when I need all
  functionality of my notebook till the end of the battery ( because I
  have another one in my bag :P ), and sometimes I _really_ need to save
  energy, from the first second of boot. I can mark units for that cases as
  Conflicts=powersaving.target or as ConditionBatteryPower=20%.  In
  first case some external service (or even I with systemctl cmd) could
  make decision to trigger event, on another - systemd will do the
  job. To reconfigure behavior in first case I should reconfigure single
  external service, in the other case find and fix every unit and
  reload daemon. Just now I manually start powesaving.target only when I
  really need itm for example.

So, my point is: 

1. It would be cool, if we have generic approach to manipulate the
   groups(tag sets, targets, ..) of units, that formed with any of
  - external deps    (with .wants)
  - interal  deps    (with rules in unit)
  - ad-hoc           (when some unit/target wants started one, but not
                      started it because of some conditions)
  - orphaned ad-hoc  (with systemctl/dbus, whitout Wants)
2. Creating external service, that control that groups with some rules
   (in generic way, i.e. via standard start/stop/.. operations)
   is better, then having per-unit based configuration. 

I apologize for the confusion, if there any.

// wbr, Alex

By the way, could You review the patch for [Install] with trivial templates?

http://lists.freedesktop.org/archives/systemd-devel/2012-November/007306.html


More information about the systemd-devel mailing list