Discussion:
[systemd-devel] instantiated services set up
Jan Včelák
2014-08-26 14:43:47 UTC
Permalink
Hello list!

I have a few questions regarding a proper way to setup and use template
instantiated services.

We develop an authoritative DNS server called Knot DNS. Currently, we provide
knot.service unit file to start a single instance of the server. However, some
of our users need multiple instances running with different configuration.
Andrei Borzenkov
2014-08-26 15:40:48 UTC
Permalink
В Tue, 26 Aug 2014 16:43:47 +0200
Post by Jan Včelák
Hello list!
I have a few questions regarding a proper way to setup and use template
instantiated services.
We develop an authoritative DNS server called Knot DNS. Currently, we provide
knot.service unit file to start a single instance of the server. However, some
of our users need multiple instances running with different configuration.
Lennart Poettering
2014-08-26 17:43:17 UTC
Permalink
[Unit]
Description=Knot DNS Server
After=syslog.target network.target
[Service]
ExecStart=/usr/sbin/knotd -c /etc/knot/knot.conf
ExecReload=/usr/sbin/knotc -c /etc/knot/knot.conf reload
[Install]
WantedBy=multi-user.target
[Unit]
Description=Knot DNS Server (%i.conf)
After=syslog.target network.target
After=syslog.target is redundant since a long time. Consider removing
this. And After=network.target usually doesn't do what one might thing
it does and with well written software that listens to rtnl or uses
IP_FREEBIND not even necessary...
[Service]
ExecStart=/usr/sbin/knotd -c /etc/knot/%i.conf
ExecReload=/usr/sbin/knotc -c /etc/knot/%i.conf reload
[Install]
WantedBy=multi-user.target
Sure, but for the sake of simplicity and not confusing the user I would
avoid this.

I'd just ship the templated version, and then maybe add
DefaultInstance=something to the [Install] section in order to make one
instance the "default" one...
Most of the users will run a single instance of Knot DNS. Therefore I want to
keep existing knot.service in place. In this case, specifying knot(.service)
as an instance name in a systemctl command is more comfortable than a bit
a way that if one of these is running, the other will fail to start?
makes the conflicting service to stop silently. That is fine, but may be
confusing for the user. I would rather see systemctl to fail with an error
message. Is that possible?
Hmm, we currently don't support any dependency type like this. And I am
very conservative about adding new dep types, unless we have a very
strong reason for it...
3.) In case of multiple instances, is there a way to control them all at once?
$ systemctl start <all-knot-instances>
where <all-knot-instances> stands for something which means all instances
without enumerating them.
One of our users suggested to create a knot.target, install the instances into
a proper use of BindsTo and additionally, this does work for
start/stop/restart only and doesn't work for reload.
Use PartOf= for this...

Lennart
--
Lennart Poettering, Red Hat
Jan Včelák
2014-09-15 11:03:16 UTC
Permalink
Post by Lennart Poettering
After=syslog.target is redundant since a long time. Consider removing
this. And After=network.target usually doesn't do what one might thing
it does and with well written software that listens to rtnl or uses
IP_FREEBIND not even necessary...
OK. I will remove the syslog. But I will have to keep network.target for now
as we support non-Linux systems as well. Adding support for rtnl or
IP_FREEBIND would mean duplicating a lot of code... probably.
Post by Lennart Poettering
Sure, but for the sake of simplicity and not confusing the user I would
avoid this.
I'd just ship the templated version, and then maybe add
DefaultInstance=something to the [Install] section in order to make one
instance the "default" one...
DefaultInstance sounds great. Will this get backported into systemd-stable at
some time? Because I'm looking for a solution for RHEL 7.
Post by Lennart Poettering
conflict in a way that if one of these is running, the other will fail to
start?
which makes the conflicting service to stop silently. That is fine, but
may be confusing for the user. I would rather see systemctl to fail with
an error message. Is that possible?
Hmm, we currently don't support any dependency type like this. And I am
very conservative about adding new dep types, unless we have a very
strong reason for it...
Fine. This is not that important.
Post by Lennart Poettering
3.) In case of multiple instances, is there a way to control them all at once?
Use PartOf= for this...
OK. Thanks. I will take a look at it!

Jan
Colin Guthrie
2014-09-15 13:35:39 UTC
Permalink
Post by Jan Včelák
Post by Lennart Poettering
3.) In case of multiple instances, is there a way to control them all at once?
Use PartOf= for this...
OK. Thanks. I will take a look at it!
Just for a few more hints here:

You would create a knot.target unit which is just a standard target
unit, with a name and not much else, but it *would* have it's own
[Install] section with "WantedBy=multi-user.target"


In the ***@.service you would add: PartOf=knot.target and you would
*replace* the WantedBy=multi-user.target with WantedBy=knot.target.

This way, you can "systemctl enable ***@.service" and the default
instance will be enabled. But in this context, enabling it just means it
will start whenever knot.target starts, not multi-user.target.

THis means an admin can easily disable all instances of ***@.service
simply by doing: "systemctl disable knot.target"

This approach gives you nice flexibility and control over instance
units, but still gives you the ability to start/stop individual
instances and control all of them at once too!

HTHs

Col
--
Colin Guthrie
gmane(at)colin.guthr.ie
http://colin.guthr.ie/

Day Job:
Tribalogic Limited http://www.tribalogic.net/
Open Source:
Mageia Contributor http://www.mageia.org/
PulseAudio Hacker http://www.pulseaudio.org/
Trac Hacker http://trac.edgewall.org/
Jan Včelák
2014-09-16 11:22:39 UTC
Permalink
Hi Colin,
Post by Colin Guthrie
This approach gives you nice flexibility and control over instance
units, but still gives you the ability to start/stop individual
instances and control all of them at once too!
Yes, you are right. I tried this and it works pretty well.

However, the knot.target can be used only for start, stop, and restart. It
cannot be used for reload... :-(

Jan
Zbigniew Jędrzejewski-Szmek
2014-10-05 21:56:11 UTC
Permalink
Post by Jan Včelák
Hi Colin,
Post by Colin Guthrie
This approach gives you nice flexibility and control over instance
units, but still gives you the ability to start/stop individual
instances and control all of them at once too!
Yes, you are right. I tried this and it works pretty well.
However, the knot.target can be used only for start, stop, and restart. It
cannot be used for reload... :-(
ReloadPropagatedFrom=/ReloadPropagatedTo= ?

Zbyszek
Lennart Poettering
2014-10-22 11:12:19 UTC
Permalink
Post by Jan Včelák
Post by Lennart Poettering
After=syslog.target is redundant since a long time. Consider removing
this. And After=network.target usually doesn't do what one might thing
it does and with well written software that listens to rtnl or uses
IP_FREEBIND not even necessary...
OK. I will remove the syslog. But I will have to keep network.target for now
as we support non-Linux systems as well. Adding support for rtnl or
IP_FREEBIND would mean duplicating a lot of code... probably.
Note that invoking IP_FREEBIND is just a single setsockopt() line...
Post by Jan Včelák
Post by Lennart Poettering
Sure, but for the sake of simplicity and not confusing the user I would
avoid this.
I'd just ship the templated version, and then maybe add
DefaultInstance=something to the [Install] section in order to make one
instance the "default" one...
DefaultInstance sounds great. Will this get backported into systemd-stable at
some time? Because I'm looking for a solution for RHEL 7.
Please file a bug for RHEL 7 and the right peple will make sure this happens.

Lennart
--
Lennart Poettering, Red Hat
Jan Včelák
2014-11-04 19:56:48 UTC
Permalink
Hi!
Post by Lennart Poettering
Post by Jan Včelák
OK. I will remove the syslog. But I will have to keep network.target for
now as we support non-Linux systems as well. Adding support for rtnl or
IP_FREEBIND would mean duplicating a lot of code... probably.
Note that invoking IP_FREEBIND is just a single setsockopt() line...
You are right. We enabled IP_FREEBIND after all. (And we also added IP_BINDANY
and IPV6_BINDANY on FreeBSD to achieve the same behavior.)

On the other hand, we cannot give the administrator proper feedback when the
daemon is configured incorrectly.
Post by Lennart Poettering
Post by Jan Včelák
DefaultInstance sounds great. Will this get backported into systemd-stable
at some time? Because I'm looking for a solution for RHEL 7.
Please file a bug for RHEL 7 and the right peple will make sure this happens.
OK. I will do that.

Thanks a lot.

Jan
Tomasz Torcz
2014-11-04 20:42:31 UTC
Permalink
Post by Jan Včelák
Hi!
Post by Lennart Poettering
Post by Jan Včelák
OK. I will remove the syslog. But I will have to keep network.target for
now as we support non-Linux systems as well. Adding support for rtnl or
IP_FREEBIND would mean duplicating a lot of code... probably.
Note that invoking IP_FREEBIND is just a single setsockopt() line...
You are right. We enabled IP_FREEBIND after all. (And we also added IP_BINDANY
and IPV6_BINDANY on FreeBSD to achieve the same behavior.)
On the other hand, we cannot give the administrator proper feedback when the
daemon is configured incorrectly.
If you need, you can first try binding without IP_FREEBIND. If it fails,
you can print "Configured address (xxx) not available yet", enable IP_FREEBIND
and call bind() again.
--
Tomasz Torcz "Never underestimate the bandwidth of a station
xmpp: ***@chrome.pl wagon filled with backup tapes." -- Jim Gray
Lennart Poettering
2014-11-05 11:30:38 UTC
Permalink
Post by Tomasz Torcz
Post by Jan Včelák
Hi!
Post by Lennart Poettering
Post by Jan Včelák
OK. I will remove the syslog. But I will have to keep network.target for
now as we support non-Linux systems as well. Adding support for rtnl or
IP_FREEBIND would mean duplicating a lot of code... probably.
Note that invoking IP_FREEBIND is just a single setsockopt() line...
You are right. We enabled IP_FREEBIND after all. (And we also added IP_BINDANY
and IPV6_BINDANY on FreeBSD to achieve the same behavior.)
On the other hand, we cannot give the administrator proper feedback when the
daemon is configured incorrectly.
If you need, you can first try binding without IP_FREEBIND. If it fails,
you can print "Configured address (xxx) not available yet", enable IP_FREEBIND
and call bind() again.
I'd recommend this, too. I'd check for the right errno first though,
given that there might be other reasons why bind() could fail, and one
shouldn't confuse the user with misleadin error messages.

Lennart
--
Lennart Poettering, Red Hat
Loading...