Compare commits

..

10 Commits

Author SHA1 Message Date
Christian Göttsche 67f5ae2d69 socket-util: reset length argument for second getsockopt call in fd_[gs]et_rcvbuf
In case the first getsockopt() call changes the value.
2020-09-15 09:35:36 +09:00
Yu Watanabe 3c460bfde6
Merge pull request #16976 from keszybz/systemctl-service-log-levels
systemctl: add service-log-{level,target} verbs
2020-09-15 09:34:07 +09:00
Yu Watanabe c2c61531a2
Merge pull request #17055 from keszybz/two-coverity-fixes
Two coverity fixes
2020-09-15 09:22:39 +09:00
Zbigniew Jędrzejewski-Szmek e2146e9b67 basic/copy: vodify unlinkat() call
Not much we can do at this point.

Coverity CID#1432670.
2020-09-14 22:34:43 +02:00
Zbigniew Jędrzejewski-Szmek 649bde89ca test: use pclose() for popen()
Coverity CID#1432701.
2020-09-14 22:32:52 +02:00
Zbigniew Jędrzejewski-Szmek e6e691aebf systemctl: give a nice hint about org.freedesktop.LogControl1 when applicable 2020-09-14 22:12:14 +02:00
Zbigniew Jędrzejewski-Szmek d94bab0805 systemctl: immediately reject invalid log levels
Symbolic names and number in the appropriate range are allowed
(log_level_from_string() DTRT already).

The target names are more messy, so we leave the verification to the service.
2020-09-12 10:22:51 +02:00
Zbigniew Jędrzejewski-Szmek 77db9433a7 systemctl: merge log_target(), log_level(), service_log_setting() 2020-09-12 10:22:51 +02:00
Zbigniew Jędrzejewski-Szmek 6824c132e9 systemctl: add service-log-{level,target} verbs
Heavily inspired by #15622. This adds:
  systemctl service-log-level systemd-resolved
  systemctl service-log-level systemd-resolved info
  systemctl service-log-target systemd-resolved
  systemctl service-log-target systemd-resolved console

We already have systemctl verbs log-level, log-target, and service-watchdogs.
Those two new verbs tie nicely into this scheme.
2020-09-12 10:22:51 +02:00
Zbigniew Jędrzejewski-Szmek 172338d51b systemctl: list unit introspection verbs first, modification second
The list was rather ad hoc, with "reset-failed" sandwiched between
"help" and "list-dependencies". Since a person will usually either want
to introspect state in various ways or modify state in a certain way, let's
put all the introspection commands together and all the ones that actually
have an effect second.
2020-09-09 16:59:18 +02:00
8 changed files with 410 additions and 239 deletions

View File

@ -24,8 +24,8 @@
<title>Introduction</title> <title>Introduction</title>
<para><interfacename>org.freedesktop.LogControl1</interfacename> is a generic interface that is intended <para><interfacename>org.freedesktop.LogControl1</interfacename> is a generic interface that is intended
to be used by any daemon which should allow setting the log level and target over D-Bus. It is implemented to be used by any daemon which allows the log level and target to be set over D-Bus. It is implemented by
by various daemons that are part of the various daemons that are part of the
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry> suite.</para> <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry> suite.</para>
<para>It is assumed that those settings are global for the whole program, so a fixed object path is <para>It is assumed that those settings are global for the whole program, so a fixed object path is
@ -95,12 +95,35 @@ node /org/freedesktop/LogControl1 {
It is a short string that identifies the program that is the source of log messages that is passed to It is a short string that identifies the program that is the source of log messages that is passed to
the <citerefentry project="man-pages"><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry> call. the <citerefentry project="man-pages"><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry> call.
</para> </para>
<para>Note: <command>journalctl</command> option <option>-p</option>/<option>--priority=</option> may
be used to filter log messages by log level, option <option>-t</option>/<option>--identifier=</option>
may be used to by the syslog identifier, and filters like <literal>_TRANSPORT=syslog</literal>,
<literal>_TRANSPORT=journal</literal>, and <literal>_TRANSPORT=kernel</literal> may be used to filter
messages by the mechanism through which they reached <command>systemd-journald</command>.</para>
</refsect2> </refsect2>
</refsect1> </refsect1>
<refsect1>
<title>Tools</title>
<para><command>journalctl</command> option <option>-p</option>/<option>--priority=</option> may be used
to filter log messages by log level, option <option>-t</option>/<option>--identifier=</option> may be
used to by the syslog identifier, and filters like <literal>_TRANSPORT=syslog</literal>,
<literal>_TRANSPORT=journal</literal>, and <literal>_TRANSPORT=kernel</literal> may be used to filter
messages by the mechanism through which they reached <command>systemd-journald</command>.</para>
<para><command>systemctl log-level</command> and <command>systemctl log-target</command> verbs may be
used to query and set the <varname>LogLevel</varname> and <varname>LogTarget</varname> properties of the
service manager. <command>systemctl service-log-level</command> and <command>systemctl
service-log-target</command> may similarly be used for individual services. (Services must have the
<varname>BusName=</varname> property set and must implement the interface described here. See
<citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>
for details about <varname>BusName=</varname>.)</para>
</refsect1>
<refsect1>
<title>See Also</title>
<para>
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
<citerefentry><refentrytitle>journalctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
<citerefentry project='man-pages'><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry>
</para>
</refsect1>
</refentry> </refentry>

View File

@ -50,7 +50,7 @@
<para>The following commands are understood:</para> <para>The following commands are understood:</para>
<refsect2> <refsect2>
<title>Unit Commands</title> <title>Unit Commands (Introspection and Modification)</title>
<variablelist> <variablelist>
<varlistentry> <varlistentry>
@ -151,6 +151,196 @@ Sun 2017-02-26 20:57:49 EST 2h 3min left Sun 2017-02-26 11:56:36 EST 6h ago
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><command>is-active <replaceable>PATTERN</replaceable></command></term>
<listitem>
<para>Check whether any of the specified units are active
(i.e. running). Returns an exit code
<constant>0</constant> if at least one is active, or
non-zero otherwise. Unless <option>--quiet</option> is
specified, this will also print the current unit state to
standard output.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command>is-failed <replaceable>PATTERN</replaceable></command></term>
<listitem>
<para>Check whether any of the specified units are in a
"failed" state. Returns an exit code
<constant>0</constant> if at least one has failed,
non-zero otherwise. Unless <option>--quiet</option> is
specified, this will also print the current unit state to
standard output.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command>status</command> <optional><replaceable>PATTERN</replaceable>…|<replaceable>PID</replaceable>…]</optional></term>
<listitem>
<para>Show terse runtime status information about one or
more units, followed by most recent log data from the
journal. If no units are specified, show system status. If
combined with <option>--all</option>, also show the status of
all units (subject to limitations specified with
<option>-t</option>). If a PID is passed, show information
about the unit the process belongs to.</para>
<para>This function is intended to generate human-readable
output. If you are looking for computer-parsable output,
use <command>show</command> instead. By default, this
function only shows 10 lines of output and ellipsizes
lines to fit in the terminal window. This can be changed
with <option>--lines</option> and <option>--full</option>,
see above. In addition, <command>journalctl
--unit=<replaceable>NAME</replaceable></command> or
<command>journalctl
--user-unit=<replaceable>NAME</replaceable></command> use
a similar filter for messages and might be more
convenient.
</para>
<para>systemd implicitly loads units as necessary, so just running the <command>status</command> will
attempt to load a file. The command is thus not useful for determining if something was already loaded or
not. The units may possibly also be quickly unloaded after the operation is completed if there's no reason
to keep it in memory thereafter.
</para>
<example>
<title>Example output from systemctl status </title>
<programlisting>$ systemctl status bluetooth
● bluetooth.service - Bluetooth service
Loaded: loaded (/usr/lib/systemd/system/bluetooth.service; enabled; vendor preset: enabled)
Active: active (running) since Wed 2017-01-04 13:54:04 EST; 1 weeks 0 days ago
Docs: man:bluetoothd(8)
Main PID: 930 (bluetoothd)
Status: "Running"
Tasks: 1
Memory: 648.0K
CPU: 435ms
CGroup: /system.slice/bluetooth.service
└─930 /usr/lib/bluetooth/bluetoothd
Jan 12 10:46:45 example.com bluetoothd[8900]: Not enough free handles to register service
Jan 12 10:46:45 example.com bluetoothd[8900]: Current Time Service could not be registered
Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output error (5)
</programlisting>
<para>The dot ("●") uses color on supported terminals to summarize the unit state at a glance. White
indicates an <literal>inactive</literal> or <literal>deactivating</literal> state. Red indicates a
<literal>failed</literal> or <literal>error</literal> state and green indicates an
<literal>active</literal>, <literal>reloading</literal> or <literal>activating</literal> state.
</para>
<para>The "Loaded:" line in the output will show <literal>loaded</literal> if the unit has been loaded into
memory. Other possible values for "Loaded:" include: <literal>error</literal> if there was a problem
loading it, <literal>not-found</literal> if no unit file was found for this unit,
<literal>bad-setting</literal> if an essential unit file setting could not be parsed and
<literal>masked</literal> if the unit file has been masked. Along with showing the path to the unit file,
this line will also show the enablement state. Enabled commands start at boot. See the full table of
possible enablement states — including the definition of <literal>masked</literal> — in the documentation
for the <command>is-enabled</command> command.
</para>
<para>The "Active:" line shows active state. The value is usually <literal>active</literal> or
<literal>inactive</literal>. Active could mean started, bound, plugged in, etc depending on the unit type.
The unit could also be in process of changing states, reporting a state of <literal>activating</literal> or
<literal>deactivating</literal>. A special <literal>failed</literal> state is entered when the service
failed in some way, such as a crash, exiting with an error code or timing out. If the failed state is
entered the cause will be logged for later reference.</para>
</example>
</listitem>
</varlistentry>
<varlistentry>
<term><command>show</command> <optional><replaceable>PATTERN</replaceable>…|<replaceable>JOB</replaceable></optional></term>
<listitem>
<para>Show properties of one or more units, jobs, or the manager itself. If no argument is specified,
properties of the manager will be shown. If a unit name is specified, properties of the unit are shown, and
if a job ID is specified, properties of the job are shown. By default, empty properties are suppressed. Use
<option>--all</option> to show those too. To select specific properties to show, use
<option>--property=</option>. This command is intended to be used whenever computer-parsable output is
required. Use <command>status</command> if you are looking for formatted human-readable output.</para>
<para>Many properties shown by <command>systemctl show</command> map directly to configuration settings of
the system and service manager and its unit files. Note that the properties shown by the command are
generally more low-level, normalized versions of the original configuration settings and expose runtime
state in addition to configuration. For example, properties shown for service units include the service's
current main process identifier as <literal>MainPID</literal> (which is runtime state), and time settings
are always exposed as properties ending in the <literal>…USec</literal> suffix even if a matching
configuration options end in <literal>…Sec</literal>, because microseconds is the normalized time unit used
internally by the system and service manager.</para>
<para>For details about many of these properties, see the documentation of the D-Bus interface
backing these properties, see
<citerefentry><refentrytitle>org.freedesktop.systemd1</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command>cat <replaceable>PATTERN</replaceable></command></term>
<listitem>
<para>Show backing files of one or more units. Prints the
"fragment" and "drop-ins" (source files) of units. Each
file is preceded by a comment which includes the file
name. Note that this shows the contents of the backing files
on disk, which may not match the system manager's
understanding of these units if any unit files were
updated on disk and the <command>daemon-reload</command>
command wasn't issued since.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command>help <replaceable>PATTERN</replaceable>…|<replaceable>PID</replaceable></command></term>
<listitem>
<para>Show manual pages for one or more units, if
available. If a PID is given, the manual pages for the unit
the process belongs to are shown.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<command>list-dependencies</command>
<optional><replaceable>UNIT</replaceable>...</optional>
</term>
<listitem>
<para>Shows units required and wanted by the specified
units. This recursively lists units following the
<varname>Requires=</varname>,
<varname>Requisite=</varname>,
<varname>ConsistsOf=</varname>,
<varname>Wants=</varname>, <varname>BindsTo=</varname>
dependencies. If no units are specified,
<filename>default.target</filename> is implied.</para>
<para>By default, only target units are recursively
expanded. When <option>--all</option> is passed, all other
units are recursively expanded as well.</para>
<para>Options <option>--reverse</option>,
<option>--after</option>, <option>--before</option>
may be used to change what types of dependencies
are shown.</para>
<para>Note that this command only lists units currently loaded into memory by the service manager. In
particular, this command is not suitable to get a comprehensive list at all reverse dependencies on a
specific unit, as it won't list the dependencies declared by units currently not loaded.</para>
</listitem>
</varlistentry>
<!-- Commands that modify unit state start here -->
<varlistentry> <varlistentry>
<term><command>start <replaceable>PATTERN</replaceable></command></term> <term><command>start <replaceable>PATTERN</replaceable></command></term>
@ -325,148 +515,6 @@ Sun 2017-02-26 20:57:49 EST 2h 3min left Sun 2017-02-26 11:56:36 EST 6h ago
processes in the unit's cgroup.</para> processes in the unit's cgroup.</para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><command>is-active <replaceable>PATTERN</replaceable></command></term>
<listitem>
<para>Check whether any of the specified units are active
(i.e. running). Returns an exit code
<constant>0</constant> if at least one is active, or
non-zero otherwise. Unless <option>--quiet</option> is
specified, this will also print the current unit state to
standard output.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command>is-failed <replaceable>PATTERN</replaceable></command></term>
<listitem>
<para>Check whether any of the specified units are in a
"failed" state. Returns an exit code
<constant>0</constant> if at least one has failed,
non-zero otherwise. Unless <option>--quiet</option> is
specified, this will also print the current unit state to
standard output.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command>status</command> <optional><replaceable>PATTERN</replaceable>…|<replaceable>PID</replaceable>…]</optional></term>
<listitem>
<para>Show terse runtime status information about one or
more units, followed by most recent log data from the
journal. If no units are specified, show system status. If
combined with <option>--all</option>, also show the status of
all units (subject to limitations specified with
<option>-t</option>). If a PID is passed, show information
about the unit the process belongs to.</para>
<para>This function is intended to generate human-readable
output. If you are looking for computer-parsable output,
use <command>show</command> instead. By default, this
function only shows 10 lines of output and ellipsizes
lines to fit in the terminal window. This can be changed
with <option>--lines</option> and <option>--full</option>,
see above. In addition, <command>journalctl
--unit=<replaceable>NAME</replaceable></command> or
<command>journalctl
--user-unit=<replaceable>NAME</replaceable></command> use
a similar filter for messages and might be more
convenient.
</para>
<para>systemd implicitly loads units as necessary, so just running the <command>status</command> will
attempt to load a file. The command is thus not useful for determining if something was already loaded or
not. The units may possibly also be quickly unloaded after the operation is completed if there's no reason
to keep it in memory thereafter.
</para>
<example>
<title>Example output from systemctl status </title>
<programlisting>$ systemctl status bluetooth
● bluetooth.service - Bluetooth service
Loaded: loaded (/usr/lib/systemd/system/bluetooth.service; enabled; vendor preset: enabled)
Active: active (running) since Wed 2017-01-04 13:54:04 EST; 1 weeks 0 days ago
Docs: man:bluetoothd(8)
Main PID: 930 (bluetoothd)
Status: "Running"
Tasks: 1
Memory: 648.0K
CPU: 435ms
CGroup: /system.slice/bluetooth.service
└─930 /usr/lib/bluetooth/bluetoothd
Jan 12 10:46:45 example.com bluetoothd[8900]: Not enough free handles to register service
Jan 12 10:46:45 example.com bluetoothd[8900]: Current Time Service could not be registered
Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output error (5)
</programlisting>
<para>The dot ("●") uses color on supported terminals to summarize the unit state at a glance. White
indicates an <literal>inactive</literal> or <literal>deactivating</literal> state. Red indicates a
<literal>failed</literal> or <literal>error</literal> state and green indicates an
<literal>active</literal>, <literal>reloading</literal> or <literal>activating</literal> state.
</para>
<para>The "Loaded:" line in the output will show <literal>loaded</literal> if the unit has been loaded into
memory. Other possible values for "Loaded:" include: <literal>error</literal> if there was a problem
loading it, <literal>not-found</literal> if no unit file was found for this unit,
<literal>bad-setting</literal> if an essential unit file setting could not be parsed and
<literal>masked</literal> if the unit file has been masked. Along with showing the path to the unit file,
this line will also show the enablement state. Enabled commands start at boot. See the full table of
possible enablement states — including the definition of <literal>masked</literal> — in the documentation
for the <command>is-enabled</command> command.
</para>
<para>The "Active:" line shows active state. The value is usually <literal>active</literal> or
<literal>inactive</literal>. Active could mean started, bound, plugged in, etc depending on the unit type.
The unit could also be in process of changing states, reporting a state of <literal>activating</literal> or
<literal>deactivating</literal>. A special <literal>failed</literal> state is entered when the service
failed in some way, such as a crash, exiting with an error code or timing out. If the failed state is
entered the cause will be logged for later reference.</para>
</example>
</listitem>
</varlistentry>
<varlistentry>
<term><command>show</command> <optional><replaceable>PATTERN</replaceable>…|<replaceable>JOB</replaceable></optional></term>
<listitem>
<para>Show properties of one or more units, jobs, or the manager itself. If no argument is specified,
properties of the manager will be shown. If a unit name is specified, properties of the unit are shown, and
if a job ID is specified, properties of the job are shown. By default, empty properties are suppressed. Use
<option>--all</option> to show those too. To select specific properties to show, use
<option>--property=</option>. This command is intended to be used whenever computer-parsable output is
required. Use <command>status</command> if you are looking for formatted human-readable output.</para>
<para>Many properties shown by <command>systemctl show</command> map directly to configuration settings of
the system and service manager and its unit files. Note that the properties shown by the command are
generally more low-level, normalized versions of the original configuration settings and expose runtime
state in addition to configuration. For example, properties shown for service units include the service's
current main process identifier as <literal>MainPID</literal> (which is runtime state), and time settings
are always exposed as properties ending in the <literal>…USec</literal> suffix even if a matching
configuration options end in <literal>…Sec</literal>, because microseconds is the normalized time unit used
internally by the system and service manager.</para>
<para>For details about many of these properties, see the documentation of the D-Bus interface
backing these properties, see
<citerefentry><refentrytitle>org.freedesktop.systemd1</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command>cat <replaceable>PATTERN</replaceable></command></term>
<listitem>
<para>Show backing files of one or more units. Prints the
"fragment" and "drop-ins" (source files) of units. Each
file is preceded by a comment which includes the file
name. Note that this shows the contents of the backing files
on disk, which may not match the system manager's
understanding of these units if any unit files were
updated on disk and the <command>daemon-reload</command>
command wasn't issued since.</para>
</listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term><command>set-property <replaceable>UNIT</replaceable> <replaceable>PROPERTY</replaceable>=<replaceable>VALUE</replaceable></command></term> <term><command>set-property <replaceable>UNIT</replaceable> <replaceable>PROPERTY</replaceable>=<replaceable>VALUE</replaceable></command></term>
@ -503,13 +551,59 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><command>help <replaceable>PATTERN</replaceable>…|<replaceable>PID</replaceable></command></term> <term><command>service-log-level</command> <replaceable>SERVICE</replaceable> [<replaceable>LEVEL</replaceable>]</term>
<listitem> <listitem><para>If the <replaceable>LEVEL</replaceable> argument is not given, print the current
<para>Show manual pages for one or more units, if log level as reported by service <replaceable>SERVICE</replaceable>.</para>
available. If a PID is given, the manual pages for the unit
the process belongs to are shown.</para> <para>If the optional argument <replaceable>LEVEL</replaceable> is provided, then change the
</listitem> current log level of the service to <replaceable>LEVEL</replaceable>. The log level should be a
typical syslog log level, i.e. a value in the range 0…7 or one of the strings
<constant>emerg</constant>, <constant>alert</constant>, <constant>crit</constant>,
<constant>err</constant>, <constant>warning</constant>, <constant>notice</constant>,
<constant>info</constant>, <constant>debug</constant>; see <citerefentry
project='man-pages'><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry>
for details.</para>
<para>The service must have the appropriate
<varname>BusName=<replaceable>destination</replaceable></varname> property and also implement the
generic
<citerefentry><refentrytitle>org.freedesktop.LogControl1</refentrytitle><manvolnum>5</manvolnum></citerefentry>
interface. (<filename>systemctl</filename> will use the generic D-Bus protocol to access the
<interfacename>org.freedesktop.LogControl1.LogLevel</interfacename> interface for the D-Bus name
<replaceable>destination</replaceable>.)</para></listitem>
</varlistentry>
<varlistentry>
<term><command>service-log-target</command> <replaceable>SERVICE</replaceable> [<replaceable>TARGET</replaceable>]</term>
<listitem><para>If the <replaceable>TARGET</replaceable> argument is not given, print the current
log target as reported by service <replaceable>SERVICE</replaceable>.</para>
<para>If the optional argument <replaceable>TARGET</replaceable> is provided, then change the
current log target of the service to <replaceable>TARGET</replaceable>. The log target should be
one of the strings <constant>console</constant> (for log output to the service's standard error
stream), <constant>kmsg</constant> (for log output to the kernel log buffer),
<constant>journal</constant> (for log output to
<citerefentry><refentrytitle>systemd-journald.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
using the native journal protocol), <constant>syslog</constant> (for log output to the classic
syslog socket <filename>/dev/log</filename>), <constant>null</constant> (for no log output
whatsoever) or <constant>auto</constant> (for an automatically determined choice, typically
equivalent to <constant>console</constant> if the service is invoked interactively, and
<constant>journal</constant> or <constant>syslog</constant> otherwise).</para>
<para>For most services, only a small subset of log targets make sense. In particular, most
"normal" services should only implement <constant>console</constant>, <constant>journal</constant>,
and <constant>null</constant>. Anything else is only appropriate for low-level services that
are active in very early boot before proper logging is established.</para>
<para>The service must have the appropriate
<varname>BusName=<replaceable>destination</replaceable></varname> property and also implement the
generic
<citerefentry><refentrytitle>org.freedesktop.LogControl1</refentrytitle><manvolnum>5</manvolnum></citerefentry>
interface. (<filename>systemctl</filename> will use the generic D-Bus protocol to access the
<interfacename>org.freedesktop.LogControl1.LogLevel</interfacename> interface for the D-Bus name
<replaceable>destination</replaceable>.)</para></listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
@ -529,37 +623,6 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err
to be started again, use this command to make it startable again.</para> to be started again, use this command to make it startable again.</para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term>
<command>list-dependencies</command>
<optional><replaceable>UNIT</replaceable>...</optional>
</term>
<listitem>
<para>Shows units required and wanted by the specified
units. This recursively lists units following the
<varname>Requires=</varname>,
<varname>Requisite=</varname>,
<varname>ConsistsOf=</varname>,
<varname>Wants=</varname>, <varname>BindsTo=</varname>
dependencies. If no units are specified,
<filename>default.target</filename> is implied.</para>
<para>By default, only target units are recursively
expanded. When <option>--all</option> is passed, all other
units are recursively expanded as well.</para>
<para>Options <option>--reverse</option>,
<option>--after</option>, <option>--before</option>
may be used to change what types of dependencies
are shown.</para>
<para>Note that this command only lists units currently loaded into memory by the service manager. In
particular, this command is not suitable to get a comprehensive list at all reverse dependencies on a
specific unit, as it won't list the dependencies declared by units currently not loaded.</para>
</listitem>
</varlistentry>
</variablelist> </variablelist>
</refsect2> </refsect2>

View File

@ -292,10 +292,11 @@
<varlistentry> <varlistentry>
<term><varname>BusName=</varname></term> <term><varname>BusName=</varname></term>
<listitem><para>Takes a D-Bus bus name that this service is <listitem><para>Takes a D-Bus destination name that this service shall use. This option is mandatory
reachable as. This option is mandatory for services where for services where <varname>Type=</varname> is set to <option>dbus</option>. It is recommended to
<varname>Type=</varname> is set to always set this property if known to make it easy to map the service name to the D-Bus destination.
<option>dbus</option>.</para> In particular, <command>systemctl service-log-level/service-log-target</command> verbs make use of
this.</para>
</listitem> </listitem>
</varlistentry> </varlistentry>

View File

@ -482,7 +482,7 @@ static int hardlink_context_realize(HardlinkContext *c) {
c->dir_fd = openat(c->parent_fd, c->subdir, O_RDONLY|O_DIRECTORY|O_CLOEXEC); c->dir_fd = openat(c->parent_fd, c->subdir, O_RDONLY|O_DIRECTORY|O_CLOEXEC);
if (c->dir_fd < 0) { if (c->dir_fd < 0) {
r = -errno; r = -errno;
unlinkat(c->parent_fd, c->subdir, AT_REMOVEDIR); (void) unlinkat(c->parent_fd, c->subdir, AT_REMOVEDIR);
return r; return r;
} }

View File

@ -640,6 +640,7 @@ int fd_set_sndbuf(int fd, size_t n, bool increase) {
/* SO_SNDBUF above may set to the kernel limit, instead of the requested size. /* SO_SNDBUF above may set to the kernel limit, instead of the requested size.
* So, we need to check the actual buffer size here. */ * So, we need to check the actual buffer size here. */
l = sizeof(value);
r = getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, &l); r = getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, &l);
if (r >= 0 && l == sizeof(value) && increase ? (size_t) value >= n*2 : (size_t) value == n*2) if (r >= 0 && l == sizeof(value) && increase ? (size_t) value >= n*2 : (size_t) value == n*2)
return 1; return 1;
@ -670,6 +671,7 @@ int fd_set_rcvbuf(int fd, size_t n, bool increase) {
/* SO_RCVBUF above may set to the kernel limit, instead of the requested size. /* SO_RCVBUF above may set to the kernel limit, instead of the requested size.
* So, we need to check the actual buffer size here. */ * So, we need to check the actual buffer size here. */
l = sizeof(value);
r = getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, &l); r = getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, &l);
if (r >= 0 && l == sizeof(value) && increase ? (size_t) value >= n*2 : (size_t) value == n*2) if (r >= 0 && l == sizeof(value) && increase ? (size_t) value >= n*2 : (size_t) value == n*2)
return 1; return 1;

