mirror of
https://git.proxmox.com/git/systemd
synced 2025-05-30 00:57:12 +00:00
New upstream version 247.3
This commit is contained in:
parent
9bb629ec19
commit
1ce460ce8d
4
README
4
README
@ -192,8 +192,8 @@ REQUIREMENTS:
|
||||
Any configuration options can be specified as -Darg=value... arguments
|
||||
to meson. After the build directory is initially configured, meson will
|
||||
refuse to run again, and options must be changed with:
|
||||
mesonconf -Darg=value...
|
||||
mesonconf without any arguments will print out available options and
|
||||
meson configure -Darg=value build/
|
||||
meson configure without any arguments will print out available options and
|
||||
their current values.
|
||||
|
||||
Useful commands:
|
||||
|
@ -145,7 +145,7 @@ names for them in UIs.
|
||||
|
||||
## Links
|
||||
|
||||
[Boot Loader Specification](https://systemd.io/BOOT_LOADER_INTERFACE)<br>
|
||||
[Boot Loader Specification](https://systemd.io/BOOT_LOADER_SPECIFICATION)<br>
|
||||
[Discoverable Partitions Specification](https://systemd.io/DISCOVERABLE_PARTITIONS)<br>
|
||||
[systemd-boot(7)](https://www.freedesktop.org/software/systemd/man/systemd-boot.html)<br>
|
||||
[bootctl(1)](https://www.freedesktop.org/software/systemd/man/bootctl.html)<br>
|
||||
|
@ -277,6 +277,25 @@
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>no-read-workqueue</option></term>
|
||||
|
||||
<listitem><para>Bypass dm-crypt internal workqueue and process read requests synchronously. The
|
||||
default is to queue these requests and process them asynchronously.</para>
|
||||
|
||||
<para>This requires kernel 5.9 or newer.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><option>no-write-workqueue</option></term>
|
||||
|
||||
<listitem><para>Bypass dm-crypt internal workqueue and process write requests synchronously. The
|
||||
default is to queue these requests and process them asynchronously.</para>
|
||||
|
||||
<para>This requires kernel 5.9 or newer.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>skip=</option></term>
|
||||
|
||||
|
@ -41,6 +41,9 @@
|
||||
symlink target name of <filename>/etc/localtime</filename>, this
|
||||
file may not be a normal file or hardlink.</para>
|
||||
|
||||
<para>If <filename>/etc/localtime</filename> is missing, the
|
||||
default <literal>UTC</literal> timezone is used.</para>
|
||||
|
||||
<para>The timezone may be overridden for individual programs by
|
||||
using the <varname>$TZ</varname> environment variable. See
|
||||
<citerefentry project='man-pages'><refentrytitle>environ</refentrytitle><manvolnum>7</manvolnum></citerefentry>.</para>
|
||||
|
@ -1063,8 +1063,10 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err
|
||||
<para><command>systemd</command> supports an environment block that is passed to processes the manager
|
||||
spawns. The names of the variables can contain ASCII letters, digits, and the underscore
|
||||
character. Variable names cannot be empty or start with a digit. In variable values, most characters
|
||||
are allowed, but non-printable characters are currently rejected. The total length of the environment
|
||||
block is limited to <constant>_SC_ARG_MAX</constant> value defined by
|
||||
are allowed, but the whole sequence must be valid UTF-8. (Note that control characters like newline
|
||||
(<constant>NL</constant>), tab (<constant>TAB</constant>), or the escape character
|
||||
(<constant>ESC</constant>), <emphasis>are</emphasis> valid ASCII and thus valid UTF-8). The total
|
||||
length of the environment block is limited to <constant>_SC_ARG_MAX</constant> value defined by
|
||||
<citerefentry project='man-pages'><refentrytitle>sysconf</refentrytitle><manvolnum>3</manvolnum></citerefentry>.
|
||||
</para>
|
||||
|
||||
@ -1123,10 +1125,12 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err
|
||||
|
||||
<listitem>
|
||||
<para>Import all, one or more environment variables set on the client into the systemd manager
|
||||
environment block. If no arguments are passed, the entire environment block is imported.
|
||||
Otherwise, a list of one or more environment variable names should be passed, whose client-side
|
||||
values are then imported into the manager's environment block. This command will silently ignore
|
||||
any assignments which do not conform to the rules listed above.</para>
|
||||
environment block. If a list of environment variable names is passed, client-side values are then
|
||||
imported into the manager's environment block. If any names are not valid environment variable
|
||||
names or have invalid values according to the rules described above, an error is raised. If no
|
||||
arguments are passed, the entire environment block inherited by the <command>systemctl</command>
|
||||
process is imported. In this mode, any inherited invalid environment variables are quietly
|
||||
ignored.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
|
@ -714,7 +714,8 @@
|
||||
this way is used, similar to the behavior if "yes" is specified. If the check is not successful (and thus
|
||||
the UID/GID range indicated in the root directory's file owner is already used elsewhere) a new – currently
|
||||
unused – UID/GID range of 65536 UIDs/GIDs is randomly chosen between the host UID/GIDs of 524288 and
|
||||
1878982656, always starting at a multiple of 65536. This setting implies
|
||||
1878982656, always starting at a multiple of 65536, and, if possible, consistently hashed from the machine
|
||||
name. This setting implies
|
||||
<option>--private-users-chown</option> (see below), which has the effect that the files and directories in
|
||||
the container's directory tree will be owned by the appropriate users of the range picked. Using this option
|
||||
makes user namespace behavior fully automatic. Note that the first invocation of a previously unused
|
||||
|
@ -361,7 +361,8 @@
|
||||
<listitem><para>Configure the default value for the per-unit <varname>TasksMax=</varname> setting. See
|
||||
<citerefentry><refentrytitle>systemd.resource-control</refentrytitle><manvolnum>5</manvolnum></citerefentry>
|
||||
for details. This setting applies to all unit types that support resource control settings, with the exception
|
||||
of slice units. Defaults to 15% of the sysctl setting <varname>kernel.pid_max=</varname> or root cgroup <varname>pids.max</varname>.
|
||||
of slice units. Defaults to 15% of the minimum of <varname>kernel.pid_max=</varname>, <varname>kernel.threads-max=</varname>
|
||||
and root cgroup <varname>pids.max</varname>.
|
||||
Kernel has a default value for <varname>kernel.pid_max=</varname> and an algorithm of counting in case of more than 32 cores.
|
||||
For example with the default <varname>kernel.pid_max=</varname>, <varname>DefaultTasksMax=</varname> defaults to 4915,
|
||||
but might be greater in other systems or smaller in OS containers.</para></listitem>
|
||||
|
@ -2304,10 +2304,10 @@ SystemCallErrorNumber=EPERM</programlisting>
|
||||
set by the service manager itself (such as <varname>$NOTIFY_SOCKET</varname> and such), or set by a PAM module
|
||||
(in case <varname>PAMName=</varname> is used).</para>
|
||||
|
||||
<para>
|
||||
See <citerefentry
|
||||
project='man-pages'><refentrytitle>environ</refentrytitle><manvolnum>7</manvolnum></citerefentry> for details
|
||||
about environment variables.</para></listitem>
|
||||
<para>See "Environment Variables in Spawned Processes" below for a description of how those
|
||||
settings combine to form the inherited environment. See <citerefentry
|
||||
project='man-pages'><refentrytitle>environ</refentrytitle><manvolnum>7</manvolnum></citerefentry> for general
|
||||
information about environment variables.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
@ -2809,7 +2809,7 @@ StandardInputData=SWNrIHNpdHplIGRhIHVuJyBlc3NlIEtsb3BzLAp1ZmYgZWVtYWwga2xvcHAncy
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
<title>Environment variables in spawned processes</title>
|
||||
<title>Environment Variables in Spawned Processes</title>
|
||||
|
||||
<para>Processes started by the service manager are executed with an environment variable block assembled from
|
||||
multiple sources. Processes started by the system service manager generally do not inherit environment variables
|
||||
@ -2822,410 +2822,427 @@ StandardInputData=SWNrIHNpdHplIGRhIHVuJyBlc3NlIEtsb3BzLAp1ZmYgZWVtYWwga2xvcHAncy
|
||||
<itemizedlist>
|
||||
<listitem><para>Variables globally configured for the service manager, using the
|
||||
<varname>DefaultEnvironment=</varname> setting in
|
||||
<citerefentry><refentrytitle>systemd-system.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>, the kernel command line option <varname>systemd.setenv=</varname> (see
|
||||
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>) or via
|
||||
<command>systemctl set-environment</command> (see <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>).</para></listitem>
|
||||
<citerefentry><refentrytitle>systemd-system.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
|
||||
the kernel command line option <varname>systemd.setenv=</varname> understood by
|
||||
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>, or via
|
||||
<citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>
|
||||
<command>set-environment</command> verb.</para></listitem>
|
||||
|
||||
<listitem><para>Variables defined by the service manager itself (see the list below)</para></listitem>
|
||||
<listitem><para>Variables defined by the service manager itself (see the list below).</para></listitem>
|
||||
|
||||
<listitem><para>Variables set in the service manager's own environment variable block (subject to <varname>PassEnvironment=</varname> for the system service manager)</para></listitem>
|
||||
<listitem><para>Variables set in the service manager's own environment variable block (subject to
|
||||
<varname>PassEnvironment=</varname> for the system service manager).</para></listitem>
|
||||
|
||||
<listitem><para>Variables set via <varname>Environment=</varname> in the unit file</para></listitem>
|
||||
<listitem><para>Variables set via <varname>Environment=</varname> in the unit file.</para></listitem>
|
||||
|
||||
<listitem><para>Variables read from files specified via <varname>EnvironmentFile=</varname> in the unit file</para></listitem>
|
||||
<listitem><para>Variables read from files specified via <varname>EnvironmentFile=</varname> in the unit
|
||||
file.</para></listitem>
|
||||
|
||||
<listitem><para>Variables set by any PAM modules in case <varname>PAMName=</varname> is in effect,
|
||||
cf. <citerefentry
|
||||
project='man-pages'><refentrytitle>pam_env</refentrytitle><manvolnum>8</manvolnum></citerefentry></para></listitem>
|
||||
project='man-pages'><refentrytitle>pam_env</refentrytitle><manvolnum>8</manvolnum></citerefentry>.
|
||||
</para></listitem>
|
||||
</itemizedlist>
|
||||
|
||||
<para>If the same environment variables are set by multiple of these sources, the later source — according to the
|
||||
order of the list above — wins. Note that as final step all variables listed in
|
||||
<varname>UnsetEnvironment=</varname> are removed again from the compiled environment variable list, immediately
|
||||
<para>If the same environment variable is set by multiple of these sources, the later source — according
|
||||
to the order of the list above — wins. Note that as the final step all variables listed in
|
||||
<varname>UnsetEnvironment=</varname> are removed from the compiled environment variable list, immediately
|
||||
before it is passed to the executed process.</para>
|
||||
|
||||
<para>The following environment variables are set or propagated by the service manager for each invoked
|
||||
process:</para>
|
||||
<para>The general philosophy is to expose a small curated list of environment variables to processes.
|
||||
Services started by the system manager (PID 1) will be started, without additional service-specific
|
||||
configuration, with just a few environment variables. The user manager inherits environment variables as
|
||||
any other system service, but in addition may receive additional environment variables from PAM, and,
|
||||
typically, additional imported variables when the user starts a graphical session. It is recommended to
|
||||
keep the environment blocks in both the system and user managers managers lean.</para>
|
||||
|
||||
<variablelist class='environment-variables'>
|
||||
<varlistentry>
|
||||
<term><varname>$PATH</varname></term>
|
||||
<para>Hint: <command>systemd-run -P env</command> and <command>systemd-run --user -P env</command> print
|
||||
the effective system and user service environment blocks.</para>
|
||||
|
||||
<listitem><para>Colon-separated list of directories to use when launching
|
||||
executables. <command>systemd</command> uses a fixed value of
|
||||
<literal><filename>/usr/local/sbin</filename>:<filename>/usr/local/bin</filename>:<filename>/usr/sbin</filename>:<filename>/usr/bin</filename></literal>
|
||||
in the system manager. When compiled for systems with "unmerged /usr" (<filename>/bin</filename> is
|
||||
not a symlink to <filename>/usr/bin</filename>),
|
||||
<literal>:<filename>/sbin</filename>:<filename>/bin</filename></literal> is appended. In case of the
|
||||
the user manager, a different path may be configured by the distribution. It is recommended to not
|
||||
rely on the order of entries, and have only one program with a given name in
|
||||
<varname>$PATH</varname>.</para></listitem>
|
||||
</varlistentry>
|
||||
<refsect2>
|
||||
<title>Environment Variables Set or Propagated by the Service Manager</title>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>$LANG</varname></term>
|
||||
<para>The following environment variables are propagated by the service manager or generated internally
|
||||
for each invoked process:</para>
|
||||
|
||||
<listitem><para>Locale. Can be set in
|
||||
<citerefentry project='man-pages'><refentrytitle>locale.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>
|
||||
or on the kernel command line (see
|
||||
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>
|
||||
and
|
||||
<citerefentry><refentrytitle>kernel-command-line</refentrytitle><manvolnum>7</manvolnum></citerefentry>).
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
<variablelist class='environment-variables'>
|
||||
<varlistentry>
|
||||
<term><varname>$PATH</varname></term>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>$USER</varname></term>
|
||||
<term><varname>$LOGNAME</varname></term>
|
||||
<term><varname>$HOME</varname></term>
|
||||
<term><varname>$SHELL</varname></term>
|
||||
<listitem><para>Colon-separated list of directories to use when launching
|
||||
executables. <command>systemd</command> uses a fixed value of
|
||||
<literal><filename>/usr/local/sbin</filename>:<filename>/usr/local/bin</filename>:<filename>/usr/sbin</filename>:<filename>/usr/bin</filename></literal>
|
||||
in the system manager. When compiled for systems with "unmerged <filename>/usr/</filename>"
|
||||
(<filename>/bin</filename> is not a symlink to <filename>/usr/bin</filename>),
|
||||
<literal>:<filename>/sbin</filename>:<filename>/bin</filename></literal> is appended. In case of
|
||||
the the user manager, a different path may be configured by the distribution. It is recommended to
|
||||
not rely on the order of entries, and have only one program with a given name in
|
||||
<varname>$PATH</varname>.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<listitem><para>User name (twice), home directory, and the
|
||||
login shell. The variables are set for the units that have
|
||||
<varname>User=</varname> set, which includes user
|
||||
<command>systemd</command> instances. See
|
||||
<citerefentry project='die-net'><refentrytitle>passwd</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><varname>$LANG</varname></term>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>$INVOCATION_ID</varname></term>
|
||||
<listitem><para>Locale. Can be set in <citerefentry
|
||||
project='man-pages'><refentrytitle>locale.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>
|
||||
or on the kernel command line (see
|
||||
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry> and
|
||||
<citerefentry><refentrytitle>kernel-command-line</refentrytitle><manvolnum>7</manvolnum></citerefentry>).
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<listitem><para>Contains a randomized, unique 128bit ID identifying each runtime cycle of the unit, formatted
|
||||
as 32 character hexadecimal string. A new ID is assigned each time the unit changes from an inactive state into
|
||||
an activating or active state, and may be used to identify this specific runtime cycle, in particular in data
|
||||
stored offline, such as the journal. The same ID is passed to all processes run as part of the
|
||||
unit.</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><varname>$USER</varname></term>
|
||||
<term><varname>$LOGNAME</varname></term>
|
||||
<term><varname>$HOME</varname></term>
|
||||
<term><varname>$SHELL</varname></term>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>$XDG_RUNTIME_DIR</varname></term>
|
||||
<listitem><para>User name (twice), home directory, and the
|
||||
login shell. The variables are set for the units that have
|
||||
<varname>User=</varname> set, which includes user
|
||||
<command>systemd</command> instances. See
|
||||
<citerefentry project='die-net'><refentrytitle>passwd</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<listitem><para>The directory to use for runtime objects (such as IPC objects) and volatile state. Set for all
|
||||
services run by the user <command>systemd</command> instance, as well as any system services that use
|
||||
<varname>PAMName=</varname> with a PAM stack that includes <command>pam_systemd</command>. See below and
|
||||
<citerefentry><refentrytitle>pam_systemd</refentrytitle><manvolnum>8</manvolnum></citerefentry> for more
|
||||
information.</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><varname>$INVOCATION_ID</varname></term>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>$RUNTIME_DIRECTORY</varname></term>
|
||||
<term><varname>$STATE_DIRECTORY</varname></term>
|
||||
<term><varname>$CACHE_DIRECTORY</varname></term>
|
||||
<term><varname>$LOGS_DIRECTORY</varname></term>
|
||||
<term><varname>$CONFIGURATION_DIRECTORY</varname></term>
|
||||
<listitem><para>Contains a randomized, unique 128bit ID identifying each runtime cycle of the unit, formatted
|
||||
as 32 character hexadecimal string. A new ID is assigned each time the unit changes from an inactive state into
|
||||
an activating or active state, and may be used to identify this specific runtime cycle, in particular in data
|
||||
stored offline, such as the journal. The same ID is passed to all processes run as part of the
|
||||
unit.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<listitem><para>Absolute paths to the directories defined with
|
||||
<varname>RuntimeDirectory=</varname>, <varname>StateDirectory=</varname>,
|
||||
<varname>CacheDirectory=</varname>, <varname>LogsDirectory=</varname>, and
|
||||
<varname>ConfigurationDirectory=</varname> when those settings are used.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><varname>$XDG_RUNTIME_DIR</varname></term>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>$CREDENTIALS_DIRECTORY</varname></term>
|
||||
<listitem><para>The directory to use for runtime objects (such as IPC objects) and volatile state. Set for all
|
||||
services run by the user <command>systemd</command> instance, as well as any system services that use
|
||||
<varname>PAMName=</varname> with a PAM stack that includes <command>pam_systemd</command>. See below and
|
||||
<citerefentry><refentrytitle>pam_systemd</refentrytitle><manvolnum>8</manvolnum></citerefentry> for more
|
||||
information.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<listitem><para>An absolute path to the per-unit directory with credentials configured via
|
||||
<varname>LoadCredential=</varname>/<varname>SetCredential=</varname>. The directory is marked
|
||||
read-only and is placed in unswappable memory (if supported and permitted), and is only accessible to
|
||||
the UID associated with the unit via <varname>User=</varname> or <varname>DynamicUser=</varname> (and
|
||||
the superuser).</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><varname>$RUNTIME_DIRECTORY</varname></term>
|
||||
<term><varname>$STATE_DIRECTORY</varname></term>
|
||||
<term><varname>$CACHE_DIRECTORY</varname></term>
|
||||
<term><varname>$LOGS_DIRECTORY</varname></term>
|
||||
<term><varname>$CONFIGURATION_DIRECTORY</varname></term>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>$MAINPID</varname></term>
|
||||
<listitem><para>Absolute paths to the directories defined with
|
||||
<varname>RuntimeDirectory=</varname>, <varname>StateDirectory=</varname>,
|
||||
<varname>CacheDirectory=</varname>, <varname>LogsDirectory=</varname>, and
|
||||
<varname>ConfigurationDirectory=</varname> when those settings are used.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<listitem><para>The PID of the unit's main process if it is
|
||||
known. This is only set for control processes as invoked by
|
||||
<varname>ExecReload=</varname> and similar. </para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><varname>$CREDENTIALS_DIRECTORY</varname></term>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>$MANAGERPID</varname></term>
|
||||
<listitem><para>An absolute path to the per-unit directory with credentials configured via
|
||||
<varname>LoadCredential=</varname>/<varname>SetCredential=</varname>. The directory is marked
|
||||
read-only and is placed in unswappable memory (if supported and permitted), and is only accessible to
|
||||
the UID associated with the unit via <varname>User=</varname> or <varname>DynamicUser=</varname> (and
|
||||
the superuser).</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<listitem><para>The PID of the user <command>systemd</command>
|
||||
instance, set for processes spawned by it. </para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><varname>$MAINPID</varname></term>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>$LISTEN_FDS</varname></term>
|
||||
<term><varname>$LISTEN_PID</varname></term>
|
||||
<term><varname>$LISTEN_FDNAMES</varname></term>
|
||||
<listitem><para>The PID of the unit's main process if it is
|
||||
known. This is only set for control processes as invoked by
|
||||
<varname>ExecReload=</varname> and similar. </para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<listitem><para>Information about file descriptors passed to a
|
||||
service for socket activation. See
|
||||
<citerefentry><refentrytitle>sd_listen_fds</refentrytitle><manvolnum>3</manvolnum></citerefentry>.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><varname>$MANAGERPID</varname></term>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>$NOTIFY_SOCKET</varname></term>
|
||||
<listitem><para>The PID of the user <command>systemd</command>
|
||||
instance, set for processes spawned by it. </para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<listitem><para>The socket
|
||||
<function>sd_notify()</function> talks to. See
|
||||
<citerefentry><refentrytitle>sd_notify</refentrytitle><manvolnum>3</manvolnum></citerefentry>.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><varname>$LISTEN_FDS</varname></term>
|
||||
<term><varname>$LISTEN_PID</varname></term>
|
||||
<term><varname>$LISTEN_FDNAMES</varname></term>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>$WATCHDOG_PID</varname></term>
|
||||
<term><varname>$WATCHDOG_USEC</varname></term>
|
||||
<listitem><para>Information about file descriptors passed to a
|
||||
service for socket activation. See
|
||||
<citerefentry><refentrytitle>sd_listen_fds</refentrytitle><manvolnum>3</manvolnum></citerefentry>.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<listitem><para>Information about watchdog keep-alive notifications. See
|
||||
<citerefentry><refentrytitle>sd_watchdog_enabled</refentrytitle><manvolnum>3</manvolnum></citerefentry>.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><varname>$NOTIFY_SOCKET</varname></term>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>$TERM</varname></term>
|
||||
<listitem><para>The socket
|
||||
<function>sd_notify()</function> talks to. See
|
||||
<citerefentry><refentrytitle>sd_notify</refentrytitle><manvolnum>3</manvolnum></citerefentry>.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<listitem><para>Terminal type, set only for units connected to
|
||||
a terminal (<varname>StandardInput=tty</varname>,
|
||||
<varname>StandardOutput=tty</varname>, or
|
||||
<varname>StandardError=tty</varname>). See
|
||||
<citerefentry project='man-pages'><refentrytitle>termcap</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><varname>$WATCHDOG_PID</varname></term>
|
||||
<term><varname>$WATCHDOG_USEC</varname></term>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>$LOG_NAMESPACE</varname></term>
|
||||
<listitem><para>Information about watchdog keep-alive notifications. See
|
||||
<citerefentry><refentrytitle>sd_watchdog_enabled</refentrytitle><manvolnum>3</manvolnum></citerefentry>.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<listitem><para>Contains the name of the selected logging namespace when the
|
||||
<varname>LogNamespace=</varname> service setting is used.</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><varname>$TERM</varname></term>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>$JOURNAL_STREAM</varname></term>
|
||||
<listitem><para>Terminal type, set only for units connected to
|
||||
a terminal (<varname>StandardInput=tty</varname>,
|
||||
<varname>StandardOutput=tty</varname>, or
|
||||
<varname>StandardError=tty</varname>). See
|
||||
<citerefentry project='man-pages'><refentrytitle>termcap</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<listitem><para>If the standard output or standard error output of the executed processes are connected to the
|
||||
journal (for example, by setting <varname>StandardError=journal</varname>) <varname>$JOURNAL_STREAM</varname>
|
||||
contains the device and inode numbers of the connection file descriptor, formatted in decimal, separated by a
|
||||
colon (<literal>:</literal>). This permits invoked processes to safely detect whether their standard output or
|
||||
standard error output are connected to the journal. The device and inode numbers of the file descriptors should
|
||||
be compared with the values set in the environment variable to determine whether the process output is still
|
||||
connected to the journal. Note that it is generally not sufficient to only check whether
|
||||
<varname>$JOURNAL_STREAM</varname> is set at all as services might invoke external processes replacing their
|
||||
standard output or standard error output, without unsetting the environment variable.</para>
|
||||
<varlistentry>
|
||||
<term><varname>$LOG_NAMESPACE</varname></term>
|
||||
|
||||
<para>If both standard output and standard error of the executed processes are connected to the journal via a
|
||||
stream socket, this environment variable will contain information about the standard error stream, as that's
|
||||
usually the preferred destination for log data. (Note that typically the same stream is used for both standard
|
||||
output and standard error, hence very likely the environment variable contains device and inode information
|
||||
matching both stream file descriptors.)</para>
|
||||
<listitem><para>Contains the name of the selected logging namespace when the
|
||||
<varname>LogNamespace=</varname> service setting is used.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<para>This environment variable is primarily useful to allow services to optionally upgrade their used log
|
||||
protocol to the native journal protocol (using
|
||||
<citerefentry><refentrytitle>sd_journal_print</refentrytitle><manvolnum>3</manvolnum></citerefentry> and other
|
||||
functions) if their standard output or standard error output is connected to the journal anyway, thus enabling
|
||||
delivery of structured metadata along with logged messages.</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><varname>$JOURNAL_STREAM</varname></term>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>$SERVICE_RESULT</varname></term>
|
||||
<listitem><para>If the standard output or standard error output of the executed processes are connected to the
|
||||
journal (for example, by setting <varname>StandardError=journal</varname>) <varname>$JOURNAL_STREAM</varname>
|
||||
contains the device and inode numbers of the connection file descriptor, formatted in decimal, separated by a
|
||||
colon (<literal>:</literal>). This permits invoked processes to safely detect whether their standard output or
|
||||
standard error output are connected to the journal. The device and inode numbers of the file descriptors should
|
||||
be compared with the values set in the environment variable to determine whether the process output is still
|
||||
connected to the journal. Note that it is generally not sufficient to only check whether
|
||||
<varname>$JOURNAL_STREAM</varname> is set at all as services might invoke external processes replacing their
|
||||
standard output or standard error output, without unsetting the environment variable.</para>
|
||||
|
||||
<listitem><para>Only defined for the service unit type, this environment variable is passed to all
|
||||
<varname>ExecStop=</varname> and <varname>ExecStopPost=</varname> processes, and encodes the service
|
||||
"result". Currently, the following values are defined:</para>
|
||||
<para>If both standard output and standard error of the executed processes are connected to the journal via a
|
||||
stream socket, this environment variable will contain information about the standard error stream, as that's
|
||||
usually the preferred destination for log data. (Note that typically the same stream is used for both standard
|
||||
output and standard error, hence very likely the environment variable contains device and inode information
|
||||
matching both stream file descriptors.)</para>
|
||||
|
||||
<table>
|
||||
<title>Defined <varname>$SERVICE_RESULT</varname> values</title>
|
||||
<tgroup cols='2'>
|
||||
<colspec colname='result'/>
|
||||
<colspec colname='meaning'/>
|
||||
<thead>
|
||||
<row>
|
||||
<entry>Value</entry>
|
||||
<entry>Meaning</entry>
|
||||
</row>
|
||||
</thead>
|
||||
<para>This environment variable is primarily useful to allow services to optionally upgrade their used log
|
||||
protocol to the native journal protocol (using
|
||||
<citerefentry><refentrytitle>sd_journal_print</refentrytitle><manvolnum>3</manvolnum></citerefentry> and other
|
||||
functions) if their standard output or standard error output is connected to the journal anyway, thus enabling
|
||||
delivery of structured metadata along with logged messages.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<tbody>
|
||||
<row>
|
||||
<entry><literal>success</literal></entry>
|
||||
<entry>The service ran successfully and exited cleanly.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><literal>protocol</literal></entry>
|
||||
<entry>A protocol violation occurred: the service did not take the steps required by its unit configuration (specifically what is configured in its <varname>Type=</varname> setting).</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><literal>timeout</literal></entry>
|
||||
<entry>One of the steps timed out.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><literal>exit-code</literal></entry>
|
||||
<entry>Service process exited with a non-zero exit code; see <varname>$EXIT_CODE</varname> below for the actual exit code returned.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><literal>signal</literal></entry>
|
||||
<entry>A service process was terminated abnormally by a signal, without dumping core. See <varname>$EXIT_CODE</varname> below for the actual signal causing the termination.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><literal>core-dump</literal></entry>
|
||||
<entry>A service process terminated abnormally with a signal and dumped core. See <varname>$EXIT_CODE</varname> below for the signal causing the termination.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><literal>watchdog</literal></entry>
|
||||
<entry>Watchdog keep-alive ping was enabled for the service, but the deadline was missed.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><literal>start-limit-hit</literal></entry>
|
||||
<entry>A start limit was defined for the unit and it was hit, causing the unit to fail to start. See <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>'s <varname>StartLimitIntervalSec=</varname> and <varname>StartLimitBurst=</varname> for details.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><literal>resources</literal></entry>
|
||||
<entry>A catch-all condition in case a system operation failed.</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
<varlistentry>
|
||||
<term><varname>$SERVICE_RESULT</varname></term>
|
||||
|
||||
<para>This environment variable is useful to monitor failure or successful termination of a service. Even
|
||||
though this variable is available in both <varname>ExecStop=</varname> and <varname>ExecStopPost=</varname>, it
|
||||
is usually a better choice to place monitoring tools in the latter, as the former is only invoked for services
|
||||
that managed to start up correctly, and the latter covers both services that failed during their start-up and
|
||||
those which failed during their runtime.</para></listitem>
|
||||
</varlistentry>
|
||||
<listitem><para>Only defined for the service unit type, this environment variable is passed to all
|
||||
<varname>ExecStop=</varname> and <varname>ExecStopPost=</varname> processes, and encodes the service
|
||||
"result". Currently, the following values are defined:</para>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>$EXIT_CODE</varname></term>
|
||||
<term><varname>$EXIT_STATUS</varname></term>
|
||||
<table>
|
||||
<title>Defined <varname>$SERVICE_RESULT</varname> values</title>
|
||||
<tgroup cols='2'>
|
||||
<colspec colname='result'/>
|
||||
<colspec colname='meaning'/>
|
||||
<thead>
|
||||
<row>
|
||||
<entry>Value</entry>
|
||||
<entry>Meaning</entry>
|
||||
</row>
|
||||
</thead>
|
||||
|
||||
<listitem><para>Only defined for the service unit type, these environment variables are passed to all
|
||||
<varname>ExecStop=</varname>, <varname>ExecStopPost=</varname> processes and contain exit status/code
|
||||
information of the main process of the service. For the precise definition of the exit code and status, see
|
||||
<citerefentry><refentrytitle>wait</refentrytitle><manvolnum>2</manvolnum></citerefentry>. <varname>$EXIT_CODE</varname>
|
||||
is one of <literal>exited</literal>, <literal>killed</literal>,
|
||||
<literal>dumped</literal>. <varname>$EXIT_STATUS</varname> contains the numeric exit code formatted as string
|
||||
if <varname>$EXIT_CODE</varname> is <literal>exited</literal>, and the signal name in all other cases. Note
|
||||
that these environment variables are only set if the service manager succeeded to start and identify the main
|
||||
process of the service.</para>
|
||||
<tbody>
|
||||
<row>
|
||||
<entry><literal>success</literal></entry>
|
||||
<entry>The service ran successfully and exited cleanly.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><literal>protocol</literal></entry>
|
||||
<entry>A protocol violation occurred: the service did not take the steps required by its unit configuration (specifically what is configured in its <varname>Type=</varname> setting).</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><literal>timeout</literal></entry>
|
||||
<entry>One of the steps timed out.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><literal>exit-code</literal></entry>
|
||||
<entry>Service process exited with a non-zero exit code; see <varname>$EXIT_CODE</varname> below for the actual exit code returned.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><literal>signal</literal></entry>
|
||||
<entry>A service process was terminated abnormally by a signal, without dumping core. See <varname>$EXIT_CODE</varname> below for the actual signal causing the termination.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><literal>core-dump</literal></entry>
|
||||
<entry>A service process terminated abnormally with a signal and dumped core. See <varname>$EXIT_CODE</varname> below for the signal causing the termination.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><literal>watchdog</literal></entry>
|
||||
<entry>Watchdog keep-alive ping was enabled for the service, but the deadline was missed.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><literal>start-limit-hit</literal></entry>
|
||||
<entry>A start limit was defined for the unit and it was hit, causing the unit to fail to start. See <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>'s <varname>StartLimitIntervalSec=</varname> and <varname>StartLimitBurst=</varname> for details.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><literal>resources</literal></entry>
|
||||
<entry>A catch-all condition in case a system operation failed.</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
|
||||
<table>
|
||||
<title>Summary of possible service result variable values</title>
|
||||
<tgroup cols='3'>
|
||||
<colspec colname='result' />
|
||||
<colspec colname='code' />
|
||||
<colspec colname='status' />
|
||||
<thead>
|
||||
<row>
|
||||
<entry><varname>$SERVICE_RESULT</varname></entry>
|
||||
<entry><varname>$EXIT_CODE</varname></entry>
|
||||
<entry><varname>$EXIT_STATUS</varname></entry>
|
||||
</row>
|
||||
</thead>
|
||||
<para>This environment variable is useful to monitor failure or successful termination of a service. Even
|
||||
though this variable is available in both <varname>ExecStop=</varname> and <varname>ExecStopPost=</varname>, it
|
||||
is usually a better choice to place monitoring tools in the latter, as the former is only invoked for services
|
||||
that managed to start up correctly, and the latter covers both services that failed during their start-up and
|
||||
those which failed during their runtime.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<tbody>
|
||||
<row>
|
||||
<entry morerows="1" valign="top"><literal>success</literal></entry>
|
||||
<entry valign="top"><literal>killed</literal></entry>
|
||||
<entry><literal>HUP</literal>, <literal>INT</literal>, <literal>TERM</literal>, <literal>PIPE</literal></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry valign="top"><literal>exited</literal></entry>
|
||||
<entry><literal>0</literal></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry morerows="1" valign="top"><literal>protocol</literal></entry>
|
||||
<entry valign="top">not set</entry>
|
||||
<entry>not set</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><literal>exited</literal></entry>
|
||||
<entry><literal>0</literal></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry morerows="1" valign="top"><literal>timeout</literal></entry>
|
||||
<entry valign="top"><literal>killed</literal></entry>
|
||||
<entry><literal>TERM</literal>, <literal>KILL</literal></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry valign="top"><literal>exited</literal></entry>
|
||||
<entry><literal>0</literal>, <literal>1</literal>, <literal>2</literal>, <literal
|
||||
>3</literal>, …, <literal>255</literal></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry valign="top"><literal>exit-code</literal></entry>
|
||||
<entry valign="top"><literal>exited</literal></entry>
|
||||
<entry><literal>1</literal>, <literal>2</literal>, <literal
|
||||
>3</literal>, …, <literal>255</literal></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry valign="top"><literal>signal</literal></entry>
|
||||
<entry valign="top"><literal>killed</literal></entry>
|
||||
<entry><literal>HUP</literal>, <literal>INT</literal>, <literal>KILL</literal>, …</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry valign="top"><literal>core-dump</literal></entry>
|
||||
<entry valign="top"><literal>dumped</literal></entry>
|
||||
<entry><literal>ABRT</literal>, <literal>SEGV</literal>, <literal>QUIT</literal>, …</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry morerows="2" valign="top"><literal>watchdog</literal></entry>
|
||||
<entry><literal>dumped</literal></entry>
|
||||
<entry><literal>ABRT</literal></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><literal>killed</literal></entry>
|
||||
<entry><literal>TERM</literal>, <literal>KILL</literal></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><literal>exited</literal></entry>
|
||||
<entry><literal>0</literal>, <literal>1</literal>, <literal>2</literal>, <literal
|
||||
>3</literal>, …, <literal>255</literal></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry valign="top"><literal>exec-condition</literal></entry>
|
||||
<entry><literal>exited</literal></entry>
|
||||
<entry><literal>1</literal>, <literal>2</literal>, <literal>3</literal>, <literal
|
||||
>4</literal>, …, <literal>254</literal></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry valign="top"><literal>oom-kill</literal></entry>
|
||||
<entry valign="top"><literal>killed</literal></entry>
|
||||
<entry><literal>TERM</literal>, <literal>KILL</literal></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><literal>start-limit-hit</literal></entry>
|
||||
<entry>not set</entry>
|
||||
<entry>not set</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><literal>resources</literal></entry>
|
||||
<entry>any of the above</entry>
|
||||
<entry>any of the above</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry namest="results" nameend="status">Note: the process may be also terminated by a signal not sent by systemd. In particular the process may send an arbitrary signal to itself in a handler for any of the non-maskable signals. Nevertheless, in the <literal>timeout</literal> and <literal>watchdog</literal> rows above only the signals that systemd sends have been included. Moreover, using <varname>SuccessExitStatus=</varname> additional exit statuses may be declared to indicate clean termination, which is not reflected by this table.</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
<varlistentry>
|
||||
<term><varname>$EXIT_CODE</varname></term>
|
||||
<term><varname>$EXIT_STATUS</varname></term>
|
||||
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<listitem><para>Only defined for the service unit type, these environment variables are passed to all
|
||||
<varname>ExecStop=</varname>, <varname>ExecStopPost=</varname> processes and contain exit status/code
|
||||
information of the main process of the service. For the precise definition of the exit code and status, see
|
||||
<citerefentry><refentrytitle>wait</refentrytitle><manvolnum>2</manvolnum></citerefentry>. <varname>$EXIT_CODE</varname>
|
||||
is one of <literal>exited</literal>, <literal>killed</literal>,
|
||||
<literal>dumped</literal>. <varname>$EXIT_STATUS</varname> contains the numeric exit code formatted as string
|
||||
if <varname>$EXIT_CODE</varname> is <literal>exited</literal>, and the signal name in all other cases. Note
|
||||
that these environment variables are only set if the service manager succeeded to start and identify the main
|
||||
process of the service.</para>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>$PIDFILE</varname></term>
|
||||
<table>
|
||||
<title>Summary of possible service result variable values</title>
|
||||
<tgroup cols='3'>
|
||||
<colspec colname='result' />
|
||||
<colspec colname='code' />
|
||||
<colspec colname='status' />
|
||||
<thead>
|
||||
<row>
|
||||
<entry><varname>$SERVICE_RESULT</varname></entry>
|
||||
<entry><varname>$EXIT_CODE</varname></entry>
|
||||
<entry><varname>$EXIT_STATUS</varname></entry>
|
||||
</row>
|
||||
</thead>
|
||||
|
||||
<listitem><para>The path to the configured PID file, in case the process is forked off on behalf of a
|
||||
service that uses the <varname>PIDFile=</varname> setting, see
|
||||
<citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>
|
||||
for details. Service code may use this environment variable to automatically generate a PID file at
|
||||
the location configured in the unit file. This field is set to an absolute path in the file
|
||||
system.</para></listitem>
|
||||
</varlistentry>
|
||||
<tbody>
|
||||
<row>
|
||||
<entry morerows="1" valign="top"><literal>success</literal></entry>
|
||||
<entry valign="top"><literal>killed</literal></entry>
|
||||
<entry><literal>HUP</literal>, <literal>INT</literal>, <literal>TERM</literal>, <literal>PIPE</literal></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry valign="top"><literal>exited</literal></entry>
|
||||
<entry><literal>0</literal></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry morerows="1" valign="top"><literal>protocol</literal></entry>
|
||||
<entry valign="top">not set</entry>
|
||||
<entry>not set</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><literal>exited</literal></entry>
|
||||
<entry><literal>0</literal></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry morerows="1" valign="top"><literal>timeout</literal></entry>
|
||||
<entry valign="top"><literal>killed</literal></entry>
|
||||
<entry><literal>TERM</literal>, <literal>KILL</literal></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry valign="top"><literal>exited</literal></entry>
|
||||
<entry><literal>0</literal>, <literal>1</literal>, <literal>2</literal>, <literal
|
||||
>3</literal>, …, <literal>255</literal></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry valign="top"><literal>exit-code</literal></entry>
|
||||
<entry valign="top"><literal>exited</literal></entry>
|
||||
<entry><literal>1</literal>, <literal>2</literal>, <literal
|
||||
>3</literal>, …, <literal>255</literal></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry valign="top"><literal>signal</literal></entry>
|
||||
<entry valign="top"><literal>killed</literal></entry>
|
||||
<entry><literal>HUP</literal>, <literal>INT</literal>, <literal>KILL</literal>, …</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry valign="top"><literal>core-dump</literal></entry>
|
||||
<entry valign="top"><literal>dumped</literal></entry>
|
||||
<entry><literal>ABRT</literal>, <literal>SEGV</literal>, <literal>QUIT</literal>, …</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry morerows="2" valign="top"><literal>watchdog</literal></entry>
|
||||
<entry><literal>dumped</literal></entry>
|
||||
<entry><literal>ABRT</literal></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><literal>killed</literal></entry>
|
||||
<entry><literal>TERM</literal>, <literal>KILL</literal></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><literal>exited</literal></entry>
|
||||
<entry><literal>0</literal>, <literal>1</literal>, <literal>2</literal>, <literal
|
||||
>3</literal>, …, <literal>255</literal></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry valign="top"><literal>exec-condition</literal></entry>
|
||||
<entry><literal>exited</literal></entry>
|
||||
<entry><literal>1</literal>, <literal>2</literal>, <literal>3</literal>, <literal
|
||||
>4</literal>, …, <literal>254</literal></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry valign="top"><literal>oom-kill</literal></entry>
|
||||
<entry valign="top"><literal>killed</literal></entry>
|
||||
<entry><literal>TERM</literal>, <literal>KILL</literal></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><literal>start-limit-hit</literal></entry>
|
||||
<entry>not set</entry>
|
||||
<entry>not set</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><literal>resources</literal></entry>
|
||||
<entry>any of the above</entry>
|
||||
<entry>any of the above</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry namest="results" nameend="status">Note: the process may be also terminated by a signal not sent by systemd. In particular the process may send an arbitrary signal to itself in a handler for any of the non-maskable signals. Nevertheless, in the <literal>timeout</literal> and <literal>watchdog</literal> rows above only the signals that systemd sends have been included. Moreover, using <varname>SuccessExitStatus=</varname> additional exit statuses may be declared to indicate clean termination, which is not reflected by this table.</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table></listitem>
|
||||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
<varlistentry>
|
||||
<term><varname>$PIDFILE</varname></term>
|
||||
|
||||
<listitem><para>The path to the configured PID file, in case the process is forked off on behalf of
|
||||
a service that uses the <varname>PIDFile=</varname> setting, see
|
||||
<citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>
|
||||
for details. Service code may use this environment variable to automatically generate a PID file at
|
||||
the location configured in the unit file. This field is set to an absolute path in the file
|
||||
system.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
|
||||
<para>For system services, when <varname>PAMName=</varname> is enabled and <command>pam_systemd</command> is part
|
||||
of the selected PAM stack, additional environment variables defined by systemd may be set for
|
||||
services. Specifically, these are <varname>$XDG_SEAT</varname>, <varname>$XDG_VTNR</varname>, see
|
||||
<citerefentry><refentrytitle>pam_systemd</refentrytitle><manvolnum>8</manvolnum></citerefentry> for details.</para>
|
||||
</refsect2>
|
||||
|
||||
<para>For system services, when <varname>PAMName=</varname> is enabled and <command>pam_systemd</command> is part
|
||||
of the selected PAM stack, additional environment variables defined by systemd may be set for
|
||||
services. Specifically, these are <varname>$XDG_SEAT</varname>, <varname>$XDG_VTNR</varname>, see
|
||||
<citerefentry><refentrytitle>pam_systemd</refentrytitle><manvolnum>8</manvolnum></citerefentry> for details.</para>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
<title>Process exit codes</title>
|
||||
<title>Process Exit Codes</title>
|
||||
|
||||
<para>When invoking a unit process the service manager possibly fails to apply the execution parameters configured
|
||||
with the settings above. In that case the already created service process will exit with a non-zero exit code
|
||||
|
@ -1622,9 +1622,16 @@
|
||||
<listitem>
|
||||
<para>Sets a comma-separated list of IP (v4 or v6) addresses with CIDR masks
|
||||
from which this peer is allowed to send incoming traffic and to
|
||||
which outgoing traffic for this peer is directed. The catch-all
|
||||
0.0.0.0/0 may be specified for matching all IPv4 addresses, and
|
||||
::/0 may be specified for matching all IPv6 addresses. </para>
|
||||
which outgoing traffic for this peer is directed.</para>
|
||||
<para>The catch-all 0.0.0.0/0 may be specified for matching all IPv4 addresses,
|
||||
and ::/0 may be specified for matching all IPv6 addresses.</para>
|
||||
<para>Note that this only affects "routing inside the network interface itself",
|
||||
as in, which wireguard peer packets with a specific destination address are sent to,
|
||||
and what source addresses are accepted from which peer.</para>
|
||||
<para>To cause packets to be sent via wireguard in first place, a route needs
|
||||
to be added, as well - either in the <literal>[Routes]</literal> section on the
|
||||
<literal>.network</literal> matching the wireguard interface, or outside of networkd.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
|
@ -1032,8 +1032,11 @@ IPv6Token=prefixstable:2002:da8:1::</programlisting></para>
|
||||
<varlistentry>
|
||||
<term><varname>Scope=</varname></term>
|
||||
<listitem>
|
||||
<para>The scope of the address, which can be <literal>global</literal>,
|
||||
<literal>link</literal> or <literal>host</literal> or an unsigned integer in the range 0—255.
|
||||
<para>The scope of the address, which can be
|
||||
<literal>global</literal> (valid everywhere on the network, even through a gateway),
|
||||
<literal>link</literal> (only valid on this device, will not traverse a gateway) or
|
||||
<literal>host</literal> (only valid within the device itself, e.g. 127.0.0.1)
|
||||
or an unsigned integer in the range 0—255.
|
||||
Defaults to <literal>global</literal>.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
@ -1340,12 +1343,32 @@ IPv6Token=prefixstable:2002:da8:1::</programlisting></para>
|
||||
<varlistentry>
|
||||
<term><varname>Scope=</varname></term>
|
||||
<listitem>
|
||||
<para>The scope of the route, which can be <literal>global</literal>, <literal>site</literal>,
|
||||
<literal>link</literal>, <literal>host</literal>, or <literal>nowhere</literal>. For IPv4 route,
|
||||
defaults to <literal>host</literal> if <varname>Type=</varname> is <literal>local</literal>
|
||||
or <literal>nat</literal>, and <literal>link</literal> if <varname>Type=</varname> is
|
||||
<para>The scope of the IPv4 route, which can be <literal>global</literal>, <literal>site</literal>,
|
||||
<literal>link</literal>, <literal>host</literal>, or
|
||||
<literal>nowhere</literal>:</para>
|
||||
<itemizedlist>
|
||||
<listitem><para><literal>global</literal> means the route can reach
|
||||
hosts more than one hop away.</para></listitem>
|
||||
|
||||
<listitem><para><literal>site</literal> means an interior route in
|
||||
the local autonomous system.</para></listitem>
|
||||
|
||||
<listitem><para><literal>link</literal> means the route can only
|
||||
reach hosts on the local network (one hop away).</para></listitem>
|
||||
|
||||
<listitem><para><literal>host</literal> means the route will not
|
||||
leave the local machine (used for internal addresses like
|
||||
127.0.0.1).</para></listitem>
|
||||
|
||||
<listitem><para><literal>nowhere</literal> means the destination
|
||||
doesn't exist.</para></listitem>
|
||||
</itemizedlist>
|
||||
<para>For IPv4 route, defaults to <literal>host</literal> if <varname>Type=</varname> is
|
||||
<literal>local</literal> or <literal>nat</literal>,
|
||||
and <literal>link</literal> if <varname>Type=</varname> is
|
||||
<literal>broadcast</literal>, <literal>multicast</literal>, or <literal>anycast</literal>.
|
||||
In other cases, defaults to <literal>global</literal>.</para>
|
||||
In other cases, defaults to <literal>global</literal>. The value is
|
||||
not used for IPv6.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
|
@ -110,7 +110,7 @@
|
||||
symlink in the distribution package, rather than depending on <command>systemctl
|
||||
enable</command> in the postinst scriptlets of your package. More specifically, for your
|
||||
update script create a .service file, without [Install] section, and then add a symlink like
|
||||
<filename index="false">/usr/lib/systemd/system-update.target.wants/foobar.service</filename>
|
||||
<filename index="false">/usr/lib/systemd/system/system-update.target.wants/foobar.service</filename>
|
||||
→ <filename index="false">../foobar.service</filename> to your package.</para>
|
||||
</listitem>
|
||||
|
||||
|
@ -235,7 +235,7 @@
|
||||
<listitem>
|
||||
<para>Restrict processes to be executed on specific memory NUMA nodes. Takes a list of memory NUMA nodes indices
|
||||
or ranges separated by either whitespace or commas. Memory NUMA nodes ranges are specified by the lower and upper
|
||||
CPU indices separated by a dash.</para>
|
||||
NUMA nodes indices separated by a dash.</para>
|
||||
|
||||
<para>Setting <varname>AllowedMemoryNodes=</varname> doesn't guarantee that all of the memory NUMA nodes will
|
||||
be used by the processes as it may be limited by parent units. The effective configuration is reported as
|
||||
|
@ -320,11 +320,20 @@ _systemctl () {
|
||||
elif __contains_word "$verb" ${VERBS[JOBS]}; then
|
||||
comps=$( __systemctl $mode list-jobs | { while read -r a b; do echo " $a"; done; } )
|
||||
|
||||
elif __contains_word "$verb" ${VERBS[ENVS]}; then
|
||||
elif [ "$verb" = 'unset-environment' ]; then
|
||||
comps=$( __systemctl $mode show-environment \
|
||||
| while read -r line; do echo " ${line%%=*}"; done )
|
||||
compopt -o nospace
|
||||
|
||||
elif [ "$verb" = 'set-environment' ]; then
|
||||
comps=$( __systemctl $mode show-environment \
|
||||
| while read -r line; do echo " ${line%%=*}="; done )
|
||||
compopt -o nospace
|
||||
|
||||
elif [ "$verb" = 'import-environment' ]; then
|
||||
COMPREPLY=( $(compgen -A variable -- "$cur_orig") )
|
||||
return 0
|
||||
|
||||
elif __contains_word "$verb" ${VERBS[FILE]}; then
|
||||
comps=$( compgen -A file -- "$cur" )
|
||||
compopt -o filenames
|
||||
|
@ -365,6 +365,11 @@ for fun in set-environment unset-environment ; do
|
||||
}
|
||||
done
|
||||
|
||||
(( $+functions[_systemctl_import-environment] )) || _systemctl_import-environment()
|
||||
{
|
||||
_parameters
|
||||
}
|
||||
|
||||
(( $+functions[_systemctl_link] )) || _systemctl_link() {
|
||||
_sd_unit_files
|
||||
}
|
||||
|
@ -59,16 +59,13 @@ bool env_value_is_valid(const char *e) {
|
||||
if (!utf8_is_valid(e))
|
||||
return false;
|
||||
|
||||
/* bash allows tabs and newlines in environment variables, and so
|
||||
* should we */
|
||||
if (string_has_cc(e, "\t\n"))
|
||||
return false;
|
||||
/* Note that variable *values* may contain control characters, in particular NL, TAB, BS, DEL, ESC…
|
||||
* When printing those variables with show-environment, we'll escape them. Make sure to print
|
||||
* environment variables carefully! */
|
||||
|
||||
/* POSIX says the overall size of the environment block cannot
|
||||
* be > ARG_MAX, an individual assignment hence cannot be
|
||||
* either. Discounting the shortest possible variable name of
|
||||
* length 1, the equal sign and trailing NUL this hence leaves
|
||||
* ARG_MAX-3 as longest possible variable value. */
|
||||
/* POSIX says the overall size of the environment block cannot be > ARG_MAX, an individual assignment
|
||||
* hence cannot be either. Discounting the shortest possible variable name of length 1, the equal
|
||||
* sign and trailing NUL this hence leaves ARG_MAX-3 as longest possible variable value. */
|
||||
if (strlen(e) > sc_arg_max() - 3)
|
||||
return false;
|
||||
|
||||
@ -88,10 +85,8 @@ bool env_assignment_is_valid(const char *e) {
|
||||
if (!env_value_is_valid(eq + 1))
|
||||
return false;
|
||||
|
||||
/* POSIX says the overall size of the environment block cannot
|
||||
* be > ARG_MAX, hence the individual variable assignments
|
||||
* cannot be either, but let's leave room for one trailing NUL
|
||||
* byte. */
|
||||
/* POSIX says the overall size of the environment block cannot be > ARG_MAX, hence the individual
|
||||
* variable assignments cannot be either, but let's leave room for one trailing NUL byte. */
|
||||
if (strlen(e) > sc_arg_max() - 1)
|
||||
return false;
|
||||
|
||||
|
@ -1976,3 +1976,53 @@ IteratedCache* iterated_cache_free(IteratedCache *cache) {
|
||||
|
||||
return mfree(cache);
|
||||
}
|
||||
|
||||
int set_strjoin(Set *s, const char *separator, bool wrap_with_separator, char **ret) {
|
||||
size_t separator_len, allocated = 0, len = 0;
|
||||
_cleanup_free_ char *str = NULL;
|
||||
const char *value;
|
||||
bool first;
|
||||
|
||||
assert(ret);
|
||||
|
||||
if (set_isempty(s)) {
|
||||
*ret = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
separator_len = strlen_ptr(separator);
|
||||
|
||||
if (separator_len == 0)
|
||||
wrap_with_separator = false;
|
||||
|
||||
first = !wrap_with_separator;
|
||||
|
||||
SET_FOREACH(value, s) {
|
||||
size_t l = strlen_ptr(value);
|
||||
|
||||
if (l == 0)
|
||||
continue;
|
||||
|
||||
if (!GREEDY_REALLOC(str, allocated, len + l + (first ? 0 : separator_len) + (wrap_with_separator ? separator_len : 0) + 1))
|
||||
return -ENOMEM;
|
||||
|
||||
if (separator_len > 0 && !first) {
|
||||
memcpy(str + len, separator, separator_len);
|
||||
len += separator_len;
|
||||
}
|
||||
|
||||
memcpy(str + len, value, l);
|
||||
len += l;
|
||||
first = false;
|
||||
}
|
||||
|
||||
if (wrap_with_separator) {
|
||||
memcpy(str + len, separator, separator_len);
|
||||
len += separator_len;
|
||||
}
|
||||
|
||||
str[len] = '\0';
|
||||
|
||||
*ret = TAKE_PTR(str);
|
||||
return 0;
|
||||
}
|
||||
|
@ -132,6 +132,29 @@ static int fd_fdinfo_mnt_id(int fd, const char *filename, int flags, int *ret_mn
|
||||
return safe_atoi(p, ret_mnt_id);
|
||||
}
|
||||
|
||||
static bool filename_possibly_with_slash_suffix(const char *s) {
|
||||
const char *slash, *copied;
|
||||
|
||||
/* Checks whether the specified string is either file name, or a filename with a suffix of
|
||||
* slashes. But nothing else.
|
||||
*
|
||||
* this is OK: foo, bar, foo/, bar/, foo//, bar///
|
||||
* this is not OK: "", "/", "/foo", "foo/bar", ".", ".." … */
|
||||
|
||||
slash = strchr(s, '/');
|
||||
if (!slash)
|
||||
return filename_is_valid(s);
|
||||
|
||||
if (slash - s > FILENAME_MAX) /* We want to allocate on the stack below, hence do a size check first */
|
||||
return false;
|
||||
|
||||
if (slash[strspn(slash, "/")] != 0) /* Check that the suffix consist only of one or more slashes */
|
||||
return false;
|
||||
|
||||
copied = strndupa(s, slash - s);
|
||||
return filename_is_valid(copied);
|
||||
}
|
||||
|
||||
int fd_is_mount_point(int fd, const char *filename, int flags) {
|
||||
_cleanup_free_ struct file_handle *h = NULL, *h_parent = NULL;
|
||||
int mount_id = -1, mount_id_parent = -1;
|
||||
@ -144,6 +167,11 @@ int fd_is_mount_point(int fd, const char *filename, int flags) {
|
||||
assert(filename);
|
||||
assert((flags & ~(AT_SYMLINK_FOLLOW|AT_EMPTY_PATH)) == 0);
|
||||
|
||||
/* Insist that the specified filename is actually a filename, and not a path, i.e. some inode further
|
||||
* up or down the tree then immediately below the specified directory fd. */
|
||||
if (!filename_possibly_with_slash_suffix(filename))
|
||||
return -EINVAL;
|
||||
|
||||
/* First we will try statx()' STATX_ATTR_MOUNT_ROOT attribute, which is our ideal API, available
|
||||
* since kernel 5.8.
|
||||
*
|
||||
|
@ -150,3 +150,5 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(Set*, set_free_free);
|
||||
|
||||
#define _cleanup_set_free_ _cleanup_(set_freep)
|
||||
#define _cleanup_set_free_free_ _cleanup_(set_free_freep)
|
||||
|
||||
int set_strjoin(Set *s, const char *separator, bool wrap_with_separator, char **ret);
|
||||
|
@ -5,9 +5,9 @@
|
||||
#include <inttypes.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "string-util.h"
|
||||
#include "time-util.h"
|
||||
|
||||
struct siphash {
|
||||
@ -33,11 +33,15 @@ static inline void siphash24_compress_usec_t(usec_t in, struct siphash *state) {
|
||||
siphash24_compress(&in, sizeof in, state);
|
||||
}
|
||||
|
||||
static inline void siphash24_compress_string(const char *in, struct siphash *state) {
|
||||
if (!in)
|
||||
static inline void siphash24_compress_safe(const void *in, size_t inlen, struct siphash *state) {
|
||||
if (inlen == 0)
|
||||
return;
|
||||
|
||||
siphash24_compress(in, strlen(in), state);
|
||||
siphash24_compress(in, inlen, state);
|
||||
}
|
||||
|
||||
static inline void siphash24_compress_string(const char *in, struct siphash *state) {
|
||||
siphash24_compress_safe(in, strlen_ptr(in), state);
|
||||
}
|
||||
|
||||
uint64_t siphash24_finalize(struct siphash *state);
|
||||
|
@ -226,13 +226,12 @@ int fd_is_network_fs(int fd) {
|
||||
}
|
||||
|
||||
int path_is_temporary_fs(const char *path) {
|
||||
_cleanup_close_ int fd = -1;
|
||||
struct statfs s;
|
||||
|
||||
fd = open(path, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_PATH);
|
||||
if (fd < 0)
|
||||
if (statfs(path, &s) < 0)
|
||||
return -errno;
|
||||
|
||||
return fd_is_temporary_fs(fd);
|
||||
return is_temporary_fs(&s);
|
||||
}
|
||||
|
||||
int stat_verify_regular(const struct stat *st) {
|
||||
|
@ -844,11 +844,14 @@ int bpf_firewall_supported(void) {
|
||||
* CONFIG_CGROUP_BPF is turned off, then the call will fail early with EINVAL. If it is turned on the
|
||||
* parameters are validated however, and that'll fail with EBADF then. */
|
||||
|
||||
attr = (union bpf_attr) {
|
||||
.attach_type = BPF_CGROUP_INET_EGRESS,
|
||||
.target_fd = -1,
|
||||
.attach_bpf_fd = -1,
|
||||
};
|
||||
// FIXME: Clang doesn't 0-pad with structured initialization, causing
|
||||
// the kernel to reject the bpf_attr as invalid. See:
|
||||
// https://github.com/torvalds/linux/blob/v5.9/kernel/bpf/syscall.c#L65
|
||||
// Ideally it should behave like GCC, so that we can remove these workarounds.
|
||||
zero(attr);
|
||||
attr.attach_type = BPF_CGROUP_INET_EGRESS;
|
||||
attr.target_fd = -1;
|
||||
attr.attach_bpf_fd = -1;
|
||||
|
||||
if (bpf(BPF_PROG_DETACH, &attr, sizeof(attr)) < 0) {
|
||||
if (errno != EBADF) {
|
||||
@ -868,12 +871,11 @@ int bpf_firewall_supported(void) {
|
||||
* bpf() call and the BPF_F_ALLOW_MULTI flags value. Since the flags are checked early in the system call we'll
|
||||
* get EINVAL if it's not supported, and EBADF as before if it is available. */
|
||||
|
||||
attr = (union bpf_attr) {
|
||||
.attach_type = BPF_CGROUP_INET_EGRESS,
|
||||
.target_fd = -1,
|
||||
.attach_bpf_fd = -1,
|
||||
.attach_flags = BPF_F_ALLOW_MULTI,
|
||||
};
|
||||
zero(attr);
|
||||
attr.attach_type = BPF_CGROUP_INET_EGRESS;
|
||||
attr.target_fd = -1;
|
||||
attr.attach_bpf_fd = -1;
|
||||
attr.attach_flags = BPF_F_ALLOW_MULTI;
|
||||
|
||||
if (bpf(BPF_PROG_ATTACH, &attr, sizeof(attr)) < 0) {
|
||||
if (errno == EBADF) {
|
||||
|
@ -24,7 +24,7 @@
|
||||
#include "hexdecoct.h"
|
||||
#include "io-util.h"
|
||||
#include "ioprio.h"
|
||||
#include "journal-util.h"
|
||||
#include "journal-file.h"
|
||||
#include "mountpoint-util.h"
|
||||
#include "namespace.h"
|
||||
#include "parse-util.h"
|
||||
|
@ -38,7 +38,7 @@
|
||||
#include "io-util.h"
|
||||
#include "ioprio.h"
|
||||
#include "ip-protocol-list.h"
|
||||
#include "journal-util.h"
|
||||
#include "journal-file.h"
|
||||
#include "limits-util.h"
|
||||
#include "load-fragment.h"
|
||||
#include "log.h"
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
# RPM macros for packages installing systemd unit files
|
||||
|
||||
%_systemd_util_dir @rootlibexecdir@
|
||||
%_unitdir @systemunitdir@
|
||||
%_userunitdir @userunitdir@
|
||||
%_presetdir @systempresetdir@
|
||||
|
@ -2387,6 +2387,10 @@ static int manager_dispatch_notify_fd(sd_event_source *source, int fd, uint32_t
|
||||
n = recvmsg_safe(m->notify_fd, &msghdr, MSG_DONTWAIT|MSG_CMSG_CLOEXEC|MSG_TRUNC);
|
||||
if (IN_SET(n, -EAGAIN, -EINTR))
|
||||
return 0; /* Spurious wakeup, try again */
|
||||
if (n == -EXFULL) {
|
||||
log_warning("Got message with truncated control data (too many fds sent?), ignoring.");
|
||||
return 0;
|
||||
}
|
||||
if (n < 0)
|
||||
/* If this is any other, real error, then let's stop processing this socket. This of course
|
||||
* means we won't take notification messages anymore, but that's still better than busy
|
||||
|
@ -55,6 +55,8 @@ static bool arg_verify = false;
|
||||
static bool arg_discards = false;
|
||||
static bool arg_same_cpu_crypt = false;
|
||||
static bool arg_submit_from_crypt_cpus = false;
|
||||
static bool arg_no_read_workqueue = false;
|
||||
static bool arg_no_write_workqueue = false;
|
||||
static bool arg_tcrypt_hidden = false;
|
||||
static bool arg_tcrypt_system = false;
|
||||
static bool arg_tcrypt_veracrypt = false;
|
||||
@ -218,6 +220,10 @@ static int parse_one_option(const char *option) {
|
||||
arg_same_cpu_crypt = true;
|
||||
else if (streq(option, "submit-from-crypt-cpus"))
|
||||
arg_submit_from_crypt_cpus = true;
|
||||
else if (streq(option, "no-read-workqueue"))
|
||||
arg_no_read_workqueue = true;
|
||||
else if (streq(option, "no-write-workqueue"))
|
||||
arg_no_write_workqueue = true;
|
||||
else if (streq(option, "luks"))
|
||||
arg_type = ANY_LUKS;
|
||||
/* since cryptsetup 2.3.0 (Feb 2020) */
|
||||
@ -805,6 +811,12 @@ static uint32_t determine_flags(void) {
|
||||
if (arg_submit_from_crypt_cpus)
|
||||
flags |= CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS;
|
||||
|
||||
if (arg_no_read_workqueue)
|
||||
flags |= CRYPT_ACTIVATE_NO_READ_WORKQUEUE;
|
||||
|
||||
if (arg_no_write_workqueue)
|
||||
flags |= CRYPT_ACTIVATE_NO_WRITE_WORKQUEUE;
|
||||
|
||||
#ifdef CRYPT_ACTIVATE_SERIALIZE_MEMORY_HARD_PBKDF
|
||||
/* Try to decrease the risk of OOM event if memory hard key derivation function is in use */
|
||||
/* https://gitlab.com/cryptsetup/cryptsetup/issues/446/ */
|
||||
|
2
src/fuzz/fuzz-nspawn-oci.options
Normal file
2
src/fuzz/fuzz-nspawn-oci.options
Normal file
@ -0,0 +1,2 @@
|
||||
[libfuzzer]
|
||||
max_len = 65536
|
2
src/fuzz/fuzz-nspawn-settings.options
Normal file
2
src/fuzz/fuzz-nspawn-settings.options
Normal file
@ -0,0 +1,2 @@
|
||||
[libfuzzer]
|
||||
max_len = 65536
|
2
src/fuzz/fuzz-udev-rules.options
Normal file
2
src/fuzz/fuzz-udev-rules.options
Normal file
@ -0,0 +1,2 @@
|
||||
[libfuzzer]
|
||||
max_len = 65536
|
2
src/fuzz/fuzz-unit-file.options
Normal file
2
src/fuzz/fuzz-unit-file.options
Normal file
@ -0,0 +1,2 @@
|
||||
[libfuzzer]
|
||||
max_len = 65536
|
@ -296,9 +296,8 @@ static void tar_pull_job_on_finished(PullJob *j) {
|
||||
goto finish;
|
||||
}
|
||||
|
||||
/* This is invoked if either the download completed
|
||||
* successfully, or the download was skipped because we
|
||||
* already have the etag. */
|
||||
/* This is invoked if either the download completed successfully, or the download was skipped because
|
||||
* we already have the etag. */
|
||||
|
||||
if (!tar_pull_is_done(i))
|
||||
return;
|
||||
@ -340,6 +339,10 @@ static void tar_pull_job_on_finished(PullJob *j) {
|
||||
|
||||
tar_pull_report_progress(i, TAR_FINALIZING);
|
||||
|
||||
r = import_mangle_os_tree(i->temp_path);
|
||||
if (r < 0)
|
||||
goto finish;
|
||||
|
||||
r = import_make_read_only(i->temp_path);
|
||||
if (r < 0)
|
||||
goto finish;
|
||||
|
@ -1525,6 +1525,44 @@ int journal_file_find_data_object(
|
||||
ret, ret_offset);
|
||||
}
|
||||
|
||||
bool journal_field_valid(const char *p, size_t l, bool allow_protected) {
|
||||
const char *a;
|
||||
|
||||
/* We kinda enforce POSIX syntax recommendations for
|
||||
environment variables here, but make a couple of additional
|
||||
requirements.
|
||||
|
||||
http://pubs.opengroup.org/onlinepubs/000095399/basedefs/xbd_chap08.html */
|
||||
|
||||
if (l == (size_t) -1)
|
||||
l = strlen(p);
|
||||
|
||||
/* No empty field names */
|
||||
if (l <= 0)
|
||||
return false;
|
||||
|
||||
/* Don't allow names longer than 64 chars */
|
||||
if (l > 64)
|
||||
return false;
|
||||
|
||||
/* Variables starting with an underscore are protected */
|
||||
if (!allow_protected && p[0] == '_')
|
||||
return false;
|
||||
|
||||
/* Don't allow digits as first character */
|
||||
if (p[0] >= '0' && p[0] <= '9')
|
||||
return false;
|
||||
|
||||
/* Only allow A-Z0-9 and '_' */
|
||||
for (a = p; a < p + l; a++)
|
||||
if ((*a < 'A' || *a > 'Z') &&
|
||||
(*a < '0' || *a > '9') &&
|
||||
*a != '_')
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int journal_file_append_field(
|
||||
JournalFile *f,
|
||||
const void *field, uint64_t size,
|
||||
@ -1538,6 +1576,9 @@ static int journal_file_append_field(
|
||||
assert(f);
|
||||
assert(field && size > 0);
|
||||
|
||||
if (!journal_field_valid(field, size, true))
|
||||
return -EBADMSG;
|
||||
|
||||
hash = journal_file_hash_data(f, field, size);
|
||||
|
||||
r = journal_file_find_field_object_with_hash(f, field, size, hash, &o, &p);
|
||||
|
@ -272,3 +272,5 @@ static inline bool JOURNAL_FILE_COMPRESS(JournalFile *f) {
|
||||
}
|
||||
|
||||
uint64_t journal_file_hash_data(JournalFile *f, const void *data, size_t sz);
|
||||
|
||||
bool journal_field_valid(const char *p, size_t l, bool allow_protected);
|
||||
|
@ -15,6 +15,7 @@
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
const char *namespace;
|
||||
LogTarget log_target;
|
||||
Server server;
|
||||
int r;
|
||||
|
||||
@ -25,8 +26,13 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
namespace = argc > 1 ? empty_to_null(argv[1]) : NULL;
|
||||
|
||||
log_set_prohibit_ipc(true);
|
||||
log_set_target(LOG_TARGET_AUTO);
|
||||
/* So here's the deal: journald can't be considered as regular daemon when it comes to
|
||||
* logging hence LOG_TARGET_AUTO won't do the right thing for it. Hence explicitly log to
|
||||
* the console if we're started from a console or to kmsg otherwise. */
|
||||
log_target = isatty(STDERR_FILENO) > 0 ? LOG_TARGET_CONSOLE : LOG_TARGET_KMSG;
|
||||
|
||||
log_set_prohibit_ipc(true); /* better safe than sorry */
|
||||
log_set_target(log_target);
|
||||
log_set_facility(LOG_SYSLOG);
|
||||
log_parse_environment();
|
||||
log_open();
|
||||
|
@ -38,11 +38,14 @@ static int option_append(uint8_t options[], size_t size, size_t *offset,
|
||||
size_t total = 0;
|
||||
char **s;
|
||||
|
||||
if (strv_isempty((char **) optval))
|
||||
return -EINVAL;
|
||||
|
||||
STRV_FOREACH(s, (char **) optval) {
|
||||
size_t len = strlen(*s);
|
||||
|
||||
if (len > 255)
|
||||
return -ENAMETOOLONG;
|
||||
if (len > 255 || len == 0)
|
||||
return -EINVAL;
|
||||
|
||||
total += 1 + len;
|
||||
}
|
||||
@ -51,14 +54,13 @@ static int option_append(uint8_t options[], size_t size, size_t *offset,
|
||||
return -ENOBUFS;
|
||||
|
||||
options[*offset] = code;
|
||||
options[*offset + 1] = total;
|
||||
options[*offset + 1] = total;
|
||||
*offset += 2;
|
||||
|
||||
STRV_FOREACH(s, (char **) optval) {
|
||||
size_t len = strlen(*s);
|
||||
|
||||
options[*offset] = len;
|
||||
|
||||
memcpy(&options[*offset + 1], *s, len);
|
||||
*offset += 1 + len;
|
||||
}
|
||||
|
@ -99,8 +99,8 @@ int dhcp6_option_append(uint8_t **buf, size_t *buflen, uint16_t code,
|
||||
int dhcp6_option_append_ia(uint8_t **buf, size_t *buflen, const DHCP6IA *ia);
|
||||
int dhcp6_option_append_pd(uint8_t *buf, size_t len, const DHCP6IA *pd, DHCP6Address *hint_pd_prefix);
|
||||
int dhcp6_option_append_fqdn(uint8_t **buf, size_t *buflen, const char *fqdn);
|
||||
int dhcp6_option_append_user_class(uint8_t **buf, size_t *buflen, char **user_class);
|
||||
int dhcp6_option_append_vendor_class(uint8_t **buf, size_t *buflen, char **user_class);
|
||||
int dhcp6_option_append_user_class(uint8_t **buf, size_t *buflen, char * const *user_class);
|
||||
int dhcp6_option_append_vendor_class(uint8_t **buf, size_t *buflen, char * const *user_class);
|
||||
int dhcp6_option_append_vendor_option(uint8_t **buf, size_t *buflen, OrderedHashmap *vendor_options);
|
||||
int dhcp6_option_parse(uint8_t **buf, size_t *buflen, uint16_t *optcode,
|
||||
size_t *optlen, uint8_t **optvalue);
|
||||
|
@ -200,19 +200,22 @@ int dhcp6_option_append_fqdn(uint8_t **buf, size_t *buflen, const char *fqdn) {
|
||||
return r;
|
||||
}
|
||||
|
||||
int dhcp6_option_append_user_class(uint8_t **buf, size_t *buflen, char **user_class) {
|
||||
int dhcp6_option_append_user_class(uint8_t **buf, size_t *buflen, char * const *user_class) {
|
||||
_cleanup_free_ uint8_t *p = NULL;
|
||||
size_t total = 0, offset = 0;
|
||||
char **s;
|
||||
char * const *s;
|
||||
|
||||
assert_return(buf && *buf && buflen && user_class, -EINVAL);
|
||||
assert(buf);
|
||||
assert(*buf);
|
||||
assert(buflen);
|
||||
assert(!strv_isempty(user_class));
|
||||
|
||||
STRV_FOREACH(s, user_class) {
|
||||
size_t len = strlen(*s);
|
||||
uint8_t *q;
|
||||
|
||||
if (len > 0xffff)
|
||||
return -ENAMETOOLONG;
|
||||
if (len > 0xffff || len == 0)
|
||||
return -EINVAL;
|
||||
q = realloc(p, total + len + 2);
|
||||
if (!q)
|
||||
return -ENOMEM;
|
||||
@ -229,16 +232,16 @@ int dhcp6_option_append_user_class(uint8_t **buf, size_t *buflen, char **user_cl
|
||||
return dhcp6_option_append(buf, buflen, SD_DHCP6_OPTION_USER_CLASS, total, p);
|
||||
}
|
||||
|
||||
int dhcp6_option_append_vendor_class(uint8_t **buf, size_t *buflen, char **vendor_class) {
|
||||
int dhcp6_option_append_vendor_class(uint8_t **buf, size_t *buflen, char * const *vendor_class) {
|
||||
_cleanup_free_ uint8_t *p = NULL;
|
||||
uint32_t enterprise_identifier;
|
||||
size_t total, offset;
|
||||
char **s;
|
||||
char * const *s;
|
||||
|
||||
assert(buf);
|
||||
assert(*buf);
|
||||
assert(buflen);
|
||||
assert(vendor_class);
|
||||
assert(!strv_isempty(vendor_class));
|
||||
|
||||
enterprise_identifier = htobe32(SYSTEMD_PEN);
|
||||
|
||||
@ -253,6 +256,9 @@ int dhcp6_option_append_vendor_class(uint8_t **buf, size_t *buflen, char **vendo
|
||||
size_t len = strlen(*s);
|
||||
uint8_t *q;
|
||||
|
||||
if (len > UINT16_MAX || len == 0)
|
||||
return -EINVAL;
|
||||
|
||||
q = realloc(p, total + len + 2);
|
||||
if (!q)
|
||||
return -ENOMEM;
|
||||
|
@ -566,22 +566,26 @@ int sd_dhcp_client_set_mud_url(
|
||||
|
||||
int sd_dhcp_client_set_user_class(
|
||||
sd_dhcp_client *client,
|
||||
const char* const* user_class) {
|
||||
char * const *user_class) {
|
||||
|
||||
_cleanup_strv_free_ char **s = NULL;
|
||||
char **p;
|
||||
char * const *p;
|
||||
char **s = NULL;
|
||||
|
||||
STRV_FOREACH(p, (char **) user_class)
|
||||
if (strlen(*p) > 255)
|
||||
return -ENAMETOOLONG;
|
||||
assert_return(client, -EINVAL);
|
||||
assert_return(!strv_isempty(user_class), -EINVAL);
|
||||
|
||||
s = strv_copy((char **) user_class);
|
||||
STRV_FOREACH(p, user_class) {
|
||||
size_t n = strlen(*p);
|
||||
|
||||
if (n > 255 || n == 0)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
s = strv_copy(user_class);
|
||||
if (!s)
|
||||
return -ENOMEM;
|
||||
|
||||
client->user_class = TAKE_PTR(s);
|
||||
|
||||
return 0;
|
||||
return strv_free_and_replace(client->user_class, s);
|
||||
}
|
||||
|
||||
int sd_dhcp_client_set_client_port(
|
||||
|
@ -464,47 +464,48 @@ int sd_dhcp6_client_set_request_mud_url(sd_dhcp6_client *client, const char *mud
|
||||
return free_and_strdup(&client->mudurl, mudurl);
|
||||
}
|
||||
|
||||
int sd_dhcp6_client_set_request_user_class(sd_dhcp6_client *client, char **user_class) {
|
||||
_cleanup_strv_free_ char **s = NULL;
|
||||
char **p;
|
||||
int sd_dhcp6_client_set_request_user_class(sd_dhcp6_client *client, char * const *user_class) {
|
||||
char * const *p;
|
||||
char **s;
|
||||
|
||||
assert_return(client, -EINVAL);
|
||||
assert_return(client->state == DHCP6_STATE_STOPPED, -EBUSY);
|
||||
assert_return(!strv_isempty(user_class), -EINVAL);
|
||||
|
||||
assert_return(user_class, -EINVAL);
|
||||
STRV_FOREACH(p, user_class) {
|
||||
size_t len = strlen(*p);
|
||||
|
||||
STRV_FOREACH(p, user_class)
|
||||
if (strlen(*p) > UINT16_MAX)
|
||||
return -ENAMETOOLONG;
|
||||
if (len > UINT16_MAX || len == 0)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
s = strv_copy(user_class);
|
||||
if (!s)
|
||||
return -ENOMEM;
|
||||
|
||||
client->user_class = TAKE_PTR(s);
|
||||
|
||||
return 0;
|
||||
return strv_free_and_replace(client->user_class, s);
|
||||
}
|
||||
|
||||
int sd_dhcp6_client_set_request_vendor_class(sd_dhcp6_client *client, char **vendor_class) {
|
||||
_cleanup_strv_free_ char **s = NULL;
|
||||
char **p;
|
||||
int sd_dhcp6_client_set_request_vendor_class(sd_dhcp6_client *client, char * const *vendor_class) {
|
||||
char * const *p;
|
||||
char **s;
|
||||
|
||||
assert_return(client, -EINVAL);
|
||||
assert_return(client->state == DHCP6_STATE_STOPPED, -EBUSY);
|
||||
assert_return(vendor_class, -EINVAL);
|
||||
assert_return(!strv_isempty(vendor_class), -EINVAL);
|
||||
|
||||
STRV_FOREACH(p, vendor_class)
|
||||
if (strlen(*p) > UINT8_MAX)
|
||||
return -ENAMETOOLONG;
|
||||
STRV_FOREACH(p, vendor_class) {
|
||||
size_t len = strlen(*p);
|
||||
|
||||
if (len > UINT16_MAX || len == 0)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
s = strv_copy(vendor_class);
|
||||
if (!s)
|
||||
return -ENOMEM;
|
||||
|
||||
client->vendor_class = TAKE_PTR(s);
|
||||
|
||||
return 0;
|
||||
return strv_free_and_replace(client->vendor_class, s);
|
||||
}
|
||||
|
||||
int sd_dhcp6_client_get_prefix_delegation(sd_dhcp6_client *client, int *delegation) {
|
||||
|
@ -713,7 +713,7 @@ _public_ int sd_bus_get_name_creds(
|
||||
}
|
||||
|
||||
r = bus_creds_add_more(c, mask, pid, 0);
|
||||
if (r < 0)
|
||||
if (r < 0 && r != -ESRCH) /* Return the error, but ignore ESRCH which just means the process is already gone */
|
||||
return r;
|
||||
}
|
||||
|
||||
@ -788,7 +788,7 @@ _public_ int sd_bus_get_owner_creds(sd_bus *bus, uint64_t mask, sd_bus_creds **r
|
||||
}
|
||||
|
||||
r = bus_creds_add_more(c, mask, pid, 0);
|
||||
if (r < 0)
|
||||
if (r < 0 && r != -ESRCH) /* If the process vanished, then don't complain, just return what we got */
|
||||
return r;
|
||||
|
||||
*ret = TAKE_PTR(c);
|
||||
|
@ -603,13 +603,15 @@ _public_ int sd_bus_set_property(
|
||||
return r;
|
||||
}
|
||||
|
||||
_public_ int sd_bus_query_sender_creds(sd_bus_message *call, uint64_t mask, sd_bus_creds **creds) {
|
||||
_public_ int sd_bus_query_sender_creds(sd_bus_message *call, uint64_t mask, sd_bus_creds **ret) {
|
||||
sd_bus_creds *c;
|
||||
int r;
|
||||
|
||||
assert_return(call, -EINVAL);
|
||||
assert_return(call->sealed, -EPERM);
|
||||
assert_return(call->bus, -EINVAL);
|
||||
assert_return(!bus_pid_changed(call->bus), -ECHILD);
|
||||
assert_return(ret, -EINVAL);
|
||||
|
||||
if (!BUS_IS_OPEN(call->bus->state))
|
||||
return -ENOTCONN;
|
||||
@ -618,7 +620,7 @@ _public_ int sd_bus_query_sender_creds(sd_bus_message *call, uint64_t mask, sd_b
|
||||
|
||||
/* All data we need? */
|
||||
if (c && (mask & ~c->mask) == 0) {
|
||||
*creds = sd_bus_creds_ref(c);
|
||||
*ret = sd_bus_creds_ref(c);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -629,15 +631,22 @@ _public_ int sd_bus_query_sender_creds(sd_bus_message *call, uint64_t mask, sd_b
|
||||
|
||||
if (call->sender)
|
||||
/* There's a sender, but the creds are missing. */
|
||||
return sd_bus_get_name_creds(call->bus, call->sender, mask, creds);
|
||||
return sd_bus_get_name_creds(call->bus, call->sender, mask, ret);
|
||||
else
|
||||
/* There's no sender. For direct connections
|
||||
* the credentials of the AF_UNIX peer matter,
|
||||
* which may be queried via sd_bus_get_owner_creds(). */
|
||||
return sd_bus_get_owner_creds(call->bus, mask, creds);
|
||||
return sd_bus_get_owner_creds(call->bus, mask, ret);
|
||||
}
|
||||
|
||||
return bus_creds_extend_by_pid(c, mask, creds);
|
||||
r = bus_creds_extend_by_pid(c, mask, ret);
|
||||
if (r == -ESRCH) {
|
||||
/* Process doesn't exist anymore? propagate the few things we have */
|
||||
*ret = sd_bus_creds_ref(c);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
_public_ int sd_bus_query_sender_privilege(sd_bus_message *call, int capability) {
|
||||
|
@ -319,7 +319,10 @@ static int device_amend(sd_device *device, const char *key, const char *value) {
|
||||
for (const char *p = value;;) {
|
||||
_cleanup_free_ char *word = NULL;
|
||||
|
||||
r = extract_first_word(&p, &word, NULL, 0);
|
||||
/* udev rules may set escaped strings, and sd-device does not modify the input
|
||||
* strings. So, it is also necessary to keep the strings received through
|
||||
* sd-device-monitor. */
|
||||
r = extract_first_word(&p, &word, NULL, EXTRACT_RETAIN_ESCAPE);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0)
|
||||
|
@ -1518,30 +1518,6 @@ _public_ const char *sd_device_get_devlink_next(sd_device *device) {
|
||||
return v;
|
||||
}
|
||||
|
||||
static char *join_string_set(Set *s) {
|
||||
size_t ret_allocated = 0, ret_len;
|
||||
_cleanup_free_ char *ret = NULL;
|
||||
const char *tag;
|
||||
|
||||
if (!GREEDY_REALLOC(ret, ret_allocated, 2))
|
||||
return NULL;
|
||||
|
||||
strcpy(ret, ":");
|
||||
ret_len = 1;
|
||||
|
||||
SET_FOREACH(tag, s) {
|
||||
char *e;
|
||||
|
||||
if (!GREEDY_REALLOC(ret, ret_allocated, ret_len + strlen(tag) + 2))
|
||||
return NULL;
|
||||
|
||||
e = stpcpy(stpcpy(ret + ret_len, tag), ":");
|
||||
ret_len = e - ret;
|
||||
}
|
||||
|
||||
return TAKE_PTR(ret);
|
||||
}
|
||||
|
||||
int device_properties_prepare(sd_device *device) {
|
||||
int r;
|
||||
|
||||
@ -1557,46 +1533,39 @@ int device_properties_prepare(sd_device *device) {
|
||||
|
||||
if (device->property_devlinks_outdated) {
|
||||
_cleanup_free_ char *devlinks = NULL;
|
||||
size_t devlinks_allocated = 0, devlinks_len = 0;
|
||||
const char *devlink;
|
||||
|
||||
for (devlink = sd_device_get_devlink_first(device); devlink; devlink = sd_device_get_devlink_next(device)) {
|
||||
char *e;
|
||||
|
||||
if (!GREEDY_REALLOC(devlinks, devlinks_allocated, devlinks_len + strlen(devlink) + 2))
|
||||
return -ENOMEM;
|
||||
if (devlinks_len > 0)
|
||||
stpcpy(devlinks + devlinks_len++, " ");
|
||||
e = stpcpy(devlinks + devlinks_len, devlink);
|
||||
devlinks_len = e - devlinks;
|
||||
}
|
||||
|
||||
r = device_add_property_internal(device, "DEVLINKS", devlinks);
|
||||
r = set_strjoin(device->devlinks, " ", false, &devlinks);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!isempty(devlinks)) {
|
||||
r = device_add_property_internal(device, "DEVLINKS", devlinks);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
device->property_devlinks_outdated = false;
|
||||
}
|
||||
|
||||
if (device->property_tags_outdated) {
|
||||
_cleanup_free_ char *tags = NULL;
|
||||
|
||||
tags = join_string_set(device->all_tags);
|
||||
if (!tags)
|
||||
return -ENOMEM;
|
||||
r = set_strjoin(device->all_tags, ":", true, &tags);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!streq(tags, ":")) {
|
||||
if (!isempty(tags)) {
|
||||
r = device_add_property_internal(device, "TAGS", tags);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
free(tags);
|
||||
tags = join_string_set(device->current_tags);
|
||||
if (!tags)
|
||||
return -ENOMEM;
|
||||
tags = mfree(tags);
|
||||
r = set_strjoin(device->current_tags, ":", true, &tags);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!streq(tags, ":")) {
|
||||
if (!isempty(tags)) {
|
||||
r = device_add_property_internal(device, "CURRENT_TAGS", tags);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
@ -112,68 +112,74 @@ static void test_login(void) {
|
||||
|
||||
if (session) {
|
||||
r = sd_session_is_active(session);
|
||||
assert_se(r >= 0);
|
||||
log_info("sd_session_is_active(\"%s\") → %s", session, yes_no(r));
|
||||
if (r == -ENXIO)
|
||||
log_notice("sd_session_is_active() failed with ENXIO, it seems logind is not running.");
|
||||
else {
|
||||
/* All those tests will fail with ENXIO, so let's skip them. */
|
||||
|
||||
r = sd_session_is_remote(session);
|
||||
assert_se(r >= 0);
|
||||
log_info("sd_session_is_remote(\"%s\") → %s", session, yes_no(r));
|
||||
assert_se(r >= 0);
|
||||
log_info("sd_session_is_active(\"%s\") → %s", session, yes_no(r));
|
||||
|
||||
r = sd_session_get_state(session, &state);
|
||||
assert_se(r == 0);
|
||||
log_info("sd_session_get_state(\"%s\") → \"%s\"", session, state);
|
||||
r = sd_session_is_remote(session);
|
||||
assert_se(r >= 0);
|
||||
log_info("sd_session_is_remote(\"%s\") → %s", session, yes_no(r));
|
||||
|
||||
assert_se(sd_session_get_uid(session, &u) >= 0);
|
||||
log_info("sd_session_get_uid(\"%s\") → "UID_FMT, session, u);
|
||||
assert_se(u == u2);
|
||||
r = sd_session_get_state(session, &state);
|
||||
assert_se(r == 0);
|
||||
log_info("sd_session_get_state(\"%s\") → \"%s\"", session, state);
|
||||
|
||||
assert_se(sd_session_get_type(session, &type) >= 0);
|
||||
log_info("sd_session_get_type(\"%s\") → \"%s\"", session, type);
|
||||
assert_se(sd_session_get_uid(session, &u) >= 0);
|
||||
log_info("sd_session_get_uid(\"%s\") → "UID_FMT, session, u);
|
||||
assert_se(u == u2);
|
||||
|
||||
assert_se(sd_session_get_class(session, &class) >= 0);
|
||||
log_info("sd_session_get_class(\"%s\") → \"%s\"", session, class);
|
||||
assert_se(sd_session_get_type(session, &type) >= 0);
|
||||
log_info("sd_session_get_type(\"%s\") → \"%s\"", session, type);
|
||||
|
||||
r = sd_session_get_display(session, &display);
|
||||
assert_se(IN_SET(r, 0, -ENODATA));
|
||||
log_info("sd_session_get_display(\"%s\") → \"%s\"", session, strna(display));
|
||||
assert_se(sd_session_get_class(session, &class) >= 0);
|
||||
log_info("sd_session_get_class(\"%s\") → \"%s\"", session, class);
|
||||
|
||||
r = sd_session_get_remote_user(session, &remote_user);
|
||||
assert_se(IN_SET(r, 0, -ENODATA));
|
||||
log_info("sd_session_get_remote_user(\"%s\") → \"%s\"",
|
||||
session, strna(remote_user));
|
||||
r = sd_session_get_display(session, &display);
|
||||
assert_se(IN_SET(r, 0, -ENODATA));
|
||||
log_info("sd_session_get_display(\"%s\") → \"%s\"", session, strna(display));
|
||||
|
||||
r = sd_session_get_remote_host(session, &remote_host);
|
||||
assert_se(IN_SET(r, 0, -ENODATA));
|
||||
log_info("sd_session_get_remote_host(\"%s\") → \"%s\"",
|
||||
session, strna(remote_host));
|
||||
r = sd_session_get_remote_user(session, &remote_user);
|
||||
assert_se(IN_SET(r, 0, -ENODATA));
|
||||
log_info("sd_session_get_remote_user(\"%s\") → \"%s\"",
|
||||
session, strna(remote_user));
|
||||
|
||||
r = sd_session_get_seat(session, &seat);
|
||||
if (r >= 0) {
|
||||
assert_se(seat);
|
||||
r = sd_session_get_remote_host(session, &remote_host);
|
||||
assert_se(IN_SET(r, 0, -ENODATA));
|
||||
log_info("sd_session_get_remote_host(\"%s\") → \"%s\"",
|
||||
session, strna(remote_host));
|
||||
|
||||
log_info("sd_session_get_seat(\"%s\") → \"%s\"", session, seat);
|
||||
r = sd_session_get_seat(session, &seat);
|
||||
if (r >= 0) {
|
||||
assert_se(seat);
|
||||
|
||||
log_info("sd_session_get_seat(\"%s\") → \"%s\"", session, seat);
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||
r = sd_seat_can_multi_session(seat);
|
||||
r = sd_seat_can_multi_session(seat);
|
||||
#pragma GCC diagnostic pop
|
||||
assert_se(r == 1);
|
||||
log_info("sd_session_can_multi_seat(\"%s\") → %s", seat, yes_no(r));
|
||||
assert_se(r == 1);
|
||||
log_info("sd_session_can_multi_seat(\"%s\") → %s", seat, yes_no(r));
|
||||
|
||||
r = sd_seat_can_tty(seat);
|
||||
assert_se(r >= 0);
|
||||
log_info("sd_session_can_tty(\"%s\") → %s", seat, yes_no(r));
|
||||
r = sd_seat_can_tty(seat);
|
||||
assert_se(r >= 0);
|
||||
log_info("sd_session_can_tty(\"%s\") → %s", seat, yes_no(r));
|
||||
|
||||
r = sd_seat_can_graphical(seat);
|
||||
assert_se(r >= 0);
|
||||
log_info("sd_session_can_graphical(\"%s\") → %s", seat, yes_no(r));
|
||||
} else {
|
||||
log_info_errno(r, "sd_session_get_seat(\"%s\"): %m", session);
|
||||
assert_se(r == -ENODATA);
|
||||
r = sd_seat_can_graphical(seat);
|
||||
assert_se(r >= 0);
|
||||
log_info("sd_session_can_graphical(\"%s\") → %s", seat, yes_no(r));
|
||||
} else {
|
||||
log_info_errno(r, "sd_session_get_seat(\"%s\"): %m", session);
|
||||
assert_se(r == -ENODATA);
|
||||
}
|
||||
|
||||
assert_se(sd_uid_get_state(u, &state2) == 0);
|
||||
log_info("sd_uid_get_state("UID_FMT", …) → %s", u, state2);
|
||||
}
|
||||
|
||||
assert_se(sd_uid_get_state(u, &state2) == 0);
|
||||
log_info("sd_uid_get_state("UID_FMT", …) → %s", u, state2);
|
||||
}
|
||||
|
||||
if (seat) {
|
||||
@ -214,7 +220,7 @@ static void test_login(void) {
|
||||
assert_se(sd_get_seats(NULL) == r);
|
||||
|
||||
r = sd_seat_get_active(NULL, &t, NULL);
|
||||
assert_se(IN_SET(r, 0, -ENODATA));
|
||||
assert_se(IN_SET(r, 0, -ENODATA, -ENXIO));
|
||||
log_info("sd_seat_get_active(NULL, …) (active session on current seat) → %s / \"%s\"", e(r), strnull(t));
|
||||
free(t);
|
||||
|
||||
|
@ -532,6 +532,7 @@ int config_parse_dhcp_user_class(
|
||||
|
||||
for (const char *p = rvalue;;) {
|
||||
_cleanup_free_ char *w = NULL;
|
||||
size_t len;
|
||||
|
||||
r = extract_first_word(&p, &w, NULL, EXTRACT_CUNESCAPE|EXTRACT_UNQUOTE);
|
||||
if (r == -ENOMEM)
|
||||
@ -544,25 +545,24 @@ int config_parse_dhcp_user_class(
|
||||
if (r == 0)
|
||||
return 0;
|
||||
|
||||
len = strlen(w);
|
||||
if (ltype == AF_INET) {
|
||||
if (strlen(w) > UINT8_MAX) {
|
||||
if (len > UINT8_MAX || len == 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, 0,
|
||||
"%s length is not in the range 1-255, ignoring.", w);
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
if (strlen(w) > UINT16_MAX) {
|
||||
if (len > UINT16_MAX || len == 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, 0,
|
||||
"%s length is not in the range 1-65535, ignoring.", w);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
r = strv_push(l, w);
|
||||
r = strv_consume(l, TAKE_PTR(w));
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
w = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1452,7 +1452,7 @@ int dhcp4_configure(Link *link) {
|
||||
}
|
||||
|
||||
if (link->network->dhcp_user_class) {
|
||||
r = sd_dhcp_client_set_user_class(link->dhcp_client, (const char **) link->network->dhcp_user_class);
|
||||
r = sd_dhcp_client_set_user_class(link->dhcp_client, link->network->dhcp_user_class);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set user class: %m");
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ static int ipv6_proxy_ndp_address_configure(Link *link, const struct in6_addr *a
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not create RTM_NEWNEIGH message: %m");
|
||||
|
||||
r = sd_rtnl_message_neigh_set_flags(req, NLM_F_REQUEST | NTF_PROXY);
|
||||
r = sd_rtnl_message_neigh_set_flags(req, NTF_PROXY);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not set neighbor flags: %m");
|
||||
|
||||
|
@ -308,8 +308,6 @@ static int routing_policy_rule_add_internal(Manager *m, Set **rules, RoutingPoli
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
rule->manager = m;
|
||||
|
||||
r = routing_policy_rule_copy(rule, in);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@ -322,6 +320,8 @@ static int routing_policy_rule_add_internal(Manager *m, Set **rules, RoutingPoli
|
||||
if (r == 0)
|
||||
return -EEXIST;
|
||||
|
||||
rule->manager = m;
|
||||
|
||||
if (ret)
|
||||
*ret = rule;
|
||||
|
||||
|
@ -100,6 +100,10 @@ static int link_set_ipv6_privacy_extensions(Link *link) {
|
||||
if (!link->network)
|
||||
return 0;
|
||||
|
||||
// this is the special "kernel" value
|
||||
if (link->network->ipv6_privacy_extensions == _IPV6_PRIVACY_EXTENSIONS_INVALID)
|
||||
return 0;
|
||||
|
||||
return sysctl_write_ip_property_int(AF_INET6, link->ifname, "use_tempaddr", (int) link->network->ipv6_privacy_extensions);
|
||||
}
|
||||
|
||||
@ -194,7 +198,7 @@ int link_set_sysctl(Link *link) {
|
||||
|
||||
r = link_set_ipv6_privacy_extensions(link);
|
||||
if (r < 0)
|
||||
log_link_warning_errno(link, r, "Cannot configure IPv6 privacy extension for interface, ignoring: %m");
|
||||
log_link_warning_errno(link, r, "Cannot configure IPv6 privacy extensions for interface, ignoring: %m");
|
||||
|
||||
r = link_set_ipv6_accept_ra(link);
|
||||
if (r < 0)
|
||||
|
@ -3965,6 +3965,10 @@ static int nspawn_dispatch_notify_fd(sd_event_source *source, int fd, uint32_t r
|
||||
n = recvmsg_safe(fd, &msghdr, MSG_DONTWAIT|MSG_CMSG_CLOEXEC);
|
||||
if (IN_SET(n, -EAGAIN, -EINTR))
|
||||
return 0;
|
||||
if (n == -EXFULL) {
|
||||
log_warning("Got message with truncated control data (too many fds sent?), ignoring.");
|
||||
return 0;
|
||||
}
|
||||
if (n < 0)
|
||||
return log_warning_errno(n, "Couldn't read notification socket: %m");
|
||||
|
||||
|
@ -26,6 +26,7 @@ static int dns_query_candidate_new(DnsQueryCandidate **ret, DnsQuery *q, DnsScop
|
||||
return -ENOMEM;
|
||||
|
||||
*c = (DnsQueryCandidate) {
|
||||
.n_ref = 1,
|
||||
.query = q,
|
||||
.scope = s,
|
||||
};
|
||||
@ -49,8 +50,7 @@ static void dns_query_candidate_stop(DnsQueryCandidate *c) {
|
||||
}
|
||||
}
|
||||
|
||||
DnsQueryCandidate* dns_query_candidate_free(DnsQueryCandidate *c) {
|
||||
|
||||
static DnsQueryCandidate* dns_query_candidate_free(DnsQueryCandidate *c) {
|
||||
if (!c)
|
||||
return NULL;
|
||||
|
||||
@ -68,8 +68,10 @@ DnsQueryCandidate* dns_query_candidate_free(DnsQueryCandidate *c) {
|
||||
return mfree(c);
|
||||
}
|
||||
|
||||
DEFINE_PUBLIC_TRIVIAL_REF_UNREF_FUNC(DnsQueryCandidate, dns_query_candidate, dns_query_candidate_free);
|
||||
|
||||
static int dns_query_candidate_next_search_domain(DnsQueryCandidate *c) {
|
||||
DnsSearchDomain *next = NULL;
|
||||
DnsSearchDomain *next;
|
||||
|
||||
assert(c);
|
||||
|
||||
@ -130,12 +132,16 @@ static int dns_query_candidate_add_transaction(DnsQueryCandidate *c, DnsResource
|
||||
}
|
||||
|
||||
static int dns_query_candidate_go(DnsQueryCandidate *c) {
|
||||
_cleanup_(dns_query_candidate_unrefp) DnsQueryCandidate *keep_c = NULL;
|
||||
DnsTransaction *t;
|
||||
int r;
|
||||
unsigned n = 0;
|
||||
|
||||
assert(c);
|
||||
|
||||
/* Let's keep a reference to the query while we're operating */
|
||||
keep_c = dns_query_candidate_ref(c);
|
||||
|
||||
/* Start the transactions that are not started yet */
|
||||
SET_FOREACH(t, c->transactions) {
|
||||
if (t->state != DNS_TRANSACTION_NULL)
|
||||
@ -297,11 +303,11 @@ static void dns_query_stop(DnsQuery *q) {
|
||||
dns_query_candidate_stop(c);
|
||||
}
|
||||
|
||||
static void dns_query_free_candidates(DnsQuery *q) {
|
||||
static void dns_query_unref_candidates(DnsQuery *q) {
|
||||
assert(q);
|
||||
|
||||
while (q->candidates)
|
||||
dns_query_candidate_free(q->candidates);
|
||||
dns_query_candidate_unref(q->candidates);
|
||||
}
|
||||
|
||||
static void dns_query_reset_answer(DnsQuery *q) {
|
||||
@ -330,7 +336,7 @@ DnsQuery *dns_query_free(DnsQuery *q) {
|
||||
LIST_REMOVE(auxiliary_queries, q->auxiliary_for->auxiliary_queries, q);
|
||||
}
|
||||
|
||||
dns_query_free_candidates(q);
|
||||
dns_query_unref_candidates(q);
|
||||
|
||||
dns_question_unref(q->question_idna);
|
||||
dns_question_unref(q->question_utf8);
|
||||
@ -505,7 +511,7 @@ static int on_query_timeout(sd_event_source *s, usec_t usec, void *userdata) {
|
||||
}
|
||||
|
||||
static int dns_query_add_candidate(DnsQuery *q, DnsScope *s) {
|
||||
_cleanup_(dns_query_candidate_freep) DnsQueryCandidate *c = NULL;
|
||||
_cleanup_(dns_query_candidate_unrefp) DnsQueryCandidate *c = NULL;
|
||||
int r;
|
||||
|
||||
assert(q);
|
||||
@ -592,8 +598,8 @@ static int dns_query_try_etc_hosts(DnsQuery *q) {
|
||||
|
||||
assert(q);
|
||||
|
||||
/* Looks in /etc/hosts for matching entries. Note that this is done *before* the normal lookup is done. The
|
||||
* data from /etc/hosts hence takes precedence over the network. */
|
||||
/* Looks in /etc/hosts for matching entries. Note that this is done *before* the normal lookup is
|
||||
* done. The data from /etc/hosts hence takes precedence over the network. */
|
||||
|
||||
r = manager_etc_hosts_lookup(
|
||||
q->manager,
|
||||
@ -926,7 +932,7 @@ static int dns_query_cname_redirect(DnsQuery *q, const DnsResourceRecord *cname)
|
||||
dns_question_unref(q->question_utf8);
|
||||
q->question_utf8 = TAKE_PTR(nq_utf8);
|
||||
|
||||
dns_query_free_candidates(q);
|
||||
dns_query_unref_candidates(q);
|
||||
dns_query_reset_answer(q);
|
||||
|
||||
q->state = DNS_TRANSACTION_NULL;
|
||||
|
@ -16,12 +16,14 @@ typedef struct DnsStubListenerExtra DnsStubListenerExtra;
|
||||
#include "resolved-dns-transaction.h"
|
||||
|
||||
struct DnsQueryCandidate {
|
||||
unsigned n_ref;
|
||||
int error_code;
|
||||
|
||||
DnsQuery *query;
|
||||
DnsScope *scope;
|
||||
|
||||
DnsSearchDomain *search_domain;
|
||||
|
||||
int error_code;
|
||||
Set *transactions;
|
||||
|
||||
LIST_FIELDS(DnsQueryCandidate, candidates_by_query);
|
||||
@ -31,19 +33,19 @@ struct DnsQueryCandidate {
|
||||
struct DnsQuery {
|
||||
Manager *manager;
|
||||
|
||||
/* When resolving a service, we first create a TXT+SRV query,
|
||||
* and then for the hostnames we discover auxiliary A+AAAA
|
||||
* queries. This pointer always points from the auxiliary
|
||||
* queries back to the TXT+SRV query. */
|
||||
/* When resolving a service, we first create a TXT+SRV query, and then for the hostnames we discover
|
||||
* auxiliary A+AAAA queries. This pointer always points from the auxiliary queries back to the
|
||||
* TXT+SRV query. */
|
||||
DnsQuery *auxiliary_for;
|
||||
LIST_HEAD(DnsQuery, auxiliary_queries);
|
||||
unsigned n_auxiliary_queries;
|
||||
int auxiliary_result;
|
||||
|
||||
/* The question, formatted in IDNA for use on classic DNS, and as UTF8 for use in LLMNR or mDNS. Note that even
|
||||
* on classic DNS some labels might use UTF8 encoding. Specifically, DNS-SD service names (in contrast to their
|
||||
* domain suffixes) use UTF-8 encoding even on DNS. Thus, the difference between these two fields is mostly
|
||||
* relevant only for explicit *hostname* lookups as well as the domain suffixes of service lookups. */
|
||||
/* The question, formatted in IDNA for use on classic DNS, and as UTF8 for use in LLMNR or mDNS. Note
|
||||
* that even on classic DNS some labels might use UTF8 encoding. Specifically, DNS-SD service names
|
||||
* (in contrast to their domain suffixes) use UTF-8 encoding even on DNS. Thus, the difference
|
||||
* between these two fields is mostly relevant only for explicit *hostname* lookups as well as the
|
||||
* domain suffixes of service lookups. */
|
||||
DnsQuestion *question_idna;
|
||||
DnsQuestion *question_utf8;
|
||||
|
||||
@ -101,8 +103,9 @@ enum {
|
||||
DNS_QUERY_RESTARTED,
|
||||
};
|
||||
|
||||
DnsQueryCandidate* dns_query_candidate_free(DnsQueryCandidate *c);
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(DnsQueryCandidate*, dns_query_candidate_free);
|
||||
DnsQueryCandidate* dns_query_candidate_ref(DnsQueryCandidate*);
|
||||
DnsQueryCandidate* dns_query_candidate_unref(DnsQueryCandidate*);
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(DnsQueryCandidate*, dns_query_candidate_unref);
|
||||
|
||||
void dns_query_candidate_notify(DnsQueryCandidate *c);
|
||||
|
||||
|
@ -1373,7 +1373,7 @@ void dns_resource_record_hash_func(const DnsResourceRecord *rr, struct siphash *
|
||||
DnsTxtItem *j;
|
||||
|
||||
LIST_FOREACH(items, j, rr->txt.items) {
|
||||
siphash24_compress(j->data, j->length, state);
|
||||
siphash24_compress_safe(j->data, j->length, state);
|
||||
|
||||
/* Add an extra NUL byte, so that "a" followed by "b" doesn't result in the same hash as "ab"
|
||||
* followed by "". */
|
||||
@ -1418,14 +1418,14 @@ void dns_resource_record_hash_func(const DnsResourceRecord *rr, struct siphash *
|
||||
case DNS_TYPE_SSHFP:
|
||||
siphash24_compress(&rr->sshfp.algorithm, sizeof(rr->sshfp.algorithm), state);
|
||||
siphash24_compress(&rr->sshfp.fptype, sizeof(rr->sshfp.fptype), state);
|
||||
siphash24_compress(rr->sshfp.fingerprint, rr->sshfp.fingerprint_size, state);
|
||||
siphash24_compress_safe(rr->sshfp.fingerprint, rr->sshfp.fingerprint_size, state);
|
||||
break;
|
||||
|
||||
case DNS_TYPE_DNSKEY:
|
||||
siphash24_compress(&rr->dnskey.flags, sizeof(rr->dnskey.flags), state);
|
||||
siphash24_compress(&rr->dnskey.protocol, sizeof(rr->dnskey.protocol), state);
|
||||
siphash24_compress(&rr->dnskey.algorithm, sizeof(rr->dnskey.algorithm), state);
|
||||
siphash24_compress(rr->dnskey.key, rr->dnskey.key_size, state);
|
||||
siphash24_compress_safe(rr->dnskey.key, rr->dnskey.key_size, state);
|
||||
break;
|
||||
|
||||
case DNS_TYPE_RRSIG:
|
||||
@ -1437,7 +1437,7 @@ void dns_resource_record_hash_func(const DnsResourceRecord *rr, struct siphash *
|
||||
siphash24_compress(&rr->rrsig.inception, sizeof(rr->rrsig.inception), state);
|
||||
siphash24_compress(&rr->rrsig.key_tag, sizeof(rr->rrsig.key_tag), state);
|
||||
dns_name_hash_func(rr->rrsig.signer, state);
|
||||
siphash24_compress(rr->rrsig.signature, rr->rrsig.signature_size, state);
|
||||
siphash24_compress_safe(rr->rrsig.signature, rr->rrsig.signature_size, state);
|
||||
break;
|
||||
|
||||
case DNS_TYPE_NSEC:
|
||||
@ -1451,15 +1451,15 @@ void dns_resource_record_hash_func(const DnsResourceRecord *rr, struct siphash *
|
||||
siphash24_compress(&rr->ds.key_tag, sizeof(rr->ds.key_tag), state);
|
||||
siphash24_compress(&rr->ds.algorithm, sizeof(rr->ds.algorithm), state);
|
||||
siphash24_compress(&rr->ds.digest_type, sizeof(rr->ds.digest_type), state);
|
||||
siphash24_compress(rr->ds.digest, rr->ds.digest_size, state);
|
||||
siphash24_compress_safe(rr->ds.digest, rr->ds.digest_size, state);
|
||||
break;
|
||||
|
||||
case DNS_TYPE_NSEC3:
|
||||
siphash24_compress(&rr->nsec3.algorithm, sizeof(rr->nsec3.algorithm), state);
|
||||
siphash24_compress(&rr->nsec3.flags, sizeof(rr->nsec3.flags), state);
|
||||
siphash24_compress(&rr->nsec3.iterations, sizeof(rr->nsec3.iterations), state);
|
||||
siphash24_compress(rr->nsec3.salt, rr->nsec3.salt_size, state);
|
||||
siphash24_compress(rr->nsec3.next_hashed_name, rr->nsec3.next_hashed_name_size, state);
|
||||
siphash24_compress_safe(rr->nsec3.salt, rr->nsec3.salt_size, state);
|
||||
siphash24_compress_safe(rr->nsec3.next_hashed_name, rr->nsec3.next_hashed_name_size, state);
|
||||
/* FIXME: We leave the bitmaps out */
|
||||
break;
|
||||
|
||||
@ -1467,18 +1467,18 @@ void dns_resource_record_hash_func(const DnsResourceRecord *rr, struct siphash *
|
||||
siphash24_compress(&rr->tlsa.cert_usage, sizeof(rr->tlsa.cert_usage), state);
|
||||
siphash24_compress(&rr->tlsa.selector, sizeof(rr->tlsa.selector), state);
|
||||
siphash24_compress(&rr->tlsa.matching_type, sizeof(rr->tlsa.matching_type), state);
|
||||
siphash24_compress(rr->tlsa.data, rr->tlsa.data_size, state);
|
||||
siphash24_compress_safe(rr->tlsa.data, rr->tlsa.data_size, state);
|
||||
break;
|
||||
|
||||
case DNS_TYPE_CAA:
|
||||
siphash24_compress(&rr->caa.flags, sizeof(rr->caa.flags), state);
|
||||
string_hash_func(rr->caa.tag, state);
|
||||
siphash24_compress(rr->caa.value, rr->caa.value_size, state);
|
||||
siphash24_compress_safe(rr->caa.value, rr->caa.value_size, state);
|
||||
break;
|
||||
|
||||
case DNS_TYPE_OPENPGPKEY:
|
||||
default:
|
||||
siphash24_compress(rr->generic.data, rr->generic.data_size, state);
|
||||
siphash24_compress_safe(rr->generic.data, rr->generic.data_size, state);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -105,7 +105,7 @@ DnsScope* dns_scope_free(DnsScope *s) {
|
||||
dns_scope_abort_transactions(s);
|
||||
|
||||
while (s->query_candidates)
|
||||
dns_query_candidate_free(s->query_candidates);
|
||||
dns_query_candidate_unref(s->query_candidates);
|
||||
|
||||
hashmap_free(s->transactions_by_key);
|
||||
|
||||
|
@ -152,8 +152,8 @@ bool dns_transaction_gc(DnsTransaction *t) {
|
||||
static uint16_t pick_new_id(Manager *m) {
|
||||
uint16_t new_id;
|
||||
|
||||
/* Find a fresh, unused transaction id. Note that this loop is bounded because there's a limit on the number of
|
||||
* transactions, and it's much lower than the space of IDs. */
|
||||
/* Find a fresh, unused transaction id. Note that this loop is bounded because there's a limit on the
|
||||
* number of transactions, and it's much lower than the space of IDs. */
|
||||
|
||||
assert_cc(TRANSACTIONS_MAX < 0xFFFF);
|
||||
|
||||
@ -1338,6 +1338,10 @@ static int dns_transaction_prepare(DnsTransaction *t, usec_t ts) {
|
||||
|
||||
assert(t);
|
||||
|
||||
/* Returns 0 if dns_transaction_complete() has been called. In that case the transaction and query
|
||||
* candidate objects may have been invalidated and must not be accessed. Returns 1 if the transaction
|
||||
* has been prepared. */
|
||||
|
||||
dns_transaction_stop_timeout(t);
|
||||
|
||||
if (!dns_scope_network_good(t->scope)) {
|
||||
@ -1465,7 +1469,6 @@ static int dns_transaction_prepare(DnsTransaction *t, usec_t ts) {
|
||||
}
|
||||
|
||||
static int dns_transaction_make_packet_mdns(DnsTransaction *t) {
|
||||
|
||||
_cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
|
||||
bool add_known_answers = false;
|
||||
DnsTransaction *other;
|
||||
@ -1633,8 +1636,9 @@ int dns_transaction_go(DnsTransaction *t) {
|
||||
|
||||
assert(t);
|
||||
|
||||
/* Returns > 0 if the transaction is now pending, returns 0 if could be processed immediately and has finished
|
||||
* now. */
|
||||
/* Returns > 0 if the transaction is now pending, returns 0 if could be processed immediately and has
|
||||
* finished now. In the latter case, the transaction and query candidate objects must not be accessed.
|
||||
*/
|
||||
|
||||
assert_se(sd_event_now(t->scope->manager->event, clock_boottime_or_monotonic(), &ts) >= 0);
|
||||
|
||||
@ -1692,7 +1696,7 @@ int dns_transaction_go(DnsTransaction *t) {
|
||||
t->state = DNS_TRANSACTION_PENDING;
|
||||
|
||||
log_debug("Delaying %s transaction for " USEC_FMT "us.", dns_protocol_to_string(t->scope->protocol), jitter);
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Otherwise, we need to ask the network */
|
||||
|
@ -943,6 +943,10 @@ int ask_password_agent(
|
||||
n = recvmsg_safe(socket_fd, &msghdr, 0);
|
||||
if (IN_SET(n, -EAGAIN, -EINTR))
|
||||
continue;
|
||||
if (n == -EXFULL) {
|
||||
log_debug("Got message with truncated control data, ignoring.");
|
||||
continue;
|
||||
}
|
||||
if (n < 0) {
|
||||
r = (int) n;
|
||||
goto finish;
|
||||
|
@ -76,15 +76,18 @@ int bpf_program_load_kernel(BPFProgram *p, char *log_buf, size_t log_size) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
attr = (union bpf_attr) {
|
||||
.prog_type = p->prog_type,
|
||||
.insns = PTR_TO_UINT64(p->instructions),
|
||||
.insn_cnt = p->n_instructions,
|
||||
.license = PTR_TO_UINT64("GPL"),
|
||||
.log_buf = PTR_TO_UINT64(log_buf),
|
||||
.log_level = !!log_buf,
|
||||
.log_size = log_size,
|
||||
};
|
||||
// FIXME: Clang doesn't 0-pad with structured initialization, causing
|
||||
// the kernel to reject the bpf_attr as invalid. See:
|
||||
// https://github.com/torvalds/linux/blob/v5.9/kernel/bpf/syscall.c#L65
|
||||
// Ideally it should behave like GCC, so that we can remove these workarounds.
|
||||
zero(attr);
|
||||
attr.prog_type = p->prog_type;
|
||||
attr.insns = PTR_TO_UINT64(p->instructions);
|
||||
attr.insn_cnt = p->n_instructions;
|
||||
attr.license = PTR_TO_UINT64("GPL");
|
||||
attr.log_buf = PTR_TO_UINT64(log_buf);
|
||||
attr.log_level = !!log_buf;
|
||||
attr.log_size = log_size;
|
||||
|
||||
p->kernel_fd = bpf(BPF_PROG_LOAD, &attr, sizeof(attr));
|
||||
if (p->kernel_fd < 0)
|
||||
@ -101,9 +104,8 @@ int bpf_program_load_from_bpf_fs(BPFProgram *p, const char *path) {
|
||||
if (p->kernel_fd >= 0) /* don't overwrite an assembled or loaded program */
|
||||
return -EBUSY;
|
||||
|
||||
attr = (union bpf_attr) {
|
||||
.pathname = PTR_TO_UINT64(path),
|
||||
};
|
||||
zero(attr);
|
||||
attr.pathname = PTR_TO_UINT64(path);
|
||||
|
||||
p->kernel_fd = bpf(BPF_OBJ_GET, &attr, sizeof(attr));
|
||||
if (p->kernel_fd < 0)
|
||||
@ -158,12 +160,11 @@ int bpf_program_cgroup_attach(BPFProgram *p, int type, const char *path, uint32_
|
||||
if (fd < 0)
|
||||
return -errno;
|
||||
|
||||
attr = (union bpf_attr) {
|
||||
.attach_type = type,
|
||||
.target_fd = fd,
|
||||
.attach_bpf_fd = p->kernel_fd,
|
||||
.attach_flags = flags,
|
||||
};
|
||||
zero(attr);
|
||||
attr.attach_type = type;
|
||||
attr.target_fd = fd;
|
||||
attr.attach_bpf_fd = p->kernel_fd;
|
||||
attr.attach_flags = flags;
|
||||
|
||||
if (bpf(BPF_PROG_ATTACH, &attr, sizeof(attr)) < 0)
|
||||
return -errno;
|
||||
@ -194,11 +195,10 @@ int bpf_program_cgroup_detach(BPFProgram *p) {
|
||||
} else {
|
||||
union bpf_attr attr;
|
||||
|
||||
attr = (union bpf_attr) {
|
||||
.attach_type = p->attached_type,
|
||||
.target_fd = fd,
|
||||
.attach_bpf_fd = p->kernel_fd,
|
||||
};
|
||||
zero(attr);
|
||||
attr.attach_type = p->attached_type;
|
||||
attr.target_fd = fd;
|
||||
attr.attach_bpf_fd = p->kernel_fd;
|
||||
|
||||
if (bpf(BPF_PROG_DETACH, &attr, sizeof(attr)) < 0)
|
||||
return -errno;
|
||||
@ -210,15 +210,16 @@ int bpf_program_cgroup_detach(BPFProgram *p) {
|
||||
}
|
||||
|
||||
int bpf_map_new(enum bpf_map_type type, size_t key_size, size_t value_size, size_t max_entries, uint32_t flags) {
|
||||
union bpf_attr attr = {
|
||||
.map_type = type,
|
||||
.key_size = key_size,
|
||||
.value_size = value_size,
|
||||
.max_entries = max_entries,
|
||||
.map_flags = flags,
|
||||
};
|
||||
union bpf_attr attr;
|
||||
int fd;
|
||||
|
||||
zero(attr);
|
||||
attr.map_type = type;
|
||||
attr.key_size = key_size;
|
||||
attr.value_size = value_size;
|
||||
attr.max_entries = max_entries;
|
||||
attr.map_flags = flags;
|
||||
|
||||
fd = bpf(BPF_MAP_CREATE, &attr, sizeof(attr));
|
||||
if (fd < 0)
|
||||
return -errno;
|
||||
@ -227,12 +228,12 @@ int bpf_map_new(enum bpf_map_type type, size_t key_size, size_t value_size, size
|
||||
}
|
||||
|
||||
int bpf_map_update_element(int fd, const void *key, void *value) {
|
||||
union bpf_attr attr;
|
||||
|
||||
union bpf_attr attr = {
|
||||
.map_fd = fd,
|
||||
.key = PTR_TO_UINT64(key),
|
||||
.value = PTR_TO_UINT64(value),
|
||||
};
|
||||
zero(attr);
|
||||
attr.map_fd = fd;
|
||||
attr.key = PTR_TO_UINT64(key);
|
||||
attr.value = PTR_TO_UINT64(value);
|
||||
|
||||
if (bpf(BPF_MAP_UPDATE_ELEM, &attr, sizeof(attr)) < 0)
|
||||
return -errno;
|
||||
@ -241,12 +242,12 @@ int bpf_map_update_element(int fd, const void *key, void *value) {
|
||||
}
|
||||
|
||||
int bpf_map_lookup_element(int fd, const void *key, void *value) {
|
||||
union bpf_attr attr;
|
||||
|
||||
union bpf_attr attr = {
|
||||
.map_fd = fd,
|
||||
.key = PTR_TO_UINT64(key),
|
||||
.value = PTR_TO_UINT64(value),
|
||||
};
|
||||
zero(attr);
|
||||
attr.map_fd = fd;
|
||||
attr.key = PTR_TO_UINT64(key);
|
||||
attr.value = PTR_TO_UINT64(value);
|
||||
|
||||
if (bpf(BPF_MAP_LOOKUP_ELEM, &attr, sizeof(attr)) < 0)
|
||||
return -errno;
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "sd-bus.h"
|
||||
#include "sd-event.h"
|
||||
|
||||
#include "errno-util.h"
|
||||
#include "macro.h"
|
||||
#include "string-util.h"
|
||||
#include "time-util.h"
|
||||
@ -39,13 +40,21 @@ int bus_connect_transport(BusTransport transport, const char *host, bool user, s
|
||||
int bus_connect_transport_systemd(BusTransport transport, const char *host, bool user, sd_bus **bus);
|
||||
|
||||
#define bus_log_address_error(r) \
|
||||
log_error_errno(r, \
|
||||
r == -ENOMEDIUM ? "Failed to set bus address: $DBUS_SESSION_BUS_ADDRESS and $XDG_RUNTIME_DIR not defined" : \
|
||||
"Failed to set bus address: %m")
|
||||
({ \
|
||||
int _k = (r); \
|
||||
log_error_errno(_k, \
|
||||
_k == -ENOMEDIUM ? "Failed to set bus address: $DBUS_SESSION_BUS_ADDRESS and $XDG_RUNTIME_DIR not defined (consider using --machine=<user>@.host --user to connect to bus of other user)" : \
|
||||
"Failed to set bus address: %m"); \
|
||||
})
|
||||
|
||||
#define bus_log_connect_error(r) \
|
||||
log_error_errno(r, \
|
||||
r == -ENOMEDIUM ? "Failed to connect to bus: $DBUS_SESSION_BUS_ADDRESS and $XDG_RUNTIME_DIR not defined" : \
|
||||
"Failed to connect to bus: %m")
|
||||
({ \
|
||||
int _k = (r); \
|
||||
log_error_errno(_k, \
|
||||
_k == -ENOMEDIUM ? "Failed to connect to bus: $DBUS_SESSION_BUS_ADDRESS and $XDG_RUNTIME_DIR not defined (consider using --machine=<user>@.host --user to connect to bus of other user)" : \
|
||||
ERRNO_IS_PRIVILEGE(_k) ? "Failed to connect to bus: Operation not permitted (consider using --machine=<user>@.host --user to connect to bus of other user)" : \
|
||||
"Failed to connect to bus: %m"); \
|
||||
})
|
||||
|
||||
#define bus_log_parse_error(r) \
|
||||
log_error_errno(r, "Failed to parse bus message: %m")
|
||||
|
@ -6,6 +6,14 @@
|
||||
#if HAVE_LIBCRYPTSETUP
|
||||
#include <libcryptsetup.h>
|
||||
|
||||
/* These next two are defined in libcryptsetup.h from cryptsetup version 2.3.4 forwards. */
|
||||
#ifndef CRYPT_ACTIVATE_NO_READ_WORKQUEUE
|
||||
#define CRYPT_ACTIVATE_NO_READ_WORKQUEUE (1 << 24)
|
||||
#endif
|
||||
#ifndef CRYPT_ACTIVATE_NO_WRITE_WORKQUEUE
|
||||
#define CRYPT_ACTIVATE_NO_WRITE_WORKQUEUE (1 << 25)
|
||||
#endif
|
||||
|
||||
extern int (*sym_crypt_activate_by_passphrase)(struct crypt_device *cd, const char *name, int keyslot, const char *passphrase, size_t passphrase_size, uint32_t flags);
|
||||
#if HAVE_CRYPT_ACTIVATE_BY_SIGNED_KEY
|
||||
extern int (*sym_crypt_activate_by_signed_key)(struct crypt_device *cd, const char *name, const char *volume_key, size_t volume_key_size, const char *signature, size_t signature_size, uint32_t flags);
|
||||
|
@ -2123,7 +2123,7 @@ int verity_settings_load(
|
||||
}
|
||||
}
|
||||
|
||||
if (verity->root_hash && !verity->root_hash_sig) {
|
||||
if ((root_hash || verity->root_hash) && !verity->root_hash_sig) {
|
||||
if (root_hash_sig_path) {
|
||||
r = read_full_file_full(AT_FDCWD, root_hash_sig_path, 0, NULL, (char**) &root_hash_sig, &root_hash_sig_size);
|
||||
if (r < 0 && r != -ENOENT)
|
||||
|
@ -1277,7 +1277,7 @@ int dns_name_apply_idna(const char *name, char **ret) {
|
||||
int r;
|
||||
|
||||
r = dlopen_idn();
|
||||
if (r == EOPNOTSUPP) {
|
||||
if (r == -EOPNOTSUPP) {
|
||||
*ret = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
@ -334,6 +334,16 @@ int journal_importer_process_data(JournalImporter *imp) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
} else {
|
||||
if (!journal_field_valid(line, n - 1, true)) {
|
||||
char buf[64], *t;
|
||||
|
||||
t = strndupa(line, n - 1);
|
||||
log_debug("Ignoring invalid field: \"%s\"",
|
||||
cellescape(buf, sizeof buf, t));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* replace \n with = */
|
||||
line[n-1] = '=';
|
||||
|
||||
|
@ -137,41 +137,3 @@ int journal_access_check_and_warn(sd_journal *j, bool quiet, bool want_other_use
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
bool journal_field_valid(const char *p, size_t l, bool allow_protected) {
|
||||
const char *a;
|
||||
|
||||
/* We kinda enforce POSIX syntax recommendations for
|
||||
environment variables here, but make a couple of additional
|
||||
requirements.
|
||||
|
||||
http://pubs.opengroup.org/onlinepubs/000095399/basedefs/xbd_chap08.html */
|
||||
|
||||
if (l == (size_t) -1)
|
||||
l = strlen(p);
|
||||
|
||||
/* No empty field names */
|
||||
if (l <= 0)
|
||||
return false;
|
||||
|
||||
/* Don't allow names longer than 64 chars */
|
||||
if (l > 64)
|
||||
return false;
|
||||
|
||||
/* Variables starting with an underscore are protected */
|
||||
if (!allow_protected && p[0] == '_')
|
||||
return false;
|
||||
|
||||
/* Don't allow digits as first character */
|
||||
if (p[0] >= '0' && p[0] <= '9')
|
||||
return false;
|
||||
|
||||
/* Only allow A-Z0-9 and '_' */
|
||||
for (a = p; a < p + l; a++)
|
||||
if ((*a < 'A' || *a > 'Z') &&
|
||||
(*a < '0' || *a > '9') &&
|
||||
*a != '_')
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -6,6 +6,5 @@
|
||||
|
||||
#include "sd-journal.h"
|
||||
|
||||
bool journal_field_valid(const char *p, size_t l, bool allow_protected);
|
||||
int journal_access_blocked(sd_journal *j);
|
||||
int journal_access_check_and_warn(sd_journal *j, bool quiet, bool want_other_users);
|
||||
|
@ -702,9 +702,11 @@ static int output_verbose(
|
||||
|
||||
c = memchr(data, '=', length);
|
||||
if (!c)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||
"Invalid field.");
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Invalid field.");
|
||||
|
||||
fieldlen = c - (const char*) data;
|
||||
if (!journal_field_valid(data, fieldlen, true))
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Invalid field.");
|
||||
|
||||
r = field_set_test(output_fields, data, fieldlen);
|
||||
if (r < 0)
|
||||
@ -798,6 +800,7 @@ static int output_export(
|
||||
sd_id128_to_string(boot_id, sid));
|
||||
|
||||
JOURNAL_FOREACH_DATA_RETVAL(j, data, length, r) {
|
||||
size_t fieldlen;
|
||||
const char *c;
|
||||
|
||||
/* We already printed the boot id from the data in the header, hence let's suppress it here */
|
||||
@ -806,10 +809,13 @@ static int output_export(
|
||||
|
||||
c = memchr(data, '=', length);
|
||||
if (!c)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||
"Invalid field.");
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Invalid field.");
|
||||
|
||||
r = field_set_test(output_fields, data, c - (const char *) data);
|
||||
fieldlen = c - (const char*) data;
|
||||
if (!journal_field_valid(data, fieldlen, true))
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Invalid field.");
|
||||
|
||||
r = field_set_test(output_fields, data, fieldlen);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (!r)
|
||||
@ -820,11 +826,11 @@ static int output_export(
|
||||
else {
|
||||
uint64_t le64;
|
||||
|
||||
fwrite(data, c - (const char*) data, 1, f);
|
||||
fwrite(data, fieldlen, 1, f);
|
||||
fputc('\n', f);
|
||||
le64 = htole64(length - (c - (const char*) data) - 1);
|
||||
le64 = htole64(length - fieldlen - 1);
|
||||
fwrite(&le64, sizeof(le64), 1, f);
|
||||
fwrite(c + 1, length - (c - (const char*) data) - 1, 1, f);
|
||||
fwrite(c + 1, length - fieldlen - 1, 1, f);
|
||||
}
|
||||
|
||||
fputc('\n', f);
|
||||
@ -961,6 +967,7 @@ static int update_json_data_split(
|
||||
const void *data,
|
||||
size_t size) {
|
||||
|
||||
size_t fieldlen;
|
||||
const char *eq;
|
||||
char *name;
|
||||
|
||||
@ -974,14 +981,15 @@ static int update_json_data_split(
|
||||
if (!eq)
|
||||
return 0;
|
||||
|
||||
if (eq == data)
|
||||
return 0;
|
||||
fieldlen = eq - (const char*) data;
|
||||
if (!journal_field_valid(data, fieldlen, true))
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Invalid field.");
|
||||
|
||||
name = strndupa(data, eq - (const char*) data);
|
||||
name = strndupa(data, fieldlen);
|
||||
if (output_fields && !set_contains(output_fields, name))
|
||||
return 0;
|
||||
|
||||
return update_json_data(h, flags, name, eq + 1, size - (eq - (const char*) data) - 1);
|
||||
return update_json_data(h, flags, name, eq + 1, size - fieldlen - 1);
|
||||
}
|
||||
|
||||
static int output_json(
|
||||
|
@ -1,12 +1,6 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include <net/ethernet.h>
|
||||
#include <linux/nl80211.h>
|
||||
|
||||
#include "sd-bus.h"
|
||||
|
||||
#include "log.h"
|
||||
#include "netlink-util.h"
|
||||
#include "wifi-util.h"
|
||||
|
||||
int wifi_get_interface(sd_netlink *genl, int ifindex, enum nl80211_iftype *iftype, char **ssid) {
|
||||
@ -35,8 +29,10 @@ int wifi_get_interface(sd_netlink *genl, int ifindex, enum nl80211_iftype *iftyp
|
||||
}
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "Failed to request information about wifi interface %d: %m", ifindex);
|
||||
if (!reply)
|
||||
if (!reply) {
|
||||
log_debug_errno(r, "No reply received to request for information about wifi interface %d, ignoring.", ifindex);
|
||||
goto nodata;
|
||||
}
|
||||
|
||||
r = sd_netlink_message_get_errno(reply);
|
||||
if (r < 0)
|
||||
@ -62,8 +58,8 @@ int wifi_get_interface(sd_netlink *genl, int ifindex, enum nl80211_iftype *iftyp
|
||||
if (ssid) {
|
||||
r = sd_netlink_message_read_string_strdup(reply, NL80211_ATTR_SSID, ssid);
|
||||
if (r == -ENODATA)
|
||||
goto nodata;
|
||||
if (r < 0)
|
||||
*ssid = NULL;
|
||||
else if (r < 0)
|
||||
return log_debug_errno(r, "Failed to get NL80211_ATTR_SSID attribute: %m");
|
||||
}
|
||||
|
||||
@ -101,8 +97,10 @@ int wifi_get_station(sd_netlink *genl, int ifindex, struct ether_addr *bssid) {
|
||||
r = sd_netlink_call(genl, m, 0, &reply);
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "Failed to request information about wifi station: %m");
|
||||
if (!reply)
|
||||
if (!reply) {
|
||||
log_debug_errno(r, "No reply received to request for information about wifi station, ignoring.");
|
||||
goto nodata;
|
||||
}
|
||||
|
||||
r = sd_netlink_message_get_errno(reply);
|
||||
if (r < 0)
|
||||
|
@ -3,8 +3,9 @@
|
||||
#pragma once
|
||||
|
||||
#include <linux/nl80211.h>
|
||||
#include <net/ethernet.h>
|
||||
|
||||
#include "netlink-util.h"
|
||||
#include "sd-netlink.h"
|
||||
|
||||
int wifi_get_interface(sd_netlink *genl, int ifindex, enum nl80211_iftype *iftype, char **ssid);
|
||||
int wifi_get_station(sd_netlink *genl, int ifindex, struct ether_addr *bssid);
|
||||
|
@ -398,16 +398,14 @@ static int find_paths_to_edit(sd_bus *bus, char **names, char ***paths) {
|
||||
/* If loading of the unit failed server side complete, then the server won't tell us
|
||||
* the unit file path. In that case, find the file client side. */
|
||||
log_debug_errno(r, "Unit '%s' was not loaded correctly, retrying client-side.", *name);
|
||||
r = unit_find_paths(bus, *name, &lp, true, &cached_name_map, &cached_id_map, &path, NULL);
|
||||
r = unit_find_paths(bus, *name, &lp, true, &cached_name_map, &cached_id_map, &path, &unit_paths);
|
||||
}
|
||||
if (r == -ERFKILL)
|
||||
return log_error_errno(r, "Unit '%s' masked, cannot edit.", *name);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (r == 0) {
|
||||
assert(!path);
|
||||
|
||||
if (!path) {
|
||||
if (!arg_force) {
|
||||
log_info("Run 'systemctl edit%s --force --full %s' to create a new unit.",
|
||||
arg_scope == UNIT_FILE_GLOBAL ? " --global" :
|
||||
@ -422,8 +420,6 @@ static int find_paths_to_edit(sd_bus *bus, char **names, char ***paths) {
|
||||
arg_full ? NULL : ".d/override.conf",
|
||||
NULL, &new_path, &tmp_path);
|
||||
} else {
|
||||
assert(path);
|
||||
|
||||
unit_name = basename(path);
|
||||
/* We follow unit aliases, but we need to propagate the instance */
|
||||
if (unit_name_is_valid(*name, UNIT_NAME_INSTANCE) &&
|
||||
|
@ -120,7 +120,7 @@ int unit_is_enabled(int argc, char *argv[], void *userdata) {
|
||||
if (r < 0)
|
||||
return bus_log_parse_error(r);
|
||||
|
||||
if (STR_IN_SET(s, "enabled", "enabled-runtime", "static", "indirect", "generated"))
|
||||
if (STR_IN_SET(s, "enabled", "enabled-runtime", "static", "alias", "indirect", "generated"))
|
||||
enabled = true;
|
||||
|
||||
if (!arg_quiet) {
|
||||
|
@ -127,6 +127,12 @@ int import_environment(int argc, char *argv[], void *userdata) {
|
||||
|
||||
strv_env_clean_with_callback(copy, invalid_callback, NULL);
|
||||
|
||||
char **e;
|
||||
STRV_FOREACH(e, copy)
|
||||
if (string_has_cc(*e, NULL))
|
||||
log_notice("Environment variable $%.*s contains control characters, importing anyway.",
|
||||
(int) strcspn(*e, "="), *e);
|
||||
|
||||
r = sd_bus_message_append_strv(m, copy);
|
||||
|
||||
} else {
|
||||
@ -139,21 +145,30 @@ int import_environment(int argc, char *argv[], void *userdata) {
|
||||
STRV_FOREACH(a, strv_skip(argv, 1)) {
|
||||
|
||||
if (!env_name_is_valid(*a))
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Not a valid environment variable name: %s", *a);
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||
"Not a valid environment variable name: %s", *a);
|
||||
|
||||
bool found = false;
|
||||
STRV_FOREACH(b, environ) {
|
||||
const char *eq;
|
||||
|
||||
eq = startswith(*b, *a);
|
||||
if (eq && *eq == '=') {
|
||||
if (string_has_cc(eq + 1, NULL))
|
||||
log_notice("Environment variable $%.*s contains control characters, importing anyway.",
|
||||
(int) (eq - *b), *b);
|
||||
|
||||
r = sd_bus_message_append(m, "s", *b);
|
||||
if (r < 0)
|
||||
return bus_log_create_error(r);
|
||||
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
log_notice("Environment variable $%s not set, ignoring.", *a);
|
||||
}
|
||||
|
||||
r = sd_bus_message_close_container(m);
|
||||
|
@ -16,7 +16,7 @@
|
||||
#include "hexdecoct.h"
|
||||
#include "hostname-util.h"
|
||||
#include "in-addr-util.h"
|
||||
#include "journal-util.h"
|
||||
#include "journal-file.h"
|
||||
#include "list.h"
|
||||
#include "locale-util.h"
|
||||
#include "memory-util.h"
|
||||
|
@ -179,7 +179,7 @@ int sd_dhcp_client_set_mud_url(
|
||||
const char *mudurl);
|
||||
int sd_dhcp_client_set_user_class(
|
||||
sd_dhcp_client *client,
|
||||
const char* const *user_class);
|
||||
char * const *user_class);
|
||||
int sd_dhcp_client_get_lease(
|
||||
sd_dhcp_client *client,
|
||||
sd_dhcp_lease **ret);
|
||||
|
@ -133,10 +133,10 @@ int sd_dhcp6_client_set_request_mud_url(
|
||||
const char *mudurl);
|
||||
int sd_dhcp6_client_set_request_user_class(
|
||||
sd_dhcp6_client *client,
|
||||
char** user_class);
|
||||
char * const *user_class);
|
||||
int sd_dhcp6_client_set_request_vendor_class(
|
||||
sd_dhcp6_client *client,
|
||||
char** vendor_class);
|
||||
char * const *vendor_class);
|
||||
int sd_dhcp6_client_set_prefix_delegation_hint(
|
||||
sd_dhcp6_client *client,
|
||||
uint8_t prefixlen,
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "hashmap.h"
|
||||
#include "main-func.h"
|
||||
#include "mount-util.h"
|
||||
#include "nscd-flush.h"
|
||||
#include "pager.h"
|
||||
#include "path-util.h"
|
||||
#include "pretty-print.h"
|
||||
@ -798,6 +799,9 @@ static int write_files(void) {
|
||||
return r;
|
||||
|
||||
group_tmp = mfree(group_tmp);
|
||||
|
||||
if (!arg_root && !arg_image)
|
||||
(void) nscd_flush_cache(STRV_MAKE("group"));
|
||||
}
|
||||
if (gshadow) {
|
||||
r = rename_and_apply_smack_floor_label(gshadow_tmp, gshadow_path);
|
||||
@ -813,6 +817,9 @@ static int write_files(void) {
|
||||
return r;
|
||||
|
||||
passwd_tmp = mfree(passwd_tmp);
|
||||
|
||||
if (!arg_root && !arg_image)
|
||||
(void) nscd_flush_cache(STRV_MAKE("passwd"));
|
||||
}
|
||||
if (shadow) {
|
||||
r = rename_and_apply_smack_floor_label(shadow_tmp, shadow_path);
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "bpf-program.h"
|
||||
#include "load-fragment.h"
|
||||
#include "manager.h"
|
||||
#include "memory-util.h"
|
||||
#include "rm-rf.h"
|
||||
#include "service.h"
|
||||
#include "tests.h"
|
||||
@ -77,11 +78,10 @@ int main(int argc, char *argv[]) {
|
||||
assert(r >= 0);
|
||||
|
||||
if (test_custom_filter) {
|
||||
attr = (union bpf_attr) {
|
||||
.pathname = PTR_TO_UINT64(test_prog),
|
||||
.bpf_fd = p->kernel_fd,
|
||||
.file_flags = 0,
|
||||
};
|
||||
zero(attr);
|
||||
attr.pathname = PTR_TO_UINT64(test_prog);
|
||||
attr.bpf_fd = p->kernel_fd;
|
||||
attr.file_flags = 0;
|
||||
|
||||
(void) unlink(test_prog);
|
||||
|
||||
|
@ -265,6 +265,7 @@ static void test_env_clean(void) {
|
||||
"another=one",
|
||||
"another=final one",
|
||||
"CRLF=\r\n",
|
||||
"LESS_TERMCAP_mb=\x1b[01;31m",
|
||||
"BASH_FUNC_foo%%=() { echo foo\n}");
|
||||
assert_se(e);
|
||||
assert_se(!strv_env_is_valid(e));
|
||||
@ -277,7 +278,9 @@ static void test_env_clean(void) {
|
||||
assert_se(streq(e[3], "abcd=äöüß"));
|
||||
assert_se(streq(e[4], "xyz=xyz\n"));
|
||||
assert_se(streq(e[5], "another=final one"));
|
||||
assert_se(e[6] == NULL);
|
||||
assert_se(streq(e[6], "CRLF=\r\n"));
|
||||
assert_se(streq(e[7], "LESS_TERMCAP_mb=\x1b[01;31m"));
|
||||
assert_se(e[8] == NULL);
|
||||
}
|
||||
|
||||
static void test_env_name_is_valid(void) {
|
||||
@ -302,8 +305,11 @@ static void test_env_value_is_valid(void) {
|
||||
assert_se(env_value_is_valid("printf \"\\x1b]0;<mock-chroot>\\x07<mock-chroot>\""));
|
||||
assert_se(env_value_is_valid("tab\tcharacter"));
|
||||
assert_se(env_value_is_valid("new\nline"));
|
||||
assert_se(!env_value_is_valid("Show this?\rNope. Show that!"));
|
||||
assert_se(!env_value_is_valid("new DOS\r\nline"));
|
||||
assert_se(env_value_is_valid("Show this?\rNope. Show that!"));
|
||||
assert_se(env_value_is_valid("new DOS\r\nline"));
|
||||
|
||||
assert_se(!env_value_is_valid("\xc5")); /* A truncated utf-8-encoded "ł".
|
||||
* We currently disallow that. */
|
||||
}
|
||||
|
||||
static void test_env_assignment_is_valid(void) {
|
||||
|
@ -256,6 +256,37 @@ static void test_path_is_mount_point(void) {
|
||||
assert_se(rm_rf(tmp_dir, REMOVE_ROOT|REMOVE_PHYSICAL) == 0);
|
||||
}
|
||||
|
||||
static void test_fd_is_mount_point(void) {
|
||||
_cleanup_close_ int fd = -1;
|
||||
|
||||
log_info("/* %s */", __func__);
|
||||
|
||||
fd = open("/", O_RDONLY|O_CLOEXEC|O_DIRECTORY|O_NOCTTY);
|
||||
assert_se(fd >= 0);
|
||||
|
||||
/* Not allowed, since "/" is a path, not a plain filename */
|
||||
assert_se(fd_is_mount_point(fd, "/", 0) == -EINVAL);
|
||||
assert_se(fd_is_mount_point(fd, ".", 0) == -EINVAL);
|
||||
assert_se(fd_is_mount_point(fd, "./", 0) == -EINVAL);
|
||||
assert_se(fd_is_mount_point(fd, "..", 0) == -EINVAL);
|
||||
assert_se(fd_is_mount_point(fd, "../", 0) == -EINVAL);
|
||||
assert_se(fd_is_mount_point(fd, "", 0) == -EINVAL);
|
||||
assert_se(fd_is_mount_point(fd, "/proc", 0) == -EINVAL);
|
||||
assert_se(fd_is_mount_point(fd, "/proc/", 0) == -EINVAL);
|
||||
assert_se(fd_is_mount_point(fd, "proc/sys", 0) == -EINVAL);
|
||||
assert_se(fd_is_mount_point(fd, "proc/sys/", 0) == -EINVAL);
|
||||
|
||||
/* This one definitely is a mount point */
|
||||
assert_se(fd_is_mount_point(fd, "proc", 0) > 0);
|
||||
assert_se(fd_is_mount_point(fd, "proc/", 0) > 0);
|
||||
|
||||
/* /root's entire raison d'etre is to be on the root file system (i.e. not in /home/ which might be
|
||||
* split off), so that the user can always log in, so it cannot be a mount point unless the system is
|
||||
* borked. Let's allow for it to be missing though. */
|
||||
assert_se(IN_SET(fd_is_mount_point(fd, "root", 0), -ENOENT, 0));
|
||||
assert_se(IN_SET(fd_is_mount_point(fd, "root/", 0), -ENOENT, 0));
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
test_setup_logging(LOG_DEBUG);
|
||||
|
||||
@ -279,6 +310,7 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
test_mnt_id();
|
||||
test_path_is_mount_point();
|
||||
test_fd_is_mount_point();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -6,7 +6,6 @@
|
||||
#include "alloc-util.h"
|
||||
#include "fd-util.h"
|
||||
#include "macro.h"
|
||||
#include "mountpoint-util.h"
|
||||
#include "path-util.h"
|
||||
#include "rm-rf.h"
|
||||
#include "stat-util.h"
|
||||
@ -40,8 +39,6 @@ static void test_path_simplify(const char *in, const char *out, const char *out_
|
||||
}
|
||||
|
||||
static void test_path(void) {
|
||||
_cleanup_close_ int fd = -1;
|
||||
|
||||
log_info("/* %s */", __func__);
|
||||
|
||||
test_path_compare("/goo", "/goo", 0);
|
||||
@ -80,10 +77,6 @@ static void test_path(void) {
|
||||
assert_se(streq(basename("/aa///file..."), "file..."));
|
||||
assert_se(streq(basename("file.../"), ""));
|
||||
|
||||
fd = open("/", O_RDONLY|O_CLOEXEC|O_DIRECTORY|O_NOCTTY);
|
||||
assert_se(fd >= 0);
|
||||
assert_se(fd_is_mount_point(fd, "/", 0) > 0);
|
||||
|
||||
test_path_simplify("aaa/bbb////ccc", "aaa/bbb/ccc", "aaa/bbb/ccc");
|
||||
test_path_simplify("//aaa/.////ccc", "/aaa/./ccc", "/aaa/ccc");
|
||||
test_path_simplify("///", "/", "/");
|
||||
|
@ -150,6 +150,83 @@ static void test_set_ensure_consume(void) {
|
||||
assert_se(set_size(m) == 2);
|
||||
}
|
||||
|
||||
static void test_set_strjoin(void) {
|
||||
_cleanup_set_free_ Set *m = NULL;
|
||||
_cleanup_free_ char *joined = NULL;
|
||||
|
||||
/* Empty set */
|
||||
assert_se(set_strjoin(m, NULL, false, &joined) >= 0);
|
||||
assert_se(!joined);
|
||||
assert_se(set_strjoin(m, "", false, &joined) >= 0);
|
||||
assert_se(!joined);
|
||||
assert_se(set_strjoin(m, " ", false, &joined) >= 0);
|
||||
assert_se(!joined);
|
||||
assert_se(set_strjoin(m, "xxx", false, &joined) >= 0);
|
||||
assert_se(!joined);
|
||||
assert_se(set_strjoin(m, NULL, true, &joined) >= 0);
|
||||
assert_se(!joined);
|
||||
assert_se(set_strjoin(m, "", true, &joined) >= 0);
|
||||
assert_se(!joined);
|
||||
assert_se(set_strjoin(m, " ", true, &joined) >= 0);
|
||||
assert_se(!joined);
|
||||
assert_se(set_strjoin(m, "xxx", true, &joined) >= 0);
|
||||
assert_se(!joined);
|
||||
|
||||
/* Single entry */
|
||||
assert_se(set_put_strdup(&m, "aaa") == 1);
|
||||
assert_se(set_strjoin(m, NULL, false, &joined) >= 0);
|
||||
assert_se(streq(joined, "aaa"));
|
||||
joined = mfree(joined);
|
||||
assert_se(set_strjoin(m, "", false, &joined) >= 0);
|
||||
assert_se(streq(joined, "aaa"));
|
||||
joined = mfree(joined);
|
||||
assert_se(set_strjoin(m, " ", false, &joined) >= 0);
|
||||
assert_se(streq(joined, "aaa"));
|
||||
joined = mfree(joined);
|
||||
assert_se(set_strjoin(m, "xxx", false, &joined) >= 0);
|
||||
assert_se(streq(joined, "aaa"));
|
||||
joined = mfree(joined);
|
||||
assert_se(set_strjoin(m, NULL, true, &joined) >= 0);
|
||||
assert_se(streq(joined, "aaa"));
|
||||
joined = mfree(joined);
|
||||
assert_se(set_strjoin(m, "", true, &joined) >= 0);
|
||||
assert_se(streq(joined, "aaa"));
|
||||
joined = mfree(joined);
|
||||
assert_se(set_strjoin(m, " ", true, &joined) >= 0);
|
||||
assert_se(streq(joined, " aaa "));
|
||||
joined = mfree(joined);
|
||||
assert_se(set_strjoin(m, "xxx", true, &joined) >= 0);
|
||||
assert_se(streq(joined, "xxxaaaxxx"));
|
||||
|
||||
/* Two entries */
|
||||
assert_se(set_put_strdup(&m, "bbb") == 1);
|
||||
assert_se(set_put_strdup(&m, "aaa") == 0);
|
||||
joined = mfree(joined);
|
||||
assert_se(set_strjoin(m, NULL, false, &joined) >= 0);
|
||||
assert_se(STR_IN_SET(joined, "aaabbb", "bbbaaa"));
|
||||
joined = mfree(joined);
|
||||
assert_se(set_strjoin(m, "", false, &joined) >= 0);
|
||||
assert_se(STR_IN_SET(joined, "aaabbb", "bbbaaa"));
|
||||
joined = mfree(joined);
|
||||
assert_se(set_strjoin(m, " ", false, &joined) >= 0);
|
||||
assert_se(STR_IN_SET(joined, "aaa bbb", "bbb aaa"));
|
||||
joined = mfree(joined);
|
||||
assert_se(set_strjoin(m, "xxx", false, &joined) >= 0);
|
||||
assert_se(STR_IN_SET(joined, "aaaxxxbbb", "bbbxxxaaa"));
|
||||
joined = mfree(joined);
|
||||
assert_se(set_strjoin(m, NULL, true, &joined) >= 0);
|
||||
assert_se(STR_IN_SET(joined, "aaabbb", "bbbaaa"));
|
||||
joined = mfree(joined);
|
||||
assert_se(set_strjoin(m, "", true, &joined) >= 0);
|
||||
assert_se(STR_IN_SET(joined, "aaabbb", "bbbaaa"));
|
||||
joined = mfree(joined);
|
||||
assert_se(set_strjoin(m, " ", true, &joined) >= 0);
|
||||
assert_se(STR_IN_SET(joined, " aaa bbb ", " bbb aaa "));
|
||||
joined = mfree(joined);
|
||||
assert_se(set_strjoin(m, "xxx", true, &joined) >= 0);
|
||||
assert_se(STR_IN_SET(joined, "xxxaaaxxxbbbxxx", "xxxbbbxxxaaaxxx"));
|
||||
}
|
||||
|
||||
int main(int argc, const char *argv[]) {
|
||||
test_set_steal_first();
|
||||
test_set_free_with_destructor();
|
||||
@ -160,6 +237,7 @@ int main(int argc, const char *argv[]) {
|
||||
test_set_ensure_allocated();
|
||||
test_set_ensure_put();
|
||||
test_set_ensure_consume();
|
||||
test_set_strjoin();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ static void test_fgetxattrat_fake(void) {
|
||||
assert_se(touch(x) >= 0);
|
||||
|
||||
r = setxattr(x, "user.foo", "bar", 3, 0);
|
||||
if (r < 0 && errno == EOPNOTSUPP) /* no xattrs supported on /var/tmp... */
|
||||
if (r < 0 && ERRNO_IS_NOT_SUPPORTED(errno)) /* no xattrs supported on /var/tmp... */
|
||||
goto cleanup;
|
||||
assert_se(r >= 0);
|
||||
|
||||
@ -42,7 +42,8 @@ static void test_fgetxattrat_fake(void) {
|
||||
safe_close(fd);
|
||||
fd = open("/", O_RDONLY|O_DIRECTORY|O_CLOEXEC|O_NOCTTY);
|
||||
assert_se(fd >= 0);
|
||||
assert_se(fgetxattrat_fake(fd, "usr", "user.idontexist", v, 3, 0, &size) == -ENODATA);
|
||||
r = fgetxattrat_fake(fd, "usr", "user.idontexist", v, 3, 0, &size);
|
||||
assert_se(r == -ENODATA || ERRNO_IS_NOT_SUPPORTED(r));
|
||||
|
||||
cleanup:
|
||||
assert_se(unlink(x) >= 0);
|
||||
|
@ -771,7 +771,7 @@ static int method_set_local_rtc(sd_bus_message *m, void *userdata, sd_bus_error
|
||||
log_debug_errno(r, "Failed to get hardware clock, ignoring: %m");
|
||||
else {
|
||||
/* And set the system clock with this */
|
||||
mktime_or_timegm(&tm, !c->local_rtc);
|
||||
ts.tv_sec = mktime_or_timegm(&tm, !c->local_rtc);
|
||||
|
||||
if (clock_settime(CLOCK_REALTIME, &ts) < 0)
|
||||
log_debug_errno(errno, "Failed to update system clock, ignoring: %m");
|
||||
|
@ -194,7 +194,7 @@ static int link_find_prioritized(sd_device *dev, bool add, const char *stackdir,
|
||||
|
||||
/* manage "stack of names" with possibly specified device priorities */
|
||||
static int link_update(sd_device *dev, const char *slink, bool add) {
|
||||
_cleanup_free_ char *target = NULL, *filename = NULL, *dirname = NULL;
|
||||
_cleanup_free_ char *filename = NULL, *dirname = NULL;
|
||||
char name_enc[PATH_MAX];
|
||||
const char *id_filename;
|
||||
int i, r, retries;
|
||||
@ -237,6 +237,7 @@ static int link_update(sd_device *dev, const char *slink, bool add) {
|
||||
retries = sd_device_get_is_initialized(dev) > 0 ? LINK_UPDATE_MAX_RETRIES : 1;
|
||||
|
||||
for (i = 0; i < retries; i++) {
|
||||
_cleanup_free_ char *target = NULL;
|
||||
struct stat st1 = {}, st2 = {};
|
||||
|
||||
r = stat(dirname, &st1);
|
||||
|
@ -3,7 +3,11 @@ set -e
|
||||
|
||||
TEST_DESCRIPTION="test MUMAPolicy= and NUMAMask= options"
|
||||
TEST_NO_NSPAWN=1
|
||||
QEMU_OPTIONS="-numa node,nodeid=0"
|
||||
. $TEST_BASE_DIR/test-functions
|
||||
if qemu_min_version "5.2.0"; then
|
||||
QEMU_OPTIONS="-object memory-backend-ram,id=mem0,size=512M -numa node,memdev=mem0,nodeid=0"
|
||||
else
|
||||
QEMU_OPTIONS="-numa node,nodeid=0"
|
||||
fi
|
||||
|
||||
do_test "$@" 36
|
||||
|
BIN
test/fuzz/fuzz-journal-remote/oss-fuzz-25353
Normal file
BIN
test/fuzz/fuzz-journal-remote/oss-fuzz-25353
Normal file
Binary file not shown.
BIN
test/fuzz/fuzz-journal-remote/oss-fuzz-28817
Normal file
BIN
test/fuzz/fuzz-journal-remote/oss-fuzz-28817
Normal file
Binary file not shown.
@ -227,6 +227,24 @@ function find_qemu_bin() {
|
||||
fi
|
||||
}
|
||||
|
||||
# Compares argument #1=X.Y.Z (X&Y&Z = numeric) to the version of the installed qemu
|
||||
# returns 0 if newer or equal
|
||||
# returns 1 if older
|
||||
# returns 2 if failing
|
||||
function qemu_min_version() {
|
||||
find_qemu_bin || return 2
|
||||
|
||||
# get version from binary
|
||||
qemu_ver=$($QEMU_BIN --version | awk '/^QEMU emulator version ([0-9]*\.[0-9]*\.[0-9]*) / {print $4}')
|
||||
|
||||
# Check version string format
|
||||
echo "$qemu_ver" | grep -q '^[0-9]*\.[0-9]*\.[0-9]*$' || return 2
|
||||
echo "$1" | grep -q '^[0-9]*\.[0-9]*\.[0-9]*$' || return 2
|
||||
|
||||
# compare as last command to return that value
|
||||
printf "%s\n%s\n" "$1" "$qemu_ver" | sort -V -C
|
||||
}
|
||||
|
||||
# Return 0 if QEMU did run (then you must check the result state/logs for actual
|
||||
# success), or 1 if QEMU is not available.
|
||||
run_qemu() {
|
||||
|
@ -18,6 +18,11 @@ try:
|
||||
except ImportError as e:
|
||||
shlex_join = e
|
||||
|
||||
try:
|
||||
from shlex import quote as shlex_quote
|
||||
except ImportError as e:
|
||||
shlex_quote = e
|
||||
|
||||
class NoCommand(Exception):
|
||||
pass
|
||||
|
||||
@ -186,10 +191,13 @@ def subst_output(document, programlisting, stats):
|
||||
interface = programlisting.get('interface')
|
||||
|
||||
argv = [f'{opts.build_dir}/{executable}', f'--bus-introspect={interface}']
|
||||
print(f'COMMAND: {shlex_join(argv)}')
|
||||
if isinstance(shlex_join, Exception):
|
||||
print(f'COMMAND: {" ".join(shlex_quote(arg) for arg in argv)}')
|
||||
else:
|
||||
print(f'COMMAND: {shlex_join(argv)}')
|
||||
|
||||
try:
|
||||
out = subprocess.check_output(argv, text=True)
|
||||
out = subprocess.check_output(argv, universal_newlines=True)
|
||||
except FileNotFoundError:
|
||||
print(f'{executable} not found, ignoring', file=sys.stderr)
|
||||
return
|
||||
@ -296,7 +304,7 @@ def parse_args():
|
||||
if __name__ == '__main__':
|
||||
opts = parse_args()
|
||||
|
||||
for item in (etree, shlex_join):
|
||||
for item in (etree, shlex_quote):
|
||||
if isinstance(item, Exception):
|
||||
print(item, file=sys.stderr)
|
||||
exit(77 if opts.test else 1)
|
||||
@ -308,7 +316,7 @@ if __name__ == '__main__':
|
||||
|
||||
# Let's print all statistics at the end
|
||||
mlen = max(len(page) for page in stats)
|
||||
total = sum((item['stats'] for item in stats.values()), start=collections.Counter())
|
||||
total = sum((item['stats'] for item in stats.values()), collections.Counter())
|
||||
total = 'total', dict(stats=total, outdated=False)
|
||||
outdated = []
|
||||
for page, info in sorted(stats.items()) + [total]:
|
||||
|
Loading…
Reference in New Issue
Block a user