Discussion:
service.d/.conf files and multi-valued options
(too old to reply)
Igor Bukanov
2015-01-23 10:32:54 UTC
Permalink
It is not clear from the systemd.unit manual page what happens when
foo.service.d/bar.conf sets an option like Service/ExecStartPre that
can be specified multiple times. From experimenting I see that *.conf
files supply additional values to the option and to overwrite or
remove already given values for the option one have to copy the whole
file into /etc and edit it there. Is it so?
Matthias Urlichs
2015-01-23 11:21:23 UTC
Permalink
Hi,
Post by Igor Bukanov
It is not clear from the systemd.unit manual page what happens when
foo.service.d/bar.conf sets an option like Service/ExecStartPre that
can be specified multiple times. From experimenting I see that *.conf
files supply additional values to the option and to overwrite or
remove already given values for the option one have to copy the whole
file into /etc and edit it there. Is it so?
Doesn't the manpage state that an empty entry clears the list?
--
-- Matthias Urlichs
Christian Seiler
2015-01-23 13:15:30 UTC
Permalink
Post by Matthias Urlichs
Post by Igor Bukanov
It is not clear from the systemd.unit manual page what happens when
foo.service.d/bar.conf sets an option like Service/ExecStartPre that
can be specified multiple times. From experimenting I see that *.conf
files supply additional values to the option and to overwrite or
remove already given values for the option one have to copy the whole
file into /etc and edit it there. Is it so?
Doesn't the manpage state that an empty entry clears the list?
Yes, it does, although only in the general systemd.unit(5), not in the
specific options, so maybe it's not that easy to find.

I think it would be nice to have some kind of man page that is a
tutorial as to what are the best practices to override distro service
files with your own site-specific configuration, which also includes
a couple of simple examples that cover the most common cases.

Btw. it would also be nice to have a possibility to just remove a
specific entry from a list, not to reset it completely. Probably less
for things like Exec*=, but more for After=/Before=/...

For example, if there's a unit with After=b.service c.service und as
an admin I want to not order it after c.service, I will have to first
reset the list (empty After=) and then add all the current other
units it orders after again. If an update then makes the unit also be
ordered after d.service to fix some other bug, the local setting will
override the After=d.service too...

Maybe something like 'After-=c.service'? Although that would probably
break traditional ini parsers trying to process unit files...

Christian
Lennart Poettering
2015-01-23 13:27:41 UTC
Permalink
Post by Christian Seiler
Post by Matthias Urlichs
Post by Igor Bukanov
It is not clear from the systemd.unit manual page what happens when
foo.service.d/bar.conf sets an option like Service/ExecStartPre that
can be specified multiple times. From experimenting I see that *.conf
files supply additional values to the option and to overwrite or
remove already given values for the option one have to copy the whole
file into /etc and edit it there. Is it so?
Doesn't the manpage state that an empty entry clears the list?
Yes, it does, although only in the general systemd.unit(5), not in the
specific options, so maybe it's not that easy to find.
Actually, it kinda says it in the specific options. From the
explanation of ExecStart=:

"...If the empty string is assigned to this option, the list of
commands to start is reset, prior assignments of this option will have
no effect..."

And at the explanation of ExecStartPre= says the syntax is identical
to ExecStart=. So I think we are covered here. I mean, we could
certainly duplicate the discussion of ExecStart= at ExecStartPre=, but
I think it's nicer to just reference it again.
Post by Christian Seiler
Btw. it would also be nice to have a possibility to just remove a
specific entry from a list, not to reset it completely. Probably less
for things like Exec*=, but more for After=/Before=/...
For example, if there's a unit with After=b.service c.service und as
an admin I want to not order it after c.service, I will have to first
reset the list (empty After=) and then add all the current other
units it orders after again. If an update then makes the unit also be
ordered after d.service to fix some other bug, the local setting will
override the After=d.service too...
Maybe something like 'After-=c.service'? Although that would probably
break traditional ini parsers trying to process unit files...
I'd be very careful with coming up with more and more syntaxes like
this. People have also requested "+=", to append things to existing
lines.

I think for simplicity's sake the right approach to remove parts of a
unit file is to copy it from /usr to /etc, and then modify it
there. .d/ is not the answer to everything. I am aware of course that
copying the files from /usr to /etc will also disconnect you from
new unit files added by package updates, but I guess you cannot have a
cake and eat it too...

Lennart
--
Lennart Poettering, Red Hat
Christian Seiler
2015-01-23 13:57:50 UTC
Permalink
Post by Lennart Poettering
Post by Christian Seiler
Yes, it does, although only in the general systemd.unit(5), not in the
specific options, so maybe it's not that easy to find.
Actually, it kinda says it in the specific options. From the
"...If the empty string is assigned to this option, the list of
commands to start is reset, prior assignments of this option will have
no effect..."
Oh, I didn't see that while skimming the man page. Still, I think a
tutorial manpage as I described (different ways to override distro
configuration) would be a good idea. Would you accept a patch for
something like that? If so, what should the man page be called?
Post by Lennart Poettering
And at the explanation of ExecStartPre= says the syntax is identical
to ExecStart=. So I think we are covered here.
No, sure, I don't think ExecStartPre= needs additional information,
I just didn't see the sentence in ExecStart=, sorry about that.
Post by Lennart Poettering
Post by Christian Seiler
Btw. it would also be nice to have a possibility to just remove a
specific entry from a list, not to reset it completely. Probably less
for things like Exec*=, but more for After=/Before=/...
For example, if there's a unit with After=b.service c.service und as
an admin I want to not order it after c.service, I will have to first
reset the list (empty After=) and then add all the current other
units it orders after again. If an update then makes the unit also be
ordered after d.service to fix some other bug, the local setting will
override the After=d.service too...
Maybe something like 'After-=c.service'? Although that would
probably
break traditional ini parsers trying to process unit files...
I'd be very careful with coming up with more and more syntaxes like
this. People have also requested "+=", to append things to existing
lines.
I think for simplicity's sake the right approach to remove parts of a
unit file is to copy it from /usr to /etc, and then modify it
there. .d/ is not the answer to everything. I am aware of course that
copying the files from /usr to /etc will also disconnect you from
new unit files added by package updates, but I guess you cannot have a
cake and eat it too...
But if I want to add something to After=/Before=/..., I can easily do
that with a drop-in just containing After=foo.service. And that's
indeed
very useful, I've used that a couple of times. So for symmetry reasons,
I think the converse would also be quite useful (although I haven't
needed it that often). I don't have a good idea for the syntax just
now,
but would you be opposed to at least adding 'design a syntax for this'
to the TODO list?

Christian
Lennart Poettering
2015-01-23 14:12:11 UTC
Permalink
Post by Christian Seiler
Post by Lennart Poettering
Post by Christian Seiler
Yes, it does, although only in the general systemd.unit(5), not in the
specific options, so maybe it's not that easy to find.
Actually, it kinda says it in the specific options. From the
"...If the empty string is assigned to this option, the list of
commands to start is reset, prior assignments of this option will have
no effect..."
Oh, I didn't see that while skimming the man page. Still, I think a
tutorial manpage as I described (different ways to override distro
configuration) would be a good idea. Would you accept a patch for
something like that? If so, what should the man page be called?
Sure, we can always use more man pages! Maybe simply call it
"systemd.turorial" or so, which could then get sections explainaining
how to best write new unit files, how to override/extend vendor unit
files, and so on.
Post by Christian Seiler
Post by Lennart Poettering
I think for simplicity's sake the right approach to remove parts of a
unit file is to copy it from /usr to /etc, and then modify it
there. .d/ is not the answer to everything. I am aware of course that
copying the files from /usr to /etc will also disconnect you from
new unit files added by package updates, but I guess you cannot have a
cake and eat it too...
But if I want to add something to After=/Before=/..., I can easily do
that with a drop-in just containing After=foo.service. And that's indeed
very useful, I've used that a couple of times. So for symmetry reasons,
I think the converse would also be quite useful (although I haven't
needed it that often). I don't have a good idea for the syntax just now,
but would you be opposed to at least adding 'design a syntax for this'
to the TODO list?
It's not just the syntax I am concerned about. It's more about
overloading the language with too many features. It's supposed to be
easy to parse, just a bunch of assigments. In fact the assignment of
the empty string to reset lists is already a bit in the territory of
"this might be too complex"...

