mirror of
https://github.com/systemd/systemd.git
synced 2025-03-19 22:50:17 +03:00
systemctl: allow globbing in commands which take multiple unit names
This commit is contained in:
parent
8d5ba5a946
commit
e3e0314b56
@ -580,15 +580,24 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service
|
|||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><command>start <replaceable>NAME</replaceable>...</command></term>
|
<term><command>start <replaceable>PATTERN</replaceable>...</command></term>
|
||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>Start (activate) one or more units specified on the
|
<para>Start (activate) one or more units specified on the
|
||||||
command line.</para>
|
command line.</para>
|
||||||
|
|
||||||
|
<para>Note that glob patterns operate on a list of currently
|
||||||
|
loaded units. Units which are not active and are not in a
|
||||||
|
failed state usually are not loaded, and would not be
|
||||||
|
matched by any pattern. In addition, in case of
|
||||||
|
instantiated units, systemd is often unaware of the
|
||||||
|
instance name until the instance has been started. Therefore
|
||||||
|
using glob patterns with <command>start</command>
|
||||||
|
has limited usefulness.</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><command>stop <replaceable>NAME</replaceable>...</command></term>
|
<term><command>stop <replaceable>PATTERN</replaceable>...</command></term>
|
||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>Stop (deactivate) one or more units specified on the
|
<para>Stop (deactivate) one or more units specified on the
|
||||||
@ -596,7 +605,7 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service
|
|||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><command>reload <replaceable>NAME</replaceable>...</command></term>
|
<term><command>reload <replaceable>PATTERN</replaceable>...</command></term>
|
||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>Asks all units listed on the command line to reload
|
<para>Asks all units listed on the command line to reload
|
||||||
@ -617,7 +626,7 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service
|
|||||||
|
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><command>restart <replaceable>NAME</replaceable>...</command></term>
|
<term><command>restart <replaceable>PATTERN</replaceable>...</command></term>
|
||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>Restart one or more units specified on the command
|
<para>Restart one or more units specified on the command
|
||||||
@ -626,7 +635,7 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service
|
|||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><command>try-restart <replaceable>NAME</replaceable>...</command></term>
|
<term><command>try-restart <replaceable>PATTERN</replaceable>...</command></term>
|
||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>Restart one or more units specified on the command
|
<para>Restart one or more units specified on the command
|
||||||
@ -637,7 +646,7 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service
|
|||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><command>reload-or-restart <replaceable>NAME</replaceable>...</command></term>
|
<term><command>reload-or-restart <replaceable>PATTERN</replaceable>...</command></term>
|
||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>Reload one or more units if they support it. If not,
|
<para>Reload one or more units if they support it. If not,
|
||||||
@ -646,7 +655,7 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service
|
|||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><command>reload-or-try-restart <replaceable>NAME</replaceable>...</command></term>
|
<term><command>reload-or-try-restart <replaceable>PATTERN</replaceable>...</command></term>
|
||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>Reload one or more units if they support it. If not,
|
<para>Reload one or more units if they support it. If not,
|
||||||
@ -676,7 +685,7 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service
|
|||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><command>kill <replaceable>NAME</replaceable>...</command></term>
|
<term><command>kill <replaceable>PATTERN</replaceable>...</command></term>
|
||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>Send a signal to one or more processes of the
|
<para>Send a signal to one or more processes of the
|
||||||
@ -687,7 +696,7 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service
|
|||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><command>is-active <replaceable>NAME</replaceable>...</command></term>
|
<term><command>is-active <replaceable>PATTERN</replaceable>...</command></term>
|
||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>Check whether any of the specified units are active
|
<para>Check whether any of the specified units are active
|
||||||
@ -698,7 +707,7 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service
|
|||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><command>is-failed <replaceable>NAME</replaceable>...</command></term>
|
<term><command>is-failed <replaceable>PATTERN</replaceable>...</command></term>
|
||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>Check whether any of the specified units are in a "failed" state.
|
<para>Check whether any of the specified units are in a "failed" state.
|
||||||
@ -709,7 +718,7 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service
|
|||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><command>status</command> <optional><replaceable>NAME</replaceable>...|<replaceable>PID</replaceable>...]</optional></term>
|
<term><command>status</command> <optional><replaceable>PATTERN</replaceable>...|<replaceable>PID</replaceable>...]</optional></term>
|
||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>Show terse runtime status information about one or
|
<para>Show terse runtime status information about one or
|
||||||
@ -735,7 +744,7 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service
|
|||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><command>show</command> <optional><replaceable>NAME</replaceable>...|<replaceable>JOB</replaceable>...</optional></term>
|
<term><command>show</command> <optional><replaceable>PATTERN</replaceable>...|<replaceable>JOB</replaceable>...</optional></term>
|
||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>Show properties of one or more units, jobs, or the
|
<para>Show properties of one or more units, jobs, or the
|
||||||
@ -752,7 +761,7 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service
|
|||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><command>cat <replaceable>NAME</replaceable>...</command></term>
|
<term><command>cat <replaceable>PATTERN</replaceable>...</command></term>
|
||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>Show backing files of one or more units. Prints the
|
<para>Show backing files of one or more units. Prints the
|
||||||
@ -788,7 +797,7 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service
|
|||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><command>help <replaceable>NAME</replaceable>...|<replaceable>PID</replaceable>...</command></term>
|
<term><command>help <replaceable>PATTERN</replaceable>...|<replaceable>PID</replaceable>...</command></term>
|
||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>Show manual pages for one or more units, if
|
<para>Show manual pages for one or more units, if
|
||||||
@ -798,7 +807,7 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service
|
|||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><command>reset-failed [<replaceable>NAME</replaceable>...]</command></term>
|
<term><command>reset-failed [<replaceable>PATTERN</replaceable>...]</command></term>
|
||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>Reset the <literal>failed</literal> state of the
|
<para>Reset the <literal>failed</literal> state of the
|
||||||
@ -1137,7 +1146,7 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service
|
|||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><command>delete <replaceable>NAME</replaceable>...</command></term>
|
<term><command>delete <replaceable>PATTERN</replaceable>...</command></term>
|
||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>Remove a snapshot previously created with
|
<para>Remove a snapshot previously created with
|
||||||
@ -1383,23 +1392,55 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service
|
|||||||
<refsect2>
|
<refsect2>
|
||||||
<title>Parameter Syntax</title>
|
<title>Parameter Syntax</title>
|
||||||
|
|
||||||
<para>For unit commands, the specified
|
<para>Unit ommands listed above take either a single unit name
|
||||||
<replaceable>NAME</replaceable> should be the full name of the
|
(designated as <replaceable>NAME</replaceable>), or multiple
|
||||||
unit, or an abbreviated name which is automatically extended with
|
unit specifications (designated as
|
||||||
the <literal>.service</literal> suffix.
|
<replaceable>PATTERN</replaceable>...). In the first case, the
|
||||||
<programlisting># systemctl start foo.service</programlisting> is equivalent to:
|
unit name with or without a suffix must be given. If the suffix
|
||||||
<programlisting># systemctl start foo</programlisting>
|
is not specified, systemctl will append a suitable suffix,
|
||||||
Note that (absolute) paths to device nodes are automatically converted to device unit names, and other (absolute) paths to mount unit names.
|
<literal>.service</literal> by default, and a type-specific
|
||||||
<programlisting># systemctl status /dev/sda
|
suffix in case of commands which operate only on specific unit
|
||||||
# systemctl status /home</programlisting> is equivalent to:
|
types. For example,
|
||||||
<programlisting># systemctl status dev-sda.device
|
<programlisting># systemctl start sshd</programlisting> and
|
||||||
# systemctl status home.mount</programlisting></para>
|
<programlisting># systemctl start sshd.service</programlisting>
|
||||||
|
are equivalent, as are
|
||||||
|
<programlisting># systemctl isolate snapshot-11</programlisting>
|
||||||
|
and
|
||||||
|
<programlisting># systemctl isolate snapshot-11.snapshot</programlisting>
|
||||||
|
Note that (absolute) paths to device nodes are automatically
|
||||||
|
converted to device unit names, and other (absolute) paths to
|
||||||
|
mount unit names.
|
||||||
|
<programlisting># systemctl status /dev/sda
|
||||||
|
# systemctl status /home</programlisting>
|
||||||
|
are equivalent to:
|
||||||
|
<programlisting># systemctl status dev-sda.device
|
||||||
|
# systemctl status home.mount</programlisting>
|
||||||
|
In the second case, shell-style globs will be matched against
|
||||||
|
currently loaded units, and literal unit names, with or without
|
||||||
|
a suffix, will be treated as in the first case. This means that
|
||||||
|
literal unit names always refer to exactly one unit, but globs
|
||||||
|
may match zero units and this is not considered an error.</para>
|
||||||
|
|
||||||
<para>For unit file commands, the
|
<para>Glob patterns use
|
||||||
specified <replaceable>NAME</replaceable> should be the full name
|
<citerefentry><refentrytitle>fnmatch</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
||||||
of the unit file, or the absolute path to the unit file.
|
so normal shell-style globbing rules are used, and
|
||||||
<programlisting># systemctl link /path/to/foo.service</programlisting>
|
<literal>*</literal>, <literal>?</literal>,
|
||||||
</para>
|
<literal>[]</literal> may be used. See
|
||||||
|
<citerefentry><refentrytitle>glob</refentrytitle><manvolnum>7</manvolnum></citerefentry>
|
||||||
|
for more details. The patterns are matched against the names of
|
||||||
|
currently loaded units, and patterns which don't match anything
|
||||||
|
are silently skipped. For example:
|
||||||
|
<programlisting># systemctl stop sshd@*.service</programlisting>
|
||||||
|
will stop all <filename>sshd@.service</filename> instances.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>For unit file commands, the specified
|
||||||
|
<replaceable>NAME</replaceable> should be the full name of the
|
||||||
|
unit file, or the absolute path to the unit file:
|
||||||
|
<programlisting># systemctl enable foo.service</programlisting>
|
||||||
|
or
|
||||||
|
<programlisting># systemctl link /path/to/foo.service</programlisting>
|
||||||
|
</para>
|
||||||
</refsect2>
|
</refsect2>
|
||||||
|
|
||||||
</refsect1>
|
</refsect1>
|
||||||
@ -1441,6 +1482,7 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service
|
|||||||
<citerefentry><refentrytitle>systemd.special</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
|
<citerefentry><refentrytitle>systemd.special</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
|
||||||
<citerefentry><refentrytitle>wall</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
|
<citerefentry><refentrytitle>wall</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
|
||||||
<citerefentry><refentrytitle>systemd.preset</refentrytitle><manvolnum>5</manvolnum></citerefentry>
|
<citerefentry><refentrytitle>systemd.preset</refentrytitle><manvolnum>5</manvolnum></citerefentry>
|
||||||
|
<citerefentry><refentrytitle>glob</refentrytitle><manvolnum>7</manvolnum></citerefentry>
|
||||||
</para>
|
</para>
|
||||||
</refsect1>
|
</refsect1>
|
||||||
|
|
||||||
|
@ -268,7 +268,7 @@ static int device_update_unit(Manager *m, struct udev_device *dev, const char *p
|
|||||||
memcpy(e, w, l);
|
memcpy(e, w, l);
|
||||||
e[l] = 0;
|
e[l] = 0;
|
||||||
|
|
||||||
n = unit_name_mangle(e);
|
n = unit_name_mangle(e, false);
|
||||||
if (!n) {
|
if (!n) {
|
||||||
r = -ENOMEM;
|
r = -ENOMEM;
|
||||||
goto fail;
|
goto fail;
|
||||||
|
@ -991,7 +991,7 @@ static int add_units(sd_journal *j) {
|
|||||||
assert(j);
|
assert(j);
|
||||||
|
|
||||||
STRV_FOREACH(i, arg_system_units) {
|
STRV_FOREACH(i, arg_system_units) {
|
||||||
u = unit_name_mangle(*i);
|
u = unit_name_mangle(*i, false);
|
||||||
if (!u)
|
if (!u)
|
||||||
return log_oom();
|
return log_oom();
|
||||||
r = add_matches_for_unit(j, u);
|
r = add_matches_for_unit(j, u);
|
||||||
@ -1003,7 +1003,7 @@ static int add_units(sd_journal *j) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
STRV_FOREACH(i, arg_user_units) {
|
STRV_FOREACH(i, arg_user_units) {
|
||||||
u = unit_name_mangle(*i);
|
u = unit_name_mangle(*i, false);
|
||||||
if (!u)
|
if (!u)
|
||||||
return log_oom();
|
return log_oom();
|
||||||
|
|
||||||
|
@ -208,7 +208,7 @@ static int message_start_transient_unit_new(sd_bus *bus, const char *name, sd_bu
|
|||||||
if (!isempty(arg_slice)) {
|
if (!isempty(arg_slice)) {
|
||||||
_cleanup_free_ char *slice;
|
_cleanup_free_ char *slice;
|
||||||
|
|
||||||
slice = unit_name_mangle_with_suffix(arg_slice, ".slice");
|
slice = unit_name_mangle_with_suffix(arg_slice, false, ".slice");
|
||||||
if (!slice)
|
if (!slice)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
@ -255,7 +255,7 @@ static int start_transient_service(
|
|||||||
int r;
|
int r;
|
||||||
|
|
||||||
if (arg_unit)
|
if (arg_unit)
|
||||||
name = unit_name_mangle_with_suffix(arg_unit, ".service");
|
name = unit_name_mangle_with_suffix(arg_unit, false, ".service");
|
||||||
else
|
else
|
||||||
asprintf(&name, "run-%lu.service", (unsigned long) getpid());
|
asprintf(&name, "run-%lu.service", (unsigned long) getpid());
|
||||||
if (!name)
|
if (!name)
|
||||||
@ -342,7 +342,7 @@ static int start_transient_scope(
|
|||||||
assert(bus);
|
assert(bus);
|
||||||
|
|
||||||
if (arg_unit)
|
if (arg_unit)
|
||||||
name = unit_name_mangle_with_suffix(arg_unit, ".scope");
|
name = unit_name_mangle_with_suffix(arg_unit, false, ".scope");
|
||||||
else
|
else
|
||||||
asprintf(&name, "run-%lu.scope", (unsigned long) getpid());
|
asprintf(&name, "run-%lu.scope", (unsigned long) getpid());
|
||||||
if (!name)
|
if (!name)
|
||||||
|
@ -481,15 +481,18 @@ int unit_name_from_dbus_path(const char *path, char **name) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *unit_name_mangle(const char *name) {
|
|
||||||
|
/**
|
||||||
|
* Try to turn a string that might not be a unit name into a
|
||||||
|
* sensible unit name.
|
||||||
|
*/
|
||||||
|
char *unit_name_mangle(const char *name, bool allow_globs) {
|
||||||
char *r, *t;
|
char *r, *t;
|
||||||
const char *f;
|
const char *f;
|
||||||
|
const char* valid_chars = allow_globs ? "@" VALID_CHARS "[]!-*?" : "@" VALID_CHARS;
|
||||||
|
|
||||||
assert(name);
|
assert(name);
|
||||||
|
|
||||||
/* Try to turn a string that might not be a unit name into a
|
|
||||||
* sensible unit name. */
|
|
||||||
|
|
||||||
if (is_device_path(name))
|
if (is_device_path(name))
|
||||||
return unit_name_from_path(name, ".device");
|
return unit_name_from_path(name, ".device");
|
||||||
|
|
||||||
@ -506,7 +509,7 @@ char *unit_name_mangle(const char *name) {
|
|||||||
for (f = name, t = r; *f; f++) {
|
for (f = name, t = r; *f; f++) {
|
||||||
if (*f == '/')
|
if (*f == '/')
|
||||||
*(t++) = '-';
|
*(t++) = '-';
|
||||||
else if (!strchr("@" VALID_CHARS, *f))
|
else if (!strchr(valid_chars, *f))
|
||||||
t = do_escape_char(*f, t);
|
t = do_escape_char(*f, t);
|
||||||
else
|
else
|
||||||
*(t++) = *f;
|
*(t++) = *f;
|
||||||
@ -520,7 +523,12 @@ char *unit_name_mangle(const char *name) {
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *unit_name_mangle_with_suffix(const char *name, const char *suffix) {
|
|
||||||
|
/**
|
||||||
|
* Similar to unit_name_mangle(), but is called when we know
|
||||||
|
* that this is about a specific unit type.
|
||||||
|
*/
|
||||||
|
char *unit_name_mangle_with_suffix(const char *name, bool allow_globs, const char *suffix) {
|
||||||
char *r, *t;
|
char *r, *t;
|
||||||
const char *f;
|
const char *f;
|
||||||
|
|
||||||
@ -528,9 +536,6 @@ char *unit_name_mangle_with_suffix(const char *name, const char *suffix) {
|
|||||||
assert(suffix);
|
assert(suffix);
|
||||||
assert(suffix[0] == '.');
|
assert(suffix[0] == '.');
|
||||||
|
|
||||||
/* Similar to unit_name_mangle(), but is called when we know
|
|
||||||
* that this is about snapshot units. */
|
|
||||||
|
|
||||||
r = new(char, strlen(name) * 4 + strlen(suffix) + 1);
|
r = new(char, strlen(name) * 4 + strlen(suffix) + 1);
|
||||||
if (!r)
|
if (!r)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -98,7 +98,7 @@ char *unit_name_to_path(const char *name);
|
|||||||
char *unit_dbus_path_from_name(const char *name);
|
char *unit_dbus_path_from_name(const char *name);
|
||||||
int unit_name_from_dbus_path(const char *path, char **name);
|
int unit_name_from_dbus_path(const char *path, char **name);
|
||||||
|
|
||||||
char *unit_name_mangle(const char *name);
|
char *unit_name_mangle(const char *name, bool allow_globs);
|
||||||
char *unit_name_mangle_with_suffix(const char *name, const char *suffix);
|
char *unit_name_mangle_with_suffix(const char *name, bool allow_globs, const char *suffix);
|
||||||
|
|
||||||
int build_subslice(const char *slice, const char*name, char **subslice);
|
int build_subslice(const char *slice, const char*name, char **subslice);
|
||||||
|
@ -47,9 +47,10 @@
|
|||||||
|
|
||||||
/* What is interpreted as whitespace? */
|
/* What is interpreted as whitespace? */
|
||||||
#define WHITESPACE " \t\n\r"
|
#define WHITESPACE " \t\n\r"
|
||||||
#define NEWLINE "\n\r"
|
#define NEWLINE "\n\r"
|
||||||
#define QUOTES "\"\'"
|
#define QUOTES "\"\'"
|
||||||
#define COMMENTS "#;"
|
#define COMMENTS "#;"
|
||||||
|
#define GLOB_CHARS "*?["
|
||||||
|
|
||||||
#define FORMAT_BYTES_MAX 8
|
#define FORMAT_BYTES_MAX 8
|
||||||
|
|
||||||
@ -627,6 +628,13 @@ bool path_is_safe(const char *p) _pure_;
|
|||||||
bool string_is_safe(const char *p) _pure_;
|
bool string_is_safe(const char *p) _pure_;
|
||||||
bool string_has_cc(const char *p) _pure_;
|
bool string_has_cc(const char *p) _pure_;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a string contains any glob patterns.
|
||||||
|
*/
|
||||||
|
_pure_ static inline bool string_is_glob(const char *p) {
|
||||||
|
return !!strpbrk(p, GLOB_CHARS);
|
||||||
|
}
|
||||||
|
|
||||||
void *xbsearch_r(const void *key, const void *base, size_t nmemb, size_t size,
|
void *xbsearch_r(const void *key, const void *base, size_t nmemb, size_t size,
|
||||||
int (*compar) (const void *, const void *, void *),
|
int (*compar) (const void *, const void *, void *),
|
||||||
void *arg);
|
void *arg);
|
||||||
|
@ -421,12 +421,10 @@ static void output_units_list(const UnitInfo *unit_infos, unsigned c) {
|
|||||||
const char *on, *off;
|
const char *on, *off;
|
||||||
|
|
||||||
if (n_shown) {
|
if (n_shown) {
|
||||||
printf("\nLOAD = Reflects whether the unit definition was properly loaded.\n"
|
puts("\nLOAD = Reflects whether the unit definition was properly loaded.\n"
|
||||||
"ACTIVE = The high-level unit activation state, i.e. generalization of SUB.\n"
|
"ACTIVE = The high-level unit activation state, i.e. generalization of SUB.\n"
|
||||||
"SUB = The low-level unit activation state, values depend on unit type.\n");
|
"SUB = The low-level unit activation state, values depend on unit type.");
|
||||||
if (job_count)
|
puts(job_count ? "JOB = Pending job for the unit.\n" : "");
|
||||||
printf("JOB = Pending job for the unit.\n");
|
|
||||||
puts("");
|
|
||||||
on = ansi_highlight();
|
on = ansi_highlight();
|
||||||
off = ansi_highlight_off();
|
off = ansi_highlight_off();
|
||||||
} else {
|
} else {
|
||||||
@ -1377,7 +1375,7 @@ static int list_dependencies(sd_bus *bus, char **args) {
|
|||||||
assert(bus);
|
assert(bus);
|
||||||
|
|
||||||
if (args[1]) {
|
if (args[1]) {
|
||||||
unit = unit_name_mangle(args[1]);
|
unit = unit_name_mangle(args[1], false);
|
||||||
if (!unit)
|
if (!unit)
|
||||||
return log_oom();
|
return log_oom();
|
||||||
u = unit;
|
u = unit;
|
||||||
@ -1477,7 +1475,7 @@ static int set_default(sd_bus *bus, char **args) {
|
|||||||
unsigned n_changes = 0;
|
unsigned n_changes = 0;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
unit = unit_name_mangle_with_suffix(args[1], ".target");
|
unit = unit_name_mangle_with_suffix(args[1], false, ".target");
|
||||||
if (!unit)
|
if (!unit)
|
||||||
return log_oom();
|
return log_oom();
|
||||||
|
|
||||||
@ -1706,17 +1704,12 @@ static int cancel_job(sd_bus *bus, char **args) {
|
|||||||
|
|
||||||
static int need_daemon_reload(sd_bus *bus, const char *unit) {
|
static int need_daemon_reload(sd_bus *bus, const char *unit) {
|
||||||
_cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
|
_cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
|
||||||
_cleanup_free_ char *n = NULL;
|
|
||||||
const char *path;
|
const char *path;
|
||||||
int b, r;
|
int b, r;
|
||||||
|
|
||||||
/* We ignore all errors here, since this is used to show a
|
/* We ignore all errors here, since this is used to show a
|
||||||
* warning only */
|
* warning only */
|
||||||
|
|
||||||
n = unit_name_mangle(unit);
|
|
||||||
if (!n)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
/* We don't use unit_dbus_path_from_name() directly since we
|
/* We don't use unit_dbus_path_from_name() directly since we
|
||||||
* don't want to load the unit if it isn't loaded. */
|
* don't want to load the unit if it isn't loaded. */
|
||||||
|
|
||||||
@ -1728,7 +1721,7 @@ static int need_daemon_reload(sd_bus *bus, const char *unit) {
|
|||||||
"GetUnit",
|
"GetUnit",
|
||||||
NULL,
|
NULL,
|
||||||
&reply,
|
&reply,
|
||||||
"s", n);
|
"s", unit);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
@ -1894,8 +1887,10 @@ static int wait_for_jobs(sd_bus *bus, Set *s) {
|
|||||||
|
|
||||||
while (!set_isempty(s)) {
|
while (!set_isempty(s)) {
|
||||||
q = bus_process_wait(bus);
|
q = bus_process_wait(bus);
|
||||||
if (q < 0)
|
if (q < 0) {
|
||||||
|
log_error("Failed to wait for response: %s", strerror(-r));
|
||||||
return q;
|
return q;
|
||||||
|
}
|
||||||
|
|
||||||
if (d.result) {
|
if (d.result) {
|
||||||
q = check_wait_response(&d);
|
q = check_wait_response(&d);
|
||||||
@ -1903,6 +1898,8 @@ static int wait_for_jobs(sd_bus *bus, Set *s) {
|
|||||||
* meaningful. */
|
* meaningful. */
|
||||||
if (q < 0 && r == 0)
|
if (q < 0 && r == 0)
|
||||||
r = q;
|
r = q;
|
||||||
|
log_debug("Got result %s/%s for job %s",
|
||||||
|
strna(d.result), strerror(-q), strna(d.name));
|
||||||
}
|
}
|
||||||
|
|
||||||
free(d.name);
|
free(d.name);
|
||||||
@ -1927,7 +1924,7 @@ static int check_one_unit(sd_bus *bus, const char *name, const char *good_states
|
|||||||
|
|
||||||
assert(name);
|
assert(name);
|
||||||
|
|
||||||
n = unit_name_mangle(name);
|
n = unit_name_mangle(name, false);
|
||||||
if (!n)
|
if (!n)
|
||||||
return log_oom();
|
return log_oom();
|
||||||
|
|
||||||
@ -1984,7 +1981,7 @@ static int check_triggering_units(
|
|||||||
char **i;
|
char **i;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
n = unit_name_mangle(name);
|
n = unit_name_mangle(name, false);
|
||||||
if (!n)
|
if (!n)
|
||||||
return log_oom();
|
return log_oom();
|
||||||
|
|
||||||
@ -2051,7 +2048,6 @@ static int start_unit_one(
|
|||||||
Set *s) {
|
Set *s) {
|
||||||
|
|
||||||
_cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
|
_cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
|
||||||
_cleanup_free_ char *n;
|
|
||||||
const char *path;
|
const char *path;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
@ -2060,10 +2056,7 @@ static int start_unit_one(
|
|||||||
assert(mode);
|
assert(mode);
|
||||||
assert(error);
|
assert(error);
|
||||||
|
|
||||||
n = unit_name_mangle(name);
|
log_debug("Calling manager for %s on %s, %s", method, name, mode);
|
||||||
if (!n)
|
|
||||||
return log_oom();
|
|
||||||
|
|
||||||
r = sd_bus_call_method(
|
r = sd_bus_call_method(
|
||||||
bus,
|
bus,
|
||||||
"org.freedesktop.systemd1",
|
"org.freedesktop.systemd1",
|
||||||
@ -2072,14 +2065,14 @@ static int start_unit_one(
|
|||||||
method,
|
method,
|
||||||
error,
|
error,
|
||||||
&reply,
|
&reply,
|
||||||
"ss", n, mode);
|
"ss", name, mode);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
|
if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
|
||||||
/* There's always a fallback possible for
|
/* There's always a fallback possible for
|
||||||
* legacy actions. */
|
* legacy actions. */
|
||||||
return -EADDRNOTAVAIL;
|
return -EADDRNOTAVAIL;
|
||||||
|
|
||||||
log_error("Failed to start %s: %s", name, bus_error_message(error, r));
|
log_error("Failed to %s %s: %s", method, name, bus_error_message(error, r));
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2087,9 +2080,9 @@ static int start_unit_one(
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
return bus_log_parse_error(r);
|
return bus_log_parse_error(r);
|
||||||
|
|
||||||
if (need_daemon_reload(bus, n) > 0)
|
if (need_daemon_reload(bus, name) > 0)
|
||||||
log_warning("Warning: Unit file of %s changed on disk, 'systemctl%s daemon-reload' recommended.",
|
log_warning("Warning: Unit file of %s changed on disk, 'systemctl%s daemon-reload' recommended.",
|
||||||
n, arg_scope == UNIT_FILE_SYSTEM ? "" : " --user");
|
name, arg_scope == UNIT_FILE_SYSTEM ? "" : " --user");
|
||||||
|
|
||||||
if (s) {
|
if (s) {
|
||||||
char *p;
|
char *p;
|
||||||
@ -2098,6 +2091,7 @@ static int start_unit_one(
|
|||||||
if (!p)
|
if (!p)
|
||||||
return log_oom();
|
return log_oom();
|
||||||
|
|
||||||
|
log_debug("Adding %s to the set", p);
|
||||||
r = set_consume(s, p);
|
r = set_consume(s, p);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_oom();
|
return log_oom();
|
||||||
@ -2106,6 +2100,52 @@ static int start_unit_one(
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int expand_names(sd_bus *bus, char **names, const char* suffix, char ***ret) {
|
||||||
|
|
||||||
|
_cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
|
||||||
|
_cleanup_strv_free_ char **mangled = NULL, **globs = NULL;
|
||||||
|
char **name;
|
||||||
|
int r = 0, i;
|
||||||
|
|
||||||
|
STRV_FOREACH(name, names) {
|
||||||
|
char *t;
|
||||||
|
|
||||||
|
if (suffix)
|
||||||
|
t = unit_name_mangle_with_suffix(*name, true, suffix);
|
||||||
|
else
|
||||||
|
t = unit_name_mangle(*name, true);
|
||||||
|
if (!t)
|
||||||
|
return log_oom();
|
||||||
|
|
||||||
|
if (string_is_glob(t))
|
||||||
|
r = strv_push(&globs, t);
|
||||||
|
else
|
||||||
|
r = strv_push(&mangled, t);
|
||||||
|
if (r < 0) {
|
||||||
|
free(t);
|
||||||
|
return log_oom();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Query the manager only if any of the names are a glob, since
|
||||||
|
* this is fairly expensive */
|
||||||
|
if (!strv_isempty(globs)) {
|
||||||
|
_cleanup_free_ UnitInfo *unit_infos = NULL;
|
||||||
|
|
||||||
|
r = get_unit_list(bus, &reply, &unit_infos, globs);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
for (i = 0; i < r; i++)
|
||||||
|
if (strv_extend(&mangled, unit_infos[i].id) < 0)
|
||||||
|
return log_oom();
|
||||||
|
}
|
||||||
|
|
||||||
|
*ret = mangled;
|
||||||
|
mangled = NULL; /* do not free */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static const struct {
|
static const struct {
|
||||||
const char *target;
|
const char *target;
|
||||||
const char *verb;
|
const char *verb;
|
||||||
@ -2139,12 +2179,11 @@ static enum action verb_to_action(const char *verb) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int start_unit(sd_bus *bus, char **args) {
|
static int start_unit(sd_bus *bus, char **args) {
|
||||||
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
|
|
||||||
_cleanup_set_free_free_ Set *s = NULL;
|
_cleanup_set_free_free_ Set *s = NULL;
|
||||||
const char *method, *mode;
|
_cleanup_strv_free_ char **names = NULL;
|
||||||
|
const char *method, *mode, *one_name;
|
||||||
char **name;
|
char **name;
|
||||||
int r = 0;
|
int r = 0;
|
||||||
char **names, *strv[] = {NULL, NULL}; /* at most one name */
|
|
||||||
|
|
||||||
assert(bus);
|
assert(bus);
|
||||||
|
|
||||||
@ -2172,7 +2211,7 @@ static int start_unit(sd_bus *bus, char **args) {
|
|||||||
mode = streq(args[0], "isolate") ? "isolate" :
|
mode = streq(args[0], "isolate") ? "isolate" :
|
||||||
action_table[action].mode ?: arg_job_mode;
|
action_table[action].mode ?: arg_job_mode;
|
||||||
|
|
||||||
strv[0] = (char*) action_table[action].target;
|
one_name = action_table[action].target;
|
||||||
} else {
|
} else {
|
||||||
assert(arg_action < ELEMENTSOF(action_table));
|
assert(arg_action < ELEMENTSOF(action_table));
|
||||||
assert(action_table[arg_action].target);
|
assert(action_table[arg_action].target);
|
||||||
@ -2180,13 +2219,16 @@ static int start_unit(sd_bus *bus, char **args) {
|
|||||||
method = "StartUnit";
|
method = "StartUnit";
|
||||||
|
|
||||||
mode = action_table[arg_action].mode;
|
mode = action_table[arg_action].mode;
|
||||||
strv[0] = (char*) action_table[arg_action].target;
|
one_name = action_table[arg_action].target;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strv[0])
|
if (one_name)
|
||||||
names = strv;
|
names = strv_new(one_name, NULL);
|
||||||
else
|
else {
|
||||||
names = args + 1;
|
r = expand_names(bus, args + 1, NULL, &names);
|
||||||
|
if (r < 0)
|
||||||
|
log_error("Failed to expand names: %s", strerror(-r));
|
||||||
|
}
|
||||||
|
|
||||||
if (!arg_no_block) {
|
if (!arg_no_block) {
|
||||||
r = enable_wait_for_jobs(bus);
|
r = enable_wait_for_jobs(bus);
|
||||||
@ -2201,13 +2243,12 @@ static int start_unit(sd_bus *bus, char **args) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
STRV_FOREACH(name, names) {
|
STRV_FOREACH(name, names) {
|
||||||
|
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
|
||||||
int q;
|
int q;
|
||||||
|
|
||||||
q = start_unit_one(bus, method, *name, mode, &error, s);
|
q = start_unit_one(bus, method, *name, mode, &error, s);
|
||||||
if (r == 0 && q < 0) {
|
if (r >= 0 && q < 0)
|
||||||
r = translate_bus_error_to_exit_status(q, &error);
|
r = translate_bus_error_to_exit_status(q, &error);
|
||||||
sd_bus_error_free(&error);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!arg_no_block) {
|
if (!arg_no_block) {
|
||||||
@ -2444,17 +2485,23 @@ static int start_special(sd_bus *bus, char **args) {
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int check_unit_active(sd_bus *bus, char **args) {
|
static int check_unit_generic(sd_bus *bus, int code, const char *good_states, char **args) {
|
||||||
|
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
|
||||||
|
_cleanup_strv_free_ char **names = NULL;
|
||||||
char **name;
|
char **name;
|
||||||
int r = 3; /* According to LSB: "program is not running" */
|
int r = code;
|
||||||
|
|
||||||
assert(bus);
|
assert(bus);
|
||||||
assert(args);
|
assert(args);
|
||||||
|
|
||||||
STRV_FOREACH(name, args+1) {
|
r = expand_names(bus, args, NULL, &names);
|
||||||
|
if (r < 0)
|
||||||
|
log_error("Failed to expand names: %s", strerror(-r));
|
||||||
|
|
||||||
|
STRV_FOREACH(name, names) {
|
||||||
int state;
|
int state;
|
||||||
|
|
||||||
state = check_one_unit(bus, *name, "active\0reloading\0", arg_quiet);
|
state = check_one_unit(bus, *name, good_states, arg_quiet);
|
||||||
if (state < 0)
|
if (state < 0)
|
||||||
return state;
|
return state;
|
||||||
if (state > 0)
|
if (state > 0)
|
||||||
@ -2464,30 +2511,20 @@ static int check_unit_active(sd_bus *bus, char **args) {
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int check_unit_active(sd_bus *bus, char **args) {
|
||||||
|
/* According to LSB: 3, "program is not running" */
|
||||||
|
return check_unit_generic(bus, 3, "active\0reloading\0", args + 1);
|
||||||
|
}
|
||||||
|
|
||||||
static int check_unit_failed(sd_bus *bus, char **args) {
|
static int check_unit_failed(sd_bus *bus, char **args) {
|
||||||
char **name;
|
return check_unit_generic(bus, 1, "failed\0", args + 1);
|
||||||
int r = 1;
|
|
||||||
|
|
||||||
assert(bus);
|
|
||||||
assert(args);
|
|
||||||
|
|
||||||
STRV_FOREACH(name, args+1) {
|
|
||||||
int state;
|
|
||||||
|
|
||||||
state = check_one_unit(bus, *name, "failed\0", arg_quiet);
|
|
||||||
if (state < 0)
|
|
||||||
return state;
|
|
||||||
if (state > 0)
|
|
||||||
r = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return r;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int kill_unit(sd_bus *bus, char **args) {
|
static int kill_unit(sd_bus *bus, char **args) {
|
||||||
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
|
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
|
||||||
|
_cleanup_strv_free_ char **names = NULL;
|
||||||
char **name;
|
char **name;
|
||||||
int r = 0;
|
int r, q;
|
||||||
|
|
||||||
assert(bus);
|
assert(bus);
|
||||||
assert(args);
|
assert(args);
|
||||||
@ -2495,14 +2532,12 @@ static int kill_unit(sd_bus *bus, char **args) {
|
|||||||
if (!arg_kill_who)
|
if (!arg_kill_who)
|
||||||
arg_kill_who = "all";
|
arg_kill_who = "all";
|
||||||
|
|
||||||
STRV_FOREACH(name, args+1) {
|
r = expand_names(bus, args + 1, NULL, &names);
|
||||||
_cleanup_free_ char *n = NULL;
|
if (r < 0)
|
||||||
|
log_error("Failed to expand names: %s", strerror(-r));
|
||||||
|
|
||||||
n = unit_name_mangle(*name);
|
STRV_FOREACH(name, names) {
|
||||||
if (!n)
|
q = sd_bus_call_method(
|
||||||
return log_oom();
|
|
||||||
|
|
||||||
r = sd_bus_call_method(
|
|
||||||
bus,
|
bus,
|
||||||
"org.freedesktop.systemd1",
|
"org.freedesktop.systemd1",
|
||||||
"/org/freedesktop/systemd1",
|
"/org/freedesktop/systemd1",
|
||||||
@ -2510,14 +2545,16 @@ static int kill_unit(sd_bus *bus, char **args) {
|
|||||||
"KillUnit",
|
"KillUnit",
|
||||||
&error,
|
&error,
|
||||||
NULL,
|
NULL,
|
||||||
"ssi", n, arg_kill_who, arg_signal);
|
"ssi", *names, arg_kill_who, arg_signal);
|
||||||
if (r < 0) {
|
if (q < 0) {
|
||||||
log_error("Failed to kill unit %s: %s", n, bus_error_message(&error, r));
|
log_error("Failed to kill unit %s: %s",
|
||||||
return r;
|
*names, bus_error_message(&error, r));
|
||||||
|
if (r == 0)
|
||||||
|
r = q;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct ExecStatusInfo {
|
typedef struct ExecStatusInfo {
|
||||||
@ -3563,6 +3600,8 @@ static int show_one(
|
|||||||
assert(path);
|
assert(path);
|
||||||
assert(new_line);
|
assert(new_line);
|
||||||
|
|
||||||
|
log_debug("Showing one %s", path);
|
||||||
|
|
||||||
r = sd_bus_call_method(
|
r = sd_bus_call_method(
|
||||||
bus,
|
bus,
|
||||||
"org.freedesktop.systemd1",
|
"org.freedesktop.systemd1",
|
||||||
@ -3735,33 +3774,34 @@ static int show_all(
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int cat(sd_bus *bus, char **args) {
|
static int cat(sd_bus *bus, char **args) {
|
||||||
_cleanup_free_ char *unit = NULL, *n = NULL;
|
_cleanup_free_ char *unit = NULL;
|
||||||
int r = 0;
|
_cleanup_strv_free_ char **names = NULL;
|
||||||
char **name;
|
char **name;
|
||||||
bool first = true;
|
bool first = true;
|
||||||
|
int r = 0;
|
||||||
|
|
||||||
assert(bus);
|
assert(bus);
|
||||||
assert(args);
|
assert(args);
|
||||||
|
|
||||||
|
r = expand_names(bus, args + 1, NULL, &names);
|
||||||
|
if (r < 0)
|
||||||
|
log_error("Failed to expand names: %s", strerror(-r));
|
||||||
|
|
||||||
pager_open_if_enabled();
|
pager_open_if_enabled();
|
||||||
|
|
||||||
STRV_FOREACH(name, args+1) {
|
STRV_FOREACH(name, names) {
|
||||||
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
|
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
|
||||||
_cleanup_strv_free_ char **dropin_paths = NULL;
|
_cleanup_strv_free_ char **dropin_paths = NULL;
|
||||||
_cleanup_free_ char *fragment_path = NULL;
|
_cleanup_free_ char *fragment_path = NULL;
|
||||||
char **path;
|
char **path;
|
||||||
|
|
||||||
n = unit_name_mangle(*name);
|
unit = unit_dbus_path_from_name(*name);
|
||||||
if (!n)
|
|
||||||
return log_oom();
|
|
||||||
|
|
||||||
unit = unit_dbus_path_from_name(n);
|
|
||||||
if (!unit)
|
if (!unit)
|
||||||
return log_oom();
|
return log_oom();
|
||||||
|
|
||||||
if (need_daemon_reload(bus, n) > 0)
|
if (need_daemon_reload(bus, *name) > 0)
|
||||||
log_warning("Unit file of %s changed on disk. Run 'systemctl%s daemon-reload'.",
|
log_warning("Unit file of %s changed on disk. Run 'systemctl%s daemon-reload'.",
|
||||||
n, arg_scope == UNIT_FILE_SYSTEM ? "" : " --user");
|
*name, arg_scope == UNIT_FILE_SYSTEM ? "" : " --user");
|
||||||
|
|
||||||
r = sd_bus_get_property_string(
|
r = sd_bus_get_property_string(
|
||||||
bus,
|
bus,
|
||||||
@ -3828,10 +3868,9 @@ static int cat(sd_bus *bus, char **args) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int show(sd_bus *bus, char **args) {
|
static int show(sd_bus *bus, char **args) {
|
||||||
int r, ret = 0;
|
|
||||||
bool show_properties, show_status, new_line = false;
|
bool show_properties, show_status, new_line = false;
|
||||||
char **name;
|
|
||||||
bool ellipsized = false;
|
bool ellipsized = false;
|
||||||
|
int r, ret = 0;
|
||||||
|
|
||||||
assert(bus);
|
assert(bus);
|
||||||
assert(args);
|
assert(args);
|
||||||
@ -3849,23 +3888,19 @@ static int show(sd_bus *bus, char **args) {
|
|||||||
|
|
||||||
if (show_status && strv_length(args) <= 1)
|
if (show_status && strv_length(args) <= 1)
|
||||||
ret = show_all(args[0], bus, false, &new_line, &ellipsized);
|
ret = show_all(args[0], bus, false, &new_line, &ellipsized);
|
||||||
else
|
else {
|
||||||
STRV_FOREACH(name, args+1) {
|
_cleanup_free_ char **patterns = NULL;
|
||||||
|
char **name;
|
||||||
|
|
||||||
|
STRV_FOREACH(name, args + 1) {
|
||||||
_cleanup_free_ char *unit = NULL;
|
_cleanup_free_ char *unit = NULL;
|
||||||
uint32_t id;
|
uint32_t id;
|
||||||
|
|
||||||
if (safe_atou32(*name, &id) < 0) {
|
if (safe_atou32(*name, &id) < 0) {
|
||||||
_cleanup_free_ char *n = NULL;
|
if (strv_push(&patterns, *name) < 0)
|
||||||
/* Interpret as unit name */
|
|
||||||
|
|
||||||
n = unit_name_mangle(*name);
|
|
||||||
if (!n)
|
|
||||||
return log_oom();
|
|
||||||
|
|
||||||
unit = unit_dbus_path_from_name(n);
|
|
||||||
if (!unit)
|
|
||||||
return log_oom();
|
return log_oom();
|
||||||
|
|
||||||
|
continue;
|
||||||
} else if (show_properties) {
|
} else if (show_properties) {
|
||||||
/* Interpret as job id */
|
/* Interpret as job id */
|
||||||
if (asprintf(&unit, "/org/freedesktop/systemd1/job/%u", id) < 0)
|
if (asprintf(&unit, "/org/freedesktop/systemd1/job/%u", id) < 0)
|
||||||
@ -3883,6 +3918,25 @@ static int show(sd_bus *bus, char **args) {
|
|||||||
show_one(args[0], bus, unit, show_properties, &new_line, &ellipsized);
|
show_one(args[0], bus, unit, show_properties, &new_line, &ellipsized);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!strv_isempty(patterns)) {
|
||||||
|
_cleanup_strv_free_ char **names = NULL;
|
||||||
|
|
||||||
|
r = expand_names(bus, patterns, NULL, &names);
|
||||||
|
if (r < 0)
|
||||||
|
log_error("Failed to expand names: %s", strerror(-r));
|
||||||
|
|
||||||
|
STRV_FOREACH(name, names) {
|
||||||
|
_cleanup_free_ char *unit;
|
||||||
|
|
||||||
|
unit = unit_dbus_path_from_name(*name);
|
||||||
|
if (!unit)
|
||||||
|
return log_oom();
|
||||||
|
|
||||||
|
show_one(args[0], bus, unit, show_properties, &new_line, &ellipsized);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (ellipsized && !arg_quiet)
|
if (ellipsized && !arg_quiet)
|
||||||
printf("Hint: Some lines were ellipsized, use -l to show in full.\n");
|
printf("Hint: Some lines were ellipsized, use -l to show in full.\n");
|
||||||
|
|
||||||
@ -4063,7 +4117,7 @@ static int set_property(sd_bus *bus, char **args) {
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
return bus_log_create_error(r);
|
return bus_log_create_error(r);
|
||||||
|
|
||||||
n = unit_name_mangle(args[1]);
|
n = unit_name_mangle(args[1], false);
|
||||||
if (!n)
|
if (!n)
|
||||||
return log_oom();
|
return log_oom();
|
||||||
|
|
||||||
@ -4110,7 +4164,7 @@ static int snapshot(sd_bus *bus, char **args) {
|
|||||||
int r;
|
int r;
|
||||||
|
|
||||||
if (strv_length(args) > 1)
|
if (strv_length(args) > 1)
|
||||||
n = unit_name_mangle_with_suffix(args[1], ".snapshot");
|
n = unit_name_mangle_with_suffix(args[1], false, ".snapshot");
|
||||||
else
|
else
|
||||||
n = strdup("");
|
n = strdup("");
|
||||||
if (!n)
|
if (!n)
|
||||||
@ -4155,19 +4209,18 @@ static int snapshot(sd_bus *bus, char **args) {
|
|||||||
|
|
||||||
static int delete_snapshot(sd_bus *bus, char **args) {
|
static int delete_snapshot(sd_bus *bus, char **args) {
|
||||||
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
|
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
|
||||||
|
_cleanup_strv_free_ char **names = NULL;
|
||||||
char **name;
|
char **name;
|
||||||
int r;
|
int r, q;
|
||||||
|
|
||||||
assert(args);
|
assert(args);
|
||||||
|
|
||||||
STRV_FOREACH(name, args+1) {
|
r = expand_names(bus, args + 1, ".snapshot", &names);
|
||||||
_cleanup_free_ char *n = NULL;
|
if (r < 0)
|
||||||
|
log_error("Failed to expand names: %s", strerror(-r));
|
||||||
|
|
||||||
n = unit_name_mangle_with_suffix(*name, ".snapshot");
|
STRV_FOREACH(name, names) {
|
||||||
if (!n)
|
q = sd_bus_call_method(
|
||||||
return log_oom();
|
|
||||||
|
|
||||||
r = sd_bus_call_method(
|
|
||||||
bus,
|
bus,
|
||||||
"org.freedesktop.systemd1",
|
"org.freedesktop.systemd1",
|
||||||
"/org/freedesktop/systemd1",
|
"/org/freedesktop/systemd1",
|
||||||
@ -4175,14 +4228,16 @@ static int delete_snapshot(sd_bus *bus, char **args) {
|
|||||||
"RemoveSnapshot",
|
"RemoveSnapshot",
|
||||||
&error,
|
&error,
|
||||||
NULL,
|
NULL,
|
||||||
"s", n);
|
"s", *name);
|
||||||
if (r < 0) {
|
if (q < 0) {
|
||||||
log_error("Failed to remove snapshot %s: %s", n, bus_error_message(&error, r));
|
log_error("Failed to remove snapshot %s: %s",
|
||||||
return r;
|
*name, bus_error_message(&error, r));
|
||||||
|
if (r == 0)
|
||||||
|
r = q;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int daemon_reload(sd_bus *bus, char **args) {
|
static int daemon_reload(sd_bus *bus, char **args) {
|
||||||
@ -4236,20 +4291,19 @@ static int daemon_reload(sd_bus *bus, char **args) {
|
|||||||
|
|
||||||
static int reset_failed(sd_bus *bus, char **args) {
|
static int reset_failed(sd_bus *bus, char **args) {
|
||||||
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
|
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
|
||||||
|
_cleanup_strv_free_ char **names = NULL;
|
||||||
char **name;
|
char **name;
|
||||||
int r;
|
int r, q;
|
||||||
|
|
||||||
if (strv_length(args) <= 1)
|
if (strv_length(args) <= 1)
|
||||||
return daemon_reload(bus, args);
|
return daemon_reload(bus, args);
|
||||||
|
|
||||||
STRV_FOREACH(name, args+1) {
|
r = expand_names(bus, args + 1, NULL, &names);
|
||||||
_cleanup_free_ char *n;
|
if (r < 0)
|
||||||
|
log_error("Failed to expand names: %s", strerror(-r));
|
||||||
|
|
||||||
n = unit_name_mangle(*name);
|
STRV_FOREACH(name, names) {
|
||||||
if (!n)
|
q = sd_bus_call_method(
|
||||||
return log_oom();
|
|
||||||
|
|
||||||
r = sd_bus_call_method(
|
|
||||||
bus,
|
bus,
|
||||||
"org.freedesktop.systemd1",
|
"org.freedesktop.systemd1",
|
||||||
"/org/freedesktop/systemd1",
|
"/org/freedesktop/systemd1",
|
||||||
@ -4257,14 +4311,16 @@ static int reset_failed(sd_bus *bus, char **args) {
|
|||||||
"ResetFailedUnit",
|
"ResetFailedUnit",
|
||||||
&error,
|
&error,
|
||||||
NULL,
|
NULL,
|
||||||
"s", n);
|
"s", *name);
|
||||||
if (r < 0) {
|
if (q < 0) {
|
||||||
log_error("Failed to reset failed state of unit %s: %s", n, bus_error_message(&error, r));
|
log_error("Failed to reset failed state of unit %s: %s",
|
||||||
return r;
|
*name, bus_error_message(&error, r));
|
||||||
|
if (r == 0)
|
||||||
|
r = q;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int show_environment(sd_bus *bus, char **args) {
|
static int show_environment(sd_bus *bus, char **args) {
|
||||||
@ -4563,7 +4619,7 @@ static int mangle_names(char **original_names, char ***mangled_names) {
|
|||||||
if (is_path(*name))
|
if (is_path(*name))
|
||||||
*i = strdup(*name);
|
*i = strdup(*name);
|
||||||
else
|
else
|
||||||
*i = unit_name_mangle(*name);
|
*i = unit_name_mangle(*name, false);
|
||||||
|
|
||||||
if (!*i) {
|
if (!*i) {
|
||||||
strv_free(l);
|
strv_free(l);
|
||||||
@ -4580,7 +4636,7 @@ static int mangle_names(char **original_names, char ***mangled_names) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int enable_unit(sd_bus *bus, char **args) {
|
static int enable_unit(sd_bus *bus, char **args) {
|
||||||
_cleanup_strv_free_ char **mangled_names = NULL;
|
_cleanup_strv_free_ char **names = NULL;
|
||||||
const char *verb = args[0];
|
const char *verb = args[0];
|
||||||
UnitFileChange *changes = NULL;
|
UnitFileChange *changes = NULL;
|
||||||
unsigned n_changes = 0;
|
unsigned n_changes = 0;
|
||||||
@ -4590,32 +4646,32 @@ static int enable_unit(sd_bus *bus, char **args) {
|
|||||||
if (!args[1])
|
if (!args[1])
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
r = mangle_names(args+1, &mangled_names);
|
r = mangle_names(args+1, &names);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
r = enable_sysv_units(verb, mangled_names);
|
r = enable_sysv_units(verb, names);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
if (!bus || avoid_bus()) {
|
if (!bus || avoid_bus()) {
|
||||||
if (streq(verb, "enable")) {
|
if (streq(verb, "enable")) {
|
||||||
r = unit_file_enable(arg_scope, arg_runtime, arg_root, mangled_names, arg_force, &changes, &n_changes);
|
r = unit_file_enable(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
|
||||||
carries_install_info = r;
|
carries_install_info = r;
|
||||||
} else if (streq(verb, "disable"))
|
} else if (streq(verb, "disable"))
|
||||||
r = unit_file_disable(arg_scope, arg_runtime, arg_root, mangled_names, &changes, &n_changes);
|
r = unit_file_disable(arg_scope, arg_runtime, arg_root, names, &changes, &n_changes);
|
||||||
else if (streq(verb, "reenable")) {
|
else if (streq(verb, "reenable")) {
|
||||||
r = unit_file_reenable(arg_scope, arg_runtime, arg_root, mangled_names, arg_force, &changes, &n_changes);
|
r = unit_file_reenable(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
|
||||||
carries_install_info = r;
|
carries_install_info = r;
|
||||||
} else if (streq(verb, "link"))
|
} else if (streq(verb, "link"))
|
||||||
r = unit_file_link(arg_scope, arg_runtime, arg_root, mangled_names, arg_force, &changes, &n_changes);
|
r = unit_file_link(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
|
||||||
else if (streq(verb, "preset")) {
|
else if (streq(verb, "preset")) {
|
||||||
r = unit_file_preset(arg_scope, arg_runtime, arg_root, mangled_names, arg_force, &changes, &n_changes);
|
r = unit_file_preset(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
|
||||||
carries_install_info = r;
|
carries_install_info = r;
|
||||||
} else if (streq(verb, "mask"))
|
} else if (streq(verb, "mask"))
|
||||||
r = unit_file_mask(arg_scope, arg_runtime, arg_root, mangled_names, arg_force, &changes, &n_changes);
|
r = unit_file_mask(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
|
||||||
else if (streq(verb, "unmask"))
|
else if (streq(verb, "unmask"))
|
||||||
r = unit_file_unmask(arg_scope, arg_runtime, arg_root, mangled_names, &changes, &n_changes);
|
r = unit_file_unmask(arg_scope, arg_runtime, arg_root, names, &changes, &n_changes);
|
||||||
else
|
else
|
||||||
assert_not_reached("Unknown verb");
|
assert_not_reached("Unknown verb");
|
||||||
|
|
||||||
@ -4667,7 +4723,7 @@ static int enable_unit(sd_bus *bus, char **args) {
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
return bus_log_create_error(r);
|
return bus_log_create_error(r);
|
||||||
|
|
||||||
r = sd_bus_message_append_strv(m, mangled_names);
|
r = sd_bus_message_append_strv(m, names);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return bus_log_create_error(r);
|
return bus_log_create_error(r);
|
||||||
|
|
||||||
@ -4724,16 +4780,16 @@ finish:
|
|||||||
static int unit_is_enabled(sd_bus *bus, char **args) {
|
static int unit_is_enabled(sd_bus *bus, char **args) {
|
||||||
|
|
||||||
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
|
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
|
||||||
_cleanup_strv_free_ char **mangled_names = NULL;
|
_cleanup_strv_free_ char **names = NULL;
|
||||||
bool enabled;
|
bool enabled;
|
||||||
char **name;
|
char **name;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
r = mangle_names(args+1, &mangled_names);
|
r = mangle_names(args+1, &names);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
r = enable_sysv_units(args[0], mangled_names);
|
r = enable_sysv_units(args[0], names);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
@ -4741,7 +4797,7 @@ static int unit_is_enabled(sd_bus *bus, char **args) {
|
|||||||
|
|
||||||
if (!bus || avoid_bus()) {
|
if (!bus || avoid_bus()) {
|
||||||
|
|
||||||
STRV_FOREACH(name, mangled_names) {
|
STRV_FOREACH(name, names) {
|
||||||
UnitFileState state;
|
UnitFileState state;
|
||||||
|
|
||||||
state = unit_file_get_state(arg_scope, arg_root, *name);
|
state = unit_file_get_state(arg_scope, arg_root, *name);
|
||||||
@ -4760,7 +4816,7 @@ static int unit_is_enabled(sd_bus *bus, char **args) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
STRV_FOREACH(name, mangled_names) {
|
STRV_FOREACH(name, names) {
|
||||||
_cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
|
_cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
|
||||||
const char *s;
|
const char *s;
|
||||||
|
|
||||||
|
@ -92,8 +92,8 @@ static void test_replacements(void) {
|
|||||||
#define expect(pattern) \
|
#define expect(pattern) \
|
||||||
{ \
|
{ \
|
||||||
_cleanup_free_ char *k, *t; \
|
_cleanup_free_ char *k, *t; \
|
||||||
assert_se(t = unit_name_mangle(pattern)); \
|
assert_se(t = unit_name_mangle(pattern, false)); \
|
||||||
assert_se(k = unit_name_mangle(t)); \
|
assert_se(k = unit_name_mangle(t, false)); \
|
||||||
puts(t); \
|
puts(t); \
|
||||||
assert_se(streq(t, k)); \
|
assert_se(streq(t, k)); \
|
||||||
}
|
}
|
||||||
|
@ -961,7 +961,7 @@ static int rule_add_key(struct rule_tmp *rule_tmp, enum token_type type,
|
|||||||
int has_glob;
|
int has_glob;
|
||||||
|
|
||||||
has_split = (strchr(value, '|') != NULL);
|
has_split = (strchr(value, '|') != NULL);
|
||||||
has_glob = (strchr(value, '*') != NULL || strchr(value, '?') != NULL || strchr(value, '[') != NULL);
|
has_glob = string_is_glob(value);
|
||||||
if (has_split && has_glob) {
|
if (has_split && has_glob) {
|
||||||
glob = GL_SPLIT_GLOB;
|
glob = GL_SPLIT_GLOB;
|
||||||
} else if (has_split) {
|
} else if (has_split) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user