View File

@ -81,6 +81,7 @@
#include "stat-util.h" #include "stat-util.h"
#include "string-table.h" #include "string-table.h"
#include "strv.h" #include "strv.h"
#include "syslog-util.h"
#include "sysv-compat.h" #include "sysv-compat.h"
#include "terminal-util.h" #include "terminal-util.h"
#include "tmpfile-util.h" #include "tmpfile-util.h"
@ -6298,62 +6299,139 @@ static int switch_root(int argc, char *argv[], void *userdata) {
return 0; return 0;
} }
static int log_level(int argc, char *argv[], void *userdata) { static void give_log_control1_hint(const char *name) {
sd_bus *bus; _cleanup_free_ char *link = NULL;
if (arg_quiet)
return;
(void) terminal_urlify_man("org.freedesktop.LogControl1", "5", &link);
log_notice("Hint: the service must declare BusName= and implement the appropriate D-Bus interface.\n"
" See the %s for details.", link ?: "org.freedesktop.LogControl1(5) man page");
}
static int log_setting_internal(sd_bus *bus, const BusLocator* bloc, const char *verb, const char *value) {
assert(bus);
assert(STR_IN_SET(verb, "log-level", "log-target", "service-log-level", "service-log-target"));
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
bool level = endswith(verb, "log-level");
int r; int r;
if (value) {
if (level) {
if (log_level_from_string(value) < 0)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"\"%s\" is not a valid log level.", value);
}
r = bus_set_property(bus, bloc,
level ? "LogLevel" : "LogTarget",
&error, "s", value);
if (r >= 0)
return 0;
log_error_errno(r, "Failed to set log %s of %s to %s: %s",
level ? "level" : "target",
bloc->destination, value, bus_error_message(&error, r));
} else {
_cleanup_free_ char *t = NULL;
r = bus_get_property_string(bus, bloc,
level ? "LogLevel" : "LogTarget",
&error, &t);
if (r >= 0) {
puts(t);
return 0;
}
log_error_errno(r, "Failed to get log %s of %s: %s",
level ? "level" : "target",
bloc->destination, bus_error_message(&error, r));
}
if (sd_bus_error_has_names(&error, SD_BUS_ERROR_UNKNOWN_METHOD,
SD_BUS_ERROR_UNKNOWN_OBJECT,
SD_BUS_ERROR_UNKNOWN_INTERFACE,
SD_BUS_ERROR_UNKNOWN_PROPERTY))
give_log_control1_hint(bloc->destination);
return r;
}
static int log_setting(int argc, char *argv[], void *userdata) {
sd_bus *bus;
int r;
assert(argc >= 1 && argc <= 2);
r = acquire_bus(BUS_MANAGER, &bus); r = acquire_bus(BUS_MANAGER, &bus);
if (r < 0) if (r < 0)
return r; return r;
if (argc == 1) { return log_setting_internal(bus, bus_systemd_mgr, argv[0], argv[1]);
_cleanup_free_ char *level = NULL; }
r = bus_get_property_string(bus, bus_systemd_mgr, "LogLevel", &error, &level); static int service_name_to_dbus(sd_bus *bus, const char *name, char **ret_dbus_name) {
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
_cleanup_free_ char *bus_name = NULL;
int r;
/* First, look for the BusName= property */
_cleanup_free_ char *dbus_path = unit_dbus_path_from_name(name);
if (!dbus_path)
return log_oom();
r = sd_bus_get_property_string(
bus,
"org.freedesktop.systemd1",
dbus_path,
"org.freedesktop.systemd1.Service",
"BusName",
&error,
&bus_name);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to get log level: %s", bus_error_message(&error, r)); return log_error_errno(r, "Failed to obtain BusName= property of %s: %s",
name, bus_error_message(&error, r));
puts(level); if (isempty(bus_name)) {
log_error("Unit %s doesn't declare BusName=.", name);
} else { give_log_control1_hint(name);
assert(argc == 2); return -ENOLINK;
r = bus_set_property(bus, bus_systemd_mgr, "LogLevel", &error, "s", argv[1]);
if (r < 0)
return log_error_errno(r, "Failed to set log level: %s", bus_error_message(&error, r));
} }
*ret_dbus_name = TAKE_PTR(bus_name);
return 0; return 0;
} }
static int log_target(int argc, char *argv[], void *userdata) { static int service_log_setting(int argc, char *argv[], void *userdata) {
sd_bus *bus; sd_bus *bus;
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; _cleanup_free_ char *unit = NULL, *dbus_name = NULL;
int r; int r;
r = acquire_bus(BUS_MANAGER, &bus); assert(argc >= 2 && argc <= 3);
r = acquire_bus(BUS_FULL, &bus);
if (r < 0) if (r < 0)
return r; return r;
if (argc == 1) { r = unit_name_mangle_with_suffix(argv[1], argv[0],
_cleanup_free_ char *target = NULL; arg_quiet ? 0 : UNIT_NAME_MANGLE_WARN,
".service", &unit);
r = bus_get_property_string(bus, bus_systemd_mgr, "LogTarget", &error, &target);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to get log target: %s", bus_error_message(&error, r)); return log_error_errno(r, "Failed to mangle unit name: %m");
puts(target); r = service_name_to_dbus(bus, unit, &dbus_name);
} else {
assert(argc == 2);
r = bus_set_property(bus, bus_systemd_mgr, "LogTarget", &error, "s", argv[1]);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to set log target: %s", bus_error_message(&error, r)); return r;
}
return 0; const BusLocator bloc = {
.destination = dbus_name,
.path = "/org/freedesktop/LogControl1",
.interface = "org.freedesktop.LogControl1",
};
return log_setting_internal(bus, &bloc, argv[0], argv[2]);
} }
static int service_watchdogs(int argc, char *argv[], void *userdata) { static int service_watchdogs(int argc, char *argv[], void *userdata) {
@ -7708,6 +7786,16 @@ static int systemctl_help(void) {
" ordered by address\n" " ordered by address\n"
" list-timers [PATTERN...] List timer units currently in memory,\n" " list-timers [PATTERN...] List timer units currently in memory,\n"
" ordered by next elapse\n" " ordered by next elapse\n"
" is-active PATTERN... Check whether units are active\n"
" is-failed PATTERN... Check whether units are failed\n"
" status [PATTERN...|PID...] Show runtime status of one or more units\n"
" show [PATTERN...|JOB...] Show properties of one or more\n"
" units/jobs or the manager\n"
" cat PATTERN... Show files and drop-ins of specified units\n"
" help PATTERN...|PID... Show manual for one or more units\n"
" list-dependencies [UNIT...] Recursively show units which are required\n"
" or wanted by the units or by which those\n"
" units are required or wanted\n"
" start UNIT... Start (activate) one or more units\n" " start UNIT... Start (activate) one or more units\n"
" stop UNIT... Stop (deactivate) one or more units\n" " stop UNIT... Stop (deactivate) one or more units\n"
" reload UNIT... Reload one or more units\n" " reload UNIT... Reload one or more units\n"
@ -7723,19 +7811,11 @@ static int systemctl_help(void) {
" configuration of unit\n" " configuration of unit\n"
" freeze PATTERN... Freeze execution of unit processes\n" " freeze PATTERN... Freeze execution of unit processes\n"
" thaw PATTERN... Resume execution of a frozen unit\n" " thaw PATTERN... Resume execution of a frozen unit\n"
" is-active PATTERN... Check whether units are active\n"
" is-failed PATTERN... Check whether units are failed\n"
" status [PATTERN...|PID...] Show runtime status of one or more units\n"
" show [PATTERN...|JOB...] Show properties of one or more\n"
" units/jobs or the manager\n"
" cat PATTERN... Show files and drop-ins of specified units\n"
" set-property UNIT PROPERTY=VALUE... Sets one or more properties of a unit\n" " set-property UNIT PROPERTY=VALUE... Sets one or more properties of a unit\n"
" help PATTERN...|PID... Show manual for one or more units\n" " service-log-level SERVICE [LEVEL] Get/set logging threshold for service\n"
" service-log-target SERVICE [TARGET] Get/set logging target for service\n"
" reset-failed [PATTERN...] Reset failed state for all, one, or more\n" " reset-failed [PATTERN...] Reset failed state for all, one, or more\n"
" units\n" " units"
" list-dependencies [UNIT...] Recursively show units which are required\n"
" or wanted by the units or by which those\n"
" units are required or wanted"
"\n%3$sUnit File Commands:%4$s\n" "\n%3$sUnit File Commands:%4$s\n"
" list-unit-files [PATTERN...] List installed unit files\n" " list-unit-files [PATTERN...] List installed unit files\n"
" enable [UNIT...|PATH...] Enable one or more unit files\n" " enable [UNIT...|PATH...] Enable one or more unit files\n"
@ -9032,8 +9112,10 @@ static int systemctl_main(int argc, char *argv[]) {
{ "help", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, show }, { "help", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, show },
{ "daemon-reload", VERB_ANY, 1, VERB_ONLINE_ONLY, daemon_reload }, { "daemon-reload", VERB_ANY, 1, VERB_ONLINE_ONLY, daemon_reload },
{ "daemon-reexec", VERB_ANY, 1, VERB_ONLINE_ONLY, daemon_reload }, { "daemon-reexec", VERB_ANY, 1, VERB_ONLINE_ONLY, daemon_reload },
{ "log-level", VERB_ANY, 2, VERB_ONLINE_ONLY, log_level }, { "log-level", VERB_ANY, 2, VERB_ONLINE_ONLY, log_setting },
{ "log-target", VERB_ANY, 2, VERB_ONLINE_ONLY, log_target }, { "log-target", VERB_ANY, 2, VERB_ONLINE_ONLY, log_setting },
{ "service-log-level", 2, 3, VERB_ONLINE_ONLY, service_log_setting },
{ "service-log-target", 2, 3, VERB_ONLINE_ONLY, service_log_setting },
{ "service-watchdogs", VERB_ANY, 2, VERB_ONLINE_ONLY, service_watchdogs }, { "service-watchdogs", VERB_ANY, 2, VERB_ONLINE_ONLY, service_watchdogs },
{ "show-environment", VERB_ANY, 1, VERB_ONLINE_ONLY, show_environment }, { "show-environment", VERB_ANY, 1, VERB_ONLINE_ONLY, show_environment },
{ "set-environment", 2, VERB_ANY, VERB_ONLINE_ONLY, set_environment }, { "set-environment", 2, VERB_ANY, VERB_ONLINE_ONLY, set_environment },

View File

@ -151,7 +151,7 @@ static void test_write_and_load_env_file(void) {
_cleanup_(unlink_and_freep) char *p = NULL; _cleanup_(unlink_and_freep) char *p = NULL;
_cleanup_strv_free_ char **l = NULL; _cleanup_strv_free_ char **l = NULL;
_cleanup_free_ char *j = NULL, *w = NULL, *cmd = NULL, *from_shell = NULL; _cleanup_free_ char *j = NULL, *w = NULL, *cmd = NULL, *from_shell = NULL;
_cleanup_fclose_ FILE *f = NULL; _cleanup_pclose_ FILE *f = NULL;
size_t sz; size_t sz;
assert_se(tempfn_random_child(NULL, NULL, &p) >= 0); assert_se(tempfn_random_child(NULL, NULL, &p) >= 0);

View File

@ -153,7 +153,7 @@ static void test_parse_env_file(void) {
static void test_one_shell_var(const char *file, const char *variable, const char *value) { static void test_one_shell_var(const char *file, const char *variable, const char *value) {
_cleanup_free_ char *cmd = NULL, *from_shell = NULL; _cleanup_free_ char *cmd = NULL, *from_shell = NULL;
_cleanup_fclose_ FILE *f = NULL; _cleanup_pclose_ FILE *f = NULL;
size_t sz; size_t sz;
assert_se(cmd = strjoin(". ", file, " && /bin/echo -n \"$", variable, "\"")); assert_se(cmd = strjoin(". ", file, " && /bin/echo -n \"$", variable, "\""));