Lennart
--
Lennart Poettering, Red Hat
Zbigniew Jędrzejewski-Szmek
2015-01-23 14:20:37 UTC
Permalink
Post by Lennart Poettering
Post by Christian Seiler
Post by Lennart Poettering
Post by Christian Seiler
Yes, it does, although only in the general systemd.unit(5), not in the
specific options, so maybe it's not that easy to find.
Actually, it kinda says it in the specific options. From the
"...If the empty string is assigned to this option, the list of
commands to start is reset, prior assignments of this option will have
no effect..."
Oh, I didn't see that while skimming the man page. Still, I think a
tutorial manpage as I described (different ways to override distro
configuration) would be a good idea. Would you accept a patch for
something like that? If so, what should the man page be called?
Sure, we can always use more man pages! Maybe simply call it
"systemd.turorial" or so, which could then get sections explainaining
how to best write new unit files, how to override/extend vendor unit
files, and so on.
I think it might be better to stick it into systemd.unit. There's really
no reason not to, and this way it'll have more exposure. People are more
likely to miss a separate page.

I think it would be great to have an Examples section in systemd.{unit,
service,socket,path,...} giving a semi-realistic example of a unit that
can serve as a template. For systemd.socket there should be two: an
Accept=yes and Accept=no.

Zbyszek
Christian Seiler
2015-01-24 13:13:00 UTC
Permalink
Post by Zbigniew Jędrzejewski-Szmek
I think it would be great to have an Examples section in
systemd.{unit, service,socket,path,...} giving a semi-realistic
example of a unit that can serve as a template. For systemd.socket
there should be two: an Accept=yes and Accept=no.
I've attached a git format-patch of adding an example section to
systemd.unit for the two most common tasks about modifying units, to see
whether you consider that style acceptable.

Christian
Zbigniew Jędrzejewski-Szmek
2015-01-24 14:18:28 UTC
Permalink
Post by Christian Seiler
Post by Zbigniew Jędrzejewski-Szmek
I think it would be great to have an Examples section in
systemd.{unit, service,socket,path,...} giving a semi-realistic
example of a unit that can serve as a template. For systemd.socket
there should be two: an Accept=yes and Accept=no.
I've attached a git format-patch of adding an example section to
systemd.unit for the two most common tasks about modifying units, to see
whether you consider that style acceptable.
Christian
From 7f448c58296d3b10392fa98975d28f13745bb845 Mon Sep 17 00:00:00 2001
Date: Sat, 24 Jan 2015 14:04:03 +0100
Subject: [PATCH] systemd.unit(5): add examples for common tasks
Add examples for (a) making units enableable and (b) overriding vendor
settings to the man page.
---
man/systemd.unit.xml | 153 +++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 153 insertions(+)
diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml
index bf0deb1..1d89bc9 100644
--- a/man/systemd.unit.xml
+++ b/man/systemd.unit.xml
@@ -1574,6 +1574,159 @@
</refsect1>
<refsect1>
+ <title>Examples</title>
+
+ <example>
+ <title>Making a unit enableable</title>
+
+ <para>The following snippet makes a unit
+ (e.g. <filename>foo.service</filename>)
+ enableable via
+ <command>systemctl enable</command>:</para>
+
+ <programlisting>[Install]
+WantedBy=multi-user.target</programlisting>
+
+ <para>After running
+ <command>systemctl enable</command>, a symlink
+ <filename>/etc/systemd/system/multi-user.target.wants/foo.service</filename>
+ linking to the actual unit will be created. It
+ tells systemd to pull in the unit when starting
+ <filename>multi-user.target</filename>. The
+ converse <command>systemctl disable</command>
+ will remove that symlink again.</para>
The description is good. I wonder if it might better to inlcude a complete
unit here and discuss all lines, instead of just a snippet.
Post by Christian Seiler
+ </example>
+
+ <example>
+ <title>Overriding vendor settings</title>
+
+ <para>There are two methods of overriding
+ vendor settings in unit files: copying the unit
+ file from
+ <filename>/usr/lib/systemd/system</filename>
+ to <filename>/etc/systemd/system</filename> and
+ modifying the chosen settings. Alternatively,
+ one can create a directory named
+ <filename><replaceable>unit</replaceable>.d/</filename>
+ within
+ <filename>/etc/systemd/system</filename> and
+ place a drop-in file
+ <filename><replaceable>name</replaceable>.conf</filename>
+ there that only changes the specific settings
+ one is interested in. Note that multiple such
+ drop-in files are read if present.</para>
+
+ <para>The advantage of the first method is
+ that one easily overrides the complete unit,
+ the vendor unit is not parsed at all anymore.
+ It has the disadvantage that improvements to
+ the unit file by the vendor are not
+ automatically incorporated on updates.</para>
+
+ <para>The advantage of the second method is
+ that one only overrides the settings one
+ specifically wants, where updates to the unit
+ by the vendor automatically apply. This has the
+ disadvantage that some future updates by the
+ vendor might be incompatible with the local
+ changes.</para>
+
+ <para>Note that for drop-in files, if one wants
+ to remove entries from a setting that is parsed
+ as a list, such as
+ <varname>After=</varname> or
+ <varname>Before=</varname> (or e.g.
+ <varname>ExecStart=</varname> in service
+ units), one needs to first clear the list
+ before re-adding all entries except the one
+ that is to be removed. See below for an
+ example.</para>
+
+ <para>This also applies for user instances of
+ systemd, but with different locations for the
+ unit files. See the section on unit load paths
+ for further details.</para>
+
+ <para>Suppose there is a vendor-supplied unit
+ <filename>/usr/lib/systemd/system/httpd.service</filename>
+ with the following contents:</para>
+
+ <programlisting>[Unit]
+Description=Some HTTP server
+After=network.target remote-fs.target nss-lookup.target sqldb.service
+Requires=sqldb.service
+
+[Service]
+Type=notify
+ExecStart=/usr/sbin/some-fancy-httpd-server
+TimeoutStartSec=5
+
+[Install]
+WantedBy=multi-user.target</programlisting>
+
+ <para>Now one wants to change some settings as
+ an administrator: firstly, in the local setup,
+ <filename>nss-lookup.target</filename> might
+ take a long time to be reached at boot. But
+ because of the local configuration it is not
+ actually required for the service to run, so
+ the administrator would like to remove it from
+ the dependencies, to make the service start up
+ faster. Secondly, the local configuration makes
+ the HTTP server also depend on a memory cache
+ service,
+ <filename>memcached.service</filename>, that
+ should be pulled in
+ (<varname>Requires=</varname>) and also be
+ ordered appropriately
+ (<varname>After=</varname>). Thirdly, in order
+ to harden the service a bit more, the
+ administrator would like to set the
+ <varname>PrivateTmp=</varname>
+ setting (see
+ <citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+ for details). And lastly, the timeout for the
+ service startup should be increased to 1
+ minute.</para>
+
+ <para>The first possibility is to copy the unit
+ file to
+ <filename>/etc/systemd/system/httpd.service</filename>
+ and change the chosen settings:</para>
+
+ <programlisting>[Unit]
+Description=Some HTTP server
+<emphasis>After=network.target remote-fs.target sqldb.service memcached.service</emphasis>
+Requires=sqldb.service <emphasis>memcached.service</emphasis>
+
+[Service]
+Type=notify
+ExecStart=/usr/sbin/some-fancy-httpd-server
+<emphasis>TimeoutStartSec=1min</emphasis>
+<emphasis>PrivateTmp=yes</emphasis>
+
+[Install]
+WantedBy=multi-user.target</programlisting>
+
+ <para>Alternatively, the administrator could
+ create a drop-in file
+ <filename>/etc/systemd/system/httpd.service.d/local.conf</filename>
+ with the following contents:</para>
+
+ <programlisting>[Unit]
+# reset After= list to empty to remove nss-lookup.target
+After=
+After=network.target remote-fs.target sqldb.service memcached.service
+# since Requires= is not reset, this is just appended
+Requires=memcached.service
+
+[Service]
+TimeoutStartSec=1min
+PrivateTmp=yes</programlisting>
+ </example>
+ </refsect1>
This part looks nice too.

