Bug#727708: init system thoughts
On 31 December 2013 12:55, Colin Watson <cjwatson@debian.org> wrote:
> The criticisms of Upstart's event model in the systemd position
> statement simply do not make sense to me. Events model how things
> actually happen in reality; dependencies are artificial constructions on
> top of them, and making them work requires the plethora of different
> directives in systemd (e.g. Wants, which is sort of a non-depending
> dependency) to avoid blocking the boot process on a single failing
> service.
Riffing off this more than replying to it.
I tend to think dependencies and events are both useful ways of
describing when to start up parts of the system. In particular, it
seems like:
- when a network is connected, start web server
- when a usb disk is connected, mount it
- when a VPN is started, sync various things
are best described by an "event" model, while:
- in order to run GNOME, logind must be started
- in order to run logind, dbus must be available
- as part of making the system ready for a user, network-manager
should be running
make the most sense when described by "dependencies". In particular,
in many of those cases, the reverse might not be true: For debugging,
I might want to start the web server manually without connecting the
network; or I might want logind running without GNOME, or
network-manager running without the other parts of my desktop
environment.
Events and dependencies aren't that different; an event essentially
lets a service X say that:
whenever Y happens, X happens
whenever Y happens, X stops happening
while a (systemd'ish) dependency says either:
when X happens, Y happens as well [X Requires: Y]
before X happens, Y happens as well [X Requires: Y, After: Y]
after X happens, Y happens as well [X Requires: Y, Before: Y]
(with Wants and Requisite and Overridable variants as well; also
RequiredBy and WantedBy variants)
If you look at "Y", there are a few phases it could go through:
no-Y
Y-starts-starting
Y-started
Y-begins-ending
no-Y
If you wanted to emulate upstart events with dependencies, you'd need
to do four things, I think:
* create a dummy "Y-started-event" unit ["network-is-available",
"usb-is-available"]
* invoke "systemctl start Y-started-event" when Y is finished starting
* invoke "systemctl stop Y-started-event" when Y begins ending
* add "RequiredBy: Y-started-event" and "PartOf: Y-started-event"
to X's unit file
That seems reasonably straight forward to me? If the event is
something systemd already knows about, you might only need to do
something equivalent to the last step. I don't think invoking
systemctl start/stop is any better or worse than whatever would be
needed to notify upstart of the same events.
To emulate systemd dependencies in an event model (ie, X depends on
Y), you'd need to do either:
* change Y's job to say "start on starting X"
* add "stop on stopping Y" to X's job description
or
* add a pre-start script to X in order to start Y first
* add "stop on stopping Y" to X's job description
The latter looks like it's the documented way of doing things. Neither
of those seem particularly great -- I think that's due to upstart not
letting you reverse event descriptions in the same way that systemd
has Requires/RequiredBy statements. If you could say:
* on starting start Y
* stop on stopping Y
in X's job description, by contrast, I think that would be a fine way
of declaring a "dependency" from X to Y without leaving the "event"
model. Not having a simple way of specifying this sort of dependency
seems pretty weak on upstart's behalf.
It would probably also be nice to have a way of saying "when a new
network comes up, reload/refresh service X" -- so that it could bind
to new ports or whatever even if it was already running; that seems
like the sort of thing that would be easier to specify in an event
model ("on new-network-interface-started reload or start"), than in a
dependency model.
Cheers,
aj
Reply to: