mirror of
https://github.com/systemd/systemd
synced 2025-09-22 13:24:45 +02:00
Compare commits
20 Commits
87afd40b5a
...
9e12d5bf63
Author | SHA1 | Date | |
---|---|---|---|
![]() |
9e12d5bf63 | ||
![]() |
c28904dae0 | ||
![]() |
eff7c2d3c9 | ||
![]() |
7f3a5eb70e | ||
![]() |
fc58c0c7bf | ||
![]() |
c92391f52f | ||
![]() |
31b8895af7 | ||
![]() |
15d7ab87c4 | ||
![]() |
9c894b8579 | ||
![]() |
bce84e10f8 | ||
![]() |
babccf14ce | ||
![]() |
8f7b256665 | ||
![]() |
c39b7821f6 | ||
![]() |
4cb1015e6b | ||
![]() |
9321e23c40 | ||
![]() |
d8b065e056 | ||
![]() |
ae98f726ff | ||
![]() |
77102db288 | ||
![]() |
b8239b9c50 | ||
![]() |
26b8190841 |
@ -113,7 +113,7 @@ Here's the step-by-step guide:
|
||||
home directory temporarily and copy the data in.
|
||||
|
||||
```
|
||||
homectl with foobar -- rsync -aHAXv --delete-during /home/foobar.saved/ .
|
||||
homectl with foobar -- rsync -aHAXv --remove-source-files /home/foobar.saved/ .
|
||||
```
|
||||
|
||||
This mounts the home directory of the user, and then runs the specified
|
||||
@ -121,7 +121,7 @@ Here's the step-by-step guide:
|
||||
new. The new home directory is the working directory of the invoked `rsync`
|
||||
process. We are invoking this command as root, hence the `rsync` runs as
|
||||
root too. When the `rsync` command completes the home directory is
|
||||
automatically unmounted again. Since we used `--delete-during` all files
|
||||
automatically unmounted again. Since we used `--remove-source-files` all files
|
||||
copied are removed from the old home directory as the copy progresses. After
|
||||
the command completes the old home directory should be empty. Let's remove
|
||||
it hence:
|
||||
|
@ -132,6 +132,25 @@
|
||||
<para>
|
||||
<constant>SD_BUS_VTABLE_END</constant>
|
||||
</para>
|
||||
<para>
|
||||
<constant>SD_BUS_METHOD_WITH_ARGS_OFFSET(
|
||||
<replaceable>member</replaceable>,
|
||||
<replaceable>args</replaceable>,
|
||||
<replaceable>result</replaceable>,
|
||||
<replaceable>handler</replaceable>,
|
||||
<replaceable>offset</replaceable>,
|
||||
<replaceable>flags</replaceable>)
|
||||
</constant>
|
||||
</para>
|
||||
<para>
|
||||
<constant>SD_BUS_METHOD_WITH_ARGS(
|
||||
<replaceable>member</replaceable>,
|
||||
<replaceable>args</replaceable>,
|
||||
<replaceable>result</replaceable>,
|
||||
<replaceable>handler</replaceable>,
|
||||
<replaceable>flags</replaceable>)
|
||||
</constant>
|
||||
</para>
|
||||
<para>
|
||||
<constant>SD_BUS_METHOD_WITH_NAMES_OFFSET(
|
||||
<replaceable>member</replaceable>,
|
||||
@ -174,6 +193,13 @@
|
||||
<replaceable>flags</replaceable>)
|
||||
</constant>
|
||||
</para>
|
||||
<para>
|
||||
<constant>SD_BUS_SIGNAL_WITH_ARGS(
|
||||
<replaceable>member</replaceable>,
|
||||
<replaceable>args</replaceable>,
|
||||
<replaceable>flags</replaceable>)
|
||||
</constant>
|
||||
</para>
|
||||
<para>
|
||||
<constant>SD_BUS_SIGNAL_WITH_NAMES(
|
||||
<replaceable>member</replaceable>,
|
||||
@ -210,6 +236,10 @@
|
||||
</para>
|
||||
<para>
|
||||
<constant>SD_BUS_PARAM(<replaceable>name</replaceable>)</constant>
|
||||
<constant>SD_BUS_ARGS(<replaceable>...</replaceable>)</constant>
|
||||
<constant>SD_BUS_RESULT(<replaceable>...</replaceable>)</constant>
|
||||
<constant>SD_BUS_NO_ARGS</constant>
|
||||
<constant>SD_BUS_NO_RESULT</constant>
|
||||
</para>
|
||||
</funcsynopsis>
|
||||
</refsynopsisdiv>
|
||||
@ -315,6 +345,40 @@
|
||||
<listitem><para>Those must always be the first and last element.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><constant>SD_BUS_METHOD_WITH_ARGS_OFFSET()</constant></term>
|
||||
<term><constant>SD_BUS_METHOD_WITH_ARGS()</constant></term>
|
||||
|
||||
<listitem><para>Declare a D-Bus method with the name <replaceable>member</replaceable>,
|
||||
arguments <replaceable>args</replaceable> and result <replaceable>result</replaceable>.
|
||||
<replaceable>args</replaceable> expects a sequence of argument type/name pairs wrapped in the
|
||||
<constant>SD_BUS_ARGS()</constant> macro. The elements at even indices in this list describe the
|
||||
types of the method's arguments. The method's parameter signature is the concatenation of all the
|
||||
string literals at even indices in <replaceable>args</replaceable>. If a method has no parameters,
|
||||
pass <constant>SD_BUS_NO_ARGS</constant> to <replaceable>args</replaceable>. The elements at uneven
|
||||
indices describe the names of the method's arguments. <replaceable>result</replaceable> expects a
|
||||
sequence of type/name pairs wrapped in the <constant>SD_BUS_RESULT()</constant> macro in the same
|
||||
format as <constant>SD_BUS_ARGS()</constant>. The method's result signature is the concatenation of
|
||||
all the string literals at even indices in <replaceable>result</replaceable>. If a method has no
|
||||
result, pass <constant>SD_BUS_NO_RESULT</constant> to <replaceable>result</replaceable>. Note that
|
||||
argument types are expected to be quoted string literals and argument names are expected to be
|
||||
unquoted string literals. See below for a complete example.</para>
|
||||
|
||||
<para>The handler function <replaceable>handler</replaceable> must be of type
|
||||
<function>sd_bus_message_handler_t</function>. It will be called to handle the incoming messages
|
||||
that call this method. It receives a pointer that is the <replaceable>userdata</replaceable>
|
||||
parameter passed to the registration function offset by <replaceable>offset</replaceable> bytes.
|
||||
This may be used to pass pointers to different fields in the same data structure to different
|
||||
methods in the same vtable. To send a reply from <parameter>handler</parameter>, call
|
||||
<citerefentry><refentrytitle>sd_bus_reply_method_return</refentrytitle><manvolnum>3</manvolnum></citerefentry>
|
||||
with the message the callback was invoked with. Parameter <replaceable>flags</replaceable> is a
|
||||
combination of flags, see below.</para>
|
||||
|
||||
<constant>SD_BUS_METHOD_WITH_ARGS()</constant> is a shorthand for calling
|
||||
<constant>SD_BUS_METHOD_WITH_ARGS_OFFSET()</constant> with an offset of zero.
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><constant>SD_BUS_METHOD_WITH_NAMES_OFFSET()</constant></term>
|
||||
<term><constant>SD_BUS_METHOD_WITH_NAMES()</constant></term>
|
||||
@ -325,27 +389,37 @@
|
||||
parameter signature <replaceable>signature</replaceable>, result signature
|
||||
<replaceable>result</replaceable>. Parameters <replaceable>in_names</replaceable> and
|
||||
<replaceable>out_names</replaceable> specify the argument names of the input and output
|
||||
arguments in the function signature. The handler function
|
||||
<replaceable>handler</replaceable> must be of type
|
||||
<function>sd_bus_message_handler_t</function>. It will be called to handle the incoming
|
||||
messages that call this method. It receives a pointer that is the
|
||||
<replaceable>userdata</replaceable> parameter passed to the registration function offset
|
||||
by <replaceable>offset</replaceable> bytes. This may be used to pass pointers to different
|
||||
fields in the same data structure to different methods in the same vtable. To send a reply
|
||||
from <parameter>handler</parameter>, call
|
||||
<citerefentry><refentrytitle>sd_bus_reply_method_return</refentrytitle><manvolnum>3</manvolnum></citerefentry>
|
||||
with the message the callback was invoked with. <replaceable>in_names</replaceable> and
|
||||
arguments in the function signature. <replaceable>in_names</replaceable> and
|
||||
<replaceable>out_names</replaceable> should be created using the
|
||||
<constant>SD_BUS_PARAM()</constant> macro, see below. Parameter
|
||||
<replaceable>flags</replaceable> is a combination of flags, see below.</para>
|
||||
<constant>SD_BUS_PARAM()</constant> macro, see below. In all other regards, this macro behaves
|
||||
exactly the same as <constant>SD_BUS_METHOD_WITH_ARGS_OFFSET()</constant>.</para>
|
||||
|
||||
<para><constant>SD_BUS_METHOD_WITH_NAMES()</constant>,
|
||||
<constant>SD_BUS_METHOD_WITH_OFFSET()</constant>, and <constant>SD_BUS_METHOD()</constant>
|
||||
are variants which specify zero offset (<replaceable>userdata</replaceable> parameter is
|
||||
passed with no change), leave the names unset (i.e. no parameter names), or both.</para>
|
||||
|
||||
<para>Prefer using <constant>SD_BUS_METHOD_WITH_ARGS_OFFSET()</constant> and
|
||||
<constant>SD_BUS_METHOD_WITH_ARGS()</constant> over these macros as they allow specifying argument
|
||||
types and names next to each other which is less error-prone than first specifying all argument
|
||||
types followed by specifying all argument names.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><constant>SD_BUS_SIGNAL_WITH_ARGS()</constant></term>
|
||||
|
||||
<listitem><para>>Declare a D-Bus signal with the name <replaceable>member</replaceable> and
|
||||
arguments <replaceable>args</replaceable>. <replaceable>args</replaceable> expects a sequence of
|
||||
argument type/name pairs wrapped in the <constant>SD_BUS_ARGS()</constant> macro. The elements at
|
||||
even indices in this list describe the types of the signal's arguments. The signal's parameter
|
||||
signature is the concatenation of all the string literals at even indices in
|
||||
<replaceable>args</replaceable>. If a signal has no parameters, pass
|
||||
<constant>SD_BUS_NO_ARGS</constant> to <replaceable>args</replaceable>. The elements at uneven
|
||||
indices describe the names of the signal's arguments. Parameter <replaceable>flags</replaceable> is
|
||||
a combination of flags. See below for a complete example.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><constant>SD_BUS_SIGNAL_WITH_NAMES()</constant></term>
|
||||
<term><constant>SD_BUS_SIGNAL()</constant></term>
|
||||
@ -357,8 +431,13 @@
|
||||
Parameter <replaceable>flags</replaceable> is a combination of flags, see below.
|
||||
</para>
|
||||
|
||||
<para>Equivalent to <constant>SD_BUS_SIGNAL_WITH_NAMES()</constant> with the
|
||||
<replaceable>names</replaceable> parameter unset (i.e. no parameter names).</para>
|
||||
<para><constant>SD_BUS_SIGNAL()</constant> is equivalent to
|
||||
<constant>SD_BUS_SIGNAL_WITH_NAMES()</constant> with the <replaceable>names</replaceable> parameter
|
||||
unset (i.e. no parameter names).</para>
|
||||
|
||||
<para>Prefer using <constant>SD_BUS_SIGNAL_WITH_ARGS()</constant> over these macros as it allows
|
||||
specifying argument types and names next to each other which is less error-prone than first
|
||||
specifying all argument types followed by specifying all argument names.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
|
@ -753,6 +753,11 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err
|
||||
<row>
|
||||
<entry><literal>linked-runtime</literal></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><literal>alias</literal></entry>
|
||||
<entry>The name is an alias (symlink to another unit file).</entry>
|
||||
<entry>0</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><literal>masked</literal></entry>
|
||||
<entry morerows='1'>Completely disabled, so that any start operation on it fails (permanently in <filename>/etc/systemd/system/</filename> or transiently in <filename>/run/systemd/systemd/</filename>).</entry>
|
||||
|
@ -67,6 +67,13 @@
|
||||
<listitem><para>Sets the maximum number of simultaneous connections, defaults to 256.
|
||||
If the limit of concurrent connections is reached further connections will be refused.</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><option>--exit-idle-time=</option></term>
|
||||
|
||||
<listitem><para>Sets the time before exiting when there are no connections, defaults to
|
||||
<constant>infinity</constant>. Takes a unit-less value in seconds, or a time span value such
|
||||
as <literal>5min 20s</literal>.</para></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
<refsect1>
|
||||
@ -115,6 +122,9 @@ server {
|
||||
<programlisting><![CDATA[# systemctl enable --now proxy-to-nginx.socket
|
||||
$ curl http://localhost:80/]]></programlisting>
|
||||
</example>
|
||||
<para>If <filename>nginx.service</filename> has <varname>StopWhenUnneeded=</varname> set, then
|
||||
passing <option>--exit-idle-time=</option> to <command>systemd-socket-proxyd</command> allows
|
||||
both services to stop during idle periods.</para>
|
||||
</refsect2>
|
||||
<refsect2>
|
||||
<title>Namespace Example</title>
|
||||
|
@ -891,10 +891,11 @@ CapabilityBoundingSet=~CAP_B CAP_C</programlisting>
|
||||
<term><varname>ProtectSystem=</varname></term>
|
||||
|
||||
<listitem><para>Takes a boolean argument or the special values <literal>full</literal> or
|
||||
<literal>strict</literal>. If true, mounts the <filename>/usr</filename> and <filename>/boot</filename>
|
||||
directories read-only for processes invoked by this unit. If set to <literal>full</literal>, the
|
||||
<filename>/etc</filename> directory is mounted read-only, too. If set to <literal>strict</literal> the entire
|
||||
file system hierarchy is mounted read-only, except for the API file system subtrees <filename>/dev</filename>,
|
||||
<literal>strict</literal>. If true, mounts the <filename>/usr</filename> and the boot loader
|
||||
directories (<filename>/boot</filename> and <filename>/efi</filename>) read-only for processes
|
||||
invoked by this unit. If set to <literal>full</literal>, the <filename>/etc</filename> directory is
|
||||
mounted read-only, too. If set to <literal>strict</literal> the entire file system hierarchy is
|
||||
mounted read-only, except for the API file system subtrees <filename>/dev</filename>,
|
||||
<filename>/proc</filename> and <filename>/sys</filename> (protect these directories using
|
||||
<varname>PrivateDevices=</varname>, <varname>ProtectKernelTunables=</varname>,
|
||||
<varname>ProtectControlGroups=</varname>). This setting ensures that any modification of the vendor-supplied
|
||||
|
@ -27,6 +27,30 @@ static const sd_bus_vtable vtable[] = {
|
||||
"s", SD_BUS_PARAM(returnstring),
|
||||
method, offsetof(object, number),
|
||||
SD_BUS_VTABLE_DEPRECATED),
|
||||
SD_BUS_METHOD_WITH_ARGS_OFFSET(
|
||||
"Method3",
|
||||
SD_BUS_ARGS("s", string, "o", path),
|
||||
SD_BUS_RESULT("s", returnstring),
|
||||
method, offsetof(object, number),
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD_WITH_ARGS(
|
||||
"Method4",
|
||||
SD_BUS_NO_ARGS,
|
||||
SD_BUS_NO_RESULT,
|
||||
method,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_SIGNAL(
|
||||
"Signal1",
|
||||
"so",
|
||||
0),
|
||||
SD_BUS_SIGNAL_WITH_NAMES(
|
||||
"Signal2",
|
||||
"so", SD_BUS_PARAM(string) SD_BUS_PARAM(path),
|
||||
0),
|
||||
SD_BUS_SIGNAL_WITH_ARGS(
|
||||
"Signal3",
|
||||
SD_BUS_ARGS("s", string, "o", path),
|
||||
0),
|
||||
SD_BUS_WRITABLE_PROPERTY(
|
||||
"AutomaticStringProperty", "s", NULL, NULL,
|
||||
offsetof(object, name),
|
||||
|
@ -377,9 +377,6 @@ possible_cc_flags = [
|
||||
'-Wno-error=#warnings', # clang
|
||||
'-Wno-string-plus-int', # clang
|
||||
|
||||
# work-around for gcc 7.1 turning this on on its own.
|
||||
'-Wno-error=nonnull',
|
||||
|
||||
# Disable -Wmaybe-uninitialized, since it's noisy on gcc 8 with
|
||||
# optimizations enabled, producing essentially false positives.
|
||||
'-Wno-maybe-uninitialized',
|
||||
|
@ -4316,7 +4316,8 @@ int unit_get_unit_file_preset(Unit *u) {
|
||||
u->unit_file_preset = unit_file_query_preset(
|
||||
u->manager->unit_file_scope,
|
||||
NULL,
|
||||
basename(u->fragment_path));
|
||||
basename(u->fragment_path),
|
||||
NULL);
|
||||
|
||||
return u->unit_file_preset;
|
||||
}
|
||||
|
@ -1855,162 +1855,117 @@ static const sd_bus_vtable resolve_vtable[] = {
|
||||
SD_BUS_PROPERTY("DNSSECNegativeTrustAnchors", "as", bus_property_get_ntas, 0, 0),
|
||||
SD_BUS_PROPERTY("DNSStubListener", "s", bus_property_get_dns_stub_listener_mode, offsetof(Manager, dns_stub_listener_mode), 0),
|
||||
|
||||
SD_BUS_METHOD_WITH_NAMES("ResolveHostname",
|
||||
"isit",
|
||||
SD_BUS_PARAM(ifindex)
|
||||
SD_BUS_PARAM(name)
|
||||
SD_BUS_PARAM(family)
|
||||
SD_BUS_PARAM(flags),
|
||||
"a(iiay)st",
|
||||
SD_BUS_PARAM(addresses)
|
||||
SD_BUS_PARAM(canonical)
|
||||
SD_BUS_PARAM(flags),
|
||||
bus_method_resolve_hostname,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD_WITH_NAMES("ResolveAddress",
|
||||
"iiayt",
|
||||
SD_BUS_PARAM(ifindex)
|
||||
SD_BUS_PARAM(family)
|
||||
SD_BUS_PARAM(address)
|
||||
SD_BUS_PARAM(flags),
|
||||
"a(is)t",
|
||||
SD_BUS_PARAM(names)
|
||||
SD_BUS_PARAM(flags),
|
||||
bus_method_resolve_address,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD_WITH_NAMES("ResolveRecord",
|
||||
"isqqt",
|
||||
SD_BUS_PARAM(ifindex)
|
||||
SD_BUS_PARAM(name)
|
||||
SD_BUS_PARAM(class)
|
||||
SD_BUS_PARAM(type)
|
||||
SD_BUS_PARAM(flags),
|
||||
"a(iqqay)t",
|
||||
SD_BUS_PARAM(records)
|
||||
SD_BUS_PARAM(flags),
|
||||
bus_method_resolve_record,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD_WITH_NAMES("ResolveService",
|
||||
"isssit",
|
||||
SD_BUS_PARAM(ifindex)
|
||||
SD_BUS_PARAM(name)
|
||||
SD_BUS_PARAM(type)
|
||||
SD_BUS_PARAM(domain)
|
||||
SD_BUS_PARAM(family)
|
||||
SD_BUS_PARAM(flags),
|
||||
"a(qqqsa(iiay)s)aayssst",
|
||||
SD_BUS_PARAM(srv_data)
|
||||
SD_BUS_PARAM(txt_data)
|
||||
SD_BUS_PARAM(canonical_name)
|
||||
SD_BUS_PARAM(canonical_type)
|
||||
SD_BUS_PARAM(canonical_domain)
|
||||
SD_BUS_PARAM(flags),
|
||||
bus_method_resolve_service,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD_WITH_NAMES("GetLink",
|
||||
"i",
|
||||
SD_BUS_PARAM(ifindex),
|
||||
"o",
|
||||
SD_BUS_PARAM(path),
|
||||
bus_method_get_link,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD_WITH_NAMES("SetLinkDNS",
|
||||
"ia(iay)",
|
||||
SD_BUS_PARAM(ifindex)
|
||||
SD_BUS_PARAM(addresses),
|
||||
NULL,,
|
||||
bus_method_set_link_dns_servers,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD_WITH_NAMES("SetLinkDomains",
|
||||
"ia(sb)",
|
||||
SD_BUS_PARAM(ifindex)
|
||||
SD_BUS_PARAM(domains),
|
||||
NULL,,
|
||||
bus_method_set_link_domains,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD_WITH_NAMES("SetLinkDefaultRoute",
|
||||
"ib",
|
||||
SD_BUS_PARAM(ifindex)
|
||||
SD_BUS_PARAM(enable),
|
||||
NULL,,
|
||||
bus_method_set_link_default_route,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD_WITH_NAMES("SetLinkLLMNR",
|
||||
"is",
|
||||
SD_BUS_PARAM(ifindex)
|
||||
SD_BUS_PARAM(mode),
|
||||
NULL,,
|
||||
bus_method_set_link_llmnr,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD_WITH_NAMES("SetLinkMulticastDNS",
|
||||
"is",
|
||||
SD_BUS_PARAM(ifindex)
|
||||
SD_BUS_PARAM(mode),
|
||||
NULL,,
|
||||
bus_method_set_link_mdns,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD_WITH_NAMES("SetLinkDNSOverTLS",
|
||||
"is",
|
||||
SD_BUS_PARAM(ifindex)
|
||||
SD_BUS_PARAM(mode),
|
||||
NULL,,
|
||||
bus_method_set_link_dns_over_tls,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD_WITH_NAMES("SetLinkDNSSEC",
|
||||
"is",
|
||||
SD_BUS_PARAM(ifindex)
|
||||
SD_BUS_PARAM(mode),
|
||||
NULL,,
|
||||
bus_method_set_link_dnssec,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD_WITH_NAMES("SetLinkDNSSECNegativeTrustAnchors",
|
||||
"ias",
|
||||
SD_BUS_PARAM(ifindex)
|
||||
SD_BUS_PARAM(names),
|
||||
NULL,,
|
||||
bus_method_set_link_dnssec_negative_trust_anchors,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD_WITH_NAMES("RevertLink",
|
||||
"i",
|
||||
SD_BUS_PARAM(ifindex),
|
||||
NULL,,
|
||||
bus_method_revert_link,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD_WITH_NAMES("RegisterService",
|
||||
"sssqqqaa{say}",
|
||||
SD_BUS_PARAM(name)
|
||||
SD_BUS_PARAM(name_template)
|
||||
SD_BUS_PARAM(type)
|
||||
SD_BUS_PARAM(service_port)
|
||||
SD_BUS_PARAM(service_priority)
|
||||
SD_BUS_PARAM(serwise_weight)
|
||||
SD_BUS_PARAM(txt_datas),
|
||||
"o",
|
||||
SD_BUS_PARAM(service_path),
|
||||
bus_method_register_service,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD_WITH_NAMES("UnregisterService",
|
||||
"o",
|
||||
SD_BUS_PARAM(service_path),
|
||||
NULL,,
|
||||
bus_method_unregister_service,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
|
||||
SD_BUS_METHOD("ResetStatistics",
|
||||
NULL,
|
||||
NULL,
|
||||
bus_method_reset_statistics,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD("FlushCaches",
|
||||
NULL,
|
||||
NULL,
|
||||
bus_method_flush_caches,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD("ResetServerFeatures",
|
||||
NULL,
|
||||
NULL,
|
||||
bus_method_reset_server_features,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD_WITH_ARGS("ResolveHostname",
|
||||
SD_BUS_ARGS("i", ifindex, "s", name, "i", family, "t", flags),
|
||||
SD_BUS_RESULT("a(iiay)", addresses, "s", canonical, "t", flags),
|
||||
bus_method_resolve_hostname,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD_WITH_ARGS("ResolveAddress",
|
||||
SD_BUS_ARGS("i", ifindex, "i", family, "ay", address, "t", flags),
|
||||
SD_BUS_RESULT("a(is)", names, "t", flags),
|
||||
bus_method_resolve_address,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD_WITH_ARGS("ResolveRecord",
|
||||
SD_BUS_ARGS("i", ifindex, "s", name, "q", class, "q", type, "t", flags),
|
||||
SD_BUS_RESULT("a(iqqay)", records, "t", flags),
|
||||
bus_method_resolve_record,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD_WITH_ARGS("ResolveService",
|
||||
SD_BUS_ARGS("i", ifindex,
|
||||
"s", name,
|
||||
"s", type,
|
||||
"s", domain,
|
||||
"i", family,
|
||||
"t", flags),
|
||||
SD_BUS_RESULT("a(qqqsa(iiay)s)", srv_data,
|
||||
"aay", txt_data,
|
||||
"s", canonical_name,
|
||||
"s", canonical_type,
|
||||
"s", canonical_domain,
|
||||
"t", flags),
|
||||
bus_method_resolve_service,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD_WITH_ARGS("GetLink",
|
||||
SD_BUS_ARGS("i", ifindex),
|
||||
SD_BUS_RESULT("o", path),
|
||||
bus_method_get_link,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD_WITH_ARGS("SetLinkDNS",
|
||||
SD_BUS_ARGS("i", ifindex, "a(iay)", addresses),
|
||||
SD_BUS_NO_RESULT,
|
||||
bus_method_set_link_dns_servers,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD_WITH_ARGS("SetLinkDomains",
|
||||
SD_BUS_ARGS("i", ifindex, "a(sb)", domains),
|
||||
SD_BUS_NO_RESULT,
|
||||
bus_method_set_link_domains,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD_WITH_ARGS("SetLinkDefaultRoute",
|
||||
SD_BUS_ARGS("i", ifindex, "b", enable),
|
||||
SD_BUS_NO_RESULT,
|
||||
bus_method_set_link_default_route,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD_WITH_ARGS("SetLinkLLMNR",
|
||||
SD_BUS_ARGS("i", ifindex, "s", mode),
|
||||
SD_BUS_NO_RESULT,
|
||||
bus_method_set_link_llmnr,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD_WITH_ARGS("SetLinkMulticastDNS",
|
||||
SD_BUS_ARGS("i", ifindex, "s", mode),
|
||||
SD_BUS_NO_RESULT,
|
||||
bus_method_set_link_mdns,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD_WITH_ARGS("SetLinkDNSOverTLS",
|
||||
SD_BUS_ARGS("i", ifindex, "s", mode),
|
||||
SD_BUS_NO_RESULT,
|
||||
bus_method_set_link_dns_over_tls,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD_WITH_ARGS("SetLinkDNSSEC",
|
||||
SD_BUS_ARGS("i", ifindex, "s", mode),
|
||||
SD_BUS_NO_RESULT,
|
||||
bus_method_set_link_dnssec,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD_WITH_ARGS("SetLinkDNSSECNegativeTrustAnchors",
|
||||
SD_BUS_ARGS("i", ifindex, "as", names),
|
||||
SD_BUS_NO_RESULT,
|
||||
bus_method_set_link_dnssec_negative_trust_anchors,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD_WITH_ARGS("RevertLink",
|
||||
SD_BUS_ARGS("i", ifindex),
|
||||
SD_BUS_NO_RESULT,
|
||||
bus_method_revert_link,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD_WITH_ARGS("RegisterService",
|
||||
SD_BUS_ARGS("s", name,
|
||||
"s", name_template,
|
||||
"s", type,
|
||||
"q", service_port,
|
||||
"q", service_priority,
|
||||
"q", service_weight,
|
||||
"a{say}", txt_datas),
|
||||
SD_BUS_RESULT("o", service_path),
|
||||
bus_method_register_service,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD_WITH_ARGS("UnregisterService",
|
||||
SD_BUS_ARGS("o", service_path),
|
||||
SD_BUS_NO_RESULT,
|
||||
bus_method_unregister_service,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD_WITH_ARGS("ResetStatistics",
|
||||
SD_BUS_NO_ARGS,
|
||||
SD_BUS_NO_RESULT,
|
||||
bus_method_reset_statistics,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD_WITH_ARGS("FlushCaches",
|
||||
SD_BUS_NO_ARGS,
|
||||
SD_BUS_NO_RESULT,
|
||||
bus_method_flush_caches,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD_WITH_ARGS("ResetServerFeatures",
|
||||
SD_BUS_NO_ARGS,
|
||||
SD_BUS_NO_RESULT,
|
||||
bus_method_reset_server_features,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
|
||||
SD_BUS_VTABLE_END,
|
||||
};
|
||||
|
@ -697,56 +697,51 @@ const sd_bus_vtable link_vtable[] = {
|
||||
SD_BUS_PROPERTY("DNSSECNegativeTrustAnchors", "as", property_get_ntas, 0, 0),
|
||||
SD_BUS_PROPERTY("DNSSECSupported", "b", property_get_dnssec_supported, 0, 0),
|
||||
|
||||
SD_BUS_METHOD_WITH_NAMES("SetDNS",
|
||||
"a(iay)",
|
||||
SD_BUS_PARAM(addresses),
|
||||
NULL,,
|
||||
bus_link_method_set_dns_servers,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD_WITH_NAMES("SetDomains",
|
||||
"a(sb)",
|
||||
SD_BUS_PARAM(domains),
|
||||
NULL,,
|
||||
bus_link_method_set_domains,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD_WITH_NAMES("SetDefaultRoute",
|
||||
"b",
|
||||
SD_BUS_PARAM(enable),
|
||||
NULL,,
|
||||
bus_link_method_set_default_route,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD_WITH_NAMES("SetLLMNR",
|
||||
"s",
|
||||
SD_BUS_PARAM(mode),
|
||||
NULL,,
|
||||
bus_link_method_set_llmnr,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD_WITH_NAMES("SetMulticastDNS",
|
||||
"s",
|
||||
SD_BUS_PARAM(mode),
|
||||
NULL,,
|
||||
bus_link_method_set_mdns,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD_WITH_NAMES("SetDNSOverTLS",
|
||||
"s",
|
||||
SD_BUS_PARAM(mode),
|
||||
NULL,,
|
||||
bus_link_method_set_dns_over_tls,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD_WITH_NAMES("SetDNSSEC",
|
||||
"s",
|
||||
SD_BUS_PARAM(mode),
|
||||
NULL,,
|
||||
bus_link_method_set_dnssec,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD_WITH_NAMES("SetDNSSECNegativeTrustAnchors",
|
||||
"as",
|
||||
SD_BUS_PARAM(names),
|
||||
NULL,,
|
||||
bus_link_method_set_dnssec_negative_trust_anchors,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
|
||||
SD_BUS_METHOD("Revert", NULL, NULL, bus_link_method_revert, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD_WITH_ARGS("SetDNS",
|
||||
SD_BUS_ARGS("a(iay)", addresses),
|
||||
SD_BUS_NO_RESULT,
|
||||
bus_link_method_set_dns_servers,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD_WITH_ARGS("SetDomains",
|
||||
SD_BUS_ARGS("a(sb)", domains),
|
||||
SD_BUS_NO_RESULT,
|
||||
bus_link_method_set_domains,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD_WITH_ARGS("SetDefaultRoute",
|
||||
SD_BUS_ARGS("b", enable),
|
||||
SD_BUS_NO_RESULT,
|
||||
bus_link_method_set_default_route,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD_WITH_ARGS("SetLLMNR",
|
||||
SD_BUS_ARGS("s", mode),
|
||||
SD_BUS_NO_RESULT,
|
||||
bus_link_method_set_llmnr,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD_WITH_ARGS("SetMulticastDNS",
|
||||
SD_BUS_ARGS("s", mode),
|
||||
SD_BUS_NO_RESULT,
|
||||
bus_link_method_set_mdns,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD_WITH_ARGS("SetDNSOverTLS",
|
||||
SD_BUS_ARGS("s", mode),
|
||||
SD_BUS_NO_RESULT,
|
||||
bus_link_method_set_dns_over_tls,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD_WITH_ARGS("SetDNSSEC",
|
||||
SD_BUS_ARGS("s", mode),
|
||||
SD_BUS_NO_RESULT,
|
||||
bus_link_method_set_dnssec,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD_WITH_ARGS("SetDNSSECNegativeTrustAnchors",
|
||||
SD_BUS_ARGS("as", names),
|
||||
SD_BUS_NO_RESULT,
|
||||
bus_link_method_set_dnssec_negative_trust_anchors,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD_WITH_ARGS("Revert",
|
||||
SD_BUS_NO_ARGS,
|
||||
SD_BUS_NO_RESULT,
|
||||
bus_link_method_revert,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
|
||||
SD_BUS_VTABLE_END
|
||||
};
|
||||
|
@ -55,16 +55,11 @@ typedef enum {
|
||||
PRESET_DISABLE,
|
||||
} PresetAction;
|
||||
|
||||
typedef struct {
|
||||
struct UnitFilePresetRule {
|
||||
char *pattern;
|
||||
PresetAction action;
|
||||
char **instances;
|
||||
} PresetRule;
|
||||
|
||||
typedef struct {
|
||||
PresetRule *rules;
|
||||
size_t n_rules;
|
||||
} Presets;
|
||||
};
|
||||
|
||||
static bool unit_file_install_info_has_rules(const UnitFileInstallInfo *i) {
|
||||
assert(i);
|
||||
@ -80,7 +75,7 @@ static bool unit_file_install_info_has_also(const UnitFileInstallInfo *i) {
|
||||
return !strv_isempty(i->also);
|
||||
}
|
||||
|
||||
static void presets_freep(Presets *p) {
|
||||
void unit_file_presets_freep(UnitFilePresets *p) {
|
||||
size_t i;
|
||||
|
||||
if (!p)
|
||||
@ -1231,7 +1226,7 @@ static int unit_file_load(
|
||||
return -EINVAL;
|
||||
if (unit_name_is_valid(info->name, UNIT_NAME_TEMPLATE|UNIT_NAME_INSTANCE) && !unit_type_may_template(type))
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||
"Unit type %s cannot be templated.", unit_type_to_string(type));
|
||||
"%s: unit type %s cannot be templated, ignoring.", path, unit_type_to_string(type));
|
||||
|
||||
if (!(flags & SEARCH_LOAD)) {
|
||||
r = lstat(path, &st);
|
||||
@ -2772,6 +2767,12 @@ int unit_file_lookup_state(
|
||||
break;
|
||||
|
||||
case UNIT_FILE_TYPE_REGULAR:
|
||||
/* Check if the name we were querying is actually an alias */
|
||||
if (!streq(name, basename(i->path)) && !unit_name_is_valid(i->name, UNIT_NAME_INSTANCE)) {
|
||||
state = UNIT_FILE_ALIAS;
|
||||
break;
|
||||
}
|
||||
|
||||
r = path_is_generator(paths, i->path);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@ -2913,8 +2914,8 @@ static int presets_find_config(UnitFileScope scope, const char *root_dir, char *
|
||||
return conf_files_list_strv(files, ".preset", root_dir, 0, dirs);
|
||||
}
|
||||
|
||||
static int read_presets(UnitFileScope scope, const char *root_dir, Presets *presets) {
|
||||
_cleanup_(presets_freep) Presets ps = {};
|
||||
static int read_presets(UnitFileScope scope, const char *root_dir, UnitFilePresets *presets) {
|
||||
_cleanup_(unit_file_presets_freep) UnitFilePresets ps = {};
|
||||
size_t n_allocated = 0;
|
||||
_cleanup_strv_free_ char **files = NULL;
|
||||
char **p;
|
||||
@ -2942,7 +2943,7 @@ static int read_presets(UnitFileScope scope, const char *root_dir, Presets *pres
|
||||
|
||||
for (;;) {
|
||||
_cleanup_free_ char *line = NULL;
|
||||
PresetRule rule = {};
|
||||
UnitFilePresetRule rule = {};
|
||||
const char *parameter;
|
||||
char *l;
|
||||
|
||||
@ -2972,7 +2973,7 @@ static int read_presets(UnitFileScope scope, const char *root_dir, Presets *pres
|
||||
continue;
|
||||
}
|
||||
|
||||
rule = (PresetRule) {
|
||||
rule = (UnitFilePresetRule) {
|
||||
.pattern = unit_name,
|
||||
.action = PRESET_ENABLE,
|
||||
.instances = instances,
|
||||
@ -2987,7 +2988,7 @@ static int read_presets(UnitFileScope scope, const char *root_dir, Presets *pres
|
||||
if (!pattern)
|
||||
return -ENOMEM;
|
||||
|
||||
rule = (PresetRule) {
|
||||
rule = (UnitFilePresetRule) {
|
||||
.pattern = pattern,
|
||||
.action = PRESET_DISABLE,
|
||||
};
|
||||
@ -3005,14 +3006,15 @@ static int read_presets(UnitFileScope scope, const char *root_dir, Presets *pres
|
||||
}
|
||||
}
|
||||
|
||||
ps.initialized = true;
|
||||
*presets = ps;
|
||||
ps = (Presets){};
|
||||
ps = (UnitFilePresets){};
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pattern_match_multiple_instances(
|
||||
const PresetRule rule,
|
||||
const UnitFilePresetRule rule,
|
||||
const char *unit_name,
|
||||
char ***ret) {
|
||||
|
||||
@ -3066,17 +3068,17 @@ static int pattern_match_multiple_instances(
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int query_presets(const char *name, const Presets presets, char ***instance_name_list) {
|
||||
static int query_presets(const char *name, const UnitFilePresets *presets, char ***instance_name_list) {
|
||||
PresetAction action = PRESET_UNKNOWN;
|
||||
size_t i;
|
||||
char **s;
|
||||
if (!unit_name_is_valid(name, UNIT_NAME_ANY))
|
||||
return -EINVAL;
|
||||
|
||||
for (i = 0; i < presets.n_rules; i++)
|
||||
if (pattern_match_multiple_instances(presets.rules[i], name, instance_name_list) > 0 ||
|
||||
fnmatch(presets.rules[i].pattern, name, FNM_NOESCAPE) == 0) {
|
||||
action = presets.rules[i].action;
|
||||
for (i = 0; i < presets->n_rules; i++)
|
||||
if (pattern_match_multiple_instances(presets->rules[i], name, instance_name_list) > 0 ||
|
||||
fnmatch(presets->rules[i].pattern, name, FNM_NOESCAPE) == 0) {
|
||||
action = presets->rules[i].action;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -3099,15 +3101,19 @@ static int query_presets(const char *name, const Presets presets, char ***instan
|
||||
}
|
||||
}
|
||||
|
||||
int unit_file_query_preset(UnitFileScope scope, const char *root_dir, const char *name) {
|
||||
_cleanup_(presets_freep) Presets presets = {};
|
||||
int unit_file_query_preset(UnitFileScope scope, const char *root_dir, const char *name, UnitFilePresets *cached) {
|
||||
_cleanup_(unit_file_presets_freep) UnitFilePresets tmp = {};
|
||||
int r;
|
||||
|
||||
r = read_presets(scope, root_dir, &presets);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (!cached)
|
||||
cached = &tmp;
|
||||
if (!cached->initialized) {
|
||||
r = read_presets(scope, root_dir, cached);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
return query_presets(name, presets, NULL);
|
||||
return query_presets(name, cached, NULL);
|
||||
}
|
||||
|
||||
static int execute_preset(
|
||||
@ -3162,7 +3168,7 @@ static int preset_prepare_one(
|
||||
InstallContext *minus,
|
||||
LookupPaths *paths,
|
||||
const char *name,
|
||||
Presets presets,
|
||||
const UnitFilePresets *presets,
|
||||
UnitFileChange **changes,
|
||||
size_t *n_changes) {
|
||||
|
||||
@ -3221,7 +3227,7 @@ int unit_file_preset(
|
||||
|
||||
_cleanup_(install_context_done) InstallContext plus = {}, minus = {};
|
||||
_cleanup_(lookup_paths_free) LookupPaths paths = {};
|
||||
_cleanup_(presets_freep) Presets presets = {};
|
||||
_cleanup_(unit_file_presets_freep) UnitFilePresets presets = {};
|
||||
const char *config_path;
|
||||
char **i;
|
||||
int r;
|
||||
@ -3243,7 +3249,7 @@ int unit_file_preset(
|
||||
return r;
|
||||
|
||||
STRV_FOREACH(i, files) {
|
||||
r = preset_prepare_one(scope, &plus, &minus, &paths, *i, presets, changes, n_changes);
|
||||
r = preset_prepare_one(scope, &plus, &minus, &paths, *i, &presets, changes, n_changes);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
@ -3261,7 +3267,7 @@ int unit_file_preset_all(
|
||||
|
||||
_cleanup_(install_context_done) InstallContext plus = {}, minus = {};
|
||||
_cleanup_(lookup_paths_free) LookupPaths paths = {};
|
||||
_cleanup_(presets_freep) Presets presets = {};
|
||||
_cleanup_(unit_file_presets_freep) UnitFilePresets presets = {};
|
||||
const char *config_path = NULL;
|
||||
char **i;
|
||||
int r;
|
||||
@ -3305,7 +3311,7 @@ int unit_file_preset_all(
|
||||
continue;
|
||||
|
||||
/* we don't pass changes[] in, because we want to handle errors on our own */
|
||||
r = preset_prepare_one(scope, &plus, &minus, &paths, de->d_name, presets, NULL, 0);
|
||||
r = preset_prepare_one(scope, &plus, &minus, &paths, de->d_name, &presets, NULL, 0);
|
||||
if (r == -ERFKILL)
|
||||
r = unit_file_changes_add(changes, n_changes,
|
||||
UNIT_FILE_IS_MASKED, de->d_name, NULL);
|
||||
@ -3344,7 +3350,7 @@ int unit_file_get_list(
|
||||
char **patterns) {
|
||||
|
||||
_cleanup_(lookup_paths_free) LookupPaths paths = {};
|
||||
char **i;
|
||||
char **dirname;
|
||||
int r;
|
||||
|
||||
assert(scope >= 0);
|
||||
@ -3355,16 +3361,16 @@ int unit_file_get_list(
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
STRV_FOREACH(i, paths.search_path) {
|
||||
STRV_FOREACH(dirname, paths.search_path) {
|
||||
_cleanup_closedir_ DIR *d = NULL;
|
||||
struct dirent *de;
|
||||
|
||||
d = opendir(*i);
|
||||
d = opendir(*dirname);
|
||||
if (!d) {
|
||||
if (errno == ENOENT)
|
||||
continue;
|
||||
if (IN_SET(errno, ENOTDIR, EACCES)) {
|
||||
log_debug_errno(errno, "Failed to open \"%s\": %m", *i);
|
||||
log_debug_errno(errno, "Failed to open \"%s\": %m", *dirname);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -3392,7 +3398,7 @@ int unit_file_get_list(
|
||||
if (!f)
|
||||
return -ENOMEM;
|
||||
|
||||
f->path = path_make_absolute(de->d_name, *i);
|
||||
f->path = path_make_absolute(de->d_name, *dirname);
|
||||
if (!f->path)
|
||||
return -ENOMEM;
|
||||
|
||||
@ -3416,34 +3422,35 @@ int unit_file_get_list(
|
||||
}
|
||||
|
||||
static const char* const unit_file_state_table[_UNIT_FILE_STATE_MAX] = {
|
||||
[UNIT_FILE_ENABLED] = "enabled",
|
||||
[UNIT_FILE_ENABLED] = "enabled",
|
||||
[UNIT_FILE_ENABLED_RUNTIME] = "enabled-runtime",
|
||||
[UNIT_FILE_LINKED] = "linked",
|
||||
[UNIT_FILE_LINKED_RUNTIME] = "linked-runtime",
|
||||
[UNIT_FILE_MASKED] = "masked",
|
||||
[UNIT_FILE_MASKED_RUNTIME] = "masked-runtime",
|
||||
[UNIT_FILE_STATIC] = "static",
|
||||
[UNIT_FILE_DISABLED] = "disabled",
|
||||
[UNIT_FILE_INDIRECT] = "indirect",
|
||||
[UNIT_FILE_GENERATED] = "generated",
|
||||
[UNIT_FILE_TRANSIENT] = "transient",
|
||||
[UNIT_FILE_BAD] = "bad",
|
||||
[UNIT_FILE_LINKED] = "linked",
|
||||
[UNIT_FILE_LINKED_RUNTIME] = "linked-runtime",
|
||||
[UNIT_FILE_ALIAS] = "alias",
|
||||
[UNIT_FILE_MASKED] = "masked",
|
||||
[UNIT_FILE_MASKED_RUNTIME] = "masked-runtime",
|
||||
[UNIT_FILE_STATIC] = "static",
|
||||
[UNIT_FILE_DISABLED] = "disabled",
|
||||
[UNIT_FILE_INDIRECT] = "indirect",
|
||||
[UNIT_FILE_GENERATED] = "generated",
|
||||
[UNIT_FILE_TRANSIENT] = "transient",
|
||||
[UNIT_FILE_BAD] = "bad",
|
||||
};
|
||||
|
||||
DEFINE_STRING_TABLE_LOOKUP(unit_file_state, UnitFileState);
|
||||
|
||||
static const char* const unit_file_change_type_table[_UNIT_FILE_CHANGE_TYPE_MAX] = {
|
||||
[UNIT_FILE_SYMLINK] = "symlink",
|
||||
[UNIT_FILE_UNLINK] = "unlink",
|
||||
[UNIT_FILE_IS_MASKED] = "masked",
|
||||
[UNIT_FILE_SYMLINK] = "symlink",
|
||||
[UNIT_FILE_UNLINK] = "unlink",
|
||||
[UNIT_FILE_IS_MASKED] = "masked",
|
||||
[UNIT_FILE_IS_DANGLING] = "dangling",
|
||||
};
|
||||
|
||||
DEFINE_STRING_TABLE_LOOKUP(unit_file_change_type, UnitFileChangeType);
|
||||
|
||||
static const char* const unit_file_preset_mode_table[_UNIT_FILE_PRESET_MAX] = {
|
||||
[UNIT_FILE_PRESET_FULL] = "full",
|
||||
[UNIT_FILE_PRESET_ENABLE_ONLY] = "enable-only",
|
||||
[UNIT_FILE_PRESET_FULL] = "full",
|
||||
[UNIT_FILE_PRESET_ENABLE_ONLY] = "enable-only",
|
||||
[UNIT_FILE_PRESET_DISABLE_ONLY] = "disable-only",
|
||||
};
|
||||
|
||||
|
@ -189,7 +189,16 @@ void unit_file_dump_changes(int r, const char *verb, const UnitFileChange *chang
|
||||
|
||||
int unit_file_verify_alias(const UnitFileInstallInfo *i, const char *dst, char **ret_dst);
|
||||
|
||||
int unit_file_query_preset(UnitFileScope scope, const char *root_dir, const char *name);
|
||||
typedef struct UnitFilePresetRule UnitFilePresetRule;
|
||||
|
||||
typedef struct {
|
||||
UnitFilePresetRule *rules;
|
||||
size_t n_rules;
|
||||
bool initialized;
|
||||
} UnitFilePresets;
|
||||
|
||||
void unit_file_presets_freep(UnitFilePresets *p);
|
||||
int unit_file_query_preset(UnitFileScope scope, const char *root_dir, const char *name, UnitFilePresets *cached);
|
||||
|
||||
const char *unit_file_state_to_string(UnitFileState s) _const_;
|
||||
UnitFileState unit_file_state_from_string(const char *s) _pure_;
|
||||
|
@ -320,7 +320,7 @@ int unit_file_build_name_map(
|
||||
/* We don't explicitly check for alias loops here. unit_ids_map_get() which
|
||||
* limits the number of hops should be used to access the map. */
|
||||
|
||||
_cleanup_free_ char *target = NULL, *target_abs = NULL;
|
||||
_cleanup_free_ char *target = NULL;
|
||||
|
||||
r = readlinkat_malloc(dirfd(d), de->d_name, &target);
|
||||
if (r < 0) {
|
||||
@ -329,8 +329,9 @@ int unit_file_build_name_map(
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!path_is_absolute(target)) {
|
||||
target_abs = path_join(*dir, target);
|
||||
const bool is_abs = path_is_absolute(target);
|
||||
if (lp->root_dir || !is_abs) {
|
||||
char *target_abs = path_join(is_abs ? lp->root_dir : *dir, target);
|
||||
if (!target_abs)
|
||||
return log_oom();
|
||||
|
||||
|
@ -16,6 +16,7 @@ enum UnitFileState {
|
||||
UNIT_FILE_ENABLED_RUNTIME,
|
||||
UNIT_FILE_LINKED,
|
||||
UNIT_FILE_LINKED_RUNTIME,
|
||||
UNIT_FILE_ALIAS,
|
||||
UNIT_FILE_MASKED,
|
||||
UNIT_FILE_MASKED_RUNTIME,
|
||||
UNIT_FILE_STATIC,
|
||||
|
@ -45,10 +45,19 @@ bool running_in_chroot_or_offline(void) {
|
||||
return r > 0;
|
||||
}
|
||||
|
||||
const Verb* verbs_find_verb(const char *name, const Verb verbs[]) {
|
||||
for (size_t i = 0; verbs[i].dispatch; i++)
|
||||
if (streq_ptr(name, verbs[i].verb) ||
|
||||
(!name && FLAGS_SET(verbs[i].flags, VERB_DEFAULT)))
|
||||
return &verbs[i];
|
||||
|
||||
/* At the end of the list? */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int dispatch_verb(int argc, char *argv[], const Verb verbs[], void *userdata) {
|
||||
const Verb *verb;
|
||||
const char *name;
|
||||
unsigned i;
|
||||
int left;
|
||||
|
||||
assert(verbs);
|
||||
@ -62,31 +71,16 @@ int dispatch_verb(int argc, char *argv[], const Verb verbs[], void *userdata) {
|
||||
optind = 0;
|
||||
name = argv[0];
|
||||
|
||||
for (i = 0;; i++) {
|
||||
bool found;
|
||||
|
||||
/* At the end of the list? */
|
||||
if (!verbs[i].dispatch) {
|
||||
if (name)
|
||||
log_error("Unknown operation %s.", name);
|
||||
else
|
||||
log_error("Requires operation parameter.");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
verb = verbs_find_verb(name, verbs);
|
||||
if (!verb) {
|
||||
if (name)
|
||||
found = streq(name, verbs[i].verb);
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||
"Unknown command verb %s.", name);
|
||||
else
|
||||
found = verbs[i].flags & VERB_DEFAULT;
|
||||
|
||||
if (found) {
|
||||
verb = &verbs[i];
|
||||
break;
|
||||
}
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||
"Command verb required.");
|
||||
}
|
||||
|
||||
assert(verb);
|
||||
|
||||
if (!name)
|
||||
left = 1;
|
||||
|
||||
@ -101,10 +95,7 @@ int dispatch_verb(int argc, char *argv[], const Verb verbs[], void *userdata) {
|
||||
"Too many arguments.");
|
||||
|
||||
if ((verb->flags & VERB_ONLINE_ONLY) && running_in_chroot_or_offline()) {
|
||||
if (name)
|
||||
log_info("Running in chroot, ignoring request: %s", name);
|
||||
else
|
||||
log_info("Running in chroot, ignoring request.");
|
||||
log_info("Running in chroot, ignoring command '%s'", name ?: verb->verb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -6,8 +6,8 @@
|
||||
#define VERB_ANY ((unsigned) -1)
|
||||
|
||||
typedef enum VerbFlags {
|
||||
VERB_DEFAULT = 1 << 0,
|
||||
VERB_ONLINE_ONLY = 1 << 1,
|
||||
VERB_DEFAULT = 1 << 0, /* The verb to run if no verb is specified */
|
||||
VERB_ONLINE_ONLY = 1 << 1, /* Just do nothing when running in chroot or offline */
|
||||
} VerbFlags;
|
||||
|
||||
typedef struct {
|
||||
@ -19,4 +19,5 @@ typedef struct {
|
||||
|
||||
bool running_in_chroot_or_offline(void);
|
||||
|
||||
const Verb* verbs_find_verb(const char *name, const Verb verbs[]);
|
||||
int dispatch_verb(int argc, char *argv[], const Verb verbs[], void *userdata);
|
||||
|
@ -31,10 +31,12 @@
|
||||
|
||||
static unsigned arg_connections_max = 256;
|
||||
static const char *arg_remote_host = NULL;
|
||||
static usec_t arg_exit_idle_time = USEC_INFINITY;
|
||||
|
||||
typedef struct Context {
|
||||
sd_event *event;
|
||||
sd_resolve *resolve;
|
||||
sd_event_source *idle_time;
|
||||
|
||||
Set *listen;
|
||||
Set *connections;
|
||||
@ -75,6 +77,51 @@ static void connection_free(Connection *c) {
|
||||
free(c);
|
||||
}
|
||||
|
||||
static int idle_time_cb(sd_event_source *s, uint64_t usec, void *userdata) {
|
||||
Context *c = userdata;
|
||||
int r;
|
||||
|
||||
if (!set_isempty(c->connections)) {
|
||||
log_warning("Idle timer fired even though there are connections, ignoring");
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = sd_event_exit(c->event, 0);
|
||||
if (r < 0) {
|
||||
log_warning_errno(r, "Error while stopping event loop, ignoring: %m");
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int connection_release(Connection *c) {
|
||||
int r;
|
||||
Context *context = c->context;
|
||||
usec_t idle_instant;
|
||||
|
||||
connection_free(c);
|
||||
|
||||
if (arg_exit_idle_time < USEC_INFINITY && set_isempty(context->connections)) {
|
||||
idle_instant = usec_add(now(CLOCK_MONOTONIC), arg_exit_idle_time);
|
||||
if (context->idle_time) {
|
||||
r = sd_event_source_set_time(context->idle_time, idle_instant);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Error while setting idle time: %m");
|
||||
|
||||
r = sd_event_source_set_enabled(context->idle_time, SD_EVENT_ONESHOT);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Error while enabling idle time: %m");
|
||||
} else {
|
||||
r = sd_event_add_time(context->event, &context->idle_time, CLOCK_MONOTONIC,
|
||||
idle_instant, 0, idle_time_cb, context);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to create idle timer: %m");
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void context_clear(Context *context) {
|
||||
assert(context);
|
||||
|
||||
@ -83,6 +130,7 @@ static void context_clear(Context *context) {
|
||||
|
||||
sd_event_unref(context->event);
|
||||
sd_resolve_unref(context->resolve);
|
||||
sd_event_source_unref(context->idle_time);
|
||||
}
|
||||
|
||||
static int connection_create_pipes(Connection *c, int buffer[static 2], size_t *sz) {
|
||||
@ -206,7 +254,7 @@ static int traffic_cb(sd_event_source *s, int fd, uint32_t revents, void *userda
|
||||
return 1;
|
||||
|
||||
quit:
|
||||
connection_free(c);
|
||||
connection_release(c);
|
||||
return 0; /* ignore errors, continue serving */
|
||||
}
|
||||
|
||||
@ -269,7 +317,7 @@ static int connection_complete(Connection *c) {
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
connection_free(c);
|
||||
connection_release(c);
|
||||
return 0; /* ignore errors, continue serving */
|
||||
}
|
||||
|
||||
@ -299,7 +347,7 @@ static int connect_cb(sd_event_source *s, int fd, uint32_t revents, void *userda
|
||||
return connection_complete(c);
|
||||
|
||||
fail:
|
||||
connection_free(c);
|
||||
connection_release(c);
|
||||
return 0; /* ignore errors, continue serving */
|
||||
}
|
||||
|
||||
@ -343,7 +391,7 @@ static int connection_start(Connection *c, struct sockaddr *sa, socklen_t salen)
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
connection_free(c);
|
||||
connection_release(c);
|
||||
return 0; /* ignore errors, continue serving */
|
||||
}
|
||||
|
||||
@ -361,7 +409,7 @@ static int resolve_handler(sd_resolve_query *q, int ret, const struct addrinfo *
|
||||
return connection_start(c, ai->ai_addr, ai->ai_addrlen);
|
||||
|
||||
fail:
|
||||
connection_free(c);
|
||||
connection_release(c);
|
||||
return 0; /* ignore errors, continue serving */
|
||||
}
|
||||
|
||||
@ -409,7 +457,7 @@ static int resolve_remote(Connection *c) {
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
connection_free(c);
|
||||
connection_release(c);
|
||||
return 0; /* ignore errors, continue serving */
|
||||
}
|
||||
|
||||
@ -426,6 +474,12 @@ static int add_connection_socket(Context *context, int fd) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (context->idle_time) {
|
||||
r = sd_event_source_set_enabled(context->idle_time, SD_EVENT_OFF);
|
||||
if (r < 0)
|
||||
log_warning_errno(r, "Unable to disable idle timer, continuing: %m");
|
||||
}
|
||||
|
||||
r = set_ensure_allocated(&context->connections, NULL);
|
||||
if (r < 0) {
|
||||
log_oom();
|
||||
@ -535,9 +589,13 @@ static int add_listen_socket(Context *context, int fd) {
|
||||
|
||||
static int help(void) {
|
||||
_cleanup_free_ char *link = NULL;
|
||||
_cleanup_free_ char *time_link = NULL;
|
||||
int r;
|
||||
|
||||
r = terminal_urlify_man("systemd-socket-proxyd", "8", &link);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
r = terminal_urlify_man("systemd.time", "7", &time_link);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
@ -545,11 +603,14 @@ static int help(void) {
|
||||
"%1$s [SOCKET]\n\n"
|
||||
"Bidirectionally proxy local sockets to another (possibly remote) socket.\n\n"
|
||||
" -c --connections-max= Set the maximum number of connections to be accepted\n"
|
||||
" --exit-idle-time= Exit when without a connection for this duration. See\n"
|
||||
" the %3$s for time span format\n"
|
||||
" -h --help Show this help\n"
|
||||
" --version Show package version\n"
|
||||
"\nSee the %2$s for details.\n"
|
||||
, program_invocation_short_name
|
||||
, link
|
||||
, time_link
|
||||
);
|
||||
|
||||
return 0;
|
||||
@ -559,11 +620,13 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
|
||||
enum {
|
||||
ARG_VERSION = 0x100,
|
||||
ARG_EXIT_IDLE,
|
||||
ARG_IGNORE_ENV
|
||||
};
|
||||
|
||||
static const struct option options[] = {
|
||||
{ "connections-max", required_argument, NULL, 'c' },
|
||||
{ "exit-idle-time", required_argument, NULL, ARG_EXIT_IDLE },
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{ "version", no_argument, NULL, ARG_VERSION },
|
||||
{}
|
||||
@ -597,6 +660,12 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
|
||||
break;
|
||||
|
||||
case ARG_EXIT_IDLE:
|
||||
r = parse_sec(optarg, &arg_exit_idle_time);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to parse --exit-idle-time= argument: %s", optarg);
|
||||
break;
|
||||
|
||||
case '?':
|
||||
return -EINVAL;
|
||||
|
||||
|
@ -1456,9 +1456,18 @@ static bool output_show_unit_file(const UnitFileList *u, char **states, char **p
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool show_preset_for_state(UnitFileState state) {
|
||||
/* Don't show preset state in those unit file states, it'll only confuse users. */
|
||||
return !IN_SET(state,
|
||||
UNIT_FILE_ALIAS,
|
||||
UNIT_FILE_STATIC,
|
||||
UNIT_FILE_GENERATED,
|
||||
UNIT_FILE_TRANSIENT);
|
||||
}
|
||||
|
||||
static int output_unit_file_list(const UnitFileList *units, unsigned c) {
|
||||
_cleanup_(table_unrefp) Table *table = NULL;
|
||||
const UnitFileList *u;
|
||||
_cleanup_(unit_file_presets_freep) UnitFilePresets presets = {};
|
||||
int r;
|
||||
|
||||
table = table_new("unit file", "state", "vendor preset");
|
||||
@ -1469,9 +1478,8 @@ static int output_unit_file_list(const UnitFileList *units, unsigned c) {
|
||||
if (arg_full)
|
||||
table_set_width(table, 0);
|
||||
|
||||
for (u = units; u < units + c; u++) {
|
||||
for (const UnitFileList *u = units; u < units + c; u++) {
|
||||
const char *on_underline = NULL, *on_unit_color = NULL, *id;
|
||||
const char *on_preset_color = NULL, *unit_preset_str;
|
||||
bool underline;
|
||||
|
||||
underline = u + 1 < units + c &&
|
||||
@ -1486,32 +1494,44 @@ static int output_unit_file_list(const UnitFileList *units, unsigned c) {
|
||||
UNIT_FILE_DISABLED,
|
||||
UNIT_FILE_BAD))
|
||||
on_unit_color = underline ? ansi_highlight_red_underline() : ansi_highlight_red();
|
||||
else if (u->state == UNIT_FILE_ENABLED)
|
||||
else if (IN_SET(u->state,
|
||||
UNIT_FILE_ENABLED,
|
||||
UNIT_FILE_ALIAS))
|
||||
on_unit_color = underline ? ansi_highlight_green_underline() : ansi_highlight_green();
|
||||
else
|
||||
on_unit_color = on_underline;
|
||||
|
||||
id = basename(u->path);
|
||||
|
||||
r = unit_file_query_preset(arg_scope, NULL, id);
|
||||
if (r < 0) {
|
||||
unit_preset_str = "n/a";
|
||||
on_preset_color = underline ? on_underline : ansi_normal();
|
||||
} else if (r == 0) {
|
||||
unit_preset_str = "disabled";
|
||||
on_preset_color = underline ? ansi_highlight_red_underline() : ansi_highlight_red();
|
||||
} else {
|
||||
unit_preset_str = "enabled";
|
||||
on_preset_color = underline ? ansi_highlight_green_underline() : ansi_highlight_green();
|
||||
}
|
||||
|
||||
r = table_add_many(table,
|
||||
TABLE_STRING, id,
|
||||
TABLE_SET_COLOR, strempty(on_underline),
|
||||
TABLE_STRING, unit_file_state_to_string(u->state),
|
||||
TABLE_SET_COLOR, strempty(on_unit_color),
|
||||
TABLE_STRING, unit_preset_str,
|
||||
TABLE_SET_COLOR, strempty(on_preset_color));
|
||||
TABLE_SET_COLOR, strempty(on_unit_color));
|
||||
if (r < 0)
|
||||
return table_log_add_error(r);
|
||||
|
||||
if (show_preset_for_state(u->state)) {
|
||||
const char *unit_preset_str, *on_preset_color;
|
||||
|
||||
r = unit_file_query_preset(arg_scope, arg_root, id, &presets);
|
||||
if (r < 0) {
|
||||
unit_preset_str = "n/a";
|
||||
on_preset_color = underline ? on_underline : ansi_normal();
|
||||
} else if (r == 0) {
|
||||
unit_preset_str = "disabled";
|
||||
on_preset_color = underline ? ansi_highlight_red_underline() : ansi_highlight_red();
|
||||
} else {
|
||||
unit_preset_str = "enabled";
|
||||
on_preset_color = underline ? ansi_highlight_green_underline() : ansi_highlight_green();
|
||||
}
|
||||
|
||||
r = table_add_many(table,
|
||||
TABLE_STRING, unit_preset_str,
|
||||
TABLE_SET_COLOR, strempty(on_preset_color));
|
||||
} else
|
||||
r = table_add_many(table, TABLE_EMPTY);
|
||||
|
||||
if (r < 0)
|
||||
return table_log_add_error(r);
|
||||
}
|
||||
@ -4246,14 +4266,18 @@ static void print_status_info(
|
||||
if (!isempty(i->load_error))
|
||||
printf(" Loaded: %s%s%s (Reason: %s)\n",
|
||||
on, strna(i->load_state), off, i->load_error);
|
||||
else if (path && !isempty(i->unit_file_state) && !isempty(i->unit_file_preset) &&
|
||||
!STR_IN_SET(i->unit_file_state, "generated", "transient"))
|
||||
printf(" Loaded: %s%s%s (%s; %s; vendor preset: %s)\n",
|
||||
on, strna(i->load_state), off, path, i->unit_file_state, i->unit_file_preset);
|
||||
else if (path && !isempty(i->unit_file_state))
|
||||
printf(" Loaded: %s%s%s (%s; %s)\n",
|
||||
on, strna(i->load_state), off, path, i->unit_file_state);
|
||||
else if (path)
|
||||
else if (path && !isempty(i->unit_file_state)) {
|
||||
bool show_preset = !isempty(i->unit_file_preset) &&
|
||||
show_preset_for_state(unit_file_state_from_string(i->unit_file_state));
|
||||
|
||||
printf(" Loaded: %s%s%s (%s; %s%s%s)\n",
|
||||
on, strna(i->load_state), off,
|
||||
path,
|
||||
i->unit_file_state,
|
||||
show_preset ? "; vendor preset: " : "",
|
||||
show_preset ? i->unit_file_preset : "");
|
||||
|
||||
} else if (path)
|
||||
printf(" Loaded: %s%s%s (%s)\n",
|
||||
on, strna(i->load_state), off, path);
|
||||
else
|
||||
@ -5892,7 +5916,8 @@ static int show(int argc, char *argv[], void *userdata) {
|
||||
|
||||
if (show_mode == SYSTEMCTL_SHOW_HELP && argc <= 1)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||
"This command expects one or more unit names. Did you mean --help?");
|
||||
"'help' command expects one or more unit names.\n"
|
||||
"(Alternatively, help for systemctl itself may be shown with --help)");
|
||||
|
||||
r = acquire_bus(BUS_MANAGER, &bus);
|
||||
if (r < 0)
|
||||
@ -7367,6 +7392,7 @@ static int unit_is_enabled(int argc, char *argv[], void *userdata) {
|
||||
UNIT_FILE_ENABLED,
|
||||
UNIT_FILE_ENABLED_RUNTIME,
|
||||
UNIT_FILE_STATIC,
|
||||
UNIT_FILE_ALIAS,
|
||||
UNIT_FILE_INDIRECT,
|
||||
UNIT_FILE_GENERATED))
|
||||
enabled = true;
|
||||
@ -9211,9 +9237,9 @@ static int systemctl_main(int argc, char *argv[]) {
|
||||
{ "help", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, show },
|
||||
{ "daemon-reload", VERB_ANY, 1, VERB_ONLINE_ONLY, daemon_reload },
|
||||
{ "daemon-reexec", VERB_ANY, 1, VERB_ONLINE_ONLY, daemon_reload },
|
||||
{ "log-level", VERB_ANY, 2, 0, log_level },
|
||||
{ "log-target", VERB_ANY, 2, 0, log_target },
|
||||
{ "service-watchdogs", VERB_ANY, 2, 0, service_watchdogs },
|
||||
{ "log-level", VERB_ANY, 2, VERB_ONLINE_ONLY, log_level },
|
||||
{ "log-target", VERB_ANY, 2, VERB_ONLINE_ONLY, log_target },
|
||||
{ "service-watchdogs", VERB_ANY, 2, VERB_ONLINE_ONLY, service_watchdogs },
|
||||
{ "show-environment", VERB_ANY, 1, VERB_ONLINE_ONLY, show_environment },
|
||||
{ "set-environment", 2, VERB_ANY, VERB_ONLINE_ONLY, set_environment },
|
||||
{ "unset-environment", 2, VERB_ANY, VERB_ONLINE_ONLY, set_environment },
|
||||
@ -9253,6 +9279,12 @@ static int systemctl_main(int argc, char *argv[]) {
|
||||
{}
|
||||
};
|
||||
|
||||
const Verb *verb = verbs_find_verb(argv[optind], verbs);
|
||||
if (verb && (verb->flags & VERB_ONLINE_ONLY) && arg_root)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||
"Verb '%s' cannot be used with --root=.",
|
||||
argv[optind] ?: verb->verb);
|
||||
|
||||
return dispatch_verb(argc, argv, verbs, NULL);
|
||||
}
|
||||
|
||||
|
@ -187,6 +187,124 @@ struct sd_bus_vtable {
|
||||
.x = { { 0 } }, \
|
||||
}
|
||||
|
||||
#define _SD_ECHO(X) X
|
||||
#define _SD_CONCAT(X) #X "\0"
|
||||
|
||||
#define _SD_VARARGS_FOREACH_EVEN_01(FN, X, ...)
|
||||
#define _SD_VARARGS_FOREACH_EVEN_02(FN, X, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_01(FN, __VA_ARGS__)
|
||||
#define _SD_VARARGS_FOREACH_EVEN_03(FN, X, ...) _SD_VARARGS_FOREACH_EVEN_02(FN, __VA_ARGS__)
|
||||
#define _SD_VARARGS_FOREACH_EVEN_04(FN, X, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_03(FN, __VA_ARGS__)
|
||||
#define _SD_VARARGS_FOREACH_EVEN_05(FN, X, ...) _SD_VARARGS_FOREACH_EVEN_04(FN, __VA_ARGS__)
|
||||
#define _SD_VARARGS_FOREACH_EVEN_06(FN, X, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_05(FN, __VA_ARGS__)
|
||||
#define _SD_VARARGS_FOREACH_EVEN_07(FN, X, ...) _SD_VARARGS_FOREACH_EVEN_06(FN, __VA_ARGS__)
|
||||
#define _SD_VARARGS_FOREACH_EVEN_08(FN, X, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_07(FN, __VA_ARGS__)
|
||||
#define _SD_VARARGS_FOREACH_EVEN_09(FN, X, ...) _SD_VARARGS_FOREACH_EVEN_08(FN, __VA_ARGS__)
|
||||
#define _SD_VARARGS_FOREACH_EVEN_10(FN, X, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_09(FN, __VA_ARGS__)
|
||||
#define _SD_VARARGS_FOREACH_EVEN_11(FN, X, ...) _SD_VARARGS_FOREACH_EVEN_10(FN, __VA_ARGS__)
|
||||
#define _SD_VARARGS_FOREACH_EVEN_12(FN, X, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_11(FN, __VA_ARGS__)
|
||||
#define _SD_VARARGS_FOREACH_EVEN_13(FN, X, ...) _SD_VARARGS_FOREACH_EVEN_12(FN, __VA_ARGS__)
|
||||
#define _SD_VARARGS_FOREACH_EVEN_14(FN, X, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_13(FN, __VA_ARGS__)
|
||||
#define _SD_VARARGS_FOREACH_EVEN_15(FN, X, ...) _SD_VARARGS_FOREACH_EVEN_14(FN, __VA_ARGS__)
|
||||
#define _SD_VARARGS_FOREACH_EVEN_16(FN, X, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_15(FN, __VA_ARGS__)
|
||||
#define _SD_VARARGS_FOREACH_EVEN_17(FN, X, ...) _SD_VARARGS_FOREACH_EVEN_16(FN, __VA_ARGS__)
|
||||
#define _SD_VARARGS_FOREACH_EVEN_18(FN, X, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_17(FN, __VA_ARGS__)
|
||||
#define _SD_VARARGS_FOREACH_EVEN_19(FN, X, ...) _SD_VARARGS_FOREACH_EVEN_18(FN, __VA_ARGS__)
|
||||
#define _SD_VARARGS_FOREACH_EVEN_20(FN, X, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_19(FN, __VA_ARGS__)
|
||||
#define _SD_VARARGS_FOREACH_EVEN_21(FN, X, ...) _SD_VARARGS_FOREACH_EVEN_20(FN, __VA_ARGS__)
|
||||
#define _SD_VARARGS_FOREACH_EVEN_22(FN, X, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_21(FN, __VA_ARGS__)
|
||||
#define _SD_VARARGS_FOREACH_EVEN_23(FN, X, ...) _SD_VARARGS_FOREACH_EVEN_22(FN, __VA_ARGS__)
|
||||
#define _SD_VARARGS_FOREACH_EVEN_24(FN, X, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_23(FN, __VA_ARGS__)
|
||||
#define _SD_VARARGS_FOREACH_EVEN_25(FN, X, ...) _SD_VARARGS_FOREACH_EVEN_24(FN, __VA_ARGS__)
|
||||
#define _SD_VARARGS_FOREACH_EVEN_26(FN, X, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_25(FN, __VA_ARGS__)
|
||||
#define _SD_VARARGS_FOREACH_EVEN_27(FN, X, ...) _SD_VARARGS_FOREACH_EVEN_26(FN, __VA_ARGS__)
|
||||
#define _SD_VARARGS_FOREACH_EVEN_28(FN, X, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_27(FN, __VA_ARGS__)
|
||||
#define _SD_VARARGS_FOREACH_EVEN_29(FN, X, ...) _SD_VARARGS_FOREACH_EVEN_28(FN, __VA_ARGS__)
|
||||
#define _SD_VARARGS_FOREACH_EVEN_30(FN, X, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_29(FN, __VA_ARGS__)
|
||||
#define _SD_VARARGS_FOREACH_EVEN_31(FN, X, ...) _SD_VARARGS_FOREACH_EVEN_30(FN, __VA_ARGS__)
|
||||
#define _SD_VARARGS_FOREACH_EVEN_32(FN, X, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_31(FN, __VA_ARGS__)
|
||||
#define _SD_VARARGS_FOREACH_EVEN_33(FN, X, ...) _SD_VARARGS_FOREACH_EVEN_32(FN, __VA_ARGS__)
|
||||
#define _SD_VARARGS_FOREACH_EVEN_34(FN, X, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_33(FN, __VA_ARGS__)
|
||||
#define _SD_VARARGS_FOREACH_EVEN_35(FN, X, ...) _SD_VARARGS_FOREACH_EVEN_34(FN, __VA_ARGS__)
|
||||
#define _SD_VARARGS_FOREACH_EVEN_36(FN, X, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_35(FN, __VA_ARGS__)
|
||||
#define _SD_VARARGS_FOREACH_EVEN_37(FN, X, ...) _SD_VARARGS_FOREACH_EVEN_36(FN, __VA_ARGS__)
|
||||
#define _SD_VARARGS_FOREACH_EVEN_38(FN, X, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_37(FN, __VA_ARGS__)
|
||||
#define _SD_VARARGS_FOREACH_EVEN_39(FN, X, ...) _SD_VARARGS_FOREACH_EVEN_38(FN, __VA_ARGS__)
|
||||
#define _SD_VARARGS_FOREACH_EVEN_40(FN, X, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_39(FN, __VA_ARGS__)
|
||||
#define _SD_VARARGS_FOREACH_EVEN_41(FN, X, ...) _SD_VARARGS_FOREACH_EVEN_40(FN, __VA_ARGS__)
|
||||
#define _SD_VARARGS_FOREACH_EVEN_42(FN, X, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_41(FN, __VA_ARGS__)
|
||||
#define _SD_VARARGS_FOREACH_EVEN_43(FN, X, ...) _SD_VARARGS_FOREACH_EVEN_42(FN, __VA_ARGS__)
|
||||
#define _SD_VARARGS_FOREACH_EVEN_44(FN, X, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_43(FN, __VA_ARGS__)
|
||||
#define _SD_VARARGS_FOREACH_EVEN_45(FN, X, ...) _SD_VARARGS_FOREACH_EVEN_44(FN, __VA_ARGS__)
|
||||
#define _SD_VARARGS_FOREACH_EVEN_46(FN, X, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_45(FN, __VA_ARGS__)
|
||||
#define _SD_VARARGS_FOREACH_EVEN_47(FN, X, ...) _SD_VARARGS_FOREACH_EVEN_46(FN, __VA_ARGS__)
|
||||
#define _SD_VARARGS_FOREACH_EVEN_48(FN, X, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_47(FN, __VA_ARGS__)
|
||||
#define _SD_VARARGS_FOREACH_EVEN_49(FN, X, ...) _SD_VARARGS_FOREACH_EVEN_48(FN, __VA_ARGS__)
|
||||
#define _SD_VARARGS_FOREACH_EVEN_50(FN, X, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_49(FN, __VA_ARGS__)
|
||||
|
||||
#define _SD_VARARGS_FOREACH_EVEN_SEQ(_01, _02, _03, _04, _05, _06, _07, _08, _09, _10, \
|
||||
_11, _12, _13, _14, _15, _16, _17, _18, _19, _20, \
|
||||
_21, _22, _23, _24, _25, _26, _27, _28, _29, _30, \
|
||||
_31, _32, _33, _34, _35, _36, _37, _38, _39, _40, \
|
||||
_41, _42, _43, _44, _45, _46, _47, _48, _49, _50, \
|
||||
NAME, ...) NAME
|
||||
|
||||
#define _SD_VARARGS_FOREACH_EVEN(FN, ...) \
|
||||
_SD_VARARGS_FOREACH_EVEN_SEQ(__VA_ARGS__, \
|
||||
_SD_VARARGS_FOREACH_EVEN_50, _SD_VARARGS_FOREACH_EVEN_49, \
|
||||
_SD_VARARGS_FOREACH_EVEN_48, _SD_VARARGS_FOREACH_EVEN_47, \
|
||||
_SD_VARARGS_FOREACH_EVEN_46, _SD_VARARGS_FOREACH_EVEN_45, \
|
||||
_SD_VARARGS_FOREACH_EVEN_44, _SD_VARARGS_FOREACH_EVEN_43, \
|
||||
_SD_VARARGS_FOREACH_EVEN_42, _SD_VARARGS_FOREACH_EVEN_41, \
|
||||
_SD_VARARGS_FOREACH_EVEN_40, _SD_VARARGS_FOREACH_EVEN_39, \
|
||||
_SD_VARARGS_FOREACH_EVEN_38, _SD_VARARGS_FOREACH_EVEN_37, \
|
||||
_SD_VARARGS_FOREACH_EVEN_36, _SD_VARARGS_FOREACH_EVEN_35, \
|
||||
_SD_VARARGS_FOREACH_EVEN_34, _SD_VARARGS_FOREACH_EVEN_33, \
|
||||
_SD_VARARGS_FOREACH_EVEN_32, _SD_VARARGS_FOREACH_EVEN_31, \
|
||||
_SD_VARARGS_FOREACH_EVEN_30, _SD_VARARGS_FOREACH_EVEN_29, \
|
||||
_SD_VARARGS_FOREACH_EVEN_28, _SD_VARARGS_FOREACH_EVEN_27, \
|
||||
_SD_VARARGS_FOREACH_EVEN_26, _SD_VARARGS_FOREACH_EVEN_25, \
|
||||
_SD_VARARGS_FOREACH_EVEN_24, _SD_VARARGS_FOREACH_EVEN_23, \
|
||||
_SD_VARARGS_FOREACH_EVEN_22, _SD_VARARGS_FOREACH_EVEN_21, \
|
||||
_SD_VARARGS_FOREACH_EVEN_20, _SD_VARARGS_FOREACH_EVEN_19, \
|
||||
_SD_VARARGS_FOREACH_EVEN_18, _SD_VARARGS_FOREACH_EVEN_17, \
|
||||
_SD_VARARGS_FOREACH_EVEN_16, _SD_VARARGS_FOREACH_EVEN_15, \
|
||||
_SD_VARARGS_FOREACH_EVEN_14, _SD_VARARGS_FOREACH_EVEN_13, \
|
||||
_SD_VARARGS_FOREACH_EVEN_12, _SD_VARARGS_FOREACH_EVEN_11, \
|
||||
_SD_VARARGS_FOREACH_EVEN_10, _SD_VARARGS_FOREACH_EVEN_09, \
|
||||
_SD_VARARGS_FOREACH_EVEN_08, _SD_VARARGS_FOREACH_EVEN_07, \
|
||||
_SD_VARARGS_FOREACH_EVEN_06, _SD_VARARGS_FOREACH_EVEN_05, \
|
||||
_SD_VARARGS_FOREACH_EVEN_04, _SD_VARARGS_FOREACH_EVEN_03, \
|
||||
_SD_VARARGS_FOREACH_EVEN_02, _SD_VARARGS_FOREACH_EVEN_01) \
|
||||
(FN, __VA_ARGS__)
|
||||
|
||||
#define SD_BUS_ARGS(...) __VA_ARGS__
|
||||
#define SD_BUS_RESULT(...) __VA_ARGS__
|
||||
|
||||
#define SD_BUS_NO_ARGS SD_BUS_ARGS(NULL,)
|
||||
#define SD_BUS_NO_RESULT SD_BUS_RESULT(NULL,)
|
||||
|
||||
#define SD_BUS_METHOD_WITH_ARGS(_member, _args, _result, _handler, _flags) \
|
||||
SD_BUS_METHOD_WITH_NAMES(_member, \
|
||||
_SD_VARARGS_FOREACH_EVEN(_SD_ECHO, _args), \
|
||||
_SD_VARARGS_FOREACH_EVEN(_SD_CONCAT, _args, ""), \
|
||||
_SD_VARARGS_FOREACH_EVEN(_SD_ECHO, _result), \
|
||||
_SD_VARARGS_FOREACH_EVEN(_SD_CONCAT, _result, ""), \
|
||||
_handler, _flags)
|
||||
|
||||
#define SD_BUS_METHOD_WITH_ARGS_OFFSET(_member, _args, _result, _handler, _offset, _flags) \
|
||||
SD_BUS_METHOD_WITH_NAMES_OFFSET(_member, \
|
||||
_SD_VARARGS_FOREACH_EVEN(_SD_ECHO, _args), \
|
||||
_SD_VARARGS_FOREACH_EVEN(_SD_CONCAT, _args, ""), \
|
||||
_SD_VARARGS_FOREACH_EVEN(_SD_ECHO, _result), \
|
||||
_SD_VARARGS_FOREACH_EVEN(_SD_CONCAT, _result, ""), \
|
||||
_handler, _offset, _flags)
|
||||
|
||||
#define SD_BUS_SIGNAL_WITH_ARGS(_member, _args, _flags) \
|
||||
SD_BUS_SIGNAL_WITH_NAMES(_member, \
|
||||
_SD_VARARGS_FOREACH_EVEN(_SD_ECHO, _args), \
|
||||
_SD_VARARGS_FOREACH_EVEN(_SD_CONCAT, _args, ""), \
|
||||
_flags)
|
||||
|
||||
_SD_END_DECLARATIONS;
|
||||
|
||||
#endif
|
||||
|
@ -529,7 +529,7 @@ static int write_temporary_shadow(const char *shadow_path, FILE **tmpfile, char
|
||||
ORDERED_HASHMAP_FOREACH(i, todo_uids, iterator) {
|
||||
struct spwd n = {
|
||||
.sp_namp = i->name,
|
||||
.sp_pwdp = (char*) "!!", /* lock this password, and make it invalid */
|
||||
.sp_pwdp = (char*) "!*", /* lock this password, and make it invalid */
|
||||
.sp_lstchg = lstchg,
|
||||
.sp_min = -1,
|
||||
.sp_max = -1,
|
||||
|
@ -36,20 +36,20 @@ static void test_basic_mask_and_enable(const char *root) {
|
||||
assert_se(symlink("a.service", p) >= 0);
|
||||
|
||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "b.service", NULL) >= 0);
|
||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "b.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
|
||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "b.service", &state) >= 0 && state == UNIT_FILE_ALIAS);
|
||||
|
||||
p = strjoina(root, "/usr/lib/systemd/system/c.service");
|
||||
assert_se(symlink("/usr/lib/systemd/system/a.service", p) >= 0);
|
||||
|
||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "c.service", NULL) >= 0);
|
||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "c.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
|
||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "c.service", &state) >= 0 && state == UNIT_FILE_ALIAS);
|
||||
|
||||
p = strjoina(root, "/usr/lib/systemd/system/d.service");
|
||||
assert_se(symlink("c.service", p) >= 0);
|
||||
|
||||
/* This one is interesting, as d follows a relative, then an absolute symlink */
|
||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "d.service", NULL) >= 0);
|
||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "d.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
|
||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "d.service", &state) >= 0 && state == UNIT_FILE_ALIAS);
|
||||
|
||||
assert_se(unit_file_mask(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("a.service"), &changes, &n_changes) >= 0);
|
||||
assert_se(n_changes == 1);
|
||||
@ -89,9 +89,9 @@ static void test_basic_mask_and_enable(const char *root) {
|
||||
changes = NULL; n_changes = 0;
|
||||
|
||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "a.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
|
||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "b.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
|
||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "c.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
|
||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "d.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
|
||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "b.service", &state) >= 0 && state == UNIT_FILE_ALIAS);
|
||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "c.service", &state) >= 0 && state == UNIT_FILE_ALIAS);
|
||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "d.service", &state) >= 0 && state == UNIT_FILE_ALIAS);
|
||||
|
||||
/* Enabling it again should succeed but be a NOP */
|
||||
assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("a.service"), &changes, &n_changes) >= 0);
|
||||
@ -108,9 +108,9 @@ static void test_basic_mask_and_enable(const char *root) {
|
||||
changes = NULL; n_changes = 0;
|
||||
|
||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "a.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
|
||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "b.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
|
||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "c.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
|
||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "d.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
|
||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "b.service", &state) >= 0 && state == UNIT_FILE_ALIAS);
|
||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "c.service", &state) >= 0 && state == UNIT_FILE_ALIAS);
|
||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "d.service", &state) >= 0 && state == UNIT_FILE_ALIAS);
|
||||
|
||||
/* Disabling a disabled unit must succeed but be a NOP */
|
||||
assert_se(unit_file_disable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("a.service"), &changes, &n_changes) >= 0);
|
||||
@ -129,9 +129,9 @@ static void test_basic_mask_and_enable(const char *root) {
|
||||
changes = NULL; n_changes = 0;
|
||||
|
||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "a.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
|
||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "b.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
|
||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "c.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
|
||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "d.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
|
||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "b.service", &state) >= 0 && state == UNIT_FILE_ALIAS);
|
||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "c.service", &state) >= 0 && state == UNIT_FILE_ALIAS);
|
||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "d.service", &state) >= 0 && state == UNIT_FILE_ALIAS);
|
||||
|
||||
/* Let's try to reenable */
|
||||
|
||||
@ -147,9 +147,9 @@ static void test_basic_mask_and_enable(const char *root) {
|
||||
changes = NULL; n_changes = 0;
|
||||
|
||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "a.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
|
||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "b.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
|
||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "c.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
|
||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "d.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
|
||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "b.service", &state) >= 0 && state == UNIT_FILE_ALIAS);
|
||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "c.service", &state) >= 0 && state == UNIT_FILE_ALIAS);
|
||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "d.service", &state) >= 0 && state == UNIT_FILE_ALIAS);
|
||||
}
|
||||
|
||||
static void test_linked_units(const char *root) {
|
||||
@ -386,7 +386,7 @@ static void test_template_enable(const char *root) {
|
||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
|
||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@def.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
|
||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@foo.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
|
||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
|
||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@.service", &state) >= 0 && state == UNIT_FILE_ALIAS);
|
||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@def.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
|
||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@foo.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
|
||||
|
||||
@ -404,7 +404,7 @@ static void test_template_enable(const char *root) {
|
||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
|
||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@def.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
|
||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@foo.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
|
||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
|
||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@.service", &state) >= 0 && state == UNIT_FILE_ALIAS);
|
||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@def.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
|
||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@foo.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
|
||||
|
||||
@ -418,7 +418,7 @@ static void test_template_enable(const char *root) {
|
||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
|
||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@def.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
|
||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@foo.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
|
||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
|
||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@.service", &state) >= 0 && state == UNIT_FILE_ALIAS);
|
||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@def.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
|
||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@foo.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
|
||||
|
||||
@ -450,7 +450,7 @@ static void test_template_enable(const char *root) {
|
||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@def.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
|
||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@foo.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
|
||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@quux.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
|
||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
|
||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@.service", &state) >= 0 && state == UNIT_FILE_ALIAS);
|
||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@def.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
|
||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@foo.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
|
||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@quux.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
|
||||
@ -469,7 +469,7 @@ static void test_template_enable(const char *root) {
|
||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@def.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
|
||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@foo.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
|
||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@quux.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
|
||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@.service", &state) >= 0 && state == UNIT_FILE_INDIRECT);
|
||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@.service", &state) >= 0 && state == UNIT_FILE_ALIAS);
|
||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@def.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
|
||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@foo.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
|
||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@quux.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
|
||||
@ -500,7 +500,7 @@ static void test_indirect(const char *root) {
|
||||
|
||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "indirecta.service", &state) >= 0 && state == UNIT_FILE_INDIRECT);
|
||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "indirectb.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
|
||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "indirectc.service", &state) >= 0 && state == UNIT_FILE_INDIRECT);
|
||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "indirectc.service", &state) >= 0 && state == UNIT_FILE_ALIAS);
|
||||
|
||||
assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("indirectc.service"), &changes, &n_changes) >= 0);
|
||||
assert_se(n_changes == 1);
|
||||
@ -513,7 +513,7 @@ static void test_indirect(const char *root) {
|
||||
|
||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "indirecta.service", &state) >= 0 && state == UNIT_FILE_INDIRECT);
|
||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "indirectb.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
|
||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "indirectc.service", &state) >= 0 && state == UNIT_FILE_INDIRECT);
|
||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "indirectc.service", &state) >= 0 && state == UNIT_FILE_ALIAS);
|
||||
|
||||
assert_se(unit_file_disable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("indirectc.service"), &changes, &n_changes) >= 0);
|
||||
assert_se(n_changes == 1);
|
||||
@ -624,7 +624,7 @@ static void test_preset_and_list(const char *root) {
|
||||
got_no = true;
|
||||
assert_se(fl->state == UNIT_FILE_DISABLED);
|
||||
} else
|
||||
assert_se(IN_SET(fl->state, UNIT_FILE_DISABLED, UNIT_FILE_STATIC, UNIT_FILE_INDIRECT));
|
||||
assert_se(IN_SET(fl->state, UNIT_FILE_DISABLED, UNIT_FILE_STATIC, UNIT_FILE_INDIRECT, UNIT_FILE_ALIAS));
|
||||
}
|
||||
|
||||
unit_file_list_free(h);
|
||||
|
Loading…
x
Reference in New Issue
Block a user