Zbyszek
Post by Christian Seiler
+
+ <refsect1>
<title>See Also</title>
<para>
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
--
1.8.3.1
Christian Seiler
2015-01-24 15:01:21 UTC
Permalink
Post by Zbigniew Jędrzejewski-Szmek
Post by Christian Seiler
+ <example>
+ <title>Making a unit enableable</title>
+
+ <para>The following snippet makes a unit
+ (e.g. <filename>foo.service</filename>)
+ enableable via
+ <command>systemctl enable</command>:</para>
+
+ <programlisting>[Install]
+WantedBy=multi-user.target</programlisting>
+
+ <para>After running
+ <command>systemctl enable</command>, a symlink
+ <filename>/etc/systemd/system/multi-user.target.wants/foo.service</filename>
+ linking to the actual unit will be created. It
+ tells systemd to pull in the unit when starting
+ <filename>multi-user.target</filename>. The
+ converse <command>systemctl disable</command>
+ will remove that symlink again.</para>
The description is good. I wonder if it might better to inlcude a complete
unit here and discuss all lines, instead of just a snippet.
I wanted to keep it as minimal an example as possible, but maybe
something absolutely trivial such as:

[Unit]
Description=Foo

[Service]
ExecStart=/usr/sbin/foo-daemon

[Install]
WantedBy=multi-user.target

with the last section highlighted (<emphasis>)? I don't want to make it
too complicated.
Post by Zbigniew Jędrzejewski-Szmek
Post by Christian Seiler
[ example about overriding vendor defaults ]
This part looks nice too.
Thanks!

I'll then go on and write a couple more examples for different typical
use cases. Here's what I'd want to cover:

- systemd.service(5)
- Type=simple
- RemainAfterExit= discussion
- Type=oneshot
- RemainAfterExit= discussion
- Type=forking
- PIDFile=, GuessMainPID=
- Type=dbus
- Type=notify
- also include snippet for required code in daemon and
link to sd_notify(3)
- Type=idle: getty example

- systemd.target(5)
- use remote-fs.target to discuss how synchronization points via
targets work (but also note how DefaultDependencies= makes that
one special)
- example of service group with PartOf=

- systemd.socket(5)
- inetd style activation Accept=yes
- systemd style activation Accept=no
- also include snippet for required code in daemon and
link to sd_listen_fds()/...

- systemd.timer(5)
- just a trivial example w/ a oneshot service

- systemd.path(5)
- dynamically activate service based on presence of configuration
(and explain difference to ConditionPatchExists=)

- systemd.mount(5), systemd.automount(5) and systemd.swap(5)
- an example that is equivalent to a given entry in /etc/fstab
and then explain how additional systemd options such as
Condition...= can be used to go beyond what is possible in
/etc/fstab

I'll probably skip systemd.device(5), because I can't think of a good
example for manually using those units.

Did I forget anything?

Christian
Christian Seiler
2015-01-27 16:45:52 UTC
Permalink
Add examples for (a) making units enableable and (b) overriding vendor
settings to the man page.
---
man/systemd.unit.xml | 164 +++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 164 insertions(+)

diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml
index e820b33..8714f70 100644
--- a/man/systemd.unit.xml
+++ b/man/systemd.unit.xml
@@ -1574,6 +1574,170 @@
</refsect1>

<refsect1>
+ <title>Examples</title>
+
+ <example>
+ <title>Making a unit enableable</title>
+
+ <para>The following snippet (highlighted) makes
+ a unit (e.g. <filename>foo.service</filename>)
+ enableable via
+ <command>systemctl enable</command>:</para>
+
+ <programlisting>[Unit]
+Description=Foo
+
+[Service]
+ExecStart=/usr/sbin/foo-daemon
+
+<emphasis>[Install]</emphasis>
+<emphasis>WantedBy=multi-user.target</emphasis></programlisting>
+
+ <para>After running
+ <command>systemctl enable</command>, a symlink
+ <filename>/etc/systemd/system/multi-user.target.wants/foo.service</filename>
+ linking to the actual unit will be created. It
+ tells systemd to pull in the unit when starting
+ <filename>multi-user.target</filename>. The
+ converse <command>systemctl disable</command>
+ will remove that symlink again.</para>
+ </example>
+
+ <example>
+ <title>Overriding vendor settings</title>
+
+ <para>There are two methods of overriding
+ vendor settings in unit files: copying the unit
+ file from
+ <filename>/usr/lib/systemd/system</filename>
+ to <filename>/etc/systemd/system</filename> and
+ modifying the chosen settings. Alternatively,
+ one can create a directory named
+ <filename><replaceable>unit</replaceable>.d/</filename>
+ within
+ <filename>/etc/systemd/system</filename> and
+ place a drop-in file
+ <filename><replaceable>name</replaceable>.conf</filename>
+ there that only changes the specific settings
+ one is interested in. Note that multiple such
+ drop-in files are read if present.</para>
+
+ <para>The advantage of the first method is
+ that one easily overrides the complete unit,
+ the vendor unit is not parsed at all anymore.
+ It has the disadvantage that improvements to
+ the unit file by the vendor are not
+ automatically incorporated on updates.</para>
+
+ <para>The advantage of the second method is
+ that one only overrides the settings one
+ specifically wants, where updates to the unit
+ by the vendor automatically apply. This has the
+ disadvantage that some future updates by the
+ vendor might be incompatible with the local
+ changes.</para>
+
+ <para>Note that for drop-in files, if one wants
+ to remove entries from a setting that is parsed
+ as a list (and is not a dependency), such as
+ <varname>ConditionPathExists=</varname> (or
+ e.g. <varname>ExecStart=</varname> in service
+ units), one needs to first clear the list
+ before re-adding all entries except the one
+ that is to be removed. See below for an
+ example.</para>
+
+ <para>This also applies for user instances of
+ systemd, but with different locations for the
+ unit files. See the section on unit load paths
+ for further details.</para>
+
+ <para>Suppose there is a vendor-supplied unit
+ <filename>/usr/lib/systemd/system/httpd.service</filename>
+ with the following contents:</para>
+
+ <programlisting>[Unit]
+Description=Some HTTP server
+After=network.target remote-fs.target sqldb.service
+Requires=sqldb.service
+ConditionPathExists=/srv/webserver
+
+[Service]
+Type=notify
+ExecStart=/usr/sbin/some-fancy-httpd-server
+TimeoutStartSec=5
+
+[Install]
+WantedBy=multi-user.target</programlisting>
+
+ <para>Now one wants to change some settings as
+ an administrator: firstly, in the local setup,
+ <filename>/srv/webserver</filename> might not
+ exit, because the HTTP server is configured to
+ use <filename>/srv/www</filename> instead.
+ Secondly, the local configuration makes the
+ HTTP server also depend on a memory cache
+ service,
+ <filename>memcached.service</filename>, that
+ should be pulled in
+ (<varname>Requires=</varname>) and also be
+ ordered appropriately
+ (<varname>After=</varname>). Thirdly, in order
+ to harden the service a bit more, the
+ administrator would like to set the
+ <varname>PrivateTmp=</varname>
+ setting (see
+ <citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+ for details). And lastly, the timeout for the
+ service startup should be increased to 1
+ minute.</para>
+
+ <para>The first possibility is to copy the unit
+ file to
+ <filename>/etc/systemd/system/httpd.service</filename>
+ and change the chosen settings:</para>
+
+ <programlisting>[Unit]
+Description=Some HTTP server
+After=network.target remote-fs.target sqldb.service <emphasis>memcached.service</emphasis>
+Requires=sqldb.service <emphasis>memcached.service</emphasis>
+ConditionPathExists=<emphasis>/srv/www</emphasis>
+
+[Service]
+Type=notify
+ExecStart=/usr/sbin/some-fancy-httpd-server
+<emphasis>TimeoutStartSec=1min</emphasis>
+<emphasis>PrivateTmp=yes</emphasis>
+
+[Install]
+WantedBy=multi-user.target</programlisting>
+
+ <para>Alternatively, the administrator could
+ create a drop-in file
+ <filename>/etc/systemd/system/httpd.service.d/local.conf</filename>
+ with the following contents:</para>
+
+ <programlisting>[Unit]
+After=memcached.service
+Requires=memcached.service
+# Reset all conditions and then re-add the condition we want
+ConditionPathExists=
+ConditionPathExists=/srv/www
+
+[Service]
+TimeoutStartSec=1min
+PrivateTmp=yes</programlisting>
+
+ <para>Note that dependencies
+ (<varname>After=</varname>, etc.) cannot be
+ reset to an empty list, so dependencies can
+ only be added in drop-ins. If you want to
+ remove dependencies, you have to override the
+ entire unit.</para>
+ </example>
+ </refsect1>
+
+ <refsect1>
<title>See Also</title>
<para>
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
--
1.8.3.1
Christian Seiler
2015-01-27 16:45:53 UTC
Permalink
Add a couple of exampels, at least one for each service type that
include some explanations and pointers to various relevant options.
---
man/systemd.service.xml | 332 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 332 insertions(+)

diff --git a/man/systemd.service.xml b/man/systemd.service.xml
index 4c890df..5ccbba0 100644
--- a/man/systemd.service.xml
+++ b/man/systemd.service.xml
@@ -1358,6 +1358,338 @@ ExecStart=/bin/echo $ONE $TWO $THREE</programlisting>
</refsect1>

<refsect1>
+ <title>Examples</title>
+
+ <example>
+ <title>Simple service</title>
+
+ <para>The following unit file creates a service
+ that will execute
+ <filename>/usr/sbin/foo-daemon</filename>.
+ Since no <varname>Type=</varname> is specified,
+ the default
+ <varname>Type=</varname><option>simple</option>
+ will be assumed. systemd will assume the unit
+ to be started immediately after the program has
+ begun executing.</para>
+
+ <programlisting>[Unit]
+Description=Foo
+
+[Service]
+ExecStart=/usr/sbin/foo-daemon
+
+[Install]
+WantedBy=multi-user.target</programlisting>
+
+ <para>Note that systemd assumes here that the
+ program will continue running in the foreground
+ as long as it's active. If the program
+ backgrounds/daemonizes/forks itself, please use
+ <varname>Type=</varname><option>forking</option>
+ instead.</para>
+
+ <para>Since no <varname>ExecStop=</varname> was
+ specified, systemd will send SIGTERM to all
+ processes started from this service, and after
+ a timeout also SIGKILL. This behavior can be
+ modified, see
+ <citerefentry><refentrytitle>systemd.kill</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+ for details.</para>
+
+ <para>Note that this unit type does not include
+ any type of notification when a service has
+ completed initialization. For this, you should
+ use other unit types, such as
+ <varname>Type=</varname><option>notify</option>
+ if the service understands systemd's
+ notification protocol,
+ <varname>Type=</varname><option>forking</option>
+ if the service can background itself or
+ <varname>Type=</varname><option>dbus</option>
+ if the unit acquires a DBus name once
+ initialization is complete. See below.</para>
+ </example>
+
+ <example>
+ <title>Oneshot service</title>
+
+ <para>Sometimes units should just execute an
+ action without keeping active processes, such
+ as a filesystem check or a cleanup action on
+ boot. For this,
+ <varname>Type=</varname><option>oneshot</option>
+ exists. Units of this type will wait until the
+ process specified terminates and then fall back
+ to being inactive. The following unit will
+ perform a clenaup action:</para>
+
+ <programlisting>[Unit]
+Description=Cleanup old Foo data
+
+[Service]
+Type=oneshot
+ExecStart=/usr/sbin/foo-cleanup
+
+[Install]
+WantedBy=multi-user.target</programlisting>
+
+ <para>Note that systemd will consider the unit
+ to be in the state 'starting' until the program
+ has terminated, so ordered dependencies will
+ wait for the program to finish before starting
+ themselves. The unit will revert to the
+ 'inactive' state after the execution is
+ done. That means another request to start the
+ unit will perform the action again.</para>
+ </example>
+
+ <example>
+ <title>Stoppable oneshot service</title>
+
+ <para>Similarly to the oneshot services, there
+ are sometimes units that need to execute a
+ program to set up something and then execute
+ another to shut it down, but no process remains
+ active while they are considered
+ 'started'. Network configuration can sometimes
+ fall into this category.</para>
+
+ <para>For this, systemd knows the setting
+ <varname>RemainAfterExit=</varname><option>yes</option>,
+ which causes systemd to consider the unit to be
+ active if the start action exited successfully.
+ This directive can be used with all types, but
+ is most useful with
+ <varname>Type=</varname><option>oneshot</option>
+ and
+ <varname>Type=</varname><option>simple</option>.
+ With
+ <varname>Type=</varname><option>oneshot</option>
+ systemd waits until the start action has
+ completed before it considers the unit to be
+ active, so dependencies start only after the
+ start action has succeeded. With
+ <varname>Type=</varname><option>simple</option>
+ dependencies will start immediately after the
+ start action has been dispatched. The following
+ unit provides an example for a simple static
+ firewall.</para>
+
+ <programlisting>[Unit]
+Description=Simple firewall
+
+[Service]
+Type=oneshot
+RemainAfterExit=yes
+ExecStart=/usr/local/sbin/simple-firewall-start
+ExecStop=/usr/local/sbin/simple-firewall-stop
+
+[Install]
+WantedBy=multi-user.target</programlisting>
+
+ <para>Since the unit is considered to be
+ running after the start action has exited,
+ invoking <command>systemctl start</command> on
+ that unit again will cause no action to be
+ taken.</para>
+ </example>
+
+ <example>
+ <title>Traditional forking services</title>
+
+ <para>Many traditional daemons/services
+ background (i.e. fork, daemonize) themselves
+ when starting. Set
+ <varname>Type=</varname><option>forking</option>
+ in the service's unit file to support this mode
+ of operation. systemd will consider the service
+ to be in the process of initialization while
+ the original program is still running. Once
+ it exits successfully and at least a process
+ remains (and
+ <varname>RemainAfterExit=</varname><option>no</option>),
+ the service is considered started.</para>
+
+ <para>Often a traditional daemon only consists
+ of one process. Therefore, if only one process
+ is left after the original process terminates,
+ systemd will consider that process the main
+ process of the service. In that case, the
+ <varname>$MAINPID</varname> variable will be
+ available in <varname>ExecReload=</varname>,
+ <varname>ExecStop=</varname>, etc.</para>
+
+ <para>In case more than one process remains,
+ systemd will be unable to determine the main
+ process, so it will not assume there is one.
+ In that case, <varname>$MAINPID</varname> will
+ not expand to anything. However, if the process
+ decides to write a traditional PID file,
+ systemd will be able to read the main PID from
+ there. Please set <varname>PIDFile=</varname>
+ accordingly. Note that the daemon should write
+ that file before finishing with its
+ initialization, otherwise systemd might try to
+ read the file before it exists.</para>
+
+ <para>The following example shows a simple
+ daemon that forks and just starts one process
+ in the background:</para>
+
+ <programlisting>[Unit]
+Description=Some simple daemon
+
+[Service]
+Type=forking
+ExecStart=/usr/sbin/my-simple-daemon -d
+
+[Install]
+WantedBy=multi-user.target</programlisting>
+
+ <para>Please see
+ <citerefentry><refentrytitle>systemd.kill</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+ for details on how you can influence the way
+ systemd terminates the service.</para>
+ </example>
+
+ <example>
+ <title>DBus services</title>
+
+ <para>For services that acquire name on the
+ DBus system bus, use
+ <varname>RemainAfterExit=</varname><option>dbus</option>
+ and set <varname>BusName=</varname>
+ accordingly. The service should not fork
+ (daemonize). systemd will consider the service
+ to be initialized once the name has been
+ acquired on the system bus. The following
+ example shows a typical DBus service:</para>
+
+ <programlisting>[Unit]
+Description=Simple DBus service
+
+[Service]
+Type=dbus
+BusName=org.example.simple-dbus-service
+ExecStart=/usr/sbin/simple-dbus-service
+
+[Install]
+WantedBy=multi-user.target</programlisting>
+
+ <para>For <emphasis>bus-activatable</emphasis>
+ services, don't include a
+ <literal>[Install]</literal> section in the
+ systemd service file, but use the
+ <varname>SystemdService=</varname> option in
+ the corresponding DBus service file, for
+ example
+ (<filename>/usr/share/dbus-1/system-services/org.example.simple-dbus-service.service</filename>):</para>
+
+ <programlisting>[D-BUS Service]
+Name=org.example.simple-dbus-service
+Exec=/usr/sbin/simple-dbus-service
+User=root
+SystemdService=simple-dbus-service.service</programlisting>
+
+ <para>Please see
+ <citerefentry><refentrytitle>systemd.kill</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+ for details on how you can influence the way
+ systemd terminates the service.</para>
+ </example>
+
+ <example>
+ <title>Services that notify systemd about their initialization</title>
+
+ <para><varname>Type=</varname><option>simple</option>
+ services are really easy to write, but have the
+ major disadvantage of systemd not being able to
+ tell when initialization of the given service
+ is complete. For this reason, systemd supports
+ a simple notification protocol that allows
+ daemons to make systemd aware that they are
+ done initializing. Use
+ <varname>Type=</varname><option>notify</option>
+ for this. A typical service file for such a
+ daemon would look like this:</para>
+
+ <programlisting>[Unit]
+Description=Simple notifying service
+
+[Service]
+Type=notify
+ExecStart=/usr/sbin/simple-notifying-service
+
+[Install]
+WantedBy=multi-user.target</programlisting>
+
+ <para>Note that the daemon has to support
+ systemd's notification protocol, else systemd
+ will think the service hasn't started yet and
+ kill it after a timeout. For an example of how
+ to update daemons to support this protocol
+ transparently, take a look at
+ <citerefentry><refentrytitle>sd_notify</refentrytitle><manvolnum>3</manvolnum></citerefentry>.
+ systemd will consider the unit to be in the
+ 'starting' state until a readiness notification
+ has arrived.</para>
+
+ <para>Please see
+ <citerefentry><refentrytitle>systemd.kill</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+ for details on how you can influence the way
+ systemd terminates the service.</para>
+ </example>
+
+ <example>
+ <title>Deferred (idle) services</title>
+
+ <para>Some services should only be started once
+ the system is completely booted. For example,
+ login prompts on the console (especially where
+ boot messages appear) should only be started
+ once the boot sequence has finished. systemd
+ provides this functionality with
+ <varname>Type=</varname><option>idle</option>.
+ Services of this type behave identically to
+ services of type <option>simple</option>, the
+ only difference being the moment they are
+ initially started. The following example shows
+ a simple program that displays the current
+ time at completion of boot on
+ <filename>/dev/tty11</filename>:</para>
+
+ <programlisting>[Unit]
+Description=Boot time on /dev/tty11
+
+[Service]
+Type=idle
+ExecStartPre=-/bin/echo "Time of boot is:"
+ExecStart=-/bin/date
+RemainAfterExit=yes
+TTYPath=/dev/tty11
+StandardOutput=tty
+
+[Install]
+WantedBy=multi-user.target</programlisting>
+
+ <para><varname>RemainAfterExit=</varname><option>yes</option>
+ is set here so that systemd doesn't restart
+ the unit accidentally, which is useful for this
+ one-time unit. For login prompts or other
+ services that should automatically be restarted
+ upon exiting, please look at the
+ <varname>Restart=</varname> setting.</para>
+
+ <para>Note that systemd already has units for
+ getty login prompts in its default
+ configuration, which internally use this type.
+ Please take a look at
+ <filename>/usr/lib/systemd/system/***@.service</filename>
+ for an example of such a service.</para>
+ </example>
+ </refsect1>
+
+ <refsect1>
<title>See Also</title>
<para>
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
--
1.8.3.1
Lennart Poettering
2015-01-27 20:45:33 UTC
Permalink
Post by Christian Seiler
+ <title>Examples</title>
+
+ <example>
+ <title>Simple service</title>
+
+ <para>The following unit file creates a service
+ that will execute
+ <filename>/usr/sbin/foo-daemon</filename>.
+ Since no <varname>Type=</varname> is specified,
+ the default
+ <varname>Type=</varname><option>simple</option>
+ will be assumed. systemd will assume the unit
+ to be started immediately after the program has
+ begun executing.</para>
+
+ <programlisting>[Unit]
+Description=Foo
+
+[Service]
+ExecStart=/usr/sbin/foo-daemon
+
+[Install]
+WantedBy=multi-user.target</programlisting>
+
+ <para>Note that systemd assumes here that the
+ program will continue running in the foreground
+ as long as it's active. If the program
I think "foreground" vs. "background" here is probably something to
avoid. These are services after all, and hence kinda "background" in
all cases. I am not sure how to explain this better though... Maybe
clarify that the program does not fork on its own, and that the
process systemd starts stays running until the very end of the
daemon, or so.
Post by Christian Seiler
+ <para>Note that systemd will consider the unit
+ to be in the state 'starting' until the program
+ has terminated, so ordered dependencies will
+ wait for the program to finish before starting
+ themselves. The unit will revert to the
+ 'inactive' state after the execution is
+ done. That means another request to start the
+ unit will perform the action again.</para>
It might be worth also mentioning here that the the unit this way will
never actually be "active". It will go directly from "activating" to
"inactive", which might be surprising!
Post by Christian Seiler
+ </example>
+
+ <example>
+ <title>Stoppable oneshot service</title>
+
+ <para>Similarly to the oneshot services, there
+ are sometimes units that need to execute a
+ program to set up something and then execute
+ another to shut it down, but no process remains
+ active while they are considered
+ 'started'. Network configuration can sometimes
+ fall into this category.</para>
Another reason to use RemainAfterExit= are services that shall not
execute again and again when they are pulled in, but only the first
time...
Post by Christian Seiler
+ <example>
+ <title>DBus services</title>
+
+ <para>For services that acquire name on the
+ DBus system bus, use
+
<varname>RemainAfterExit=</varname><option>dbus</option>
Typo. Should be Type=, not RemainAfterExit=
Post by Christian Seiler
+ <example>
+ <title>Deferred (idle) services</title>
Hmm, I wonder if we maybe should remove this part. Idle services are
kinda exotic, and I figure people might be tempted to misuse them. I
think this might be something to document at the description of Type=,
but not push people towards using this beyond that.

Looks great otherwise! Thanks a ton for putting this together, much appreciated!

Lennart
--
Lennart Poettering, Red Hat
Christian Seiler
2015-01-27 21:10:44 UTC
Permalink
Post by Lennart Poettering
Post by Christian Seiler
+ <para>Note that systemd assumes here that the
+ program will continue running in the foreground
+ as long as it's active. If the program
I think "foreground" vs. "background" here is probably something to
avoid. These are services after all, and hence kinda "background" in
all cases. I am not sure how to explain this better though... Maybe
clarify that the program does not fork on its own, and that the
process systemd starts stays running until the very end of the
daemon, or so.
Yes, you are completely right. I've kept the use of 'background' at some
places, but specifically avoided foreground, since that is really,
really misleading. I've also rephrased the paragraph in question. I hope
that's better.
Post by Lennart Poettering
Post by Christian Seiler
+ <para>Note that systemd will consider the unit
+ to be in the state 'starting' until the program
+ has terminated, so ordered dependencies will
+ wait for the program to finish before starting
+ themselves. The unit will revert to the
+ 'inactive' state after the execution is
+ done. That means another request to start the
+ unit will perform the action again.</para>
It might be worth also mentioning here that the the unit this way will
never actually be "active". It will go directly from "activating" to
"inactive", which might be surprising!
Thanks for the pointer, done!

Now I also mentioned something about multiple ExecStart= for oneshot
units, which might be useful there.
Post by Lennart Poettering
Post by Christian Seiler
+ <para>Similarly to the oneshot services, there
+ are sometimes units that need to execute a
+ program to set up something and then execute
+ another to shut it down, but no process remains
+ active while they are considered
+ 'started'. Network configuration can sometimes
+ fall into this category.</para>
Another reason to use RemainAfterExit= are services that shall not
execute again and again when they are pulled in, but only the first
time...
Mentioned that, thanks!
Post by Lennart Poettering
Post by Christian Seiler
<varname>RemainAfterExit=</varname><option>dbus</option>
Typo. Should be Type=, not RemainAfterExit=
*hehe* fixed.
Post by Lennart Poettering
Post by Christian Seiler
+ <example>
+ <title>Deferred (idle) services</title>
Hmm, I wonder if we maybe should remove this part. Idle services are
kinda exotic, and I figure people might be tempted to misuse them. I
think this might be something to document at the description of Type=,
but not push people towards using this beyond that.
When I started writing this, I didn't just want to copy the getty
service (people can look that up anyway), so I decided to come up with
something else. However, once I wrote that unit, I realized that this
could have easily just been a Type=oneshot, RemainAfterExit=yes,
After=multi-user.target unit and have the same effect, and be a lot more
consistent with the rest of the way of doing things...

Type=idle is basically really just for gettys or something extremely
similar (like other interactive apps on VTs) that also get automatically
restarted.

Since these examples are supposed to provide a starting point for people
on how to write services, I've removed the section completely, and I
think this kind of special internal thing should remain in the reference
documentation.

v3 attached, I also fixed one or two other minor typos I noticed.

Christian
Lennart Poettering
2015-01-27 21:19:56 UTC
Permalink
On Tue, 27.01.15 22:10, Christian Seiler (***@iwakd.de) wrote:

Thanks a ton! Applied!
Post by Christian Seiler
Post by Lennart Poettering
Post by Christian Seiler
+ <para>Note that systemd assumes here that the
+ program will continue running in the foreground
+ as long as it's active. If the program
I think "foreground" vs. "background" here is probably something to
avoid. These are services after all, and hence kinda "background" in
all cases. I am not sure how to explain this better though... Maybe
clarify that the program does not fork on its own, and that the
process systemd starts stays running until the very end of the
daemon, or so.
Yes, you are completely right. I've kept the use of 'background' at some
places, but specifically avoided foreground, since that is really,
really misleading. I've also rephrased the paragraph in question. I hope
that's better.
Post by Lennart Poettering
Post by Christian Seiler
+ <para>Note that systemd will consider the unit
+ to be in the state 'starting' until the program
+ has terminated, so ordered dependencies will
+ wait for the program to finish before starting
+ themselves. The unit will revert to the
+ 'inactive' state after the execution is
+ done. That means another request to start the
+ unit will perform the action again.</para>
It might be worth also mentioning here that the the unit this way will
never actually be "active". It will go directly from "activating" to
"inactive", which might be surprising!
Thanks for the pointer, done!
Now I also mentioned something about multiple ExecStart= for oneshot
units, which might be useful there.
Post by Lennart Poettering
Post by Christian Seiler
+ <para>Similarly to the oneshot services, there
+ are sometimes units that need to execute a
+ program to set up something and then execute
+ another to shut it down, but no process remains
+ active while they are considered
+ 'started'. Network configuration can sometimes
+ fall into this category.</para>
Another reason to use RemainAfterExit= are services that shall not
execute again and again when they are pulled in, but only the first
time...
Mentioned that, thanks!
Post by Lennart Poettering
Post by Christian Seiler
<varname>RemainAfterExit=</varname><option>dbus</option>
Typo. Should be Type=, not RemainAfterExit=
*hehe* fixed.
Post by Lennart Poettering
Post by Christian Seiler
+ <example>
+ <title>Deferred (idle) services</title>
Hmm, I wonder if we maybe should remove this part. Idle services are
kinda exotic, and I figure people might be tempted to misuse them. I
think this might be something to document at the description of Type=,
but not push people towards using this beyond that.
When I started writing this, I didn't just want to copy the getty
service (people can look that up anyway), so I decided to come up with
something else. However, once I wrote that unit, I realized that this
could have easily just been a Type=oneshot, RemainAfterExit=yes,
After=multi-user.target unit and have the same effect, and be a lot more
consistent with the rest of the way of doing things...
Type=idle is basically really just for gettys or something extremely
similar (like other interactive apps on VTs) that also get automatically
restarted.
Since these examples are supposed to provide a starting point for people
on how to write services, I've removed the section completely, and I
think this kind of special internal thing should remain in the reference
documentation.
v3 attached, I also fixed one or two other minor typos I noticed.
Christian
From ff44c16a173b36695e4844b36fbd10ac977bf4a3 Mon Sep 17 00:00:00 2001
Date: Tue, 27 Jan 2015 17:38:02 +0100
Subject: [PATCH] systemd.service(5): add some simple examples
Add a couple of exampels, at least one for each service type that
include some explanations and pointers to various relevant options.
---
man/systemd.service.xml | 296 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 296 insertions(+)
diff --git a/man/systemd.service.xml b/man/systemd.service.xml
index 4c890df..f33e8df 100644
--- a/man/systemd.service.xml
+++ b/man/systemd.service.xml
@@ -1358,6 +1358,302 @@ ExecStart=/bin/echo $ONE $TWO $THREE</programlisting>
</refsect1>
<refsect1>
+ <title>Examples</title>
+
+ <example>
+ <title>Simple service</title>
+
+ <para>The following unit file creates a service
+ that will execute
+ <filename>/usr/sbin/foo-daemon</filename>.
+ Since no <varname>Type=</varname> is specified,
+ the default
+ <varname>Type=</varname><option>simple</option>
+ will be assumed. systemd will assume the unit
+ to be started immediately after the program has
+ begun executing.</para>
+
+ <programlisting>[Unit]
+Description=Foo
+
+[Service]
+ExecStart=/usr/sbin/foo-daemon
+
+[Install]
+WantedBy=multi-user.target</programlisting>
+
+ <para>Note that systemd assumes here that the
+ process started by systemd will continue
+ running until the service terminates. If the
+ program daemonizes itself (i.e. forks), please
+ use
+ <varname>Type=</varname><option>forking</option>
+ instead.</para>
+
+ <para>Since no <varname>ExecStop=</varname> was
+ specified, systemd will send SIGTERM to all
+ processes started from this service, and after
+ a timeout also SIGKILL. This behavior can be
+ modified, see
+ <citerefentry><refentrytitle>systemd.kill</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+ for details.</para>
+
+ <para>Note that this unit type does not include
+ any type of notification when a service has
+ completed initialization. For this, you should
+ use other unit types, such as
+ <varname>Type=</varname><option>notify</option>
+ if the service understands systemd's
+ notification protocol,
+ <varname>Type=</varname><option>forking</option>
+ if the service can background itself or
+ <varname>Type=</varname><option>dbus</option>
+ if the unit acquires a DBus name once
+ initialization is complete. See below.</para>
+ </example>
+
+ <example>
+ <title>Oneshot service</title>
+
+ <para>Sometimes units should just execute an
+ action without keeping active processes, such
+ as a filesystem check or a cleanup action on
+ boot. For this,
+ <varname>Type=</varname><option>oneshot</option>
+ exists. Units of this type will wait until the
+ process specified terminates and then fall back
+ to being inactive. The following unit will
+ perform a clenaup action:</para>
+
+ <programlisting>[Unit]
+Description=Cleanup old Foo data
+
+[Service]
+Type=oneshot
+ExecStart=/usr/sbin/foo-cleanup
+
+[Install]
+WantedBy=multi-user.target</programlisting>
+
+ <para>Note that systemd will consider the unit
+ to be in the state 'starting' until the program
+ has terminated, so ordered dependencies will
+ wait for the program to finish before starting
+ themselves. The unit will revert to the
+ 'inactive' state after the execution is
+ done, never reaching the 'active' state. That
+ means another request to start the unit will
+ perform the action again.</para>
+
+ <para><varname>Type=</varname><option>oneshot</option>
+ are the only service units that may have more
+ than one <varname>ExecStart=</varname>
+ specified. They will be executed in order until
+ either they are all successful or one of them
+ fails.</para>
+ </example>
+
+ <example>
+ <title>Stoppable oneshot service</title>
+
+ <para>Similarly to the oneshot services, there
+ are sometimes units that need to execute a
+ program to set up something and then execute
+ another to shut it down, but no process remains
+ active while they are considered
+ 'started'. Network configuration can sometimes
+ fall into this category. Another use case is if
+ a oneshot service shall not be executed a
+ each time when they are pulled in as a
+ dependency, but only the first time.</para>
+
+ <para>For this, systemd knows the setting
+ <varname>RemainAfterExit=</varname><option>yes</option>,
+ which causes systemd to consider the unit to be
+ active if the start action exited successfully.
+ This directive can be used with all types, but
+ is most useful with
+ <varname>Type=</varname><option>oneshot</option>
+ and
+ <varname>Type=</varname><option>simple</option>.
+ With
+ <varname>Type=</varname><option>oneshot</option>
+ systemd waits until the start action has
+ completed before it considers the unit to be
+ active, so dependencies start only after the
+ start action has succeeded. With
+ <varname>Type=</varname><option>simple</option>
+ dependencies will start immediately after the
+ start action has been dispatched. The following
+ unit provides an example for a simple static
+ firewall.</para>
+
+ <programlisting>[Unit]
+Description=Simple firewall
+
+[Service]
+Type=oneshot
+RemainAfterExit=yes
+ExecStart=/usr/local/sbin/simple-firewall-start
+ExecStop=/usr/local/sbin/simple-firewall-stop
+
+[Install]
+WantedBy=multi-user.target</programlisting>
+
+ <para>Since the unit is considered to be
+ running after the start action has exited,
+ invoking <command>systemctl start</command> on
+ that unit again will cause no action to be
+ taken.</para>
+ </example>
+
+ <example>
+ <title>Traditional forking services</title>
+
+ <para>Many traditional daemons/services
+ background (i.e. fork, daemonize) themselves
+ when starting. Set
+ <varname>Type=</varname><option>forking</option>
+ in the service's unit file to support this mode
+ of operation. systemd will consider the service
+ to be in the process of initialization while
+ the original program is still running. Once
+ it exits successfully and at least a process
+ remains (and
+ <varname>RemainAfterExit=</varname><option>no</option>),
+ the service is considered started.</para>
+
+ <para>Often a traditional daemon only consists
+ of one process. Therefore, if only one process
+ is left after the original process terminates,
+ systemd will consider that process the main
+ process of the service. In that case, the
+ <varname>$MAINPID</varname> variable will be
+ available in <varname>ExecReload=</varname>,
+ <varname>ExecStop=</varname>, etc.</para>
+
+ <para>In case more than one process remains,
+ systemd will be unable to determine the main
+ process, so it will not assume there is one.
+ In that case, <varname>$MAINPID</varname> will
+ not expand to anything. However, if the process
+ decides to write a traditional PID file,
+ systemd will be able to read the main PID from
+ there. Please set <varname>PIDFile=</varname>
+ accordingly. Note that the daemon should write
+ that file before finishing with its
+ initialization, otherwise systemd might try to
+ read the file before it exists.</para>
+
+ <para>The following example shows a simple
+ daemon that forks and just starts one process
+ in the background:</para>
+
+ <programlisting>[Unit]
+Description=Some simple daemon
+
+[Service]
+Type=forking
+ExecStart=/usr/sbin/my-simple-daemon -d
+
+[Install]
+WantedBy=multi-user.target</programlisting>
+
+ <para>Please see
+ <citerefentry><refentrytitle>systemd.kill</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+ for details on how you can influence the way
+ systemd terminates the service.</para>
+ </example>
+
+ <example>
+ <title>DBus services</title>
+
+ <para>For services that acquire a name on the
+ DBus system bus, use
+ <varname>Type=</varname><option>dbus</option>
+ and set <varname>BusName=</varname>
+ accordingly. The service should not fork
+ (daemonize). systemd will consider the service
+ to be initialized once the name has been
+ acquired on the system bus. The following
+ example shows a typical DBus service:</para>
+
+ <programlisting>[Unit]
+Description=Simple DBus service
+
+[Service]
+Type=dbus
+BusName=org.example.simple-dbus-service
+ExecStart=/usr/sbin/simple-dbus-service
+
+[Install]
+WantedBy=multi-user.target</programlisting>
+
+ <para>For <emphasis>bus-activatable</emphasis>
+ services, don't include a
+ <literal>[Install]</literal> section in the
+ systemd service file, but use the
+ <varname>SystemdService=</varname> option in
+ the corresponding DBus service file, for
+ example
+ (<filename>/usr/share/dbus-1/system-services/org.example.simple-dbus-service.service</filename>):</para>
+
+ <programlisting>[D-BUS Service]
+Name=org.example.simple-dbus-service
+Exec=/usr/sbin/simple-dbus-service
+User=root
+SystemdService=simple-dbus-service.service</programlisting>
+
+ <para>Please see
+ <citerefentry><refentrytitle>systemd.kill</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+ for details on how you can influence the way
+ systemd terminates the service.</para>
+ </example>
+
+ <example>
+ <title>Services that notify systemd about their initialization</title>
+
+ <para><varname>Type=</varname><option>simple</option>
+ services are really easy to write, but have the
+ major disadvantage of systemd not being able to
+ tell when initialization of the given service
+ is complete. For this reason, systemd supports
+ a simple notification protocol that allows
+ daemons to make systemd aware that they are
+ done initializing. Use
+ <varname>Type=</varname><option>notify</option>
+ for this. A typical service file for such a
+ daemon would look like this:</para>
+
+ <programlisting>[Unit]
+Description=Simple notifying service
+
+[Service]
+Type=notify
+ExecStart=/usr/sbin/simple-notifying-service
+
+[Install]
+WantedBy=multi-user.target</programlisting>
+
+ <para>Note that the daemon has to support
+ systemd's notification protocol, else systemd
+ will think the service hasn't started yet and
+ kill it after a timeout. For an example of how
+ to update daemons to support this protocol
+ transparently, take a look at
+ <citerefentry><refentrytitle>sd_notify</refentrytitle><manvolnum>3</manvolnum></citerefentry>.
+ systemd will consider the unit to be in the
+ 'starting' state until a readiness notification
+ has arrived.</para>
+
+ <para>Please see
+ <citerefentry><refentrytitle>systemd.kill</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+ for details on how you can influence the way
+ systemd terminates the service.</para>
+ </example>
+ </refsect1>
+
+ <refsect1>
<title>See Also</title>
<para>
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
--
1.8.3.1
Lennart
--
Lennart Poettering, Red Hat
Lennart Poettering
2015-01-27 18:12:03 UTC
Permalink
Post by Christian Seiler
Add examples for (a) making units enableable and (b) overriding vendor
settings to the man page.
I am not a native english speaker, but I am not sure there's a word
like "enableable" in the english language. Maybe rephrase this as
"allowing units to be enabled"?
Post by Christian Seiler
+ linking to the actual unit will be created. It
+ tells systemd to pull in the unit when starting
+ <filename>multi-user.target</filename>. The
+ converse <command>systemctl disable</command>
+ will remove that symlink again.</para>
+ </example>
converse? shouldn't it be reverse or inverse?
Post by Christian Seiler
+ <programlisting>[Unit]
+Description=Some HTTP server
+After=network.target remote-fs.target sqldb.service
Given the fact that "network.target" is so vaguely defined, and not
even necessary in most cases, I'd really suggest removing this bit
fromt the After= line.
Post by Christian Seiler
+[Service]
+Type=notify
+ExecStart=/usr/sbin/some-fancy-httpd-server
+TimeoutStartSec=5
I think the default timeout should be fine. THere's usually no good
reason to change it.
Post by Christian Seiler
+ <para>The first possibility is to copy the unit
+ file to
+ <filename>/etc/systemd/system/httpd.service</filename>
+ and change the chosen settings:</para>
+
+ <programlisting>[Unit]
+Description=Some HTTP server
+After=network.target remote-fs.target sqldb.service <emphasis>memcached.service</emphasis>
+Requires=sqldb.service <emphasis>memcached.service</emphasis>
+ConditionPathExists=<emphasis>/srv/www</emphasis>
I wonder if the example should better use AssertionXYZ rather than
ConditionXYZ for this?

Looks great otherwise!

Lennart
--
Lennart Poettering, Red Hat
Christian Seiler
2015-01-27 18:26:42 UTC
Permalink
Post by Lennart Poettering
Post by Christian Seiler
Add examples for (a) making units enableable and (b) overriding vendor
settings to the man page.
I am not a native english speaker, but I am not sure there's a word
like "enableable" in the english language. Maybe rephrase this as
"allowing units to be enabled"?
Drat. I've read that in technical contexts often enough, and for safety
I typed it into google. There were enough results there to make me think
'oh, ok, it's a real word'. A quick look in a dictionary disagrees with
that assessment. Oh well. (Although the urban dictionary does have that
word, but my guess is you won't accept that as a canonical source for
the English language. ;-))

I'll change it.
Post by Lennart Poettering
Post by Christian Seiler
+ linking to the actual unit will be created. It
+ tells systemd to pull in the unit when starting
+ <filename>multi-user.target</filename>. The
+ converse <command>systemctl disable</command>
+ will remove that symlink again.</para>
+ </example>
converse? shouldn't it be reverse or inverse?
Hmm, converse was the first word that popped into my head, but inverse
is probably better, yes.
Post by Lennart Poettering
Post by Christian Seiler
+ <programlisting>[Unit]
+Description=Some HTTP server
+After=network.target remote-fs.target sqldb.service
Given the fact that "network.target" is so vaguely defined, and not
even necessary in most cases, I'd really suggest removing this bit
fromt the After= line.
Ok.
Post by Lennart Poettering
Post by Christian Seiler
+[Service]
+Type=notify
+ExecStart=/usr/sbin/some-fancy-httpd-server
+TimeoutStartSec=5
I think the default timeout should be fine. THere's usually no good
reason to change it.
I know, but I wanted to have something that was easily understandable at
first glance that was already set in the original unit that would then
be overridden. I'll use Nice= instead, that's more likely to be used.
Post by Lennart Poettering
Post by Christian Seiler
+ <para>The first possibility is to copy the unit
+ file to
+ <filename>/etc/systemd/system/httpd.service</filename>
+ and change the chosen settings:</para>
+
+ <programlisting>[Unit]
+Description=Some HTTP server
+After=network.target remote-fs.target sqldb.service <emphasis>memcached.service</emphasis>
+Requires=sqldb.service <emphasis>memcached.service</emphasis>
+ConditionPathExists=<emphasis>/srv/www</emphasis>
I wonder if the example should better use AssertionXYZ rather than
ConditionXYZ for this?
A right, that's new, I'll use that instead.

Will send second patch after your response to my question.

Christian
Lennart Poettering
2015-01-27 18:32:08 UTC
Permalink
Post by Christian Seiler
I know, but I wanted to have something that was easily understandable at
first glance that was already set in the original unit that would then
be overridden. I'll use Nice= instead, that's more likely to be used.
Yeah, sounds like the better option.
Post by Christian Seiler
Post by Lennart Poettering
Post by Christian Seiler
+ <para>The first possibility is to copy the unit
+ file to
+ <filename>/etc/systemd/system/httpd.service</filename>
+ and change the chosen settings:</para>
+
+ <programlisting>[Unit]
+Description=Some HTTP server
+After=network.target remote-fs.target sqldb.service <emphasis>memcached.service</emphasis>
+Requires=sqldb.service <emphasis>memcached.service</emphasis>
+ConditionPathExists=<emphasis>/srv/www</emphasis>
I wonder if the example should better use AssertionXYZ rather than
ConditionXYZ for this?
A right, that's new, I'll use that instead.
Will send second patch after your response to my question.
Uh, which question are you precisely referring to?

Lennart
--
Lennart Poettering, Red Hat
Christian Seiler
2015-01-27 18:44:01 UTC
Permalink
Post by Lennart Poettering
Post by Christian Seiler
Will send second patch after your response to my question.
Uh, which question are you precisely referring to?
Forget it, I answered that question myself and forgot to edit out the
last sentence of my mail. ;-)

I've attached git format-patch's output for the revised manpage.

Christian
Lennart Poettering
2015-01-27 21:01:48 UTC
Permalink
Post by Christian Seiler
Post by Lennart Poettering
Post by Christian Seiler
Will send second patch after your response to my question.
Uh, which question are you precisely referring to?
Forget it, I answered that question myself and forgot to edit out the
last sentence of my mail. ;-)
I've attached git format-patch's output for the revised manpage.
Thanks! Applied!

Lennart
--
Lennart Poettering, Red Hat
Christian Seiler
2015-01-27 14:19:51 UTC
Permalink
Just a heads-up: while reading the "Unwants" thread I noticed that
dependencies are the only types of lists in unit files that can't be
reset, so my example in there actually doesn't work, so please don't
commit my patch just now. I'm writing more examples and will resubmit
anyway.

Christian
Zbigniew Jędrzejewski-Szmek
2015-01-27 16:09:24 UTC
Permalink
Post by Christian Seiler
Just a heads-up: while reading the "Unwants" thread I noticed that
dependencies are the only types of lists in unit files that can't be
reset, so my example in there actually doesn't work, so please don't
commit my patch just now. I'm writing more examples and will resubmit
anyway.
So the thread is still on... Things are likely to change again.

Zbyszek
Dimitri John Ledkov
2015-01-23 14:13:17 UTC
Permalink
Post by Matthias Urlichs
Hi,
Post by Igor Bukanov
It is not clear from the systemd.unit manual page what happens when
foo.service.d/bar.conf sets an option like Service/ExecStartPre that
can be specified multiple times. From experimenting I see that *.conf
files supply additional values to the option and to overwrite or
remove already given values for the option one have to copy the whole
file into /etc and edit it there. Is it so?
Doesn't the manpage state that an empty entry clears the list?
A snippet:
[Unit]
Wants=

Does not remove want dependencies declared in the unit section in the
unit file under /usr.

/me continues my unwants ramblings.
--
Regards,

Dimitri.

Intel Corporation (UK) Ltd. - Co. Reg. #1134945 - Pipers Way, Swindon SN3 1RJ.
Matthias Urlichs
2015-01-23 14:30:25 UTC
Permalink
Hi,
Post by Dimitri John Ledkov
Post by Matthias Urlichs
Post by Igor Bukanov
foo.service.d/bar.conf sets an option like Service/ExecStartPre that
can be specified multiple times.
Doesn't the manpage state that an empty entry clears the list?
[Unit]
Wants=
Does not remove want dependencies declared in the unit section in the
unit file under /usr.
Meh. Obviously that works only for some unit file entries, not for others.

Time to impart more consistency?
--
-- Matthias Urlichs
Continue reading on narkive:
Loading...