Commit 74051b9b authored by Lennart Poettering's avatar Lennart Poettering

units: for all unit settings that take lists, allow the empty string for resetting the lists

https://bugzilla.redhat.com/show_bug.cgi?id=756787
parent 4b20075e
This diff is collapsed.
......@@ -130,13 +130,15 @@
specified. <varname>PathChanged=</varname>
may be used to watch a file or
directory and activate the configured
unit whenever it changes. It is not activated
on every write to the watched file but it is
activated if the file which was open for writing
gets closed. <varname>PathModified=</varname>
is similar, but additionally it is activated
also on simple writes to the watched file.
unit whenever it changes. It is not
activated on every write to the
watched file but it is activated if
the file which was open for writing
gets
closed. <varname>PathModified=</varname>
is similar, but additionally it is
activated also on simple writes to the
watched file.
<varname>DirectoryNotEmpty=</varname>
may be used to watch a directory and
activate the configured unit whenever
......@@ -148,7 +150,12 @@
<para>Multiple directives may be
combined, of the same and of different
types, to watch multiple paths.</para>
types, to watch multiple paths. If the
empty string is assigned to any of
these options the list of paths to
watch is reset, and any prior
assignments of these options will not
have any effect.</para>
<para>If a path is already existing
(in case of
......
......@@ -315,14 +315,18 @@
for compatibility with parsers
suitable for XDG
<filename>.desktop</filename> files.
The commands are invoked one by
one sequentially in the order they
appear in the unit file.
When <varname>Type</varname> is
not <option>oneshot</option>, only one
The commands are invoked one by one
sequentially in the order they appear
in the unit file. When
<varname>Type</varname> is not
<option>oneshot</option>, only one
command may be given. Lone semicolons
may be escaped as
'<literal>\;</literal>'.</para>
'<literal>\;</literal>'. 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.</para>
<para>Unless
<varname>Type=forking</varname> is
......@@ -338,23 +342,6 @@
line (i.e. the program to execute) may
not include specifiers.</para>
<para>Optionally, if the absolute file
name is prefixed with
'<literal>@</literal>', the second token
will be passed as
<literal>argv[0]</literal> to the
executed process, followed by the
further arguments specified. If the
absolute file name is prefixed with
'<literal>-</literal>' an exit code of
the command normally considered a
failure (i.e. non-zero exit status or
abnormal exit due to signal) is ignored
and considered success. If both
'<literal>-</literal>' and
'<literal>@</literal>' are used they
can appear in either order.</para>
<para>On top of that basic environment
variable substitution is
supported. Use
......@@ -376,6 +363,23 @@
literal and absolute path
name.</para>
<para>Optionally, if the absolute file
name is prefixed with
'<literal>@</literal>', the second token
will be passed as
<literal>argv[0]</literal> to the
executed process, followed by the
further arguments specified. If the
absolute file name is prefixed with
'<literal>-</literal>' an exit code of
the command normally considered a
failure (i.e. non-zero exit status or
abnormal exit due to signal) is ignored
and considered success. If both
'<literal>-</literal>' and
'<literal>@</literal>' are used they
can appear in either order.</para>
<para>Note that this setting does not
directly support shell command
lines. If shell command lines are to
......@@ -616,8 +620,14 @@
SIGKILL</literal>", ensures that exit
codes 1, 2, 8 and the termination
signal SIGKILL are considered clean
service
terminations.</para></listitem>
service terminations. This option may
appear more than once in which case
the list of successful exit statuses
is merged. If the empty string is
assigned to this option the list is
reset, all prior assignments of this
option will have no
effect.</para></listitem>
</varlistentry>
<varlistentry>
......@@ -638,9 +648,16 @@
logic. Example:
"<literal>RestartPreventExitStatus=1 6
SIGABRT</literal>", ensures that exit
codes 1 and 6 and the termination signal
SIGABRT will not result in automatic
service restarting.</para></listitem>
codes 1 and 6 and the termination
signal SIGABRT will not result in
automatic service restarting. This
option may appear more than once in
which case the list of restart preventing
statuses is merged. If the empty
string is assigned to this option the
list is reset, all prior assignments
of this option will have no
effect.</para></listitem>
</varlistentry>
<varlistentry>
......@@ -754,13 +771,22 @@
same time. Also note that a different
service may be activated on incoming
traffic than inherits the sockets. Or
in other words: The
in other words: the
<varname>Service=</varname> setting of
<filename>.socket</filename> units
doesn't have to match the inverse of the
<varname>Sockets=</varname> setting of
the <filename>.service</filename> it
refers to.</para></listitem>
doesn't have to match the inverse of
the <varname>Sockets=</varname>
setting of the
<filename>.service</filename> it
refers to.</para>
<para>This option may appear more than
once, in which case the list of socket
units is merged. If the empty string
is assigned to this option the list of
sockets is reset, all prior uses of
this setting will have no
effect.</para></listitem>
</varlistentry>
<varlistentry>
......
......@@ -205,19 +205,24 @@
<para>These options may be specified
more than once in which case incoming
traffic on any of the sockets will trigger
service activation, and all listed
sockets will be passed to the service,
regardless whether there is incoming
traffic on them or not.</para>
<para>If an IP address is used here, it
is often desirable to listen on it
traffic on any of the sockets will
trigger service activation, and all
listed sockets will be passed to the
service, regardless whether there is
incoming traffic on them or not. If
the empty string is assigned to any of
these options, the list of addresses
to listen on is reset, all prior uses
of any of these options will have no
effect.</para>
<para>If an IP address is used here,
it is often desirable to listen on it
before the interface it is configured
on is up and running, and even
regardless whether it will be up and
running ever at all. To deal with this it is
recommended to set the
running ever at all. To deal with this
it is recommended to set the
<varname>FreeBind=</varname> option
described below.</para></listitem>
</varlistentry>
......
......@@ -115,7 +115,7 @@
machine was booted
up. <varname>OnStartupSec=</varname>
defines a timer relative to when
systemd was
systemd was first
started. <varname>OnUnitActiveSec=</varname>
defines a timer relative to when the
unit the timer is activating was last
......@@ -157,7 +157,13 @@
<para>These are monotonic timers,
independent of wall-clock time and timezones. If the
computer is temporarily suspended, the
monotonic clock stops too.</para></listitem>
monotonic clock stops too.</para>
<para>If the empty string is assigned
to any of these options the list of
timers is reset, and all prior
assignments will have no
effect.</para></listitem>
</varlistentry>
......@@ -169,8 +175,10 @@
event expressions. See
<citerefentry><refentrytitle>systemd.time</refentrytitle><manvolnum>7</manvolnum></citerefentry>
for more information on the syntax of
calendar event
expressions.</para></listitem>
calendar event expressions. Otherwise
the semantics are similar to
<varname>OnActiveSec=</varname> and
related settings.</para></listitem>
</varlistentry>
<varlistentry>
......
......@@ -254,8 +254,13 @@
reference documentation that explains
what the unit's purpose is, followed
by how it is configured, followed by
any other related
documentation.</para></listitem>
any other related documentation. This
option may be specified more than once
in which case the specified list of
URIs is merged. If the empty string is
assigned to this option the list is
reset and all prior assignments will
have no effect.</para></listitem>
</varlistentry>
<varlistentry>
......@@ -907,8 +912,12 @@
pipe symbol must be passed first, the
exclamation second. Except for
<varname>ConditionPathIsSymbolicLink=</varname>,
all path checks follow
symlinks.</para></listitem>
all path checks follow symlinks. If
any of these options is assigned the
empty string the list of conditions is
reset completely, all previous
condition settings (of any kind) will
have no effect.</para></listitem>
</varlistentry>
<varlistentry>
......
......@@ -174,13 +174,13 @@ Service.FsckPassNo, config_parse_fsck_passno, 0,
EXEC_CONTEXT_CONFIG_ITEMS(Service)m4_dnl
KILL_CONTEXT_CONFIG_ITEMS(Service)m4_dnl
m4_dnl
Socket.ListenStream, config_parse_socket_listen, 0, 0
Socket.ListenDatagram, config_parse_socket_listen, 0, 0
Socket.ListenSequentialPacket, config_parse_socket_listen, 0, 0
Socket.ListenFIFO, config_parse_socket_listen, 0, 0
Socket.ListenNetlink, config_parse_socket_listen, 0, 0
Socket.ListenSpecial, config_parse_socket_listen, 0, 0
Socket.ListenMessageQueue, config_parse_socket_listen, 0, 0
Socket.ListenStream, config_parse_socket_listen, SOCKET_SOCKET, 0
Socket.ListenDatagram, config_parse_socket_listen, SOCKET_SOCKET, 0
Socket.ListenSequentialPacket, config_parse_socket_listen, SOCKET_SOCKET, 0
Socket.ListenFIFO, config_parse_socket_listen, SOCKET_FIFO, 0
Socket.ListenNetlink, config_parse_socket_listen, SOCKET_SOCKET, 0
Socket.ListenSpecial, config_parse_socket_listen, SOCKET_SPECIAL, 0
Socket.ListenMessageQueue, config_parse_socket_listen, SOCKET_MQUEUE, 0
Socket.BindIPv6Only, config_parse_socket_bind, 0, 0,
Socket.Backlog, config_parse_unsigned, 0, offsetof(Socket, backlog)
Socket.BindToDevice, config_parse_socket_bindtodevice, 0, 0
......
This diff is collapsed.
......@@ -248,22 +248,28 @@ static void path_init(Unit *u) {
p->directory_mode = 0755;
}
static void path_done(Unit *u) {
Path *p = PATH(u);
void path_free_specs(Path *p) {
PathSpec *s;
assert(p);
unit_ref_unset(&p->unit);
while ((s = p->specs)) {
path_spec_unwatch(s, u);
path_spec_unwatch(s, UNIT(p));
LIST_REMOVE(PathSpec, spec, p->specs, s);
path_spec_done(s);
free(s);
}
}
static void path_done(Unit *u) {
Path *p = PATH(u);
assert(p);
unit_ref_unset(&p->unit);
path_free_specs(p);
}
int path_add_one_mount_link(Path *p, Mount *m) {
PathSpec *s;
int r;
......
......@@ -98,6 +98,8 @@ void path_unit_notify(Unit *u, UnitActiveState new_state);
* any of the paths of this path object */
int path_add_one_mount_link(Path *p, Mount *m);
void path_free_specs(Path *p);
extern const UnitVTable path_vtable;
const char* path_state_to_string(PathState i);
......
......@@ -102,8 +102,7 @@ static void socket_unwatch_control_pid(Socket *s) {
s->control_pid = 0;
}
static void socket_done(Unit *u) {
Socket *s = SOCKET(u);
void socket_free_ports(Socket *s) {
SocketPort *p;
assert(s);
......@@ -119,6 +118,14 @@ static void socket_done(Unit *u) {
free(p->path);
free(p);
}
}
static void socket_done(Unit *u) {
Socket *s = SOCKET(u);
assert(s);
socket_free_ports(s);
exec_context_done(&s->exec_context);
exec_command_free_array(s->exec_command, _SOCKET_EXEC_COMMAND_MAX);
......
......@@ -163,6 +163,8 @@ int socket_add_one_mount_link(Socket *s, Mount *m);
/* Called from the service code when a per-connection service ended */
void socket_connection_unref(Socket *s);
void socket_free_ports(Socket *s);
extern const UnitVTable socket_vtable;
const char* socket_state_to_string(SocketState i);
......
......@@ -48,8 +48,7 @@ static void timer_init(Unit *u) {
watch_init(&t->realtime_watch);
}
static void timer_done(Unit *u) {
Timer *t = TIMER(u);
void timer_free_values(Timer *t) {
TimerValue *v;
assert(t);
......@@ -62,6 +61,14 @@ static void timer_done(Unit *u) {
free(v);
}
}
static void timer_done(Unit *u) {
Timer *t = TIMER(u);
assert(t);
timer_free_values(t);
unit_unwatch_timer(u, &t->monotonic_watch);
unit_unwatch_timer(u, &t->realtime_watch);
......
......@@ -84,6 +84,8 @@ struct Timer {
void timer_unit_notify(Unit *u, UnitActiveState new_state);
void timer_free_values(Timer *t);
extern const UnitVTable timer_vtable;
const char *timer_state_to_string(TimerState i);
......
......@@ -377,7 +377,8 @@ int config_parse_int(
assert(rvalue);
assert(data);
if ((r = safe_atoi(rvalue, i)) < 0) {
r = safe_atoi(rvalue, i);
if (r < 0) {
log_error("[%s:%u] Failed to parse numeric value, ingoring: %s", filename, line, rvalue);
return 0;
}
......@@ -403,7 +404,8 @@ int config_parse_long(
assert(rvalue);
assert(data);
if ((r = safe_atoli(rvalue, i)) < 0) {
r = safe_atoli(rvalue, i);
if (r < 0) {
log_error("[%s:%u] Failed to parse numeric value, ignoring: %s", filename, line, rvalue);
return 0;
}
......@@ -429,7 +431,8 @@ int config_parse_uint64(
assert(rvalue);
assert(data);
if ((r = safe_atou64(rvalue, u)) < 0) {
r = safe_atou64(rvalue, u);
if (r < 0) {
log_error("[%s:%u] Failed to parse numeric value, ignoring: %s", filename, line, rvalue);
return 0;
}
......@@ -455,7 +458,8 @@ int config_parse_unsigned(
assert(rvalue);
assert(data);
if ((r = safe_atou(rvalue, u)) < 0) {
r = safe_atou(rvalue, u);
if (r < 0) {
log_error("[%s:%u] Failed to parse numeric value: %s", filename, line, rvalue);
return r;
}
......@@ -595,7 +599,7 @@ int config_parse_string(
n = strdup(rvalue);
if (!n)
return -ENOMEM;
return log_oom();
if (!utf8_is_valid(n)) {
log_error("[%s:%u] String is not UTF-8 clean, ignoring assignment: %s", filename, line, rvalue);
......@@ -644,7 +648,7 @@ int config_parse_path(
n = strdup(rvalue);
if (!n)
return -ENOMEM;
return log_oom();
path_kill_slashes(n);
......@@ -677,13 +681,19 @@ int config_parse_strv(
assert(rvalue);
assert(data);
if (isempty(rvalue)) {
/* Empty assignment resets the list */
strv_free(*sv);
*sv = NULL;
}
k = strv_length(*sv);
FOREACH_WORD_QUOTED(w, l, rvalue, state)
k++;
n = new(char*, k+1);
if (!n)
return -ENOMEM;
return log_oom();
if (*sv)
for (k = 0; (*sv)[k]; k++)
......@@ -694,7 +704,7 @@ int config_parse_strv(
FOREACH_WORD_QUOTED(w, l, rvalue, state) {
n[k] = cunescape_length(w, l);
if (!n[k]) {
r = -ENOMEM;
r = log_oom();
goto fail;
}
......@@ -744,13 +754,19 @@ int config_parse_path_strv(
assert(rvalue);
assert(data);
if (isempty(rvalue)) {
/* Empty assignment resets the list */
strv_free(*sv);
*sv = NULL;
}
k = strv_length(*sv);
FOREACH_WORD_QUOTED(w, l, rvalue, state)
k++;
n = new(char*, k+1);
if (!n)
return -ENOMEM;
return log_oom();
k = 0;
if (*sv)
......@@ -760,7 +776,7 @@ int config_parse_path_strv(
FOREACH_WORD_QUOTED(w, l, rvalue, state) {
n[k] = strndup(w, l);
if (!n[k]) {
r = -ENOMEM;
r = log_oom();
goto fail;
}
......@@ -957,6 +973,16 @@ int config_parse_set_status(
assert(rvalue);
assert(data);
if (isempty(rvalue)) {
/* Empty assignment resets the list */
set_free(status_set->signal);
set_free(status_set->code);
status_set->signal = status_set->code = NULL;
return 0;
}
FOREACH_WORD(w, l, rvalue, state) {
int val;
char *temp;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment